diff options
author | Clement Ho <clemmakesapps@gmail.com> | 2017-04-19 15:16:58 +0000 |
---|---|---|
committer | Clement Ho <clemmakesapps@gmail.com> | 2017-04-19 15:16:58 +0000 |
commit | a9446a279ad88169663cc4effb93c26426901a6a (patch) | |
tree | 46f99dba13e63b91f4bab82efebcb50451420755 | |
parent | 40a972057da58dd5c15cf0f0b2952f264dba0076 (diff) | |
parent | daf0592d256dfb84264c679b6ffa800d5bf9f366 (diff) | |
download | gitlab-ce-a9446a279ad88169663cc4effb93c26426901a6a.tar.gz |
Merge branch 'add-droplab-docs' into 'master'
Added and updated droplab docs
See merge request !10569
-rw-r--r-- | doc/development/fe_guide/droplab/droplab.md | 256 | ||||
-rw-r--r-- | doc/development/fe_guide/droplab/plugins/ajax.md | 37 | ||||
-rw-r--r-- | doc/development/fe_guide/droplab/plugins/filter.md | 45 | ||||
-rw-r--r-- | doc/development/fe_guide/droplab/plugins/input_setter.md | 60 | ||||
-rw-r--r-- | doc/development/fe_guide/index.md | 10 |
5 files changed, 408 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; +``` diff --git a/doc/development/fe_guide/droplab/plugins/ajax.md b/doc/development/fe_guide/droplab/plugins/ajax.md new file mode 100644 index 00000000000..9c7e56fa448 --- /dev/null +++ b/doc/development/fe_guide/droplab/plugins/ajax.md @@ -0,0 +1,37 @@ +# Ajax + +`Ajax` is a droplab plugin that allows for retrieving and rendering list data from a server. + +## Usage + +Add the `Ajax` object to the plugins array of a `DropLab.prototype.init` or `DropLab.prototype.addHook` call. + +`Ajax` requires 2 config values, the `endpoint` and `method`. + +* `endpoint` should be a URL to the request endpoint. +* `method` should be `setData` or `addData`. +* `setData` completely replaces the dropdown with the response data. +* `addData` appends the response data to the current dropdown list. + +```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.addHook(trigger, list, [Ajax], { + Ajax: { + endpoint: '/some-endpoint', + method: 'setData', + }, + }); +``` + +Optionally you can set `loadingTemplate` to a HTML string. This HTML string will +replace the dropdown list whilst the request is pending. + +Additionally, you can set `onError` to a function to catch any XHR errors. diff --git a/doc/development/fe_guide/droplab/plugins/filter.md b/doc/development/fe_guide/droplab/plugins/filter.md new file mode 100644 index 00000000000..0853ea4d320 --- /dev/null +++ b/doc/development/fe_guide/droplab/plugins/filter.md @@ -0,0 +1,45 @@ +# Filter + +`Filter` is a plugin that allows for filtering data that has been added +to the dropdown using a simple fuzzy string search of an input value. + +## Usage + +Add the `Filter` object to the plugins array of a `DropLab.prototype.init` or `DropLab.prototype.addHook` call. + +* `Filter` requires a config value for `template`. +* `template` should be the key of the objects within your data array that you want to compare +to the user input string, for filtering. + +```html +<input href="#" id="trigger" data-dropdown-trigger="#list"> +<ul id="list" data-dropdown data-dynamic> + <li><a href="#" data-id="{{id}}">{{text}}</a></li> +<ul> +``` +```js + const droplab = new DropLab(); + + const trigger = document.getElementById('trigger'); + const list = document.getElementById('list'); + + droplab.init(trigger, list, [Filter], { + Filter: { + template: 'text', + }, + }); + + droplab.addData('trigger', [{ + id: 0, + text: 'Jacob', + }, { + id: 1, + text: 'Jeff', + }]); +``` + +Above, the input string will be compared against the `test` key of the passed data objects. + +Optionally you can set `filterFunction` to a function. This function will be used instead +of `Filter`'s built in string search. `filterFunction` is passed 2 arguments, the first +is one of the data objects, the second is the current input value. diff --git a/doc/development/fe_guide/droplab/plugins/input_setter.md b/doc/development/fe_guide/droplab/plugins/input_setter.md new file mode 100644 index 00000000000..a549603c20d --- /dev/null +++ b/doc/development/fe_guide/droplab/plugins/input_setter.md @@ -0,0 +1,60 @@ +# InputSetter + +`InputSetter` is a plugin that allows for udating DOM out of the scope of droplab when a list item is clicked. + +## Usage + +Add the `InputSetter` object to the plugins array of a `DropLab.prototype.init` or `DropLab.prototype.addHook` call. + +* `InputSetter` requires a config value for `input` and `valueAttribute`. +* `input` should be the DOM element that you want to manipulate. +* `valueAttribute` should be a string that is the name of an attribute on your list items that is used to get the value +to update the `input` element with. + +You can also set the `InputSetter` config to an array of objects, which will allow you to update multiple elements. + + +```html +<input id="input" value=""> +<div id="div" data-selected-id=""></div> + +<input href="#" id="trigger" data-dropdown-trigger="#list"> +<ul id="list" data-dropdown data-dynamic> + <li><a href="#" data-id="{{id}}">{{text}}</a></li> +<ul> +``` +```js + const droplab = new DropLab(); + + const trigger = document.getElementById('trigger'); + const list = document.getElementById('list'); + + const input = document.getElementById('input'); + const div = document.getElementById('div'); + + droplab.init(trigger, list, [InputSetter], { + InputSetter: [{ + input: input, + valueAttribute: 'data-id', + } { + input: div, + valueAttribute: 'data-id', + inputAttribute: 'data-selected-id', + }], + }); + + droplab.addData('trigger', [{ + id: 0, + text: 'Jacob', + }, { + id: 1, + text: 'Jeff', + }]); +``` + +Above, if the second list item was clicked, it would update the `#input` element +to have a `value` of `1`, it would also update the `#div` element's `data-selected-id` to `1`. + +Optionally you can set `inputAttribute` to a string that is the name of an attribute on your `input` element that you want to update. +If you do not provide an `inputAttribute`, `InputSetter` will update the `value` of the `input` element if it is an `INPUT` element, +or the `textContent` of the `input` element if it is not an `INPUT` element. diff --git a/doc/development/fe_guide/index.md b/doc/development/fe_guide/index.md index f963bffde37..c7d4f2e9c23 100644 --- a/doc/development/fe_guide/index.md +++ b/doc/development/fe_guide/index.md @@ -90,3 +90,13 @@ Our accessibility standards and resources. [scss-lint]: https://github.com/brigade/scss-lint [install]: ../../install/installation.md#4-node [requirements]: ../../install/requirements.md#supported-web-browsers + +--- + +## [DropLab](droplab/droplab.md) +Our internal `DropLab` dropdown library. + +* [DropLab](droplab/droplab.md) +* [Ajax plugin](droplab/plugins/ajax.md) +* [Filter plugin](droplab/plugins/filter.md) +* [InputSetter plugin](droplab/plugins/input_setter.md) |