Skip to content

Instantly share code, notes, and snippets.

@cdrini
Last active May 28, 2024 09:30
Show Gist options
  • Save cdrini/be0d7551c3c55b811f55a5592c710cd8 to your computer and use it in GitHub Desktop.
Save cdrini/be0d7551c3c55b811f55a5592c710cd8 to your computer and use it in GitHub Desktop.
OL Component Docs Maybe

We have three types of components on Open Library:

  1. CSS Components: Components which only require a little bit of CSS. These could have a separate HTML template file in openlibrary/templates if it makes sense to have one, and will usually have a separate .less file in static/css/components. Note the .less file must then be imported from the corresponding page's .less file, E.g. static/css/page-user.less.
  2. JavaScript/JQuery components: These are components which require a small amount of functionality, or are legacy implementations. E.g. the multi-input-autocomplete. These will have a JS file in openlibrary/plugins/openlibrary/js, and an import line in openlibrary/plugins/openlibrary/js/index.js.
  3. Vue components: For new, more interactive components, we prefer to use Vue.js. These components will have a .vue file in openlibrary/components. For more info on Vue, read the README in that directory. E.g: LibraryExplorer.vue

All these components make use of BEM class notation to define the component parts, css, and selectors. Each component should also begin with ol-; this makes it easy for us to search for components in the codebase.

For example: The ol-searchbox component defines a search box with a search button icon on the right. We use this in various places throughout the site.

It has an html template file in openlibrary/templates/ol-searchbox.html:

$def with (q)

<div class="ol-searchbox">
    <input class="ol-searchbox__input" name="q" placeholder="$_('Search')" value="$q">
    <div>
        <input class="searchbox__btn-icon" type="submit" title="$_('Search')">
    </div>
</div>

And it has a less file in openlibrary/static/css/components/ol-searchbox.less:

.ol-searchbox {
    display: flex;
    align-items: center;
    .ol-searchbox__input {
        ...
    }
    .ol-searchbox__btn-icon {
        ...
    }
}

And an import in e.g. openlibrary/static/css/page-user.less:

@import "components/ol-searchbox.less";

If this component needed to have some JavaScript functionality, we would add a JS file in openlibrary/plugins/openlibrary/js/ol-searchbox.js:

export class OLSearchBox {
    constructor($container) {
        /** @type {JQuery} */
        this.$container = $container;
        this.$input = this.$container.find('.ol-searchbox__input');
    }

    static init() {
        $('.ol-searchbox').each((i, el) => {
            new OLSearchBox($(el));
        });
    }
}

and then to include it in the main JS file, we would add an import line in openlibrary/plugins/openlibrary/js/index.js:

if (document.querySelector('.ol-searchbox')) {
    import(/* webpackChunkName: "ol-searchbox" */ './ol-searchbox.js')
        .then((module) => module.OLSearchBox.init());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment