@materializecss/materialize 2.0.3-beta → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +16 -18
- package/dist/css/materialize.css +73 -26
- package/dist/css/materialize.min.css +3 -3
- package/dist/js/materialize.js +560 -2015
- package/dist/js/materialize.min.js +3 -3
- package/dist/js/materialize.min.js.map +1 -1
- package/dist/src/buttons.d.ts.map +1 -1
- package/dist/src/cards.d.ts.map +1 -1
- package/dist/src/collapsible.d.ts +1 -0
- package/dist/src/collapsible.d.ts.map +1 -1
- package/dist/src/dropdown.d.ts +1 -0
- package/dist/src/dropdown.d.ts.map +1 -1
- package/dist/src/global.d.ts.map +1 -1
- package/dist/src/materialbox.d.ts +14 -10
- package/dist/src/materialbox.d.ts.map +1 -1
- package/dist/src/modal.d.ts.map +1 -1
- package/dist/src/range.d.ts.map +1 -1
- package/dist/src/scrollspy.d.ts.map +1 -1
- package/dist/src/sidenav.d.ts +25 -25
- package/dist/src/sidenav.d.ts.map +1 -1
- package/dist/src/slider.d.ts +12 -12
- package/dist/src/slider.d.ts.map +1 -1
- package/dist/src/tabs.d.ts +1 -1
- package/dist/src/tabs.d.ts.map +1 -1
- package/dist/src/toasts.d.ts +7 -2
- package/dist/src/toasts.d.ts.map +1 -1
- package/dist/src/tooltip.d.ts.map +1 -1
- package/package.json +29 -44
- package/sass/components/_collapsible.scss +14 -2
- package/sass/components/_materialbox.scss +2 -2
- package/sass/components/_modal.scss +0 -1
- package/sass/components/_tooltip.scss +18 -8
- package/sass/components/_variables.scss +2 -2
- package/Gruntfile.js +0 -385
- package/src/autocomplete.ts +0 -553
- package/src/bounding.ts +0 -6
- package/src/buttons.ts +0 -260
- package/src/cards.ts +0 -53
- package/src/carousel.ts +0 -676
- package/src/characterCounter.ts +0 -117
- package/src/chips.ts +0 -439
- package/src/collapsible.ts +0 -249
- package/src/component.ts +0 -120
- package/src/datepicker.ts +0 -1076
- package/src/dropdown.ts +0 -644
- package/src/edges.ts +0 -6
- package/src/forms.ts +0 -132
- package/src/global.ts +0 -114
- package/src/index.ts +0 -26
- package/src/materialbox.ts +0 -404
- package/src/modal.ts +0 -341
- package/src/parallax.ts +0 -149
- package/src/pushpin.ts +0 -165
- package/src/range.ts +0 -198
- package/src/scrollspy.ts +0 -263
- package/src/select.ts +0 -484
- package/src/sidenav.ts +0 -543
- package/src/slider.ts +0 -474
- package/src/tabs.ts +0 -347
- package/src/tapTarget.ts +0 -273
- package/src/timepicker.ts +0 -832
- package/src/toasts.ts +0 -290
- package/src/tooltip.ts +0 -366
- package/src/utils.ts +0 -271
- package/src/waves.ts +0 -70
package/src/characterCounter.ts
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { Component, BaseOptions, InitElements, MElement } from "./component";
|
|
2
|
-
|
|
3
|
-
export interface CharacterCounterOptions extends BaseOptions {};
|
|
4
|
-
|
|
5
|
-
const _defaults = Object.freeze({});
|
|
6
|
-
|
|
7
|
-
type InputElement = HTMLInputElement | HTMLTextAreaElement;
|
|
8
|
-
|
|
9
|
-
export class CharacterCounter extends Component<{}> {
|
|
10
|
-
|
|
11
|
-
declare el: InputElement;
|
|
12
|
-
/** Stores the reference to the counter HTML element. */
|
|
13
|
-
counterEl: HTMLSpanElement;
|
|
14
|
-
/** Specifies whether the input is valid or not. */
|
|
15
|
-
isInvalid: boolean;
|
|
16
|
-
/** Specifies whether the input text has valid length or not. */
|
|
17
|
-
isValidLength: boolean;
|
|
18
|
-
|
|
19
|
-
constructor(el: HTMLInputElement | HTMLTextAreaElement, options: Partial<CharacterCounterOptions>) {
|
|
20
|
-
super(el, {}, CharacterCounter);
|
|
21
|
-
(this.el as any).M_CharacterCounter = this;
|
|
22
|
-
|
|
23
|
-
this.options = {
|
|
24
|
-
...CharacterCounter.defaults,
|
|
25
|
-
...options
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
this.isInvalid = false;
|
|
29
|
-
this.isValidLength = false;
|
|
30
|
-
|
|
31
|
-
this._setupCounter();
|
|
32
|
-
this._setupEventHandlers();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
static get defaults(): CharacterCounterOptions {
|
|
36
|
-
return _defaults;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Initializes instance of CharacterCounter.
|
|
41
|
-
* @param el HTML element.
|
|
42
|
-
* @param options Component options.
|
|
43
|
-
*/
|
|
44
|
-
static init(el: InputElement, options?: Partial<CharacterCounterOptions>): CharacterCounter;
|
|
45
|
-
/**
|
|
46
|
-
* Initializes instances of CharacterCounter.
|
|
47
|
-
* @param els HTML elements.
|
|
48
|
-
* @param options Component options.
|
|
49
|
-
*/
|
|
50
|
-
static init(els: InitElements<InputElement | MElement>, options?: Partial<CharacterCounterOptions>): CharacterCounter[];
|
|
51
|
-
/**
|
|
52
|
-
* Initializes instances of CharacterCounter.
|
|
53
|
-
* @param els HTML elements.
|
|
54
|
-
* @param options Component options.
|
|
55
|
-
*/
|
|
56
|
-
static init(els: InputElement | InitElements<InputElement | MElement>, options: Partial<CharacterCounterOptions> = {}): CharacterCounter | CharacterCounter[] {
|
|
57
|
-
return super.init(els, options, CharacterCounter);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
static getInstance(el: InputElement): CharacterCounter {
|
|
61
|
-
return (el as any).M_CharacterCounter;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
destroy() {
|
|
65
|
-
this._removeEventHandlers();
|
|
66
|
-
(this.el as any).CharacterCounter = undefined;
|
|
67
|
-
this._removeCounter();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
_setupEventHandlers() {
|
|
71
|
-
this.el.addEventListener('focus', this.updateCounter, true);
|
|
72
|
-
this.el.addEventListener('input', this.updateCounter, true);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
_removeEventHandlers() {
|
|
76
|
-
this.el.removeEventListener('focus', this.updateCounter, true);
|
|
77
|
-
this.el.removeEventListener('input', this.updateCounter, true);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
_setupCounter() {
|
|
81
|
-
this.counterEl = document.createElement('span');
|
|
82
|
-
this.counterEl.classList.add('character-counter');
|
|
83
|
-
this.counterEl.style.float = 'right';
|
|
84
|
-
this.counterEl.style.fontSize = '12px';
|
|
85
|
-
this.counterEl.style.height = '1';
|
|
86
|
-
this.el.parentElement.appendChild(this.counterEl);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
_removeCounter() {
|
|
90
|
-
this.counterEl.remove();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
updateCounter = () => {
|
|
94
|
-
let maxLength = parseInt(this.el.getAttribute('maxlength')),
|
|
95
|
-
actualLength = (this.el as HTMLInputElement).value.length;
|
|
96
|
-
|
|
97
|
-
this.isValidLength = actualLength <= maxLength;
|
|
98
|
-
let counterString = actualLength.toString();
|
|
99
|
-
if (maxLength) {
|
|
100
|
-
counterString += '/' + maxLength;
|
|
101
|
-
this._validateInput();
|
|
102
|
-
}
|
|
103
|
-
this.counterEl.innerHTML = counterString;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
_validateInput() {
|
|
107
|
-
if (this.isValidLength && this.isInvalid) {
|
|
108
|
-
this.isInvalid = false;
|
|
109
|
-
this.el.classList.remove('invalid');
|
|
110
|
-
}
|
|
111
|
-
else if (!this.isValidLength && !this.isInvalid) {
|
|
112
|
-
this.isInvalid = true;
|
|
113
|
-
this.el.classList.remove('valid');
|
|
114
|
-
this.el.classList.add('invalid');
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
package/src/chips.ts
DELETED
|
@@ -1,439 +0,0 @@
|
|
|
1
|
-
import { Utils } from "./utils";
|
|
2
|
-
import { Autocomplete, AutocompleteOptions } from "./autocomplete";
|
|
3
|
-
import { Component, BaseOptions, InitElements, MElement } from "./component";
|
|
4
|
-
|
|
5
|
-
export interface ChipData {
|
|
6
|
-
/**
|
|
7
|
-
* Unique identifier.
|
|
8
|
-
*/
|
|
9
|
-
id: number|string;
|
|
10
|
-
/**
|
|
11
|
-
* Chip text. If not specified, "id" will be used.
|
|
12
|
-
*/
|
|
13
|
-
text?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Chip image (URL).
|
|
16
|
-
*/
|
|
17
|
-
image?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface ChipsOptions extends BaseOptions{
|
|
21
|
-
/**
|
|
22
|
-
* Set the chip data.
|
|
23
|
-
* @default []
|
|
24
|
-
*/
|
|
25
|
-
data: ChipData[];
|
|
26
|
-
/**
|
|
27
|
-
* Set first placeholder when there are no tags.
|
|
28
|
-
* @default ""
|
|
29
|
-
*/
|
|
30
|
-
placeholder: string;
|
|
31
|
-
/**
|
|
32
|
-
* Set second placeholder when adding additional tags.
|
|
33
|
-
* @default ""
|
|
34
|
-
*/
|
|
35
|
-
secondaryPlaceholder: string;
|
|
36
|
-
/**
|
|
37
|
-
* Set autocomplete options.
|
|
38
|
-
* @default {}
|
|
39
|
-
*/
|
|
40
|
-
autocompleteOptions: Partial<AutocompleteOptions>;
|
|
41
|
-
/**
|
|
42
|
-
* Toggles abililty to add custom value not in autocomplete list.
|
|
43
|
-
* @default false
|
|
44
|
-
*/
|
|
45
|
-
autocompleteOnly: boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Set chips limit.
|
|
48
|
-
* @default Infinity
|
|
49
|
-
*/
|
|
50
|
-
limit: number;
|
|
51
|
-
/**
|
|
52
|
-
* Specifies class to be used in "close" button (useful when working with Material Symbols icon set).
|
|
53
|
-
* @default 'material-icons'
|
|
54
|
-
*/
|
|
55
|
-
closeIconClass: string;
|
|
56
|
-
/**
|
|
57
|
-
* Callback for chip add.
|
|
58
|
-
* @default null
|
|
59
|
-
*/
|
|
60
|
-
onChipAdd: (element: HTMLElement, chip: HTMLElement) => void;
|
|
61
|
-
/**
|
|
62
|
-
* Callback for chip select.
|
|
63
|
-
* @default null
|
|
64
|
-
*/
|
|
65
|
-
onChipSelect: (element: HTMLElement, chip: HTMLElement) => void;
|
|
66
|
-
/**
|
|
67
|
-
* Callback for chip delete.
|
|
68
|
-
* @default null
|
|
69
|
-
*/
|
|
70
|
-
onChipDelete: (element: HTMLElement, chip: HTMLElement) => void;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
let _defaults: ChipsOptions = {
|
|
74
|
-
data: [],
|
|
75
|
-
placeholder: '',
|
|
76
|
-
secondaryPlaceholder: '',
|
|
77
|
-
closeIconClass: 'material-icons',
|
|
78
|
-
autocompleteOptions: {},
|
|
79
|
-
autocompleteOnly: false,
|
|
80
|
-
limit: Infinity,
|
|
81
|
-
onChipAdd: null,
|
|
82
|
-
onChipSelect: null,
|
|
83
|
-
onChipDelete: null
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
function gGetIndex(el: HTMLElement): number {
|
|
87
|
-
return [...el.parentNode.children].indexOf(el);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export class Chips extends Component<ChipsOptions> {
|
|
91
|
-
/** Array of the current chips data. */
|
|
92
|
-
chipsData: ChipData[];
|
|
93
|
-
/** If the chips has autocomplete enabled. */
|
|
94
|
-
hasAutocomplete: boolean;
|
|
95
|
-
/** Autocomplete instance, if any. */
|
|
96
|
-
autocomplete: Autocomplete;
|
|
97
|
-
_input: HTMLInputElement;
|
|
98
|
-
_label: any;
|
|
99
|
-
_chips: HTMLElement[];
|
|
100
|
-
static _keydown: boolean;
|
|
101
|
-
private _selectedChip: any;
|
|
102
|
-
|
|
103
|
-
constructor(el: HTMLElement, options: Partial<ChipsOptions>) {
|
|
104
|
-
super(el, options, Chips);
|
|
105
|
-
(this.el as any).M_Chips = this;
|
|
106
|
-
|
|
107
|
-
this.options = {
|
|
108
|
-
...Chips.defaults,
|
|
109
|
-
...options
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
this.el.classList.add('chips', 'input-field');
|
|
113
|
-
this.chipsData = [];
|
|
114
|
-
this._chips = [];
|
|
115
|
-
this._setupInput();
|
|
116
|
-
this.hasAutocomplete = Object.keys(this.options.autocompleteOptions).length > 0;
|
|
117
|
-
|
|
118
|
-
// Set input id
|
|
119
|
-
if (!this._input.getAttribute('id'))
|
|
120
|
-
this._input.setAttribute('id', Utils.guid());
|
|
121
|
-
|
|
122
|
-
// Render initial chips
|
|
123
|
-
if (this.options.data.length) {
|
|
124
|
-
this.chipsData = this.options.data;
|
|
125
|
-
this._renderChips();
|
|
126
|
-
}
|
|
127
|
-
// Setup autocomplete if needed
|
|
128
|
-
if (this.hasAutocomplete) this._setupAutocomplete();
|
|
129
|
-
this._setPlaceholder();
|
|
130
|
-
this._setupLabel();
|
|
131
|
-
this._setupEventHandlers();
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
static get defaults() {
|
|
135
|
-
return _defaults;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Initializes instance of Chips.
|
|
140
|
-
* @param el HTML element.
|
|
141
|
-
* @param options Component options.
|
|
142
|
-
*/
|
|
143
|
-
static init(el: InitElements<MElement>, options?: Partial<ChipsOptions>): Chips;
|
|
144
|
-
/**
|
|
145
|
-
* Initializes instances of Chips.
|
|
146
|
-
* @param els HTML elements.
|
|
147
|
-
* @param options Component options.
|
|
148
|
-
*/
|
|
149
|
-
static init(els: InitElements<MElement>, options?: Partial<ChipsOptions>): Chips[];
|
|
150
|
-
/**
|
|
151
|
-
* Initializes instances of Chips.
|
|
152
|
-
* @param els HTML elements.
|
|
153
|
-
* @param options Component options.
|
|
154
|
-
*/
|
|
155
|
-
static init(els: HTMLElement | InitElements<MElement>, options: Partial<ChipsOptions> = {}): Chips | Chips[] {
|
|
156
|
-
return super.init(els, options, Chips);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
static getInstance(el: HTMLElement): Chips {
|
|
160
|
-
return (el as any).M_Chips;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
getData() {
|
|
164
|
-
return this.chipsData;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
destroy() {
|
|
168
|
-
this._removeEventHandlers();
|
|
169
|
-
this._chips.forEach(c => c.remove());
|
|
170
|
-
this._chips = [];
|
|
171
|
-
(this.el as any).M_Chips = undefined;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
_setupEventHandlers() {
|
|
175
|
-
this.el.addEventListener('click', this._handleChipClick);
|
|
176
|
-
document.addEventListener('keydown', Chips._handleChipsKeydown);
|
|
177
|
-
document.addEventListener('keyup', Chips._handleChipsKeyup);
|
|
178
|
-
this.el.addEventListener('blur', Chips._handleChipsBlur, true);
|
|
179
|
-
this._input.addEventListener('focus', this._handleInputFocus);
|
|
180
|
-
this._input.addEventListener('blur', this._handleInputBlur);
|
|
181
|
-
this._input.addEventListener('keydown', this._handleInputKeydown);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
_removeEventHandlers() {
|
|
185
|
-
this.el.removeEventListener('click', this._handleChipClick);
|
|
186
|
-
document.removeEventListener('keydown', Chips._handleChipsKeydown);
|
|
187
|
-
document.removeEventListener('keyup', Chips._handleChipsKeyup);
|
|
188
|
-
this.el.removeEventListener('blur', Chips._handleChipsBlur, true);
|
|
189
|
-
this._input.removeEventListener('focus', this._handleInputFocus);
|
|
190
|
-
this._input.removeEventListener('blur', this._handleInputBlur);
|
|
191
|
-
this._input.removeEventListener('keydown', this._handleInputKeydown);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
_handleChipClick = (e: MouseEvent) => {
|
|
195
|
-
const _chip = (<HTMLElement>e.target).closest('.chip');
|
|
196
|
-
const clickedClose = (<HTMLElement>e.target).classList.contains('close');
|
|
197
|
-
if (_chip) {
|
|
198
|
-
const index = [..._chip.parentNode.children].indexOf(_chip);
|
|
199
|
-
if (clickedClose) {
|
|
200
|
-
this.deleteChip(index);
|
|
201
|
-
this._input.focus();
|
|
202
|
-
}
|
|
203
|
-
else {
|
|
204
|
-
this.selectChip(index);
|
|
205
|
-
}
|
|
206
|
-
// Default handle click to focus on input
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
this._input.focus();
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
static _handleChipsKeydown(e: KeyboardEvent) {
|
|
214
|
-
Chips._keydown = true;
|
|
215
|
-
const chips = (<HTMLElement>e.target).closest('.chips');
|
|
216
|
-
const chipsKeydown = e.target && chips;
|
|
217
|
-
|
|
218
|
-
// Don't handle keydown inputs on input and textarea
|
|
219
|
-
const tag = (<HTMLElement>e.target).tagName;
|
|
220
|
-
if (tag === 'INPUT' || tag === 'TEXTAREA' || !chipsKeydown) return;
|
|
221
|
-
|
|
222
|
-
const currChips: Chips = (chips as any).M_Chips;
|
|
223
|
-
|
|
224
|
-
if (Utils.keys.BACKSPACE.includes(e.key) || Utils.keys.DELETE.includes(e.key)) {
|
|
225
|
-
e.preventDefault();
|
|
226
|
-
let selectIndex = currChips.chipsData.length;
|
|
227
|
-
if (currChips._selectedChip) {
|
|
228
|
-
const index = gGetIndex(currChips._selectedChip);
|
|
229
|
-
currChips.deleteChip(index);
|
|
230
|
-
currChips._selectedChip = null;
|
|
231
|
-
// Make sure selectIndex doesn't go negative
|
|
232
|
-
selectIndex = Math.max(index - 1, 0);
|
|
233
|
-
}
|
|
234
|
-
if (currChips.chipsData.length)
|
|
235
|
-
currChips.selectChip(selectIndex);
|
|
236
|
-
else
|
|
237
|
-
currChips._input.focus();
|
|
238
|
-
}
|
|
239
|
-
else if (Utils.keys.ARROW_LEFT.includes(e.key)) {
|
|
240
|
-
if (currChips._selectedChip) {
|
|
241
|
-
const selectIndex = gGetIndex(currChips._selectedChip) - 1;
|
|
242
|
-
if (selectIndex < 0) return;
|
|
243
|
-
currChips.selectChip(selectIndex);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
else if (Utils.keys.ARROW_RIGHT.includes(e.key)) {
|
|
247
|
-
if (currChips._selectedChip) {
|
|
248
|
-
const selectIndex = gGetIndex(currChips._selectedChip) + 1;
|
|
249
|
-
if (selectIndex >= currChips.chipsData.length)
|
|
250
|
-
currChips._input.focus();
|
|
251
|
-
else
|
|
252
|
-
currChips.selectChip(selectIndex);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
static _handleChipsKeyup(e: Event) {
|
|
258
|
-
Chips._keydown = false;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
static _handleChipsBlur(e: Event) {
|
|
262
|
-
if (!Chips._keydown && document.hidden) {
|
|
263
|
-
const chips = (<HTMLElement>e.target).closest('.chips');
|
|
264
|
-
const currChips: Chips = (chips as any).M_Chips;
|
|
265
|
-
currChips._selectedChip = null;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
_handleInputFocus = () => {
|
|
270
|
-
this.el.classList.add('focus');
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
_handleInputBlur = () => {
|
|
274
|
-
this.el.classList.remove('focus');
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
_handleInputKeydown = (e: KeyboardEvent) => {
|
|
278
|
-
Chips._keydown = true;
|
|
279
|
-
if (Utils.keys.ENTER.includes(e.key)) {
|
|
280
|
-
// Override enter if autocompleting.
|
|
281
|
-
if (this.hasAutocomplete && this.autocomplete && this.autocomplete.isOpen) {
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
e.preventDefault();
|
|
285
|
-
if (!this.hasAutocomplete || (this.hasAutocomplete && !this.options.autocompleteOnly)) {
|
|
286
|
-
this.addChip({id: this._input.value});
|
|
287
|
-
}
|
|
288
|
-
this._input.value = '';
|
|
289
|
-
}
|
|
290
|
-
else if (
|
|
291
|
-
(Utils.keys.BACKSPACE.includes(e.key) || Utils.keys.ARROW_LEFT.includes(e.key)) &&
|
|
292
|
-
this._input.value === '' &&
|
|
293
|
-
this.chipsData.length
|
|
294
|
-
) {
|
|
295
|
-
e.preventDefault();
|
|
296
|
-
this.selectChip(this.chipsData.length - 1);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
_renderChip(chip: ChipData): HTMLDivElement {
|
|
301
|
-
if (!chip.id) return;
|
|
302
|
-
const renderedChip = document.createElement('div');
|
|
303
|
-
renderedChip.classList.add('chip');
|
|
304
|
-
renderedChip.innerText = chip.text || <string>chip.id;
|
|
305
|
-
renderedChip.setAttribute('tabindex', "0");
|
|
306
|
-
const closeIcon = document.createElement('i');
|
|
307
|
-
closeIcon.classList.add(this.options.closeIconClass, 'close');
|
|
308
|
-
closeIcon.innerText = 'close';
|
|
309
|
-
// attach image if needed
|
|
310
|
-
if (chip.image) {
|
|
311
|
-
const img = document.createElement('img');
|
|
312
|
-
img.setAttribute('src', chip.image);
|
|
313
|
-
renderedChip.insertBefore(img, renderedChip.firstChild);
|
|
314
|
-
}
|
|
315
|
-
renderedChip.appendChild(closeIcon);
|
|
316
|
-
return renderedChip;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
_renderChips() {
|
|
320
|
-
this._chips = []; //.remove();
|
|
321
|
-
for (let i = 0; i < this.chipsData.length; i++) {
|
|
322
|
-
const chipElem = this._renderChip(this.chipsData[i]);
|
|
323
|
-
this.el.appendChild(chipElem);
|
|
324
|
-
this._chips.push(chipElem);
|
|
325
|
-
}
|
|
326
|
-
// move input to end
|
|
327
|
-
this.el.append(this._input);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
_setupAutocomplete() {
|
|
331
|
-
this.options.autocompleteOptions.onAutocomplete = (items) => {
|
|
332
|
-
if (items.length > 0) this.addChip({
|
|
333
|
-
id: items[0].id,
|
|
334
|
-
text: items[0].text,
|
|
335
|
-
image: items[0].image
|
|
336
|
-
});
|
|
337
|
-
this._input.value = '';
|
|
338
|
-
this._input.focus();
|
|
339
|
-
};
|
|
340
|
-
this.autocomplete = Autocomplete.init(this._input, this.options.autocompleteOptions);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
_setupInput() {
|
|
344
|
-
this._input = this.el.querySelector('input');
|
|
345
|
-
if (!this._input) {
|
|
346
|
-
this._input = document.createElement('input');
|
|
347
|
-
this.el.append(this._input);
|
|
348
|
-
}
|
|
349
|
-
this._input.classList.add('input');
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
_setupLabel() {
|
|
353
|
-
this._label = this.el.querySelector('label');
|
|
354
|
-
if (this._label) this._label.setAttribute('for', this._input.getAttribute('id'));
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
_setPlaceholder() {
|
|
358
|
-
if (this.chipsData !== undefined && !this.chipsData.length && this.options.placeholder) {
|
|
359
|
-
this._input.placeholder = this.options.placeholder;
|
|
360
|
-
}
|
|
361
|
-
else if (
|
|
362
|
-
(this.chipsData === undefined || !!this.chipsData.length) &&
|
|
363
|
-
this.options.secondaryPlaceholder
|
|
364
|
-
) {
|
|
365
|
-
this._input.placeholder = this.options.secondaryPlaceholder;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
_isValidAndNotExist(chip: ChipData) {
|
|
370
|
-
const isValid = !!chip.id;
|
|
371
|
-
const doesNotExist = !this.chipsData.some(item => item.id == chip.id);
|
|
372
|
-
return isValid && doesNotExist;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Add chip to input.
|
|
377
|
-
* @param chip Chip data object
|
|
378
|
-
*/
|
|
379
|
-
addChip(chip: ChipData) {
|
|
380
|
-
if (!this._isValidAndNotExist(chip) || this.chipsData.length >= this.options.limit) return;
|
|
381
|
-
const renderedChip = this._renderChip(chip);
|
|
382
|
-
this._chips.push(renderedChip);
|
|
383
|
-
this.chipsData.push(chip);
|
|
384
|
-
//$(this._input).before(renderedChip);
|
|
385
|
-
this._input.before(renderedChip);
|
|
386
|
-
this._setPlaceholder();
|
|
387
|
-
// fire chipAdd callback
|
|
388
|
-
if (typeof this.options.onChipAdd === 'function') {
|
|
389
|
-
this.options.onChipAdd(this.el, renderedChip);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* Delete nth chip.
|
|
395
|
-
* @param chipIndex Index of chip
|
|
396
|
-
*/
|
|
397
|
-
deleteChip(chipIndex: number) {
|
|
398
|
-
const chip = this._chips[chipIndex];
|
|
399
|
-
this._chips[chipIndex].remove();
|
|
400
|
-
this._chips.splice(chipIndex, 1);
|
|
401
|
-
this.chipsData.splice(chipIndex, 1);
|
|
402
|
-
this._setPlaceholder();
|
|
403
|
-
// fire chipDelete callback
|
|
404
|
-
if (typeof this.options.onChipDelete === 'function') {
|
|
405
|
-
this.options.onChipDelete(this.el, chip);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* Select nth chip.
|
|
411
|
-
* @param chipIndex Index of chip
|
|
412
|
-
*/
|
|
413
|
-
selectChip(chipIndex: number) {
|
|
414
|
-
const chip = this._chips[chipIndex];
|
|
415
|
-
this._selectedChip = chip;
|
|
416
|
-
chip.focus();
|
|
417
|
-
// fire chipSelect callback
|
|
418
|
-
if (typeof this.options.onChipSelect === 'function') {
|
|
419
|
-
this.options.onChipSelect(this.el, chip);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
static Init(){
|
|
424
|
-
document.addEventListener("DOMContentLoaded", () => {
|
|
425
|
-
// Handle removal of static chips.
|
|
426
|
-
document.body.addEventListener('click', e => {
|
|
427
|
-
if ((<HTMLElement>e.target).closest('.chip .close')) {
|
|
428
|
-
const chips = (<HTMLElement>e.target).closest('.chips');
|
|
429
|
-
if (chips && (chips as any).M_Chips == undefined) return;
|
|
430
|
-
(<HTMLElement>e.target).closest('.chip').remove();
|
|
431
|
-
}
|
|
432
|
-
});
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
static {
|
|
437
|
-
Chips._keydown = false;
|
|
438
|
-
}
|
|
439
|
-
}
|