@materializecss/materialize 2.0.0-alpha → 2.0.2-alpha
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/Gruntfile.js +7 -4
- package/README.md +24 -12
- package/dist/css/materialize.css +90 -86
- package/dist/css/materialize.min.css +2 -2
- package/dist/js/materialize.js +2869 -2764
- package/dist/js/materialize.min.js +2 -2
- package/dist/js/materialize.min.js.map +1 -1
- package/package.json +1 -1
- package/sass/components/_collapsible.scss +0 -41
- package/sass/components/_global.scss +3 -2
- package/sass/components/_icons-material-design.scss +2 -1
- package/sass/components/_navbar.scss +6 -3
- package/sass/components/_sidenav.scss +66 -37
- package/sass/components/_theme_variables.scss +98 -0
- package/sass/components/_typography.scss +2 -2
- package/sass/components/forms/_input-fields.scss +4 -10
- package/sass/materialize.scss +0 -4
- package/src/autocomplete.ts +188 -94
- package/src/buttons.ts +225 -260
- package/src/cards.ts +5 -6
- package/src/carousel.ts +611 -542
- package/src/characterCounter.ts +50 -21
- package/src/chips.ts +152 -63
- package/src/collapsible.ts +97 -32
- package/src/component.ts +99 -10
- package/src/datepicker.ts +905 -726
- package/src/dropdown.ts +576 -484
- package/src/edges.ts +4 -4
- package/src/forms.ts +17 -14
- package/src/global.ts +56 -325
- package/src/materialbox.ts +354 -298
- package/src/modal.ts +296 -211
- package/src/parallax.ts +129 -105
- package/src/pushpin.ts +148 -103
- package/src/range.ts +166 -150
- package/src/scrollspy.ts +214 -174
- package/src/select.ts +434 -398
- package/src/sidenav.ts +447 -381
- package/src/slider.ts +421 -362
- package/src/tabs.ts +284 -227
- package/src/tapTarget.ts +246 -213
- package/src/timepicker.ts +738 -614
- package/src/toasts.ts +254 -230
- package/src/tooltip.ts +315 -252
- package/src/utils.ts +271 -0
- package/src/waves.ts +10 -10
package/src/characterCounter.ts
CHANGED
|
@@ -1,34 +1,64 @@
|
|
|
1
|
-
import { Component } from "./component";
|
|
1
|
+
import { Component, BaseOptions, InitElements, MElement } from "./component";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export interface CharacterCounterOptions extends BaseOptions {};
|
|
4
4
|
|
|
5
|
-
|
|
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. */
|
|
6
15
|
isInvalid: boolean;
|
|
16
|
+
/** Specifies whether the input text has valid length or not. */
|
|
7
17
|
isValidLength: boolean;
|
|
8
|
-
private _handleUpdateCounterBound: any;
|
|
9
|
-
counterEl: HTMLSpanElement;
|
|
10
18
|
|
|
11
|
-
constructor(el:
|
|
12
|
-
super(
|
|
19
|
+
constructor(el: HTMLInputElement | HTMLTextAreaElement, options: Partial<CharacterCounterOptions>) {
|
|
20
|
+
super(el, {}, CharacterCounter);
|
|
13
21
|
(this.el as any).M_CharacterCounter = this;
|
|
14
|
-
|
|
22
|
+
|
|
23
|
+
this.options = {
|
|
24
|
+
...CharacterCounter.defaults,
|
|
25
|
+
...options
|
|
26
|
+
};
|
|
27
|
+
|
|
15
28
|
this.isInvalid = false;
|
|
16
29
|
this.isValidLength = false;
|
|
30
|
+
|
|
17
31
|
this._setupCounter();
|
|
18
32
|
this._setupEventHandlers();
|
|
19
33
|
}
|
|
20
34
|
|
|
21
|
-
static get defaults() {
|
|
35
|
+
static get defaults(): CharacterCounterOptions {
|
|
22
36
|
return _defaults;
|
|
23
37
|
}
|
|
24
38
|
|
|
25
|
-
|
|
26
|
-
|
|
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);
|
|
27
58
|
}
|
|
28
59
|
|
|
29
|
-
static getInstance(el) {
|
|
30
|
-
|
|
31
|
-
return domElem.M_CharacterCounter;
|
|
60
|
+
static getInstance(el: InputElement): CharacterCounter {
|
|
61
|
+
return (el as any).M_CharacterCounter;
|
|
32
62
|
}
|
|
33
63
|
|
|
34
64
|
destroy() {
|
|
@@ -38,14 +68,13 @@ export class CharacterCounter extends Component {
|
|
|
38
68
|
}
|
|
39
69
|
|
|
40
70
|
_setupEventHandlers() {
|
|
41
|
-
this.
|
|
42
|
-
this.el.addEventListener('
|
|
43
|
-
this.el.addEventListener('input', this._handleUpdateCounterBound, true);
|
|
71
|
+
this.el.addEventListener('focus', this.updateCounter, true);
|
|
72
|
+
this.el.addEventListener('input', this.updateCounter, true);
|
|
44
73
|
}
|
|
45
74
|
|
|
46
75
|
_removeEventHandlers() {
|
|
47
|
-
this.el.removeEventListener('focus', this.
|
|
48
|
-
this.el.removeEventListener('input', this.
|
|
76
|
+
this.el.removeEventListener('focus', this.updateCounter, true);
|
|
77
|
+
this.el.removeEventListener('input', this.updateCounter, true);
|
|
49
78
|
}
|
|
50
79
|
|
|
51
80
|
_setupCounter() {
|
|
@@ -61,8 +90,8 @@ export class CharacterCounter extends Component {
|
|
|
61
90
|
this.counterEl.remove();
|
|
62
91
|
}
|
|
63
92
|
|
|
64
|
-
updateCounter() {
|
|
65
|
-
let maxLength = parseInt(this.el.getAttribute('
|
|
93
|
+
updateCounter = () => {
|
|
94
|
+
let maxLength = parseInt(this.el.getAttribute('maxlength')),
|
|
66
95
|
actualLength = (this.el as HTMLInputElement).value.length;
|
|
67
96
|
|
|
68
97
|
this.isValidLength = actualLength <= maxLength;
|
package/src/chips.ts
CHANGED
|
@@ -1,11 +1,80 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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
|
+
}
|
|
4
72
|
|
|
5
|
-
let _defaults = {
|
|
73
|
+
let _defaults: ChipsOptions = {
|
|
6
74
|
data: [],
|
|
7
75
|
placeholder: '',
|
|
8
76
|
secondaryPlaceholder: '',
|
|
77
|
+
closeIconClass: 'material-icons',
|
|
9
78
|
autocompleteOptions: {},
|
|
10
79
|
autocompleteOnly: false,
|
|
11
80
|
limit: Infinity,
|
|
@@ -14,35 +83,31 @@ let _defaults = {
|
|
|
14
83
|
onChipDelete: null
|
|
15
84
|
};
|
|
16
85
|
|
|
17
|
-
interface DataBit {
|
|
18
|
-
id: string, // required
|
|
19
|
-
text?: string,
|
|
20
|
-
image?: string,
|
|
21
|
-
description?: string,
|
|
22
|
-
}
|
|
23
|
-
|
|
24
86
|
function gGetIndex(el: HTMLElement): number {
|
|
25
87
|
return [...el.parentNode.children].indexOf(el);
|
|
26
88
|
}
|
|
27
89
|
|
|
28
|
-
export class Chips extends Component {
|
|
29
|
-
|
|
90
|
+
export class Chips extends Component<ChipsOptions> {
|
|
91
|
+
/** Array of the current chips data. */
|
|
92
|
+
chipsData: ChipData[];
|
|
93
|
+
/** If the chips has autocomplete enabled. */
|
|
30
94
|
hasAutocomplete: boolean;
|
|
95
|
+
/** Autocomplete instance, if any. */
|
|
31
96
|
autocomplete: Autocomplete;
|
|
32
97
|
_input: HTMLInputElement;
|
|
33
98
|
_label: any;
|
|
34
99
|
_chips: HTMLElement[];
|
|
35
|
-
private _handleChipClickBound: any;
|
|
36
|
-
private _handleInputKeydownBound: any;
|
|
37
|
-
private _handleInputFocusBound: any;
|
|
38
|
-
private _handleInputBlurBound: any;
|
|
39
100
|
static _keydown: boolean;
|
|
40
101
|
private _selectedChip: any;
|
|
41
102
|
|
|
42
|
-
constructor(el, options) {
|
|
43
|
-
super(
|
|
103
|
+
constructor(el: HTMLElement, options: Partial<ChipsOptions>) {
|
|
104
|
+
super(el, options, Chips);
|
|
44
105
|
(this.el as any).M_Chips = this;
|
|
45
|
-
|
|
106
|
+
|
|
107
|
+
this.options = {
|
|
108
|
+
...Chips.defaults,
|
|
109
|
+
...options
|
|
110
|
+
};
|
|
46
111
|
|
|
47
112
|
this.el.classList.add('chips', 'input-field');
|
|
48
113
|
this.chipsData = [];
|
|
@@ -52,7 +117,7 @@ export class Chips extends Component {
|
|
|
52
117
|
|
|
53
118
|
// Set input id
|
|
54
119
|
if (!this._input.getAttribute('id'))
|
|
55
|
-
this._input.setAttribute('id',
|
|
120
|
+
this._input.setAttribute('id', Utils.guid());
|
|
56
121
|
|
|
57
122
|
// Render initial chips
|
|
58
123
|
if (this.options.data.length) {
|
|
@@ -70,13 +135,29 @@ export class Chips extends Component {
|
|
|
70
135
|
return _defaults;
|
|
71
136
|
}
|
|
72
137
|
|
|
73
|
-
|
|
74
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Initializes instance of Chips.
|
|
140
|
+
* @param el HTML element.
|
|
141
|
+
* @param options Component options.
|
|
142
|
+
*/
|
|
143
|
+
static init(el: HTMLElement, 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);
|
|
75
157
|
}
|
|
76
158
|
|
|
77
|
-
static getInstance(el) {
|
|
78
|
-
|
|
79
|
-
return domElem.M_Chips;
|
|
159
|
+
static getInstance(el: HTMLElement): Chips {
|
|
160
|
+
return (el as any).M_Chips;
|
|
80
161
|
}
|
|
81
162
|
|
|
82
163
|
getData() {
|
|
@@ -91,30 +172,26 @@ export class Chips extends Component {
|
|
|
91
172
|
}
|
|
92
173
|
|
|
93
174
|
_setupEventHandlers() {
|
|
94
|
-
this.
|
|
95
|
-
this._handleInputKeydownBound = this._handleInputKeydown.bind(this);
|
|
96
|
-
this._handleInputFocusBound = this._handleInputFocus.bind(this);
|
|
97
|
-
this._handleInputBlurBound = this._handleInputBlur.bind(this);
|
|
98
|
-
this.el.addEventListener('click', this._handleChipClickBound);
|
|
175
|
+
this.el.addEventListener('click', this._handleChipClick);
|
|
99
176
|
document.addEventListener('keydown', Chips._handleChipsKeydown);
|
|
100
177
|
document.addEventListener('keyup', Chips._handleChipsKeyup);
|
|
101
178
|
this.el.addEventListener('blur', Chips._handleChipsBlur, true);
|
|
102
|
-
this._input.addEventListener('focus', this.
|
|
103
|
-
this._input.addEventListener('blur', this.
|
|
104
|
-
this._input.addEventListener('keydown', this.
|
|
179
|
+
this._input.addEventListener('focus', this._handleInputFocus);
|
|
180
|
+
this._input.addEventListener('blur', this._handleInputBlur);
|
|
181
|
+
this._input.addEventListener('keydown', this._handleInputKeydown);
|
|
105
182
|
}
|
|
106
183
|
|
|
107
184
|
_removeEventHandlers() {
|
|
108
|
-
this.el.removeEventListener('click', this.
|
|
185
|
+
this.el.removeEventListener('click', this._handleChipClick);
|
|
109
186
|
document.removeEventListener('keydown', Chips._handleChipsKeydown);
|
|
110
187
|
document.removeEventListener('keyup', Chips._handleChipsKeyup);
|
|
111
188
|
this.el.removeEventListener('blur', Chips._handleChipsBlur, true);
|
|
112
|
-
this._input.removeEventListener('focus', this.
|
|
113
|
-
this._input.removeEventListener('blur', this.
|
|
114
|
-
this._input.removeEventListener('keydown', this.
|
|
189
|
+
this._input.removeEventListener('focus', this._handleInputFocus);
|
|
190
|
+
this._input.removeEventListener('blur', this._handleInputBlur);
|
|
191
|
+
this._input.removeEventListener('keydown', this._handleInputKeydown);
|
|
115
192
|
}
|
|
116
193
|
|
|
117
|
-
_handleChipClick(e) {
|
|
194
|
+
_handleChipClick = (e: MouseEvent) => {
|
|
118
195
|
const _chip = (<HTMLElement>e.target).closest('.chip');
|
|
119
196
|
const clickedClose = (<HTMLElement>e.target).classList.contains('close');
|
|
120
197
|
if (_chip) {
|
|
@@ -133,7 +210,7 @@ export class Chips extends Component {
|
|
|
133
210
|
}
|
|
134
211
|
}
|
|
135
212
|
|
|
136
|
-
static _handleChipsKeydown(e) {
|
|
213
|
+
static _handleChipsKeydown(e: KeyboardEvent) {
|
|
137
214
|
Chips._keydown = true;
|
|
138
215
|
const chips = (<HTMLElement>e.target).closest('.chips');
|
|
139
216
|
const chipsKeydown = e.target && chips;
|
|
@@ -141,10 +218,10 @@ export class Chips extends Component {
|
|
|
141
218
|
// Don't handle keydown inputs on input and textarea
|
|
142
219
|
const tag = (<HTMLElement>e.target).tagName;
|
|
143
220
|
if (tag === 'INPUT' || tag === 'TEXTAREA' || !chipsKeydown) return;
|
|
144
|
-
|
|
221
|
+
|
|
145
222
|
const currChips: Chips = (chips as any).M_Chips;
|
|
146
|
-
|
|
147
|
-
if (e.
|
|
223
|
+
|
|
224
|
+
if (Utils.keys.BACKSPACE.includes(e.key) || Utils.keys.DELETE.includes(e.key)) {
|
|
148
225
|
e.preventDefault();
|
|
149
226
|
let selectIndex = currChips.chipsData.length;
|
|
150
227
|
if (currChips._selectedChip) {
|
|
@@ -159,16 +236,14 @@ export class Chips extends Component {
|
|
|
159
236
|
else
|
|
160
237
|
currChips._input.focus();
|
|
161
238
|
}
|
|
162
|
-
|
|
163
|
-
else if (e.keyCode === 37) {
|
|
239
|
+
else if (Utils.keys.ARROW_LEFT.includes(e.key)) {
|
|
164
240
|
if (currChips._selectedChip) {
|
|
165
241
|
const selectIndex = gGetIndex(currChips._selectedChip) - 1;
|
|
166
242
|
if (selectIndex < 0) return;
|
|
167
243
|
currChips.selectChip(selectIndex);
|
|
168
244
|
}
|
|
169
245
|
}
|
|
170
|
-
|
|
171
|
-
else if (e.keyCode === 39) {
|
|
246
|
+
else if (Utils.keys.ARROW_RIGHT.includes(e.key)) {
|
|
172
247
|
if (currChips._selectedChip) {
|
|
173
248
|
const selectIndex = gGetIndex(currChips._selectedChip) + 1;
|
|
174
249
|
if (selectIndex >= currChips.chipsData.length)
|
|
@@ -179,11 +254,11 @@ export class Chips extends Component {
|
|
|
179
254
|
}
|
|
180
255
|
}
|
|
181
256
|
|
|
182
|
-
static _handleChipsKeyup(e) {
|
|
257
|
+
static _handleChipsKeyup(e: Event) {
|
|
183
258
|
Chips._keydown = false;
|
|
184
259
|
}
|
|
185
260
|
|
|
186
|
-
static _handleChipsBlur(e) {
|
|
261
|
+
static _handleChipsBlur(e: Event) {
|
|
187
262
|
if (!Chips._keydown && document.hidden) {
|
|
188
263
|
const chips = (<HTMLElement>e.target).closest('.chips');
|
|
189
264
|
const currChips: Chips = (chips as any).M_Chips;
|
|
@@ -191,18 +266,17 @@ export class Chips extends Component {
|
|
|
191
266
|
}
|
|
192
267
|
}
|
|
193
268
|
|
|
194
|
-
_handleInputFocus() {
|
|
269
|
+
_handleInputFocus = () => {
|
|
195
270
|
this.el.classList.add('focus');
|
|
196
271
|
}
|
|
197
272
|
|
|
198
|
-
_handleInputBlur() {
|
|
273
|
+
_handleInputBlur = () => {
|
|
199
274
|
this.el.classList.remove('focus');
|
|
200
275
|
}
|
|
201
276
|
|
|
202
|
-
_handleInputKeydown(e) {
|
|
277
|
+
_handleInputKeydown = (e: KeyboardEvent) => {
|
|
203
278
|
Chips._keydown = true;
|
|
204
|
-
|
|
205
|
-
if (e.keyCode === 13) {
|
|
279
|
+
if (Utils.keys.ENTER.includes(e.key)) {
|
|
206
280
|
// Override enter if autocompleting.
|
|
207
281
|
if (this.hasAutocomplete && this.autocomplete && this.autocomplete.isOpen) {
|
|
208
282
|
return;
|
|
@@ -212,10 +286,9 @@ export class Chips extends Component {
|
|
|
212
286
|
this.addChip({id: this._input.value});
|
|
213
287
|
}
|
|
214
288
|
this._input.value = '';
|
|
215
|
-
// delete or left
|
|
216
289
|
}
|
|
217
|
-
else if (
|
|
218
|
-
(e.
|
|
290
|
+
else if (
|
|
291
|
+
(Utils.keys.BACKSPACE.includes(e.key) || Utils.keys.ARROW_LEFT.includes(e.key)) &&
|
|
219
292
|
this._input.value === '' &&
|
|
220
293
|
this.chipsData.length
|
|
221
294
|
) {
|
|
@@ -224,14 +297,14 @@ export class Chips extends Component {
|
|
|
224
297
|
}
|
|
225
298
|
}
|
|
226
299
|
|
|
227
|
-
_renderChip(chip:
|
|
300
|
+
_renderChip(chip: ChipData): HTMLDivElement {
|
|
228
301
|
if (!chip.id) return;
|
|
229
302
|
const renderedChip = document.createElement('div');
|
|
230
303
|
renderedChip.classList.add('chip');
|
|
231
|
-
renderedChip.innerText = chip.text || chip.id;
|
|
304
|
+
renderedChip.innerText = chip.text || <string>chip.id;
|
|
232
305
|
renderedChip.setAttribute('tabindex', "0");
|
|
233
306
|
const closeIcon = document.createElement('i');
|
|
234
|
-
closeIcon.classList.add(
|
|
307
|
+
closeIcon.classList.add(this.options.closeIconClass, 'close');
|
|
235
308
|
closeIcon.innerText = 'close';
|
|
236
309
|
// attach image if needed
|
|
237
310
|
if (chip.image) {
|
|
@@ -256,7 +329,11 @@ export class Chips extends Component {
|
|
|
256
329
|
|
|
257
330
|
_setupAutocomplete() {
|
|
258
331
|
this.options.autocompleteOptions.onAutocomplete = (items) => {
|
|
259
|
-
if (items.length > 0) this.addChip(
|
|
332
|
+
if (items.length > 0) this.addChip({
|
|
333
|
+
id: items[0].id,
|
|
334
|
+
text: items[0].text,
|
|
335
|
+
image: items[0].image
|
|
336
|
+
});
|
|
260
337
|
this._input.value = '';
|
|
261
338
|
this._input.focus();
|
|
262
339
|
};
|
|
@@ -289,13 +366,17 @@ export class Chips extends Component {
|
|
|
289
366
|
}
|
|
290
367
|
}
|
|
291
368
|
|
|
292
|
-
_isValidAndNotExist(chip:
|
|
369
|
+
_isValidAndNotExist(chip: ChipData) {
|
|
293
370
|
const isValid = !!chip.id;
|
|
294
371
|
const doesNotExist = !this.chipsData.some(item => item.id == chip.id);
|
|
295
372
|
return isValid && doesNotExist;
|
|
296
373
|
}
|
|
297
374
|
|
|
298
|
-
|
|
375
|
+
/**
|
|
376
|
+
* Add chip to input.
|
|
377
|
+
* @param chip Chip data object
|
|
378
|
+
*/
|
|
379
|
+
addChip(chip: ChipData) {
|
|
299
380
|
if (!this._isValidAndNotExist(chip) || this.chipsData.length >= this.options.limit) return;
|
|
300
381
|
const renderedChip = this._renderChip(chip);
|
|
301
382
|
this._chips.push(renderedChip);
|
|
@@ -309,6 +390,10 @@ export class Chips extends Component {
|
|
|
309
390
|
}
|
|
310
391
|
}
|
|
311
392
|
|
|
393
|
+
/**
|
|
394
|
+
* Delete nth chip.
|
|
395
|
+
* @param chipIndex Index of chip
|
|
396
|
+
*/
|
|
312
397
|
deleteChip(chipIndex: number) {
|
|
313
398
|
const chip = this._chips[chipIndex];
|
|
314
399
|
this._chips[chipIndex].remove();
|
|
@@ -321,6 +406,10 @@ export class Chips extends Component {
|
|
|
321
406
|
}
|
|
322
407
|
}
|
|
323
408
|
|
|
409
|
+
/**
|
|
410
|
+
* Select nth chip.
|
|
411
|
+
* @param chipIndex Index of chip
|
|
412
|
+
*/
|
|
324
413
|
selectChip(chipIndex: number) {
|
|
325
414
|
const chip = this._chips[chipIndex];
|
|
326
415
|
this._selectedChip = chip;
|
package/src/collapsible.ts
CHANGED
|
@@ -1,25 +1,68 @@
|
|
|
1
|
-
import { Component } from "./component";
|
|
2
1
|
import anim from "animejs";
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import { Utils } from "./utils";
|
|
4
|
+
import { Component, BaseOptions, InitElements, MElement } from "./component";
|
|
5
|
+
|
|
6
|
+
export interface CollapsibleOptions extends BaseOptions {
|
|
7
|
+
/**
|
|
8
|
+
* If accordion versus collapsible.
|
|
9
|
+
* @default true
|
|
10
|
+
*/
|
|
11
|
+
accordion: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Transition in duration in milliseconds.
|
|
14
|
+
* @default 300
|
|
15
|
+
*/
|
|
16
|
+
inDuration: number;
|
|
17
|
+
/**
|
|
18
|
+
* Transition out duration in milliseconds.
|
|
19
|
+
* @default 300
|
|
20
|
+
*/
|
|
21
|
+
outDuration: number;
|
|
22
|
+
/**
|
|
23
|
+
* Callback function called before collapsible is opened.
|
|
24
|
+
* @default null
|
|
25
|
+
*/
|
|
26
|
+
onOpenStart: (el: Element) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Callback function called after collapsible is opened.
|
|
29
|
+
* @default null
|
|
30
|
+
*/
|
|
31
|
+
onOpenEnd: (el: Element) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Callback function called before collapsible is closed.
|
|
34
|
+
* @default null
|
|
35
|
+
*/
|
|
36
|
+
onCloseStart: (el: Element) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Callback function called after collapsible is closed.
|
|
39
|
+
* @default null
|
|
40
|
+
*/
|
|
41
|
+
onCloseEnd: (el: Element) => void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const _defaults: CollapsibleOptions = {
|
|
5
45
|
accordion: true,
|
|
6
|
-
onOpenStart:
|
|
7
|
-
onOpenEnd:
|
|
8
|
-
onCloseStart:
|
|
9
|
-
onCloseEnd:
|
|
46
|
+
onOpenStart: null,
|
|
47
|
+
onOpenEnd: null,
|
|
48
|
+
onCloseStart: null,
|
|
49
|
+
onCloseEnd: null,
|
|
10
50
|
inDuration: 300,
|
|
11
51
|
outDuration: 300
|
|
12
52
|
};
|
|
13
53
|
|
|
14
|
-
export class Collapsible extends Component {
|
|
54
|
+
export class Collapsible extends Component<CollapsibleOptions> {
|
|
15
55
|
private _headers: HTMLElement[];
|
|
16
|
-
private _handleCollapsibleClickBound: any;
|
|
17
|
-
private _handleCollapsibleKeydownBound: any;
|
|
18
56
|
|
|
19
|
-
constructor(el, options) {
|
|
20
|
-
super(
|
|
57
|
+
constructor(el: HTMLElement, options: Partial<CollapsibleOptions>) {
|
|
58
|
+
super(el, options, Collapsible);
|
|
21
59
|
(this.el as any).M_Collapsible = this;
|
|
22
|
-
|
|
60
|
+
|
|
61
|
+
this.options = {
|
|
62
|
+
...Collapsible.defaults,
|
|
63
|
+
...options
|
|
64
|
+
};
|
|
65
|
+
|
|
23
66
|
// Setup tab indices
|
|
24
67
|
this._headers = Array.from(this.el.querySelectorAll('li > .collapsible-header'));
|
|
25
68
|
this._headers.forEach(el => el.tabIndex = 0);
|
|
@@ -29,21 +72,37 @@ export class Collapsible extends Component {
|
|
|
29
72
|
if (this.options.accordion)
|
|
30
73
|
if (activeBodies.length > 0)
|
|
31
74
|
activeBodies[0].style.display = 'block'; // Accordion
|
|
32
|
-
else
|
|
75
|
+
else
|
|
33
76
|
activeBodies.forEach(el => el.style.display = 'block'); // Expandables
|
|
34
77
|
}
|
|
35
78
|
|
|
36
|
-
static get defaults() {
|
|
79
|
+
static get defaults(): CollapsibleOptions {
|
|
37
80
|
return _defaults;
|
|
38
81
|
}
|
|
39
82
|
|
|
40
|
-
|
|
41
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Initializes instance of Collapsible.
|
|
85
|
+
* @param el HTML element.
|
|
86
|
+
* @param options Component options.
|
|
87
|
+
*/
|
|
88
|
+
static init(el: HTMLElement, options?: Partial<CollapsibleOptions>): Collapsible;
|
|
89
|
+
/**
|
|
90
|
+
* Initializes instances of Collapsible.
|
|
91
|
+
* @param els HTML elements.
|
|
92
|
+
* @param options Component options.
|
|
93
|
+
*/
|
|
94
|
+
static init(els: InitElements<MElement>, options?: Partial<CollapsibleOptions>): Collapsible[];
|
|
95
|
+
/**
|
|
96
|
+
* Initializes instances of Collapsible.
|
|
97
|
+
* @param els HTML elements.
|
|
98
|
+
* @param options Component options.
|
|
99
|
+
*/
|
|
100
|
+
static init(els: HTMLElement | InitElements<MElement>, options: Partial<CollapsibleOptions> = {}): Collapsible | Collapsible[] {
|
|
101
|
+
return super.init(els, options, Collapsible);
|
|
42
102
|
}
|
|
43
103
|
|
|
44
|
-
static getInstance(el) {
|
|
45
|
-
|
|
46
|
-
return domElem.M_Collapsible;
|
|
104
|
+
static getInstance(el: HTMLElement): Collapsible {
|
|
105
|
+
return (el as any).M_Collapsible;
|
|
47
106
|
}
|
|
48
107
|
|
|
49
108
|
destroy() {
|
|
@@ -52,19 +111,17 @@ export class Collapsible extends Component {
|
|
|
52
111
|
}
|
|
53
112
|
|
|
54
113
|
_setupEventHandlers() {
|
|
55
|
-
this.
|
|
56
|
-
this.
|
|
57
|
-
this.el.addEventListener('click', this._handleCollapsibleClickBound);
|
|
58
|
-
this._headers.forEach(header => header.addEventListener('keydown', this._handleCollapsibleKeydownBound));
|
|
114
|
+
this.el.addEventListener('click', this._handleCollapsibleClick);
|
|
115
|
+
this._headers.forEach(header => header.addEventListener('keydown', this._handleCollapsibleKeydown));
|
|
59
116
|
}
|
|
60
117
|
|
|
61
118
|
_removeEventHandlers() {
|
|
62
|
-
this.el.removeEventListener('click', this.
|
|
63
|
-
this._headers.forEach(header => header.removeEventListener('keydown', this.
|
|
119
|
+
this.el.removeEventListener('click', this._handleCollapsibleClick);
|
|
120
|
+
this._headers.forEach(header => header.removeEventListener('keydown', this._handleCollapsibleKeydown));
|
|
64
121
|
}
|
|
65
122
|
|
|
66
|
-
_handleCollapsibleClick(e) {
|
|
67
|
-
const header = e.target.closest('.collapsible-header');
|
|
123
|
+
_handleCollapsibleClick = (e: MouseEvent | KeyboardEvent) => {
|
|
124
|
+
const header = (e.target as HTMLElement).closest('.collapsible-header');
|
|
68
125
|
if (e.target && header) {
|
|
69
126
|
const collapsible = header.closest('.collapsible');
|
|
70
127
|
if (collapsible !== this.el) return;
|
|
@@ -80,9 +137,9 @@ export class Collapsible extends Component {
|
|
|
80
137
|
}
|
|
81
138
|
}
|
|
82
139
|
|
|
83
|
-
_handleCollapsibleKeydown(e) {
|
|
84
|
-
if (e.
|
|
85
|
-
this.
|
|
140
|
+
_handleCollapsibleKeydown = (e: KeyboardEvent) => {
|
|
141
|
+
if (Utils.keys.ENTER.includes(e.key)) {
|
|
142
|
+
this._handleCollapsibleClick(e);
|
|
86
143
|
}
|
|
87
144
|
}
|
|
88
145
|
|
|
@@ -147,7 +204,11 @@ export class Collapsible extends Component {
|
|
|
147
204
|
});
|
|
148
205
|
}
|
|
149
206
|
|
|
150
|
-
|
|
207
|
+
/**
|
|
208
|
+
* Open collapsible section.
|
|
209
|
+
* @param n Nth section to open.
|
|
210
|
+
*/
|
|
211
|
+
open = (index: number) => {
|
|
151
212
|
const listItems = Array.from(this.el.children).filter(c => c.tagName === 'LI');
|
|
152
213
|
const li = listItems[index];
|
|
153
214
|
if (li && !li.classList.contains('active')) {
|
|
@@ -169,7 +230,11 @@ export class Collapsible extends Component {
|
|
|
169
230
|
}
|
|
170
231
|
}
|
|
171
232
|
|
|
172
|
-
|
|
233
|
+
/**
|
|
234
|
+
* Close collapsible section.
|
|
235
|
+
* @param n Nth section to close.
|
|
236
|
+
*/
|
|
237
|
+
close = (index: number) => {
|
|
173
238
|
const li = Array.from(this.el.children).filter(c => c.tagName === 'LI')[index];
|
|
174
239
|
if (li && li.classList.contains('active')) {
|
|
175
240
|
// onCloseStart callback
|