mirror of
https://github.com/Choices-js/Choices.git
synced 2024-06-07 08:22:21 +02:00
Move templates into own file
This commit is contained in:
parent
f98e79e218
commit
806edca24f
|
@ -1,11 +1,11 @@
|
||||||
import Fuse from 'fuse.js';
|
import Fuse from 'fuse.js';
|
||||||
import classNames from 'classnames';
|
|
||||||
import Store from './store/store';
|
import Store from './store/store';
|
||||||
import Dropdown from './components/dropdown';
|
import Dropdown from './components/dropdown';
|
||||||
import Container from './components/container';
|
import Container from './components/container';
|
||||||
import Input from './components/input';
|
import Input from './components/input';
|
||||||
import List from './components/list';
|
import List from './components/list';
|
||||||
import { DEFAULT_CONFIG, DEFAULT_CLASSNAMES, EVENTS } from './constants';
|
import { DEFAULT_CONFIG, DEFAULT_CLASSNAMES, EVENTS } from './constants';
|
||||||
|
import { TEMPLATES } from './templates';
|
||||||
import { addChoice, filterChoices, activateChoices, clearChoices } from './actions/choices';
|
import { addChoice, filterChoices, activateChoices, clearChoices } from './actions/choices';
|
||||||
import { addItem, removeItem, highlightItem } from './actions/items';
|
import { addItem, removeItem, highlightItem } from './actions/items';
|
||||||
import { addGroup } from './actions/groups';
|
import { addGroup } from './actions/groups';
|
||||||
|
@ -2247,7 +2247,8 @@ class Choices {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const templates = this.config.templates;
|
const templates = this.config.templates;
|
||||||
return templates[template](...args);
|
const globalClasses = this.config.classNames;
|
||||||
|
return templates[template].call(this, globalClasses, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2256,226 +2257,6 @@ class Choices {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_createTemplates() {
|
_createTemplates() {
|
||||||
const globalClasses = this.config.classNames;
|
|
||||||
const templates = {
|
|
||||||
containerOuter: (direction) => {
|
|
||||||
const tabIndex = this.isSelectOneElement ? 'tabindex="0"' : '';
|
|
||||||
let role = this.isSelectElement ? 'role="listbox"' : '';
|
|
||||||
let ariaAutoComplete = '';
|
|
||||||
|
|
||||||
if (this.isSelectElement && this.config.searchEnabled) {
|
|
||||||
role = 'role="combobox"';
|
|
||||||
ariaAutoComplete = 'aria-autocomplete="list"';
|
|
||||||
}
|
|
||||||
|
|
||||||
return strToEl(`
|
|
||||||
<div
|
|
||||||
class="${globalClasses.containerOuter}"
|
|
||||||
data-type="${this.passedElement.type}"
|
|
||||||
${role}
|
|
||||||
${tabIndex}
|
|
||||||
${ariaAutoComplete}
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded="false"
|
|
||||||
dir="${direction}"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
},
|
|
||||||
containerInner: () => strToEl(`
|
|
||||||
<div class="${globalClasses.containerInner}"></div>
|
|
||||||
`),
|
|
||||||
itemList: () => {
|
|
||||||
const localClasses = classNames(
|
|
||||||
globalClasses.list, {
|
|
||||||
[globalClasses.listSingle]: (this.isSelectOneElement),
|
|
||||||
[globalClasses.listItems]: (!this.isSelectOneElement),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return strToEl(`
|
|
||||||
<div class="${localClasses}"></div>
|
|
||||||
`);
|
|
||||||
},
|
|
||||||
placeholder: value => strToEl(`
|
|
||||||
<div class="${globalClasses.placeholder}">
|
|
||||||
${value}
|
|
||||||
</div>
|
|
||||||
`),
|
|
||||||
item: (data) => {
|
|
||||||
const ariaSelected = data.active ? 'aria-selected="true"' : '';
|
|
||||||
const ariaDisabled = data.disabled ? 'aria-disabled="true"' : '';
|
|
||||||
|
|
||||||
let localClasses = classNames(
|
|
||||||
globalClasses.item, {
|
|
||||||
[globalClasses.highlightedState]: data.highlighted,
|
|
||||||
[globalClasses.itemSelectable]: !data.highlighted,
|
|
||||||
[globalClasses.placeholder]: data.placeholder,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this.config.removeItemButton) {
|
|
||||||
localClasses = classNames(
|
|
||||||
globalClasses.item, {
|
|
||||||
[globalClasses.highlightedState]: data.highlighted,
|
|
||||||
[globalClasses.itemSelectable]: !data.disabled,
|
|
||||||
[globalClasses.placeholder]: data.placeholder,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return strToEl(`
|
|
||||||
<div
|
|
||||||
class="${localClasses}"
|
|
||||||
data-item
|
|
||||||
data-id="${data.id}"
|
|
||||||
data-value="${data.value}"
|
|
||||||
data-deletable
|
|
||||||
${ariaSelected}
|
|
||||||
${ariaDisabled}
|
|
||||||
>
|
|
||||||
${data.label}<!--
|
|
||||||
--><button
|
|
||||||
type="button"
|
|
||||||
class="${globalClasses.button}"
|
|
||||||
data-button
|
|
||||||
aria-label="Remove item: '${data.value}'"
|
|
||||||
>
|
|
||||||
Remove item
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return strToEl(`
|
|
||||||
<div
|
|
||||||
class="${localClasses}"
|
|
||||||
data-item
|
|
||||||
data-id="${data.id}"
|
|
||||||
data-value="${data.value}"
|
|
||||||
${ariaSelected}
|
|
||||||
${ariaDisabled}
|
|
||||||
>
|
|
||||||
${data.label}
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
},
|
|
||||||
choiceList: () => {
|
|
||||||
const ariaMultiSelectable = !this.isSelectOneElement ?
|
|
||||||
'aria-multiselectable="true"' :
|
|
||||||
'';
|
|
||||||
|
|
||||||
return strToEl(`
|
|
||||||
<div
|
|
||||||
class="${globalClasses.list}"
|
|
||||||
dir="ltr"
|
|
||||||
role="listbox"
|
|
||||||
${ariaMultiSelectable}
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
},
|
|
||||||
choiceGroup: (data) => {
|
|
||||||
const ariaDisabled = data.disabled ? 'aria-disabled="true"' : '';
|
|
||||||
const localClasses = classNames(
|
|
||||||
globalClasses.group, {
|
|
||||||
[globalClasses.itemDisabled]: data.disabled,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return strToEl(`
|
|
||||||
<div
|
|
||||||
class="${localClasses}"
|
|
||||||
data-group
|
|
||||||
data-id="${data.id}"
|
|
||||||
data-value="${data.value}"
|
|
||||||
role="group"
|
|
||||||
${ariaDisabled}
|
|
||||||
>
|
|
||||||
<div class="${globalClasses.groupHeading}">${data.value}</div>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
},
|
|
||||||
choice: (data) => {
|
|
||||||
const role = data.groupId > 0 ? 'role="treeitem"' : 'role="option"';
|
|
||||||
const localClasses = classNames(
|
|
||||||
globalClasses.item,
|
|
||||||
globalClasses.itemChoice, {
|
|
||||||
[globalClasses.itemDisabled]: data.disabled,
|
|
||||||
[globalClasses.itemSelectable]: !data.disabled,
|
|
||||||
[globalClasses.placeholder]: data.placeholder,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return strToEl(`
|
|
||||||
<div
|
|
||||||
class="${localClasses}"
|
|
||||||
data-select-text="${this.config.itemSelectText}"
|
|
||||||
data-choice
|
|
||||||
data-id="${data.id}"
|
|
||||||
data-value="${data.value}"
|
|
||||||
${data.disabled ?
|
|
||||||
'data-choice-disabled aria-disabled="true"' :
|
|
||||||
'data-choice-selectable'
|
|
||||||
}
|
|
||||||
id="${data.elementId}"
|
|
||||||
${role}
|
|
||||||
>
|
|
||||||
${data.label}
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
},
|
|
||||||
input: () => {
|
|
||||||
const localClasses = classNames(
|
|
||||||
globalClasses.input,
|
|
||||||
globalClasses.inputCloned,
|
|
||||||
);
|
|
||||||
|
|
||||||
return strToEl(`
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="${localClasses}"
|
|
||||||
autocomplete="off"
|
|
||||||
autocapitalize="off"
|
|
||||||
spellcheck="false"
|
|
||||||
role="textbox"
|
|
||||||
aria-autocomplete="list"
|
|
||||||
>
|
|
||||||
`);
|
|
||||||
},
|
|
||||||
dropdown: () => {
|
|
||||||
const localClasses = classNames(
|
|
||||||
globalClasses.list,
|
|
||||||
globalClasses.listDropdown,
|
|
||||||
);
|
|
||||||
|
|
||||||
return strToEl(`
|
|
||||||
<div
|
|
||||||
class="${localClasses}"
|
|
||||||
aria-expanded="false"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
},
|
|
||||||
notice: (label, type = '') => {
|
|
||||||
const localClasses = classNames(
|
|
||||||
globalClasses.item,
|
|
||||||
globalClasses.itemChoice, {
|
|
||||||
[globalClasses.noResults]: (type === 'no-results'),
|
|
||||||
[globalClasses.noChoices]: (type === 'no-choices'),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return strToEl(`
|
|
||||||
<div class="${localClasses}">
|
|
||||||
${label}
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
},
|
|
||||||
option: data => strToEl(`
|
|
||||||
<option value="${data.value}" selected>${data.label}</option>
|
|
||||||
`),
|
|
||||||
};
|
|
||||||
|
|
||||||
// User's custom templates
|
// User's custom templates
|
||||||
const callbackTemplate = this.config.callbackOnCreateTemplates;
|
const callbackTemplate = this.config.callbackOnCreateTemplates;
|
||||||
let userTemplates = {};
|
let userTemplates = {};
|
||||||
|
@ -2483,7 +2264,7 @@ class Choices {
|
||||||
userTemplates = callbackTemplate.call(this, strToEl);
|
userTemplates = callbackTemplate.call(this, strToEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.config.templates = extend(templates, userTemplates);
|
this.config.templates = extend(TEMPLATES, userTemplates);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
229
src/scripts/src/templates.js
Normal file
229
src/scripts/src/templates.js
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { strToEl } from './lib/utils';
|
||||||
|
|
||||||
|
export const TEMPLATES = {
|
||||||
|
containerOuter(globalClasses, direction) {
|
||||||
|
const tabIndex = this.isSelectOneElement ? 'tabindex="0"' : '';
|
||||||
|
let role = this.isSelectElement ? 'role="listbox"' : '';
|
||||||
|
let ariaAutoComplete = '';
|
||||||
|
|
||||||
|
if (this.isSelectElement && this.config.searchEnabled) {
|
||||||
|
role = 'role="combobox"';
|
||||||
|
ariaAutoComplete = 'aria-autocomplete="list"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return strToEl(`
|
||||||
|
<div
|
||||||
|
class="${globalClasses.containerOuter}"
|
||||||
|
data-type="${this.passedElement.type}"
|
||||||
|
${role}
|
||||||
|
${tabIndex}
|
||||||
|
${ariaAutoComplete}
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-expanded="false"
|
||||||
|
dir="${direction}"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
containerInner(globalClasses) {
|
||||||
|
return strToEl(`
|
||||||
|
<div class="${globalClasses.containerInner}"></div>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
itemList(globalClasses) {
|
||||||
|
const localClasses = classNames(
|
||||||
|
globalClasses.list, {
|
||||||
|
[globalClasses.listSingle]: (this.isSelectOneElement),
|
||||||
|
[globalClasses.listItems]: (!this.isSelectOneElement),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return strToEl(`
|
||||||
|
<div class="${localClasses}"></div>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
placeholder(globalClasses, value) {
|
||||||
|
return strToEl(`
|
||||||
|
<div class="${globalClasses.placeholder}">
|
||||||
|
${value}
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
item(globalClasses, data) {
|
||||||
|
const ariaSelected = data.active ? 'aria-selected="true"' : '';
|
||||||
|
const ariaDisabled = data.disabled ? 'aria-disabled="true"' : '';
|
||||||
|
|
||||||
|
let localClasses = classNames(
|
||||||
|
globalClasses.item, {
|
||||||
|
[globalClasses.highlightedState]: data.highlighted,
|
||||||
|
[globalClasses.itemSelectable]: !data.highlighted,
|
||||||
|
[globalClasses.placeholder]: data.placeholder,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this.config.removeItemButton) {
|
||||||
|
localClasses = classNames(
|
||||||
|
globalClasses.item, {
|
||||||
|
[globalClasses.highlightedState]: data.highlighted,
|
||||||
|
[globalClasses.itemSelectable]: !data.disabled,
|
||||||
|
[globalClasses.placeholder]: data.placeholder,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return strToEl(`
|
||||||
|
<div
|
||||||
|
class="${localClasses}"
|
||||||
|
data-item
|
||||||
|
data-id="${data.id}"
|
||||||
|
data-value="${data.value}"
|
||||||
|
data-deletable
|
||||||
|
${ariaSelected}
|
||||||
|
${ariaDisabled}
|
||||||
|
>
|
||||||
|
${data.label}<!--
|
||||||
|
--><button
|
||||||
|
type="button"
|
||||||
|
class="${globalClasses.button}"
|
||||||
|
data-button
|
||||||
|
aria-label="Remove item: '${data.value}'"
|
||||||
|
>
|
||||||
|
Remove item
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return strToEl(`
|
||||||
|
<div
|
||||||
|
class="${localClasses}"
|
||||||
|
data-item
|
||||||
|
data-id="${data.id}"
|
||||||
|
data-value="${data.value}"
|
||||||
|
${ariaSelected}
|
||||||
|
${ariaDisabled}
|
||||||
|
>
|
||||||
|
${data.label}
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
choiceList(globalClasses) {
|
||||||
|
const ariaMultiSelectable = !this.isSelectOneElement ?
|
||||||
|
'aria-multiselectable="true"' :
|
||||||
|
'';
|
||||||
|
|
||||||
|
return strToEl(`
|
||||||
|
<div
|
||||||
|
class="${globalClasses.list}"
|
||||||
|
dir="ltr"
|
||||||
|
role="listbox"
|
||||||
|
${ariaMultiSelectable}
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
choiceGroup(globalClasses, data) {
|
||||||
|
const ariaDisabled = data.disabled ? 'aria-disabled="true"' : '';
|
||||||
|
const localClasses = classNames(
|
||||||
|
globalClasses.group, {
|
||||||
|
[globalClasses.itemDisabled]: data.disabled,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return strToEl(`
|
||||||
|
<div
|
||||||
|
class="${localClasses}"
|
||||||
|
data-group
|
||||||
|
data-id="${data.id}"
|
||||||
|
data-value="${data.value}"
|
||||||
|
role="group"
|
||||||
|
${ariaDisabled}
|
||||||
|
>
|
||||||
|
<div class="${globalClasses.groupHeading}">${data.value}</div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
choice(globalClasses, data) {
|
||||||
|
const role = data.groupId > 0 ? 'role="treeitem"' : 'role="option"';
|
||||||
|
const localClasses = classNames(
|
||||||
|
globalClasses.item,
|
||||||
|
globalClasses.itemChoice, {
|
||||||
|
[globalClasses.itemDisabled]: data.disabled,
|
||||||
|
[globalClasses.itemSelectable]: !data.disabled,
|
||||||
|
[globalClasses.placeholder]: data.placeholder,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return strToEl(`
|
||||||
|
<div
|
||||||
|
class="${localClasses}"
|
||||||
|
data-select-text="${this.config.itemSelectText}"
|
||||||
|
data-choice
|
||||||
|
data-id="${data.id}"
|
||||||
|
data-value="${data.value}"
|
||||||
|
${data.disabled ?
|
||||||
|
'data-choice-disabled aria-disabled="true"' :
|
||||||
|
'data-choice-selectable'
|
||||||
|
}
|
||||||
|
id="${data.elementId}"
|
||||||
|
${role}
|
||||||
|
>
|
||||||
|
${data.label}
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
input(globalClasses) {
|
||||||
|
const localClasses = classNames(
|
||||||
|
globalClasses.input,
|
||||||
|
globalClasses.inputCloned,
|
||||||
|
);
|
||||||
|
|
||||||
|
return strToEl(`
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="${localClasses}"
|
||||||
|
autocomplete="off"
|
||||||
|
autocapitalize="off"
|
||||||
|
spellcheck="false"
|
||||||
|
role="textbox"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
dropdown(globalClasses) {
|
||||||
|
const localClasses = classNames(
|
||||||
|
globalClasses.list,
|
||||||
|
globalClasses.listDropdown,
|
||||||
|
);
|
||||||
|
|
||||||
|
return strToEl(`
|
||||||
|
<div
|
||||||
|
class="${localClasses}"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
notice(globalClasses, label, type = '') {
|
||||||
|
const localClasses = classNames(
|
||||||
|
globalClasses.item,
|
||||||
|
globalClasses.itemChoice, {
|
||||||
|
[globalClasses.noResults]: (type === 'no-results'),
|
||||||
|
[globalClasses.noChoices]: (type === 'no-choices'),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return strToEl(`
|
||||||
|
<div class="${localClasses}">
|
||||||
|
${label}
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
option(globalClasses, data) {
|
||||||
|
return strToEl(`
|
||||||
|
<option value="${data.value}" selected>${data.label}</option>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TEMPLATES;
|
Loading…
Reference in a new issue