wcs-core 4.1.0 → 4.2.0
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 +59 -90
- package/dist/cjs/accessibility-e99b032d.js +68 -0
- package/dist/cjs/accessibility-e99b032d.js.map +1 -0
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/wcs-checkbox.cjs.entry.js +1 -0
- package/dist/cjs/wcs-checkbox.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs-counter.cjs.entry.js +1 -0
- package/dist/cjs/wcs-counter.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs-dropdown.cjs.entry.js +3 -5
- package/dist/cjs/wcs-dropdown.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs-grid.cjs.entry.js +1 -1
- package/dist/cjs/wcs-grid.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs-input.cjs.entry.js +1 -3
- package/dist/cjs/wcs-input.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs-modal.cjs.entry.js +68 -6
- package/dist/cjs/wcs-modal.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs-native-select.cjs.entry.js +19 -0
- package/dist/cjs/wcs-native-select.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs-radio-group.cjs.entry.js +48 -4
- package/dist/cjs/wcs-radio-group.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs-radio.cjs.entry.js +17 -4
- package/dist/cjs/wcs-radio.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs-tab.cjs.entry.js +1 -1
- package/dist/cjs/wcs-tab.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs-tabs.cjs.entry.js +37 -1
- package/dist/cjs/wcs-tabs.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs-textarea.cjs.entry.js +3 -2
- package/dist/cjs/wcs-textarea.cjs.entry.js.map +1 -1
- package/dist/cjs/wcs.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +2 -2
- package/dist/collection/components/checkbox/checkbox.js +1 -0
- package/dist/collection/components/checkbox/checkbox.js.map +1 -1
- package/dist/collection/components/counter/counter.js +1 -0
- package/dist/collection/components/counter/counter.js.map +1 -1
- package/dist/collection/components/dropdown/dropdown.js +1 -0
- package/dist/collection/components/dropdown/dropdown.js.map +1 -1
- package/dist/collection/components/grid/grid.js +1 -1
- package/dist/collection/components/grid/grid.js.map +1 -1
- package/dist/collection/components/input/input.js +2 -4
- package/dist/collection/components/input/input.js.map +1 -1
- package/dist/collection/components/modal/modal.js +71 -6
- package/dist/collection/components/modal/modal.js.map +1 -1
- package/dist/collection/components/native-select/{native-select.component.js → native-select.js} +58 -7
- package/dist/collection/components/native-select/native-select.js.map +1 -0
- package/dist/collection/components/radio/radio.css +13 -1
- package/dist/collection/components/radio/{radio.component.js → radio.js} +37 -4
- package/dist/collection/components/radio/radio.js.map +1 -0
- package/dist/collection/components/radio-group/radio-group.js +60 -4
- package/dist/collection/components/radio-group/radio-group.js.map +1 -1
- package/dist/collection/components/tab/tab.js +1 -1
- package/dist/collection/components/tab/tab.js.map +1 -1
- package/dist/collection/components/tabs/tabs.js +54 -1
- package/dist/collection/components/tabs/tabs.js.map +1 -1
- package/dist/collection/components/textarea/textarea.js +8 -4
- package/dist/collection/components/textarea/textarea.js.map +1 -1
- package/dist/collection/utils/accessibility.js +58 -0
- package/dist/collection/utils/accessibility.js.map +1 -1
- package/dist/esm/accessibility-ffa12842.js +65 -0
- package/dist/esm/accessibility-ffa12842.js.map +1 -0
- package/dist/esm/{helpers-1f7170dd.js → helpers-1d55b67f.js} +2 -2
- package/dist/esm/{helpers-1f7170dd.js.map → helpers-1d55b67f.js.map} +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/wcs-button.entry.js +1 -1
- package/dist/esm/wcs-checkbox.entry.js +1 -0
- package/dist/esm/wcs-checkbox.entry.js.map +1 -1
- package/dist/esm/wcs-com-nav-category.entry.js +1 -1
- package/dist/esm/wcs-com-nav-submenu.entry.js +1 -1
- package/dist/esm/wcs-com-nav.entry.js +1 -1
- package/dist/esm/wcs-counter.entry.js +2 -1
- package/dist/esm/wcs-counter.entry.js.map +1 -1
- package/dist/esm/wcs-dropdown-item.entry.js +1 -1
- package/dist/esm/wcs-dropdown.entry.js +3 -5
- package/dist/esm/wcs-dropdown.entry.js.map +1 -1
- package/dist/esm/wcs-galactic-menu.entry.js +1 -1
- package/dist/esm/wcs-grid.entry.js +1 -1
- package/dist/esm/wcs-grid.entry.js.map +1 -1
- package/dist/esm/wcs-input.entry.js +2 -4
- package/dist/esm/wcs-input.entry.js.map +1 -1
- package/dist/esm/wcs-modal.entry.js +69 -7
- package/dist/esm/wcs-modal.entry.js.map +1 -1
- package/dist/esm/wcs-native-select.entry.js +19 -0
- package/dist/esm/wcs-native-select.entry.js.map +1 -1
- package/dist/esm/wcs-nav-item.entry.js +1 -1
- package/dist/esm/wcs-radio-group.entry.js +48 -4
- package/dist/esm/wcs-radio-group.entry.js.map +1 -1
- package/dist/esm/wcs-radio.entry.js +18 -5
- package/dist/esm/wcs-radio.entry.js.map +1 -1
- package/dist/esm/wcs-select_2.entry.js +1 -1
- package/dist/esm/wcs-tab.entry.js +1 -1
- package/dist/esm/wcs-tab.entry.js.map +1 -1
- package/dist/esm/wcs-tabs.entry.js +37 -1
- package/dist/esm/wcs-tabs.entry.js.map +1 -1
- package/dist/esm/wcs-textarea.entry.js +4 -3
- package/dist/esm/wcs-textarea.entry.js.map +1 -1
- package/dist/esm/wcs.js +1 -1
- package/dist/types/components/input/input.d.ts +1 -3
- package/dist/types/components/modal/modal.d.ts +25 -5
- package/dist/types/components/native-select/{native-select.component.d.ts → native-select.d.ts} +22 -5
- package/dist/types/components/radio/{radio.component.d.ts → radio.d.ts} +2 -0
- package/dist/types/components/radio-group/radio-group.d.ts +3 -0
- package/dist/types/components/tabs/tabs.d.ts +13 -0
- package/dist/types/components/textarea/textarea.d.ts +2 -2
- package/dist/types/components.d.ts +74 -24
- package/dist/types/utils/accessibility.d.ts +2 -0
- package/dist/wcs/p-0f8db386.js +2 -0
- package/dist/wcs/p-0f8db386.js.map +1 -0
- package/dist/wcs/{p-4b4d53e2.entry.js → p-1f8c73eb.entry.js} +2 -2
- package/dist/wcs/{p-554ca93c.entry.js → p-2185bf8b.entry.js} +2 -2
- package/dist/wcs/{p-22480bd8.entry.js → p-2f63d6c5.entry.js} +2 -2
- package/dist/wcs/p-2f63d6c5.entry.js.map +1 -0
- package/dist/wcs/p-39821dd2.entry.js +2 -0
- package/dist/wcs/p-39821dd2.entry.js.map +1 -0
- package/dist/wcs/{p-84afb8af.entry.js → p-3b1fc676.entry.js} +2 -2
- package/dist/wcs/{p-12ac2547.js → p-3dc6b507.js} +2 -2
- package/dist/wcs/p-4ffe4539.entry.js +2 -0
- package/dist/wcs/p-4ffe4539.entry.js.map +1 -0
- package/dist/wcs/p-61cab06f.entry.js +2 -0
- package/dist/wcs/p-61cab06f.entry.js.map +1 -0
- package/dist/wcs/{p-15058c29.entry.js → p-6de70331.entry.js} +2 -2
- package/dist/wcs/p-6de70331.entry.js.map +1 -0
- package/dist/wcs/{p-b6cd196d.entry.js → p-7269272f.entry.js} +2 -2
- package/dist/wcs/{p-966a241e.entry.js → p-7519a270.entry.js} +2 -2
- package/dist/wcs/{p-6b66ce85.entry.js → p-8c4ed883.entry.js} +2 -2
- package/dist/wcs/p-8c4ed883.entry.js.map +1 -0
- package/dist/wcs/p-8fed8b1c.entry.js +2 -0
- package/dist/wcs/p-8fed8b1c.entry.js.map +1 -0
- package/dist/wcs/{p-d2da0c9f.entry.js → p-ac106663.entry.js} +2 -2
- package/dist/wcs/{p-d2da0c9f.entry.js.map → p-ac106663.entry.js.map} +1 -1
- package/dist/wcs/{p-b229a91c.entry.js → p-cb90bc3a.entry.js} +2 -2
- package/dist/wcs/{p-f82e7a61.entry.js → p-e348058b.entry.js} +2 -2
- package/dist/wcs/{p-405140f9.entry.js → p-ec84d6fd.entry.js} +2 -2
- package/dist/wcs/{p-26c4c983.entry.js → p-ed3132be.entry.js} +2 -2
- package/dist/wcs/p-ed3132be.entry.js.map +1 -0
- package/dist/wcs/p-f06f48f3.entry.js +2 -0
- package/dist/wcs/{p-6acbf38a.entry.js.map → p-f06f48f3.entry.js.map} +1 -1
- package/dist/wcs/p-f20b9024.entry.js +2 -0
- package/dist/wcs/p-f20b9024.entry.js.map +1 -0
- package/dist/wcs/p-f489793d.entry.js +2 -0
- package/dist/wcs/p-f489793d.entry.js.map +1 -0
- package/dist/wcs/wcs.esm.js +1 -1
- package/dist/wcs/wcs.esm.js.map +1 -1
- package/package.json +3 -2
- package/dist/collection/components/native-select/native-select.component.js.map +0 -1
- package/dist/collection/components/radio/radio.component.js.map +0 -1
- package/dist/wcs/p-069555a1.entry.js +0 -2
- package/dist/wcs/p-069555a1.entry.js.map +0 -1
- package/dist/wcs/p-07b8cd36.entry.js +0 -2
- package/dist/wcs/p-07b8cd36.entry.js.map +0 -1
- package/dist/wcs/p-15058c29.entry.js.map +0 -1
- package/dist/wcs/p-22480bd8.entry.js.map +0 -1
- package/dist/wcs/p-26c4c983.entry.js.map +0 -1
- package/dist/wcs/p-64dd7356.entry.js +0 -2
- package/dist/wcs/p-64dd7356.entry.js.map +0 -1
- package/dist/wcs/p-6acbf38a.entry.js +0 -2
- package/dist/wcs/p-6b66ce85.entry.js.map +0 -1
- package/dist/wcs/p-732b2faa.entry.js +0 -2
- package/dist/wcs/p-732b2faa.entry.js.map +0 -1
- package/dist/wcs/p-94d95b99.entry.js +0 -2
- package/dist/wcs/p-94d95b99.entry.js.map +0 -1
- package/dist/wcs/p-b856f2f6.entry.js +0 -2
- package/dist/wcs/p-b856f2f6.entry.js.map +0 -1
- /package/dist/wcs/{p-4b4d53e2.entry.js.map → p-1f8c73eb.entry.js.map} +0 -0
- /package/dist/wcs/{p-554ca93c.entry.js.map → p-2185bf8b.entry.js.map} +0 -0
- /package/dist/wcs/{p-84afb8af.entry.js.map → p-3b1fc676.entry.js.map} +0 -0
- /package/dist/wcs/{p-12ac2547.js.map → p-3dc6b507.js.map} +0 -0
- /package/dist/wcs/{p-b6cd196d.entry.js.map → p-7269272f.entry.js.map} +0 -0
- /package/dist/wcs/{p-966a241e.entry.js.map → p-7519a270.entry.js.map} +0 -0
- /package/dist/wcs/{p-b229a91c.entry.js.map → p-cb90bc3a.entry.js.map} +0 -0
- /package/dist/wcs/{p-f82e7a61.entry.js.map → p-e348058b.entry.js.map} +0 -0
- /package/dist/wcs/{p-405140f9.entry.js.map → p-ec84d6fd.entry.js.map} +0 -0
|
@@ -8,11 +8,20 @@ export class Radio {
|
|
|
8
8
|
this.label = undefined;
|
|
9
9
|
this.checked = false;
|
|
10
10
|
this.disabled = false;
|
|
11
|
+
this.name = undefined;
|
|
11
12
|
}
|
|
12
13
|
onKeyDown(_event) {
|
|
13
14
|
if ((isSpaceKey(_event) || isEnterKey(_event)) && !this.el.checked) {
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
15
|
+
this.checked = true;
|
|
16
|
+
this.inputEl.click(); // input[radio].checked = true does not trigger any event => input[radio].click() emit a change event
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
checkedChanged(newValue) {
|
|
20
|
+
if (newValue) {
|
|
21
|
+
this.inputEl.click();
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
this.inputEl.click();
|
|
16
25
|
}
|
|
17
26
|
}
|
|
18
27
|
componentWillLoad() {
|
|
@@ -36,10 +45,11 @@ export class Radio {
|
|
|
36
45
|
});
|
|
37
46
|
}
|
|
38
47
|
render() {
|
|
39
|
-
return (h(Host, { slot: "option" }, h("input", { id: this.inputId, type: "radio", value: this.value, checked: this.checked, disabled: this.disabled, "aria-disabled": this.disabled ? 'true' : null, "aria-checked": `${this.checked}` }), h("label", { htmlFor: `${this.inputId}` }, this.label)));
|
|
48
|
+
return (h(Host, Object.assign({ slot: "option" }, (this.disabled ? { tabIndex: -1 } : {})), h("input", { id: this.inputId, type: "radio", name: this.name, value: this.value, checked: this.checked, disabled: this.disabled, "aria-disabled": this.disabled ? 'true' : null, "aria-checked": `${this.checked}` }), h("label", { htmlFor: `${this.inputId}` }, this.label)));
|
|
40
49
|
}
|
|
41
50
|
static get is() { return "wcs-radio"; }
|
|
42
51
|
static get encapsulation() { return "shadow"; }
|
|
52
|
+
static get delegatesFocus() { return true; }
|
|
43
53
|
static get originalStyleUrls() {
|
|
44
54
|
return {
|
|
45
55
|
"$": ["radio.scss"]
|
|
@@ -144,6 +154,23 @@ export class Radio {
|
|
|
144
154
|
"attribute": "disabled",
|
|
145
155
|
"reflect": false,
|
|
146
156
|
"defaultValue": "false"
|
|
157
|
+
},
|
|
158
|
+
"name": {
|
|
159
|
+
"type": "string",
|
|
160
|
+
"mutable": false,
|
|
161
|
+
"complexType": {
|
|
162
|
+
"original": "string",
|
|
163
|
+
"resolved": "string",
|
|
164
|
+
"references": {}
|
|
165
|
+
},
|
|
166
|
+
"required": false,
|
|
167
|
+
"optional": false,
|
|
168
|
+
"docs": {
|
|
169
|
+
"tags": [],
|
|
170
|
+
"text": ""
|
|
171
|
+
},
|
|
172
|
+
"attribute": "name",
|
|
173
|
+
"reflect": false
|
|
147
174
|
}
|
|
148
175
|
};
|
|
149
176
|
}
|
|
@@ -171,6 +198,12 @@ export class Radio {
|
|
|
171
198
|
}];
|
|
172
199
|
}
|
|
173
200
|
static get elementRef() { return "el"; }
|
|
201
|
+
static get watchers() {
|
|
202
|
+
return [{
|
|
203
|
+
"propName": "checked",
|
|
204
|
+
"methodName": "checkedChanged"
|
|
205
|
+
}];
|
|
206
|
+
}
|
|
174
207
|
static get listeners() {
|
|
175
208
|
return [{
|
|
176
209
|
"name": "keydown",
|
|
@@ -182,4 +215,4 @@ export class Radio {
|
|
|
182
215
|
}
|
|
183
216
|
}
|
|
184
217
|
let radioButtonIds = 0;
|
|
185
|
-
//# sourceMappingURL=radio.
|
|
218
|
+
//# sourceMappingURL=radio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radio.js","sourceRoot":"","sources":["../../../src/components/radio/radio.tsx"],"names":[],"mappings":"AAAA,OAAO,EACH,SAAS,EAET,CAAC,EACD,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,KAAK,EAEL,MAAM,EACN,KAAK,EACR,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAS7D,MAAM,OAAO,KAAK;;IACN,YAAO,GAAG,UAAU,cAAc,EAAE,EAAE,CAAC;gBAGiB,OAAO;;;mBAOvB,KAAK;oBAIjB,KAAK;;;EAOzC,SAAS,CAAC,MAAqB;IAC3B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE;MAChE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;MACpB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,qGAAqG;KAC9H;EACL,CAAC;EAGD,cAAc,CAAC,QAAiB;IAC5B,IAAG,QAAQ,EAAE;MACT,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;KACxB;SAAM;MACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;KACxB;EACL,CAAC;EAED,iBAAiB;IACb,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE;MAC1B,yDAAyD;MACzD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC;KACxC;EACL,CAAC;EAED,gBAAgB;IACZ,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACzD,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE;MACxC,IAAI,CAAC,oBAAoB,EAAE,CAAC;MAC5B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACxB,CAAC,CAAC,CAAA;EACN,CAAC;EAED,oBAAoB;IAChB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;MACpB,KAAK,EAAE,IAAI,CAAC,KAAK;MACjB,MAAM,EAAE,IAAI,CAAC,EAAE;MACf,KAAK,EAAE,IAAI,CAAC,KAAK;KACpB,CAAC,CAAC;EACP,CAAC;EAED,MAAM;IAEF,OAAO,CACH,EAAC,IAAI,kBAAC,IAAI,EAAC,QAAQ,IAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAC,QAAQ,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;MACzD,aACI,EAAE,EAAE,IAAI,CAAC,OAAO,EAChB,IAAI,EAAC,OAAO,EACZ,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ,mBACR,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,kBAC9B,GAAG,IAAI,CAAC,OAAO,EAAE,GACjC;MACF,aAAO,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,IAAG,IAAI,CAAC,KAAK,CAAS,CACpD,CACV,CAAC;EACN,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACJ;AAED,IAAI,cAAc,GAAG,CAAC,CAAC","sourcesContent":["import {\n Component,\n ComponentInterface,\n h,\n Host,\n Prop,\n Element,\n Event,\n EventEmitter,\n Listen,\n Watch\n} from '@stencil/core';\nimport { RadioChosedEvent } from './radio-interface';\nimport { RadioGroupMode } from '../radio-group/radio-group-interface';\nimport { isEnterKey, isSpaceKey } from '../../utils/helpers';\n\n@Component({\n tag: 'wcs-radio',\n styleUrl: 'radio.scss',\n shadow: {\n delegatesFocus: true\n }\n})\nexport class Radio implements ComponentInterface {\n private inputId = `wcs-rb-${radioButtonIds++}`;\n private inputEl: HTMLInputElement;\n @Element() private el!: HTMLWcsRadioElement;\n @Prop({ reflect: true, mutable: false }) mode: RadioGroupMode = 'radio';\n\n @Prop({ mutable: true, reflect: true }) value: any | any[] | undefined | null;\n @Prop({ mutable: true, reflect: true }) label: string;\n /**\n * If `true`, the radio is selected. \n */\n @Prop({mutable: true, reflect: true}) checked = false;\n /**\n * If `true`, the user cannot interact with the radio.\n */\n @Prop({ mutable: true }) disabled = false;\n // FIXME renommer l'évènement c'est pas un onclick mais un onchange\n @Event({eventName: 'wcsRadioClick' }) wcsRadioClick: EventEmitter<RadioChosedEvent>\n \n @Prop() name: string;\n\n @Listen('keydown')\n onKeyDown(_event: KeyboardEvent) {\n if ((isSpaceKey(_event) || isEnterKey(_event)) && !this.el.checked) {\n this.checked = true;\n this.inputEl.click(); // input[radio].checked = true does not trigger any event => input[radio].click() emit a change event\n }\n }\n \n @Watch(\"checked\")\n checkedChanged(newValue: boolean) {\n if(newValue) {\n this.inputEl.click();\n } else {\n this.inputEl.click();\n }\n }\n\n componentWillLoad(): Promise<void> | void {\n if (this.value === undefined) {\n // If no value was given we use the text content instead.\n this.value = this.el.innerText || '';\n }\n }\n\n componentDidLoad() {\n this.inputEl = this.el.shadowRoot.querySelector('input');\n this.inputEl.addEventListener('change', _ => {\n this.emitRadioChangeEvent();\n this.checked = true;\n })\n }\n\n emitRadioChangeEvent() {\n this.wcsRadioClick.emit({\n label: this.label,\n source: this.el,\n value: this.value\n });\n }\n\n render() {\n \n return (\n <Host slot=\"option\" {...(this.disabled ? {tabIndex: -1} : {})}>\n <input\n id={this.inputId}\n type=\"radio\"\n name={this.name}\n value={this.value}\n checked={this.checked} // Initial checked state of native input\n disabled={this.disabled}\n aria-disabled={this.disabled ? 'true' : null}\n aria-checked={`${this.checked}`}\n />\n <label htmlFor={`${this.inputId}`}>{this.label}</label>\n </Host>\n );\n }\n}\n\nlet radioButtonIds = 0;\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { h, Host } from '@stencil/core';
|
|
2
|
+
import { isDownArrowKey, isLeftArrowKey, isRightArrowKey, isUpArrowKey } from "../../utils/helpers";
|
|
2
3
|
export class RadioGroup {
|
|
3
4
|
constructor() {
|
|
4
5
|
this.value = undefined;
|
|
@@ -12,11 +13,19 @@ export class RadioGroup {
|
|
|
12
13
|
if (this.value) {
|
|
13
14
|
this.updateOptionsState(this.value, true);
|
|
14
15
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
// We set the radio group mode on all options
|
|
17
|
+
this.options.forEach(o => o.mode = this.mode);
|
|
18
|
+
this.optionsNotDisabled.forEach((option) => {
|
|
19
|
+
if (option.checked) {
|
|
20
|
+
option.tabIndex = 0;
|
|
18
21
|
}
|
|
19
|
-
|
|
22
|
+
else {
|
|
23
|
+
option.tabIndex = -1;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
// If no option is already checked we made the first non-disabled option focusable
|
|
27
|
+
if (this.optionsNotDisabled.length > 0 && this.optionsNotDisabled.findIndex(o => o.tabIndex === 0) === -1)
|
|
28
|
+
this.optionsNotDisabled[0].tabIndex = 0;
|
|
20
29
|
}
|
|
21
30
|
get options() {
|
|
22
31
|
const opts = this.el.querySelectorAll('wcs-radio');
|
|
@@ -27,12 +36,47 @@ export class RadioGroup {
|
|
|
27
36
|
? slot.assignedElements()
|
|
28
37
|
: [];
|
|
29
38
|
}
|
|
39
|
+
get optionsNotDisabled() {
|
|
40
|
+
return Array.from(this.options).filter(option => !option.disabled);
|
|
41
|
+
}
|
|
30
42
|
selectedOptionChanged(event) {
|
|
31
43
|
this.updateOptionsState(event.detail.value, false);
|
|
32
44
|
this.wcsChange.emit({
|
|
33
45
|
value: event.detail.value
|
|
34
46
|
});
|
|
35
47
|
}
|
|
48
|
+
handleKeyDown(ev) {
|
|
49
|
+
if (isDownArrowKey(ev) || isUpArrowKey(ev) || isLeftArrowKey(ev) || isRightArrowKey(ev)) {
|
|
50
|
+
ev.preventDefault();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async handleKeyUp(ev) {
|
|
54
|
+
const radiosNotDisabled = this.optionsNotDisabled;
|
|
55
|
+
// Get the index of the currently checked radio
|
|
56
|
+
const previousSelected = this.optionsNotDisabled.findIndex(o => o.checked) >= 0
|
|
57
|
+
? this.optionsNotDisabled.findIndex(o => o.checked)
|
|
58
|
+
: 0;
|
|
59
|
+
if (isDownArrowKey(ev) || isRightArrowKey(ev)) {
|
|
60
|
+
// Let the previous wcs-radio not accessible via the tab key
|
|
61
|
+
radiosNotDisabled[previousSelected].checked = false;
|
|
62
|
+
radiosNotDisabled[previousSelected].tabIndex = -1;
|
|
63
|
+
// Check the next wcs-radio from the previous selected and let accessible via tab key (tabIndex = 0)
|
|
64
|
+
const nextOptionIndex = (previousSelected + 1) % radiosNotDisabled.length; // to return at the beginning on the list when we are on the last index
|
|
65
|
+
radiosNotDisabled[nextOptionIndex].tabIndex = 0;
|
|
66
|
+
radiosNotDisabled[nextOptionIndex].focus();
|
|
67
|
+
radiosNotDisabled[nextOptionIndex].checked = true;
|
|
68
|
+
}
|
|
69
|
+
else if (isUpArrowKey(ev) || isLeftArrowKey(ev)) {
|
|
70
|
+
// Let the previous wcs-radio not accessible via the tab key
|
|
71
|
+
radiosNotDisabled[previousSelected].checked = false;
|
|
72
|
+
radiosNotDisabled[previousSelected].tabIndex = -1;
|
|
73
|
+
// Check the previous wcs-radio from the previous selected and let accessible via tab key (tabIndex = 0)
|
|
74
|
+
const previousOptionIndex = (previousSelected - 1 + radiosNotDisabled.length) % radiosNotDisabled.length; // To return at the end of the list when we are on index=0
|
|
75
|
+
radiosNotDisabled[previousOptionIndex].tabIndex = 0;
|
|
76
|
+
radiosNotDisabled[previousOptionIndex].focus();
|
|
77
|
+
radiosNotDisabled[previousOptionIndex].checked = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
36
80
|
updateOptionsState(value, markAsChecked) {
|
|
37
81
|
for (const option of this.options) {
|
|
38
82
|
if (option.value !== value) {
|
|
@@ -158,6 +202,18 @@ export class RadioGroup {
|
|
|
158
202
|
"target": undefined,
|
|
159
203
|
"capture": false,
|
|
160
204
|
"passive": false
|
|
205
|
+
}, {
|
|
206
|
+
"name": "keydown",
|
|
207
|
+
"method": "handleKeyDown",
|
|
208
|
+
"target": undefined,
|
|
209
|
+
"capture": false,
|
|
210
|
+
"passive": false
|
|
211
|
+
}, {
|
|
212
|
+
"name": "keyup",
|
|
213
|
+
"method": "handleKeyUp",
|
|
214
|
+
"target": undefined,
|
|
215
|
+
"capture": false,
|
|
216
|
+
"passive": false
|
|
161
217
|
}];
|
|
162
218
|
}
|
|
163
219
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio-group.js","sourceRoot":"","sources":["../../../src/components/radio-group/radio-group.tsx"],"names":[],"mappings":"AAAA,OAAO,EACH,SAAS,EAET,OAAO,EACP,KAAK,EAEL,CAAC,EACD,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,KAAK,EACR,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"radio-group.js","sourceRoot":"","sources":["../../../src/components/radio-group/radio-group.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n ComponentInterface,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Listen,\n Prop,\n Watch\n} from '@stencil/core';\nimport { RadioGroupChangeEventDetail, RadioGroupMode } from './radio-group-interface';\nimport { RadioChosedEvent } from '../radio/radio-interface';\nimport { isDownArrowKey, isLeftArrowKey, isRightArrowKey, isUpArrowKey } from \"../../utils/helpers\";\n\n@Component({\n tag: 'wcs-radio-group',\n styleUrl: 'radio-group.scss',\n shadow: true\n})\nexport class RadioGroup implements ComponentInterface {\n @Prop() value: any | any[] | undefined | null;\n @Prop({reflect: true, mutable: false}) name;\n @Prop({reflect: true, mutable: false}) mode: RadioGroupMode = 'radio';\n @Element() private el!: HTMLWcsRadioGroupElement;\n\n /** Emitted when the value has changed. */\n @Event() wcsChange!: EventEmitter<RadioGroupChangeEventDetail>;\n\n @Watch('value')\n onValueChangeHandler(newValue: any) {\n this.updateOptionsState(newValue, true);\n }\n\n componentDidLoad() {\n if (this.value) {\n this.updateOptionsState(this.value, true);\n }\n\n // We set the radio group mode on all options\n this.options.forEach(o => o.mode = this.mode);\n\n this.optionsNotDisabled.forEach((option) => {\n if (option.checked) {\n option.tabIndex = 0;\n } else {\n option.tabIndex = -1\n }\n });\n\n // If no option is already checked we made the first non-disabled option focusable\n if (this.optionsNotDisabled.length > 0 && this.optionsNotDisabled.findIndex(o => o.tabIndex === 0) === -1) this.optionsNotDisabled[0].tabIndex = 0;\n }\n\n private get options(): HTMLWcsRadioElement[] {\n const opts = this.el.querySelectorAll('wcs-radio');\n const slot = this.el.querySelector('slot');\n return opts.length !== 0\n ? opts as unknown as HTMLWcsRadioElement[]\n : slot !== null\n ? slot.assignedElements() as HTMLWcsRadioElement[]\n : [];\n }\n\n private get optionsNotDisabled(): HTMLWcsRadioElement[] {\n return Array.from(this.options).filter(option => !option.disabled);\n }\n\n @Listen('wcsRadioClick')\n selectedOptionChanged(event: CustomEvent<RadioChosedEvent>) {\n this.updateOptionsState(event.detail.value, false);\n this.wcsChange.emit({\n value: event.detail.value\n })\n }\n\n @Listen('keydown')\n handleKeyDown(ev: KeyboardEvent) {\n if (isDownArrowKey(ev) || isUpArrowKey(ev) || isLeftArrowKey(ev) || isRightArrowKey(ev)) {\n ev.preventDefault();\n }\n }\n\n @Listen('keyup')\n async handleKeyUp(ev: KeyboardEvent) {\n const radiosNotDisabled = this.optionsNotDisabled;\n\n // Get the index of the currently checked radio\n const previousSelected = this.optionsNotDisabled.findIndex(o => o.checked) >= 0\n ? this.optionsNotDisabled.findIndex(o => o.checked)\n : 0;\n\n if (isDownArrowKey(ev) || isRightArrowKey(ev)) {\n // Let the previous wcs-radio not accessible via the tab key\n radiosNotDisabled[previousSelected].checked = false;\n radiosNotDisabled[previousSelected].tabIndex = -1;\n\n // Check the next wcs-radio from the previous selected and let accessible via tab key (tabIndex = 0)\n const nextOptionIndex = (previousSelected + 1) % radiosNotDisabled.length; // to return at the beginning on the list when we are on the last index\n radiosNotDisabled[nextOptionIndex].tabIndex = 0;\n radiosNotDisabled[nextOptionIndex].focus();\n radiosNotDisabled[nextOptionIndex].checked = true;\n } else if (isUpArrowKey(ev) || isLeftArrowKey(ev)) {\n // Let the previous wcs-radio not accessible via the tab key\n radiosNotDisabled[previousSelected].checked = false;\n radiosNotDisabled[previousSelected].tabIndex = -1;\n\n // Check the previous wcs-radio from the previous selected and let accessible via tab key (tabIndex = 0)\n const previousOptionIndex = (previousSelected - 1 + radiosNotDisabled.length) % radiosNotDisabled.length; // To return at the end of the list when we are on index=0\n radiosNotDisabled[previousOptionIndex].tabIndex = 0;\n radiosNotDisabled[previousOptionIndex].focus();\n radiosNotDisabled[previousOptionIndex].checked = true;\n }\n }\n\n private updateOptionsState(value: string, markAsChecked: boolean) {\n for (const option of this.options) {\n if (option.value !== value) {\n option.removeAttribute('checked');\n } else {\n if (markAsChecked) {\n option.setAttribute('checked', '');\n }\n }\n }\n }\n\n render() {\n return (\n <Host>\n <slot name=\"option\"/>\n </Host>\n );\n }\n\n}\n"]}
|
|
@@ -12,7 +12,7 @@ export class Tab {
|
|
|
12
12
|
this.tabLoaded.emit();
|
|
13
13
|
}
|
|
14
14
|
render() {
|
|
15
|
-
return (h(Host, { slot: "wcs-tab" }, h("slot", null)));
|
|
15
|
+
return (h(Host, { slot: "wcs-tab", role: "tabpanel" }, h("slot", null)));
|
|
16
16
|
}
|
|
17
17
|
static get is() { return "wcs-tab"; }
|
|
18
18
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tab.js","sourceRoot":"","sources":["../../../src/components/tab/tab.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAgB,MAAM,eAAe,CAAC;AAE9E;;;GAGG;AAKH,MAAM,OAAO,GAAG;;;;;EAiBZ,gBAAgB;IACZ,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;EAC1B,CAAC;EAED,MAAM;IACF,OAAO,CACH,EAAC,IAAI,IAAC,IAAI,EAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"tab.js","sourceRoot":"","sources":["../../../src/components/tab/tab.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAgB,MAAM,eAAe,CAAC;AAE9E;;;GAGG;AAKH,MAAM,OAAO,GAAG;;;;;EAiBZ,gBAAgB;IACZ,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;EAC1B,CAAC;EAED,MAAM;IACF,OAAO,CACH,EAAC,IAAI,IAAC,IAAI,EAAC,SAAS,EAAC,IAAI,EAAE,UAAU;MACjC,eAAa,CACV,CACV,CAAC;EACN,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACJ","sourcesContent":["import { Component, Prop, h, Host, Event, EventEmitter } from '@stencil/core';\n\n/**\n * Tab content component.\n * Use this component to specify the content of a component.\n */\n@Component({\n tag: 'wcs-tab',\n shadow: true,\n})\nexport class Tab {\n /**\n * The header you want to be displayed for this tab.\n */\n @Prop({ reflect: true }) header: string;\n\n @Prop() itemKey: any;\n\n // TODO: See if there is a solution that doesn't pollute the API.\n /**\n * Do not use, meant for internal use only.\n * @inner\n * @ignore\n */\n @Event()\n tabLoaded!: EventEmitter<void>;\n\n componentDidLoad() {\n this.tabLoaded.emit();\n }\n\n render() {\n return (\n <Host slot=\"wcs-tab\" role={\"tabpanel\"}>\n <slot></slot>\n </Host>\n );\n }\n}\n"]}
|
|
@@ -13,11 +13,13 @@ import { h, Host } from '@stencil/core';
|
|
|
13
13
|
*/
|
|
14
14
|
export class Tabs {
|
|
15
15
|
constructor() {
|
|
16
|
+
this.tabsId = tabsId++;
|
|
16
17
|
this.align = 'start';
|
|
17
18
|
this.selectedIndex = 0;
|
|
18
19
|
this.selectedKey = undefined;
|
|
19
20
|
this.headersOnly = false;
|
|
20
21
|
this.gutter = undefined;
|
|
22
|
+
this.description = undefined;
|
|
21
23
|
this.headers = [];
|
|
22
24
|
this.currentActiveTabIndex = 0;
|
|
23
25
|
}
|
|
@@ -94,6 +96,22 @@ export class Tabs {
|
|
|
94
96
|
}
|
|
95
97
|
break;
|
|
96
98
|
}
|
|
99
|
+
case 'Home': {
|
|
100
|
+
const firstTab = this.el.shadowRoot.querySelector('.wcs-tab-header:first-child');
|
|
101
|
+
if (firstTab) {
|
|
102
|
+
firstTab.focus();
|
|
103
|
+
ev.preventDefault();
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
case 'End': {
|
|
108
|
+
const lastTab = this.el.shadowRoot.querySelector('.wcs-tab-header:last-child');
|
|
109
|
+
if (lastTab) {
|
|
110
|
+
lastTab.focus();
|
|
111
|
+
ev.preventDefault();
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
97
115
|
}
|
|
98
116
|
}
|
|
99
117
|
refreshHeaders() {
|
|
@@ -140,7 +158,24 @@ export class Tabs {
|
|
|
140
158
|
this.tabs.forEach((el) => el.setAttribute('style', 'display: none;'));
|
|
141
159
|
}
|
|
142
160
|
render() {
|
|
143
|
-
return (h(Host, null, h("div", { class: "wcs-tabs-headers" }, this.headers.map((header, idx) => h("div", { class: 'wcs-tab-header ' + (this.currentActiveTabIndex === idx ? 'active' : ''), onClick: () => this.selectTabAndEmitChangeEvent(idx), onKeyDown: evt => this.handleKeyDown(evt, idx), tabIndex: this.currentActiveTabIndex === idx ? 0 : -1 }, h("span", null, header)))), h("div", { class: "wcs-tabs" }, h("slot", { name: "wcs-tab" }))));
|
|
161
|
+
return (h(Host, null, h("div", { class: "wcs-tabs-headers", role: "tablist", "aria-label": this.description }, this.headers.map((header, idx) => h("div", { class: 'wcs-tab-header ' + (this.currentActiveTabIndex === idx ? 'active' : ''), onClick: () => this.selectTabAndEmitChangeEvent(idx), onKeyDown: evt => this.handleKeyDown(evt, idx), tabIndex: this.currentActiveTabIndex === idx ? 0 : -1, role: "tab", id: `tabs-id-${this.tabsId}-tab-id-${idx}`, "aria-controls": `tabs-id-${this.tabsId}-tab-panel-${idx}`, "aria-label": header, "aria-selected": this.currentActiveTabIndex === idx ? 'true' : 'false' }, h("span", null, header)))), h("div", { class: "wcs-tabs" }, h("slot", { onSlotchange: () => this.onTabsSlotChange(), name: "wcs-tab" }))));
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Observe when a new tab panel is added to the slot to let's handle accessibility properties for tabs panel:
|
|
165
|
+
* - id: to let header tab refers it proper panel
|
|
166
|
+
* - aria-label: take the same name as it's referenced header name
|
|
167
|
+
*
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
onTabsSlotChange() {
|
|
171
|
+
let tabId = 0;
|
|
172
|
+
this.tabs.forEach(tab => {
|
|
173
|
+
tab.setAttribute("aria-label", this.headers.at(tabId));
|
|
174
|
+
// set an ID to set aria-controls on header tab
|
|
175
|
+
// (https://www.w3.org/WAI/ARIA/apg/patterns/tabs/examples/tabs-automatic/#:~:text=Refers%20to%20the%20element)
|
|
176
|
+
tab.setAttribute("id", `tabs-id-${this.tabsId}-tab-panel-${tabId}`);
|
|
177
|
+
tabId++;
|
|
178
|
+
});
|
|
144
179
|
}
|
|
145
180
|
static get is() { return "wcs-tabs"; }
|
|
146
181
|
static get encapsulation() { return "shadow"; }
|
|
@@ -248,6 +283,23 @@ export class Tabs {
|
|
|
248
283
|
},
|
|
249
284
|
"attribute": "gutter",
|
|
250
285
|
"reflect": false
|
|
286
|
+
},
|
|
287
|
+
"description": {
|
|
288
|
+
"type": "string",
|
|
289
|
+
"mutable": false,
|
|
290
|
+
"complexType": {
|
|
291
|
+
"original": "string",
|
|
292
|
+
"resolved": "string",
|
|
293
|
+
"references": {}
|
|
294
|
+
},
|
|
295
|
+
"required": false,
|
|
296
|
+
"optional": false,
|
|
297
|
+
"docs": {
|
|
298
|
+
"tags": [],
|
|
299
|
+
"text": "Description is used to provide aria-label for the tabs container which has `role=\"tablist\"`."
|
|
300
|
+
},
|
|
301
|
+
"attribute": "description",
|
|
302
|
+
"reflect": false
|
|
251
303
|
}
|
|
252
304
|
};
|
|
253
305
|
}
|
|
@@ -300,4 +352,5 @@ export class Tabs {
|
|
|
300
352
|
}];
|
|
301
353
|
}
|
|
302
354
|
}
|
|
355
|
+
let tabsId = 0;
|
|
303
356
|
//# sourceMappingURL=tabs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../src/components/tabs/tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Prop,\n Element,\n State,\n ComponentInterface,\n Event,\n EventEmitter,\n Watch,\n h,\n Host,\n Listen\n} from '@stencil/core';\n\nimport { WcsTabsAlignment, WcsTabChangeEvent } from './tabs-interface';\n\n/**\n * Tabs component to switch between tab content.\n * Use in conjuction with `wcs-tab`.\n *\n * @example\n * ```html\n * <wcs-tabs>\n * <wcs-tab header=\"One\">The content !</wcs-tab>\n * <wcs-tab header=\"Two\">More content !</wcs-tab>\n * </wcs-tabs>\n * ```\n */\n@Component({\n tag: 'wcs-tabs',\n styleUrl: 'tabs.scss',\n shadow: true,\n})\nexport class Tabs implements ComponentInterface {\n /**\n * Tab headers alignment.\n */\n @Prop({reflect: true}) align: WcsTabsAlignment = 'start';\n\n /**\n * Current selected tab index.\n * Starts at 0.\n */\n @Prop() selectedIndex: number = 0;\n\n @Prop() selectedKey: any;\n\n /**\n * Whether to skip rendering the tabpanel with the content of the selected tab. Use this prop if you plan to\n * separately render the tab content.\n */\n @Prop() headersOnly: boolean = false;\n /** Determines if tabs header should have a border at the bottom */\n @Prop() gutter: boolean;\n\n /**\n *\n * Emitted when the selected tab change.\n */\n @Event() tabChange!: EventEmitter<WcsTabChangeEvent>;\n\n @Element() private el!: HTMLWcsTabsElement;\n\n @State() private headers: string[] = [];\n\n @State() private currentActiveTabIndex = 0;\n\n @Watch('selectedIndex')\n selectedIndexChanged(newValue: number) {\n this.currentActiveTabIndex = newValue;\n }\n\n @Watch('selectedKey')\n selectedTabkeyChanged(newValue: any) {\n this.updateCurrentActiveIndexByTabKey(newValue);\n }\n\n private emitActiveTabChange() {\n this.tabChange.emit({\n tabName: this.headers[this.currentActiveTabIndex],\n tabIndex: this.currentActiveTabIndex,\n selectedKey: this.tabs[this.currentActiveTabIndex].itemKey\n });\n }\n\n private updateCurrentActiveIndexByTabKey(newValue: any) {\n for (let i = 0; i < this.tabs.length; i++) {\n const tab = this.tabs[i];\n if (tab.itemKey === newValue) {\n this.currentActiveTabIndex = i;\n }\n }\n }\n\n @Listen('tabLoaded')\n onTabLoaded() {\n this.refreshHeaders();\n }\n\n componentDidLoad() {\n this.putTabsInCorrectDivIfTheyAreNot();\n this.refreshHeaders();\n if (this.selectedIndex) {\n this.currentActiveTabIndex = this.selectedIndex;\n }\n if (this.selectedKey) {\n this.updateCurrentActiveIndexByTabKey(this.selectedKey);\n }\n }\n\n // XXX: Firefox < 63\n private putTabsInCorrectDivIfTheyAreNot() {\n const tabDiv = this.el.shadowRoot.querySelector('.wcs-tabs');\n if (tabDiv.querySelector('slot') === null) {\n Array.from(this.el.querySelectorAll('wcs-tab'))\n .filter(node => node.parentNode !== tabDiv)\n .forEach(tab => {\n if (tab.parentElement.isEqualNode(this.el)) {\n this.el.removeChild(tab);\n tabDiv.appendChild(tab);\n }\n });\n }\n }\n\n handleKeyDown(ev: KeyboardEvent, tabIndex: number) {\n const target = ev.target as HTMLDivElement;\n switch (ev.key) {\n case ' ':\n case 'Enter': {\n this.currentActiveTabIndex = tabIndex;\n this.emitActiveTabChange();\n ev.preventDefault();\n break;\n }\n case 'ArrowLeft': {\n if (target.previousElementSibling?.classList.contains('wcs-tab-header')) {\n (target.previousElementSibling as HTMLDivElement).focus();\n ev.preventDefault();\n }\n break;\n }\n case 'ArrowRight': {\n if (target.nextElementSibling?.classList.contains('wcs-tab-header')) {\n (target.nextElementSibling as HTMLDivElement).focus();\n ev.preventDefault();\n }\n break;\n }\n }\n }\n\n private refreshHeaders() {\n this.headers = [];\n this.tabs\n .forEach(x => {\n this.headers.push(x.getAttribute('header'));\n });\n }\n\n private get tabs() {\n const tabsEl = this.el.shadowRoot.querySelector('.wcs-tabs');\n // FIXME: problem with this selector being too greedy in ff < 63\n const tabs = this.el.shadowRoot.querySelectorAll('.wcs-tabs > wcs-tab');\n\n return tabs.length !== 0\n ? tabs\n : tabsEl?.querySelector('slot')\n ? tabsEl?.querySelector('slot')?.assignedElements() as unknown as NodeListOf<HTMLWcsTabElement>\n : [];\n }\n\n private selectTabAndEmitChangeEvent(index: number) {\n this.currentActiveTabIndex = index;\n this.emitActiveTabChange()\n }\n\n componentWillUpdate() {\n if (!this.headersOnly) {\n this.updateTabVisibility();\n } else {\n this.hideAllTabsContent();\n }\n }\n\n private updateTabVisibility() {\n this.tabs.forEach((el: HTMLWcsTabElement, idx: number) => {\n if (idx !== this.currentActiveTabIndex) {\n el.setAttribute('style', 'display: none;');\n } else {\n el.setAttribute('style', 'display: block;');\n }\n });\n }\n\n private hideAllTabsContent() {\n this.tabs.forEach((el: HTMLWcsTabElement) => el.setAttribute('style', 'display: none;'));\n }\n\n render() {\n return (\n <Host>\n <div class=\"wcs-tabs-headers\">\n {this.headers.map((header, idx) =>\n <div class={'wcs-tab-header ' + (this.currentActiveTabIndex === idx ? 'active' : '')}\n onClick={() => this.selectTabAndEmitChangeEvent(idx)}\n onKeyDown={evt => this.handleKeyDown(evt, idx)}\n tabIndex={this.currentActiveTabIndex === idx ? 0 : -1}\n >\n <span>{header}</span>\n </div>\n )}\n </div>\n <div class=\"wcs-tabs\">\n <slot name=\"wcs-tab\"/>\n </div>\n </Host>\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../src/components/tabs/tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Prop,\n Element,\n State,\n ComponentInterface,\n Event,\n EventEmitter,\n Watch,\n h,\n Host,\n Listen\n} from '@stencil/core';\n\nimport { WcsTabsAlignment, WcsTabChangeEvent } from './tabs-interface';\n\n/**\n * Tabs component to switch between tab content.\n * Use in conjuction with `wcs-tab`.\n *\n * @example\n * ```html\n * <wcs-tabs>\n * <wcs-tab header=\"One\">The content !</wcs-tab>\n * <wcs-tab header=\"Two\">More content !</wcs-tab>\n * </wcs-tabs>\n * ```\n */\n@Component({\n tag: 'wcs-tabs',\n styleUrl: 'tabs.scss',\n shadow: true,\n})\nexport class Tabs implements ComponentInterface {\n /**\n * Tab headers alignment.\n */\n @Prop({reflect: true}) align: WcsTabsAlignment = 'start';\n\n /**\n * Current selected tab index.\n * Starts at 0.\n */\n @Prop() selectedIndex: number = 0;\n\n @Prop() selectedKey: any;\n\n /**\n * Whether to skip rendering the tabpanel with the content of the selected tab. Use this prop if you plan to\n * separately render the tab content.\n */\n @Prop() headersOnly: boolean = false;\n /** Determines if tabs header should have a border at the bottom */\n @Prop() gutter: boolean;\n\n /**\n * Description is used to provide aria-label for the tabs container which has `role=\"tablist\"`.\n */\n @Prop() description: string;\n\n /**\n *\n * Emitted when the selected tab change.\n */\n @Event() tabChange!: EventEmitter<WcsTabChangeEvent>;\n\n @Element() private el!: HTMLWcsTabsElement;\n\n @State() private headers: string[] = [];\n\n @State() private currentActiveTabIndex = 0;\n\n private tabsId: number = tabsId++;\n\n @Watch('selectedIndex')\n selectedIndexChanged(newValue: number) {\n this.currentActiveTabIndex = newValue;\n }\n\n @Watch('selectedKey')\n selectedTabkeyChanged(newValue: any) {\n this.updateCurrentActiveIndexByTabKey(newValue);\n }\n\n private emitActiveTabChange() {\n this.tabChange.emit({\n tabName: this.headers[this.currentActiveTabIndex],\n tabIndex: this.currentActiveTabIndex,\n selectedKey: this.tabs[this.currentActiveTabIndex].itemKey\n });\n }\n\n private updateCurrentActiveIndexByTabKey(newValue: any) {\n for (let i = 0; i < this.tabs.length; i++) {\n const tab = this.tabs[i];\n if (tab.itemKey === newValue) {\n this.currentActiveTabIndex = i;\n }\n }\n }\n\n @Listen('tabLoaded')\n onTabLoaded() {\n this.refreshHeaders();\n }\n\n componentDidLoad() {\n this.putTabsInCorrectDivIfTheyAreNot();\n this.refreshHeaders();\n if (this.selectedIndex) {\n this.currentActiveTabIndex = this.selectedIndex;\n }\n if (this.selectedKey) {\n this.updateCurrentActiveIndexByTabKey(this.selectedKey);\n }\n }\n\n // XXX: Firefox < 63\n private putTabsInCorrectDivIfTheyAreNot() {\n const tabDiv = this.el.shadowRoot.querySelector('.wcs-tabs');\n if (tabDiv.querySelector('slot') === null) {\n Array.from(this.el.querySelectorAll('wcs-tab'))\n .filter(node => node.parentNode !== tabDiv)\n .forEach(tab => {\n if (tab.parentElement.isEqualNode(this.el)) {\n this.el.removeChild(tab);\n tabDiv.appendChild(tab);\n }\n });\n }\n }\n\n handleKeyDown(ev: KeyboardEvent, tabIndex: number) {\n const target = ev.target as HTMLDivElement;\n switch (ev.key) {\n case ' ':\n case 'Enter': {\n this.currentActiveTabIndex = tabIndex;\n this.emitActiveTabChange();\n ev.preventDefault();\n break;\n }\n case 'ArrowLeft': {\n if (target.previousElementSibling?.classList.contains('wcs-tab-header')) {\n (target.previousElementSibling as HTMLDivElement).focus();\n ev.preventDefault();\n }\n break;\n }\n case 'ArrowRight': {\n if (target.nextElementSibling?.classList.contains('wcs-tab-header')) {\n (target.nextElementSibling as HTMLDivElement).focus();\n ev.preventDefault();\n }\n break;\n }\n case 'Home': {\n const firstTab = this.el.shadowRoot.querySelector('.wcs-tab-header:first-child');\n if (firstTab) {\n (firstTab as HTMLDivElement).focus();\n ev.preventDefault();\n }\n break;\n }\n case 'End': {\n const lastTab = this.el.shadowRoot.querySelector('.wcs-tab-header:last-child');\n if (lastTab) {\n (lastTab as HTMLDivElement).focus();\n ev.preventDefault();\n }\n break;\n }\n }\n }\n\n private refreshHeaders() {\n this.headers = [];\n this.tabs\n .forEach(x => {\n this.headers.push(x.getAttribute('header'));\n });\n }\n\n private get tabs() {\n const tabsEl = this.el.shadowRoot.querySelector('.wcs-tabs');\n // FIXME: problem with this selector being too greedy in ff < 63\n const tabs = this.el.shadowRoot.querySelectorAll('.wcs-tabs > wcs-tab');\n\n return tabs.length !== 0\n ? tabs\n : tabsEl?.querySelector('slot')\n ? tabsEl?.querySelector('slot')?.assignedElements() as unknown as NodeListOf<HTMLWcsTabElement>\n : [];\n }\n\n private selectTabAndEmitChangeEvent(index: number) {\n this.currentActiveTabIndex = index;\n this.emitActiveTabChange()\n }\n\n componentWillUpdate() {\n if (!this.headersOnly) {\n this.updateTabVisibility();\n } else {\n this.hideAllTabsContent();\n }\n }\n\n private updateTabVisibility() {\n this.tabs.forEach((el: HTMLWcsTabElement, idx: number) => {\n if (idx !== this.currentActiveTabIndex) {\n el.setAttribute('style', 'display: none;');\n } else {\n el.setAttribute('style', 'display: block;');\n }\n });\n }\n\n private hideAllTabsContent() {\n this.tabs.forEach((el: HTMLWcsTabElement) => el.setAttribute('style', 'display: none;'));\n }\n\n render() {\n return (\n <Host>\n <div class=\"wcs-tabs-headers\" role=\"tablist\" aria-label={this.description}>\n {this.headers.map((header, idx) =>\n <div class={'wcs-tab-header ' + (this.currentActiveTabIndex === idx ? 'active' : '')}\n onClick={() => this.selectTabAndEmitChangeEvent(idx)}\n onKeyDown={evt => this.handleKeyDown(evt, idx)}\n tabIndex={this.currentActiveTabIndex === idx ? 0 : -1}\n role=\"tab\"\n id={`tabs-id-${this.tabsId}-tab-id-${idx}`}\n // aria-controls refers to ID of the tab panel related to the header\n aria-controls={`tabs-id-${this.tabsId}-tab-panel-${idx}`}\n aria-label={header}\n aria-selected={this.currentActiveTabIndex === idx ? 'true' : 'false'}\n >\n <span>{header}</span>\n </div>\n )}\n </div>\n <div class=\"wcs-tabs\">\n <slot onSlotchange={() => this.onTabsSlotChange()} name=\"wcs-tab\"/>\n </div>\n </Host>\n );\n }\n\n /**\n * Observe when a new tab panel is added to the slot to let's handle accessibility properties for tabs panel:\n * - id: to let header tab refers it proper panel\n * - aria-label: take the same name as it's referenced header name\n * \n * @private\n */\n private onTabsSlotChange() {\n let tabId = 0;\n this.tabs.forEach(tab => {\n tab.setAttribute(\"aria-label\", this.headers.at(tabId));\n // set an ID to set aria-controls on header tab \n // (https://www.w3.org/WAI/ARIA/apg/patterns/tabs/examples/tabs-automatic/#:~:text=Refers%20to%20the%20element)\n tab.setAttribute(\"id\", `tabs-id-${this.tabsId}-tab-panel-${tabId}`);\n tabId++;\n });\n }\n}\n\nlet tabsId = 0;\n"]}
|
|
@@ -111,8 +111,8 @@ export class Textarea {
|
|
|
111
111
|
raf(() => this.runAutoGrow());
|
|
112
112
|
}
|
|
113
113
|
/**
|
|
114
|
-
*
|
|
115
|
-
* `textarea
|
|
114
|
+
* @deprecated use the native focus method instead
|
|
115
|
+
* Sets focus on the native `textarea` in `wcs-textarea`.
|
|
116
116
|
*/
|
|
117
117
|
async setFocus() {
|
|
118
118
|
if (this.nativeInput) {
|
|
@@ -175,6 +175,7 @@ export class Textarea {
|
|
|
175
175
|
}
|
|
176
176
|
static get is() { return "wcs-textarea"; }
|
|
177
177
|
static get encapsulation() { return "shadow"; }
|
|
178
|
+
static get delegatesFocus() { return true; }
|
|
178
179
|
static get originalStyleUrls() {
|
|
179
180
|
return {
|
|
180
181
|
"$": ["textarea.scss"]
|
|
@@ -711,8 +712,11 @@ export class Textarea {
|
|
|
711
712
|
"return": "Promise<void>"
|
|
712
713
|
},
|
|
713
714
|
"docs": {
|
|
714
|
-
"text": "
|
|
715
|
-
"tags": [
|
|
715
|
+
"text": "",
|
|
716
|
+
"tags": [{
|
|
717
|
+
"name": "deprecated",
|
|
718
|
+
"text": "use the native focus method instead \nSets focus on the native `textarea` in `wcs-textarea`."
|
|
719
|
+
}]
|
|
716
720
|
}
|
|
717
721
|
},
|
|
718
722
|
"setBlur": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../../src/components/textarea/textarea.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n ComponentInterface,\n Method,\n Prop,\n State,\n Watch,\n h,\n Host,\n EventEmitter,\n Element,\n Event,\n Build,\n readTask\n} from '@stencil/core';\nimport { debounceEvent, findItemLabel, inheritAttributes, raf } from '../../utils/helpers';\nimport { TextareaChangeEventDetail } from './textarea-interface';\n\n/**\n * Mainly inspired from Ionic Textarea Component\n *\n * @cssprop --wcs-textarea-max-height - Max height of the text area component\n *\n */\n@Component({\n tag: 'wcs-textarea',\n styleUrl: 'textarea.scss',\n shadow: true,\n})\nexport class Textarea implements ComponentInterface {\n private nativeInput?: HTMLTextAreaElement;\n private inputId = `wcs-textarea-${textareaIds++}`;\n private didBlurAfterEdit = false;\n private inheritedAttributes: { [k: string]: any } = {};\n\n /**\n * This is required for a WebKit bug which requires us to\n * blur and focus an input to properly focus the input in\n * an item with delegatesFocus. It will no longer be needed\n * with iOS 14.\n *\n * @internal\n */\n @Prop() fireFocusEvents = true;\n\n @Element() private el!: HTMLElement;\n\n @State() private hasFocus = false;\n\n /**\n * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.\n */\n @Prop() autocapitalize = 'none';\n\n /**\n * This Boolean attribute lets you specify that a form control should have input focus when the page loads.\n */\n @Prop() autofocus = false;\n\n /**\n * If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `\"password\"`, `false` for all other types.\n */\n @Prop({mutable: true}) clearOnEdit = false;\n\n /**\n * Set the amount of time, in milliseconds, to wait to trigger the `wcsChange` event after each keystroke. This also impacts form bindings such as `ngModel` or `v-model`.\n */\n @Prop() debounce = 0;\n\n @Watch('debounce')\n protected debounceChanged() {\n this.wcsChange = debounceEvent(this.wcsChange, this.debounce);\n }\n\n /**\n * If `true`, the user cannot interact with the textarea.\n */\n @Prop() disabled = false;\n\n /**\n * Name of the material icon to add to the input\n */\n @Prop() icon: string;\n\n /**\n * A hint to the browser for which keyboard to display.\n * Possible values: `\"none\"`, `\"text\"`, `\"tel\"`, `\"url\"`,\n * `\"email\"`, `\"numeric\"`, `\"decimal\"`, and `\"search\"`.\n */\n @Prop() inputmode?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';\n\n /**\n * A hint to the browser for which enter key to display.\n * Possible values: `\"enter\"`, `\"done\"`, `\"go\"`, `\"next\"`,\n * `\"previous\"`, `\"search\"`, and `\"send\"`.\n */\n @Prop() enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';\n\n /**\n * If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the maximum number of characters that the user can enter.\n */\n @Prop() maxlength?: number;\n\n /**\n * If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the minimum number of characters that the user can enter.\n */\n @Prop() minlength?: number;\n\n /**\n * The name of the control, which is submitted with the form data.\n */\n @Prop() name: string = this.inputId;\n\n /**\n * Instructional text that shows before the input has a value.\n */\n @Prop() placeholder?: string | null;\n\n /**\n * If `true`, the user cannot modify the value.\n */\n @Prop() readonly = false;\n\n /**\n * If `true`, the user must fill in a value before submitting a form.\n */\n @Prop() required = false;\n\n /**\n * If `true`, the element will have its spelling and grammar checked.\n */\n @Prop() spellcheck = false;\n\n /**\n * Specifies the state of the input. By default the input is in an initial state but you can set it to 'error' state if the data given by the user is not valid.\n */\n @Prop({reflect: true}) state: 'initial' | 'error' = 'initial';\n\n /**\n * The visible width of the text control, in average character widths. If it is specified, it must be a positive integer.\n */\n @Prop() cols?: number;\n\n /**\n * The number of visible text lines for the control.\n */\n @Prop() rows?: number;\n\n /**\n * Indicates how the control wraps text.\n */\n @Prop() wrap?: 'hard' | 'soft' | 'off';\n\n /**\n * If `true`, the element height will increase based on the value.\n */\n @Prop() autoGrow = false;\n\n /**\n * The value of the textarea.\n */\n @Prop({mutable: true}) value?: string | null = '';\n\n /**\n * Indicates how the textarea should be resizable.\n * Possible values 'both' | 'none' | 'vertical' | 'horizontal'\n */\n @Prop({reflect: true}) resize?: 'both' | 'none' | 'vertical' | 'horizontal';\n\n /**\n * Update the native input element when the value changes\n */\n @Watch('value')\n protected valueChanged() {\n const nativeInput = this.nativeInput;\n const value = this.getValue();\n if (nativeInput && nativeInput.value !== value) {\n nativeInput.value = value;\n }\n this.runAutoGrow();\n this.wcsChange.emit({value});\n }\n\n /**\n * Emitted when the input value has changed.\n */\n @Event() wcsChange!: EventEmitter<TextareaChangeEventDetail>;\n\n /**\n * Emitted when a keyboard input occurred.\n */\n @Event() wcsInput!: EventEmitter<KeyboardEvent>;\n\n /**\n * Emitted when the input loses focus.\n */\n @Event() wcsBlur!: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when the input has focus.\n */\n @Event() wcsFocus!: EventEmitter<FocusEvent>;\n\n connectedCallback() {\n this.debounceChanged();\n if (Build.isBrowser) {\n document.dispatchEvent(new CustomEvent('wcsInputDidLoad', {\n detail: this.el\n }));\n }\n }\n\n disconnectedCallback() {\n if (Build.isBrowser) {\n document.dispatchEvent(new CustomEvent('wcsInputDidUnload', {\n detail: this.el\n }));\n }\n }\n\n componentWillLoad() {\n this.inheritedAttributes = inheritAttributes(this.el, ['title']);\n }\n\n componentDidLoad() {\n raf(() => this.runAutoGrow());\n }\n\n private runAutoGrow() {\n const nativeInput = this.nativeInput;\n if (nativeInput && this.autoGrow) {\n readTask(() => {\n nativeInput.style.height = 'auto';\n nativeInput.style.height = nativeInput.scrollHeight + 'px';\n });\n }\n }\n\n /**\n * This method make the textarea automatically adopt the size of the content without a scroll bar\n */\n @Method()\n async fitContent() {\n raf(() => this.runAutoGrow());\n }\n\n /**\n * Sets focus on the native `textarea` in `wcs-textarea`. Use this method instead of the global\n * `textarea.focus()`.\n */\n @Method()\n async setFocus() {\n if (this.nativeInput) {\n this.nativeInput.focus();\n }\n }\n\n /**\n * Sets blur on the native `textarea` in `wcs-textarea`. Use this method instead of the global\n * `textarea.blur()`.\n * @internal\n */\n @Method()\n async setBlur() {\n if (this.nativeInput) {\n this.nativeInput.blur();\n }\n }\n\n /**\n * Returns the native `<textarea>` element used under the hood.\n */\n @Method()\n getInputElement(): Promise<HTMLTextAreaElement> {\n // tslint:disable-next-line:no-non-null-assertion\n return Promise.resolve(this.nativeInput!);\n }\n\n /**\n * Check if we need to clear the text input if clearOnEdit is enabled\n */\n private checkClearOnEdit() {\n if (!this.clearOnEdit) {\n return;\n }\n\n // Did the input value change after it was blurred and edited?\n if (this.didBlurAfterEdit && this.hasValue()) {\n // Clear the input\n this.value = '';\n }\n\n // Reset the flag\n this.didBlurAfterEdit = false;\n }\n\n private focusChange() {\n // If clearOnEdit is enabled and the input blurred but has a value, set a flag\n if (this.clearOnEdit && !this.hasFocus && this.hasValue()) {\n this.didBlurAfterEdit = true;\n }\n }\n\n private hasValue(): boolean {\n return this.getValue() !== '';\n }\n\n private getValue(): string {\n return this.value || '';\n }\n\n private onInput = (ev: Event) => {\n if (this.nativeInput) {\n this.value = this.nativeInput.value;\n }\n this.wcsInput.emit(ev as KeyboardEvent);\n }\n\n private onFocus = (ev: FocusEvent) => {\n this.hasFocus = true;\n this.focusChange();\n\n if (this.fireFocusEvents) {\n this.wcsFocus.emit(ev);\n }\n }\n\n private onBlur = (ev: FocusEvent) => {\n this.hasFocus = false;\n this.focusChange();\n\n if (this.fireFocusEvents) {\n this.wcsBlur.emit(ev);\n }\n }\n\n private onKeyDown = () => {\n this.checkClearOnEdit();\n }\n\n render() {\n const value = this.getValue();\n const labelId = this.inputId + '-lbl';\n const label = findItemLabel(this.el);\n if (label) {\n label.id = labelId;\n }\n const style = {\n ...(this.resize && {'resize': this.resize})\n }\n\n return (\n <Host\n aria-disabled={this.disabled ? 'true' : null}\n >\n {this.icon ? (<wcs-mat-icon icon={this.icon} size=\"m\"></wcs-mat-icon>) : null}\n <textarea\n class=\"native-textarea\"\n aria-labelledby={label ? labelId : null}\n ref={el => this.nativeInput = el}\n autoCapitalize={this.autocapitalize}\n autoFocus={this.autofocus}\n enterKeyHint={this.enterkeyhint}\n inputMode={this.inputmode}\n disabled={this.disabled}\n maxLength={this.maxlength}\n minLength={this.minlength}\n name={this.name}\n placeholder={this.placeholder || ''}\n readOnly={this.readonly}\n required={this.required}\n spellcheck={this.spellcheck}\n cols={this.cols}\n rows={this.rows}\n wrap={this.wrap}\n onInput={this.onInput}\n onBlur={this.onBlur}\n onFocus={this.onFocus}\n onKeyDown={this.onKeyDown}\n style={style}\n {...this.inheritedAttributes}\n >\n {value}\n </textarea>\n </Host>\n );\n }\n}\n\nlet textareaIds = 0;\n"]}
|
|
1
|
+
{"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../../src/components/textarea/textarea.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n ComponentInterface,\n Method,\n Prop,\n State,\n Watch,\n h,\n Host,\n EventEmitter,\n Element,\n Event,\n Build,\n readTask\n} from '@stencil/core';\nimport { debounceEvent, findItemLabel, inheritAttributes, raf } from '../../utils/helpers';\nimport { TextareaChangeEventDetail } from './textarea-interface';\n\n/**\n * Mainly inspired from Ionic Textarea Component\n *\n * @cssprop --wcs-textarea-max-height - Max height of the text area component\n *\n */\n@Component({\n tag: 'wcs-textarea',\n styleUrl: 'textarea.scss',\n shadow: {\n delegatesFocus: true\n },\n})\nexport class Textarea implements ComponentInterface {\n private nativeInput?: HTMLTextAreaElement;\n private inputId = `wcs-textarea-${textareaIds++}`;\n private didBlurAfterEdit = false;\n private inheritedAttributes: { [k: string]: any } = {};\n\n /**\n * This is required for a WebKit bug which requires us to\n * blur and focus an input to properly focus the input in\n * an item with delegatesFocus. It will no longer be needed\n * with iOS 14.\n *\n * @internal\n */\n @Prop() fireFocusEvents = true;\n\n @Element() private el!: HTMLElement;\n\n @State() private hasFocus = false;\n\n /**\n * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.\n */\n @Prop() autocapitalize = 'none';\n\n /**\n * This Boolean attribute lets you specify that a form control should have input focus when the page loads.\n */\n @Prop() autofocus = false;\n\n /**\n * If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `\"password\"`, `false` for all other types.\n */\n @Prop({mutable: true}) clearOnEdit = false;\n\n /**\n * Set the amount of time, in milliseconds, to wait to trigger the `wcsChange` event after each keystroke. This also impacts form bindings such as `ngModel` or `v-model`.\n */\n @Prop() debounce = 0;\n\n @Watch('debounce')\n protected debounceChanged() {\n this.wcsChange = debounceEvent(this.wcsChange, this.debounce);\n }\n\n /**\n * If `true`, the user cannot interact with the textarea.\n */\n @Prop() disabled = false;\n\n /**\n * Name of the material icon to add to the input\n */\n @Prop() icon: string;\n\n /**\n * A hint to the browser for which keyboard to display.\n * Possible values: `\"none\"`, `\"text\"`, `\"tel\"`, `\"url\"`,\n * `\"email\"`, `\"numeric\"`, `\"decimal\"`, and `\"search\"`.\n */\n @Prop() inputmode?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';\n\n /**\n * A hint to the browser for which enter key to display.\n * Possible values: `\"enter\"`, `\"done\"`, `\"go\"`, `\"next\"`,\n * `\"previous\"`, `\"search\"`, and `\"send\"`.\n */\n @Prop() enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';\n\n /**\n * If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the maximum number of characters that the user can enter.\n */\n @Prop() maxlength?: number;\n\n /**\n * If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the minimum number of characters that the user can enter.\n */\n @Prop() minlength?: number;\n\n /**\n * The name of the control, which is submitted with the form data.\n */\n @Prop() name: string = this.inputId;\n\n /**\n * Instructional text that shows before the input has a value.\n */\n @Prop() placeholder?: string | null;\n\n /**\n * If `true`, the user cannot modify the value.\n */\n @Prop() readonly = false;\n\n /**\n * If `true`, the user must fill in a value before submitting a form.\n */\n @Prop() required = false;\n\n /**\n * If `true`, the element will have its spelling and grammar checked.\n */\n @Prop() spellcheck = false;\n\n /**\n * Specifies the state of the input. By default the input is in an initial state but you can set it to 'error' state if the data given by the user is not valid.\n */\n @Prop({reflect: true}) state: 'initial' | 'error' = 'initial';\n\n /**\n * The visible width of the text control, in average character widths. If it is specified, it must be a positive integer.\n */\n @Prop() cols?: number;\n\n /**\n * The number of visible text lines for the control.\n */\n @Prop() rows?: number;\n\n /**\n * Indicates how the control wraps text.\n */\n @Prop() wrap?: 'hard' | 'soft' | 'off';\n\n /**\n * If `true`, the element height will increase based on the value.\n */\n @Prop() autoGrow = false;\n\n /**\n * The value of the textarea.\n */\n @Prop({mutable: true}) value?: string | null = '';\n\n /**\n * Indicates how the textarea should be resizable.\n * Possible values 'both' | 'none' | 'vertical' | 'horizontal'\n */\n @Prop({reflect: true}) resize?: 'both' | 'none' | 'vertical' | 'horizontal';\n\n /**\n * Update the native input element when the value changes\n */\n @Watch('value')\n protected valueChanged() {\n const nativeInput = this.nativeInput;\n const value = this.getValue();\n if (nativeInput && nativeInput.value !== value) {\n nativeInput.value = value;\n }\n this.runAutoGrow();\n this.wcsChange.emit({value});\n }\n\n /**\n * Emitted when the input value has changed.\n */\n @Event() wcsChange!: EventEmitter<TextareaChangeEventDetail>;\n\n /**\n * Emitted when a keyboard input occurred.\n */\n @Event() wcsInput!: EventEmitter<KeyboardEvent>;\n\n /**\n * Emitted when the input loses focus.\n */\n @Event() wcsBlur!: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when the input has focus.\n */\n @Event() wcsFocus!: EventEmitter<FocusEvent>;\n\n connectedCallback() {\n this.debounceChanged();\n if (Build.isBrowser) {\n document.dispatchEvent(new CustomEvent('wcsInputDidLoad', {\n detail: this.el\n }));\n }\n }\n\n disconnectedCallback() {\n if (Build.isBrowser) {\n document.dispatchEvent(new CustomEvent('wcsInputDidUnload', {\n detail: this.el\n }));\n }\n }\n\n componentWillLoad() {\n this.inheritedAttributes = inheritAttributes(this.el, ['title']);\n }\n\n componentDidLoad() {\n raf(() => this.runAutoGrow());\n }\n\n private runAutoGrow() {\n const nativeInput = this.nativeInput;\n if (nativeInput && this.autoGrow) {\n readTask(() => {\n nativeInput.style.height = 'auto';\n nativeInput.style.height = nativeInput.scrollHeight + 'px';\n });\n }\n }\n\n /**\n * This method make the textarea automatically adopt the size of the content without a scroll bar\n */\n @Method()\n async fitContent() {\n raf(() => this.runAutoGrow());\n }\n\n /**\n * @deprecated use the native focus method instead \n * Sets focus on the native `textarea` in `wcs-textarea`.\n */\n @Method()\n async setFocus() {\n if (this.nativeInput) {\n this.nativeInput.focus();\n }\n }\n\n /**\n * Sets blur on the native `textarea` in `wcs-textarea`. Use this method instead of the global\n * `textarea.blur()`.\n * @internal\n */\n @Method()\n async setBlur() {\n if (this.nativeInput) {\n this.nativeInput.blur();\n }\n }\n\n /**\n * Returns the native `<textarea>` element used under the hood.\n */\n @Method()\n getInputElement(): Promise<HTMLTextAreaElement> {\n // tslint:disable-next-line:no-non-null-assertion\n return Promise.resolve(this.nativeInput!);\n }\n\n /**\n * Check if we need to clear the text input if clearOnEdit is enabled\n */\n private checkClearOnEdit() {\n if (!this.clearOnEdit) {\n return;\n }\n\n // Did the input value change after it was blurred and edited?\n if (this.didBlurAfterEdit && this.hasValue()) {\n // Clear the input\n this.value = '';\n }\n\n // Reset the flag\n this.didBlurAfterEdit = false;\n }\n\n private focusChange() {\n // If clearOnEdit is enabled and the input blurred but has a value, set a flag\n if (this.clearOnEdit && !this.hasFocus && this.hasValue()) {\n this.didBlurAfterEdit = true;\n }\n }\n\n private hasValue(): boolean {\n return this.getValue() !== '';\n }\n\n private getValue(): string {\n return this.value || '';\n }\n\n private onInput = (ev: Event) => {\n if (this.nativeInput) {\n this.value = this.nativeInput.value;\n }\n this.wcsInput.emit(ev as KeyboardEvent);\n }\n\n private onFocus = (ev: FocusEvent) => {\n this.hasFocus = true;\n this.focusChange();\n\n if (this.fireFocusEvents) {\n this.wcsFocus.emit(ev);\n }\n }\n\n private onBlur = (ev: FocusEvent) => {\n this.hasFocus = false;\n this.focusChange();\n\n if (this.fireFocusEvents) {\n this.wcsBlur.emit(ev);\n }\n }\n\n private onKeyDown = () => {\n this.checkClearOnEdit();\n }\n\n render() {\n const value = this.getValue();\n const labelId = this.inputId + '-lbl';\n const label = findItemLabel(this.el);\n if (label) {\n label.id = labelId;\n }\n const style = {\n ...(this.resize && {'resize': this.resize})\n }\n\n return (\n <Host\n aria-disabled={this.disabled ? 'true' : null}\n >\n {this.icon ? (<wcs-mat-icon icon={this.icon} size=\"m\"></wcs-mat-icon>) : null}\n <textarea\n class=\"native-textarea\"\n aria-labelledby={label ? labelId : null}\n ref={el => this.nativeInput = el}\n autoCapitalize={this.autocapitalize}\n autoFocus={this.autofocus}\n enterKeyHint={this.enterkeyhint}\n inputMode={this.inputmode}\n disabled={this.disabled}\n maxLength={this.maxlength}\n minLength={this.minlength}\n name={this.name}\n placeholder={this.placeholder || ''}\n readOnly={this.readonly}\n required={this.required}\n spellcheck={this.spellcheck}\n cols={this.cols}\n rows={this.rows}\n wrap={this.wrap}\n onInput={this.onInput}\n onBlur={this.onBlur}\n onFocus={this.onFocus}\n onKeyDown={this.onKeyDown}\n style={style}\n {...this.inheritedAttributes}\n >\n {value}\n </textarea>\n </Host>\n );\n }\n}\n\nlet textareaIds = 0;\n"]}
|
|
@@ -1,4 +1,62 @@
|
|
|
1
1
|
export function isElementFocused(element) {
|
|
2
2
|
return element === document.activeElement;
|
|
3
3
|
}
|
|
4
|
+
export const wcsFocusableElements = [
|
|
5
|
+
'wcs-select',
|
|
6
|
+
'wcs-select-option',
|
|
7
|
+
'wcs-dropdown',
|
|
8
|
+
'wcs-dropdown-item',
|
|
9
|
+
'wcs-nav-item',
|
|
10
|
+
'wcs-button',
|
|
11
|
+
'wcs-input',
|
|
12
|
+
'wcs-textarea',
|
|
13
|
+
'wcs-checkbox',
|
|
14
|
+
'wcs-radio',
|
|
15
|
+
'wcs-switch',
|
|
16
|
+
'wcs-tab',
|
|
17
|
+
'wcs-counter',
|
|
18
|
+
];
|
|
19
|
+
export function isFocusable(element) {
|
|
20
|
+
if (parseInt(element.getAttribute('tabindex')) < 0) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
if (element.disabled) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const boundingRect = element.getBoundingClientRect();
|
|
27
|
+
if (boundingRect.bottom === 0 &&
|
|
28
|
+
boundingRect.top === 0 &&
|
|
29
|
+
boundingRect.left === 0 &&
|
|
30
|
+
boundingRect.right === 0 &&
|
|
31
|
+
boundingRect.height === 0 &&
|
|
32
|
+
boundingRect.width === 0 &&
|
|
33
|
+
boundingRect.x === 0 &&
|
|
34
|
+
boundingRect.y === 0) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (element.style.display === 'none' ||
|
|
38
|
+
element.style.visibility === 'hidden' ||
|
|
39
|
+
element.style.opacity === 0) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
if (element.getAttribute('role') === 'button') {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
if (wcsFocusableElements.includes(element.tagName.toLowerCase())) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
// To identify other native focus elements.
|
|
49
|
+
switch (element.nodeName) {
|
|
50
|
+
case 'A':
|
|
51
|
+
return !!element.href && element.rel !== 'ignore';
|
|
52
|
+
case 'INPUT':
|
|
53
|
+
return element.type !== 'hidden';
|
|
54
|
+
case 'BUTTON':
|
|
55
|
+
case 'SELECT':
|
|
56
|
+
case 'TEXTAREA':
|
|
57
|
+
return true;
|
|
58
|
+
default:
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
4
62
|
//# sourceMappingURL=accessibility.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessibility.js","sourceRoot":"","sources":["../../src/utils/accessibility.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAAC,OAAoB;EACjD,OAAO,OAAO,KAAK,QAAQ,CAAC,aAAa,CAAC;AAC9C,CAAC","sourcesContent":["export function isElementFocused(element: HTMLElement) {\n return element === document.activeElement;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"accessibility.js","sourceRoot":"","sources":["../../src/utils/accessibility.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAAC,OAAoB;EACjD,OAAO,OAAO,KAAK,QAAQ,CAAC,aAAa,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG;EAChC,YAAY;EACZ,mBAAmB;EACnB,cAAc;EACd,mBAAmB;EACnB,cAAc;EACd,YAAY;EACZ,WAAW;EACX,cAAc;EACd,cAAc;EACd,WAAW;EACX,YAAY;EACZ,SAAS;EACT,aAAa;CAChB,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,OAAY;EACpC,IAAI,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,EAAE;IAChD,OAAO,KAAK,CAAC;GAChB;EACD,IAAI,OAAO,CAAC,QAAQ,EAAE;IAClB,OAAO,KAAK,CAAC;GAChB;EACD,MAAM,YAAY,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;EACrD,IACI,YAAY,CAAC,MAAM,KAAK,CAAC;IACzB,YAAY,CAAC,GAAG,KAAK,CAAC;IACtB,YAAY,CAAC,IAAI,KAAK,CAAC;IACvB,YAAY,CAAC,KAAK,KAAK,CAAC;IACxB,YAAY,CAAC,MAAM,KAAK,CAAC;IACzB,YAAY,CAAC,KAAK,KAAK,CAAC;IACxB,YAAY,CAAC,CAAC,KAAK,CAAC;IACpB,YAAY,CAAC,CAAC,KAAK,CAAC,EACtB;IACE,OAAO,KAAK,CAAC;GAChB;EACD,IACI,OAAO,CAAC,KAAK,CAAC,OAAO,KAAK,MAAM;IAChC,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,QAAQ;IACrC,OAAO,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,EAC7B;IACE,OAAO,KAAK,CAAC;GAChB;EACD,IAAI,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE;IAC3C,OAAO,IAAI,CAAC;GACf;EAED,IAAI,oBAAoB,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE;IAC9D,OAAO,IAAI,CAAC;GACf;EAED,2CAA2C;EAC3C,QAAQ,OAAO,CAAC,QAAQ,EAAE;IACtB,KAAK,GAAG;MACJ,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC;IACtD,KAAK,OAAO;MACR,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC;IACrC,KAAK,QAAQ,CAAC;IACd,KAAK,QAAQ,CAAC;IACd,KAAK,UAAU;MACX,OAAO,IAAI,CAAC;IAChB;MACI,OAAO,KAAK,CAAC;GACpB;AACL,CAAC","sourcesContent":["export function isElementFocused(element: HTMLElement) {\n return element === document.activeElement;\n}\n\nexport const wcsFocusableElements = [\n 'wcs-select',\n 'wcs-select-option',\n 'wcs-dropdown',\n 'wcs-dropdown-item',\n 'wcs-nav-item',\n 'wcs-button',\n 'wcs-input',\n 'wcs-textarea',\n 'wcs-checkbox',\n 'wcs-radio',\n 'wcs-switch',\n 'wcs-tab',\n 'wcs-counter',\n];\n\nexport function isFocusable(element: any) {\n if (parseInt(element.getAttribute('tabindex')) < 0) {\n return false;\n }\n if (element.disabled) {\n return false;\n }\n const boundingRect = element.getBoundingClientRect();\n if (\n boundingRect.bottom === 0 &&\n boundingRect.top === 0 &&\n boundingRect.left === 0 &&\n boundingRect.right === 0 &&\n boundingRect.height === 0 &&\n boundingRect.width === 0 &&\n boundingRect.x === 0 &&\n boundingRect.y === 0\n ) {\n return false;\n }\n if (\n element.style.display === 'none' ||\n element.style.visibility === 'hidden' ||\n element.style.opacity === 0\n ) {\n return false;\n }\n if (element.getAttribute('role') === 'button') {\n return true;\n }\n\n if (wcsFocusableElements.includes(element.tagName.toLowerCase())) {\n return true;\n }\n\n // To identify other native focus elements.\n switch (element.nodeName) {\n case 'A':\n return !!element.href && element.rel !== 'ignore';\n case 'INPUT':\n return element.type !== 'hidden';\n case 'BUTTON':\n case 'SELECT':\n case 'TEXTAREA':\n return true;\n default:\n return false;\n }\n}\n"]}
|