Skip to content

Instantly share code, notes, and snippets.

@cdrini
Last active May 28, 2024 09:30
Show Gist options
  • Select an option

  • Save cdrini/be0d7551c3c55b811f55a5592c710cd8 to your computer and use it in GitHub Desktop.

Select an option

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:

<form class="ol-searchbox">
    <input type="text" class="ol-searchbox__input" placeholder="$_('Search Open Library')">
    <button class="ol-searchbox__button" type="submit">
        <i class="ol-searchbox__icon"></i>
    </button>
</form>

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__button {
        ...
    }
}

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