diff options
Diffstat (limited to 'doc/development/fe_guide/droplab/droplab.md')
-rw-r--r-- | doc/development/fe_guide/droplab/droplab.md | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/doc/development/fe_guide/droplab/droplab.md b/doc/development/fe_guide/droplab/droplab.md new file mode 100644 index 00000000000..8f0b6b21953 --- /dev/null +++ b/doc/development/fe_guide/droplab/droplab.md @@ -0,0 +1,256 @@ +# DropLab + +A generic dropdown for all of your custom dropdown needs. + +## Usage + +DropLab can be used by simply adding a `data-dropdown-trigger` HTML attribute. +This attribute allows us to find the "trigger" _(toggle)_ for the dropdown, +whether that is a button, link or input. + +The value of the `data-dropdown-trigger` should be a CSS selector that +DropLab can use to find the trigger's dropdown list. + +You should also add the `data-dropdown` attribute to declare the dropdown list. +The value is irrelevant. + +The DropLab class has no side effects, so you must always call `.init` when +the DOM is ready. `DropLab.prototype.init` takes the same arguments as `DropLab.prototype.addHook`. +If you do not provide any arguments, it will globally query and instantiate all droplab compatible dropdowns. + +```html +<a href="#" data-dropdown-trigger="#list">Toggle</a> + +<ul id="list" data-dropdown> + <!-- ... --> +<ul> +``` +```js +const droplab = new DropLab(); +droplab.init(); +``` + +As you can see, we have a "Toggle" link, that is declared as a trigger. +It provides a selector to find the dropdown list it should control. + +### Static data + +You can add static list items. + +```html +<a href="#" data-dropdown-trigger="#list">Toggle</a> + +<ul id="list" data-dropdown> + <li>Static value 1</li> + <li>Static value 2</li> +<ul> +``` +```js +const droplab = new DropLab(); +droplab.init(); +``` + +### Explicit instantiation + +You can pass the trigger and list elements as constructor arguments to return +a non-global instance of DropLab using the `DropLab.prototype.init` method. + +```html +<a href="#" id="trigger" data-dropdown-trigger="#list">Toggle</a> + +<ul id="list" data-dropdown> + <!-- ... --> +<ul> +``` +```js +const trigger = document.getElementById('trigger'); +const list = document.getElementById('list'); + +const droplab = new DropLab(); +droplab.init(trigger, list); +``` + +You can also add hooks to an existing DropLab instance using `DropLab.prototype.addHook`. + +```html +<a href="#" data-dropdown-trigger="#auto-dropdown">Toggle</a> +<ul id="auto-dropdown" data-dropdown><!-- ... --><ul> + +<a href="#" id="trigger" data-dropdown-trigger="#list">Toggle</a> +<ul id="list" data-dropdown><!-- ... --><ul> +``` +```js +const droplab = new DropLab(); + +droplab.init(); + +const trigger = document.getElementById('trigger'); +const list = document.getElementById('list'); + +droplab.addHook(trigger, list); +``` + + +### Dynamic data + +Adding `data-dynamic` to your dropdown element will enable dynamic list rendering. + +You can template a list item using the keys of the data object provided. +Use the handlebars syntax `{{ value }}` to HTML escape the value. +Use the `<%= value %>` syntax to simply interpolate the value. +Use the `<%= value %>` syntax to evaluate the value. + +Passing an array of objects to `DropLab.prototype.addData` will render that data +for all `data-dynamic` dropdown lists tracked by that DropLab instance. + +```html +<a href="#" data-dropdown-trigger="#list">Toggle</a> + +<ul id="list" data-dropdown data-dynamic> + <li><a href="#" data-id="{{id}}">{{text}}</a></li> +</ul> +``` +```js +const droplab = new DropLab(); + +droplab.init().addData([{ + id: 0, + text: 'Jacob', +}, { + id: 1, + text: 'Jeff', +}]); +``` + +Alternatively, you can specify a specific dropdown to add this data to but passing +the data as the second argument and and the `id` of the trigger element as the first argument. + +```html +<a href="#" data-dropdown-trigger="#list" id="trigger">Toggle</a> + +<ul id="list" data-dropdown data-dynamic> + <li><a href="#" data-id="{{id}}">{{text}}</a></li> +</ul> +``` +```js +const droplab = new DropLab(); + +droplab.init().addData('trigger', [{ + id: 0, + text: 'Jacob', +}, { + id: 1, + text: 'Jeff', +}]); +``` + +This allows you to mix static and dynamic content with ease, even with one trigger. + +Note the use of scoping regarding the `data-dropdown` attribute to capture both +dropdown lists, one of which is dynamic. + +```html +<input id="trigger" data-dropdown-trigger="#list"> +<div id="list" data-dropdown> + <ul> + <li><a href="#">Static item 1</a></li> + <li><a href="#">Static item 2</a></li> + </ul> + <ul data-dynamic> + <li><a href="#" data-id="{{id}}">{{text}}</a></li> + </ul> +</div> +``` +```js +const droplab = new DropLab(); + +droplab.init().addData('trigger', [{ + id: 0, + text: 'Jacob', +}, { + id: 1, + text: 'Jeff', +}]); +``` + +## Internal selectors + +DropLab adds some CSS classes to help lower the barrier to integration. + +For example, + +* The `droplab-item-selected` css class is added to items that have been selected +either by a mouse click or by enter key selection. +* The `droplab-item-active` css class is added to items that have been selected +using arrow key navigation. + +## Internal events + +DropLab uses some custom events to help lower the barrier to integration. + +For example, + +* The `click.dl` event is fired when an `li` list item has been clicked. It is also +fired when a list item has been selected with the keyboard. It is also fired when a +`HookButton` button is clicked (a registered `button` tag or `a` tag trigger). +* The `input.dl` event is fired when a `HookInput` (a registered `input` tag trigger) triggers an `input` event. +* The `mousedown.dl` event is fired when a `HookInput` triggers a `mousedown` event. +* The `keyup.dl` event is fired when a `HookInput` triggers a `keyup` event. +* The `keydown.dl` event is fired when a `HookInput` triggers a `keydown` event. + +These custom events add a `detail` object to the vanilla `Event` object that provides some potentially useful data. + +## Plugins + +Plugins are objects that are registered to be executed when a hook is added (when a droplab trigger and dropdown are instantiated). + +If no modules API is detected, the library will fall back as it does with `window.DropLab` and will add `window.DropLab.plugins.PluginName`. + +### Usage + +To use plugins, you can pass them in an array as the third argument of `DropLab.prototype.init` or `DropLab.prototype.addHook`. +Some plugins require configuration values, the config object can be passed as the fourth argument. + +```html +<a href="#" id="trigger" data-dropdown-trigger="#list">Toggle</a> +<ul id="list" data-dropdown><!-- ... --><ul> +``` +```js +const droplab = new DropLab(); + +const trigger = document.getElementById('trigger'); +const list = document.getElementById('list'); + +droplab.init(trigger, list, [droplabAjax], { + droplabAjax: { + endpoint: '/some-endpoint', + method: 'setData', + }, +}); +``` + +### Documentation + +* [Ajax plugin](plugins/ajax.md) +* [Filter plugin](plugins/filter.md) +* [InputSetter plugin](plugins/input_setter.md) + +### Development + +When plugins are initialised for a droplab trigger+dropdown, DropLab will +call the plugins `init` function, so this must be implemented in the plugin. + +```js +class MyPlugin { + static init() { + this.someProp = 'someProp'; + this.someMethod(); + } + + static someMethod() { + this.otherProp = 'otherProp'; + } +} + +export default MyPlugin; +``` |