voyager-ionic-core 8.8.2 → 8.8.5
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/components/ion-action-sheet.js +1 -1
- package/components/ion-checkbox.js +1 -1
- package/components/ion-content.js +1 -1
- package/components/ion-datetime.js +1 -1
- package/components/ion-input-otp.js +1 -1
- package/components/ion-modal.js +1 -1
- package/components/ion-picker-column.js +1 -1
- package/components/ion-radio-group.js +1 -1
- package/components/ion-select-modal.js +1 -1
- package/components/ion-select-popover.js +1 -1
- package/components/ion-select.js +1 -1
- package/components/p-0z8QSI5b.js +4 -0
- package/components/{p-ApmKVjaE.js → p-BGHGpkPX.js} +1 -1
- package/components/p-BlNv564p.js +4 -0
- package/components/p-D-cP12ZN.js +4 -0
- package/components/p-D3Ti70Hx.js +4 -0
- package/components/{p-Bk2zuNWT.js → p-DvOO1fxp.js} +1 -1
- package/components/p-FBcnjE5W.js +4 -0
- package/components/p-SBseW5KJ.js +4 -0
- package/css/palettes/dark.always.css +1 -1
- package/css/palettes/dark.always.css.map +1 -1
- package/css/palettes/dark.class.css +1 -1
- package/css/palettes/dark.class.css.map +1 -1
- package/css/palettes/dark.system.css +1 -1
- package/css/palettes/dark.system.css.map +1 -1
- package/css/palettes/high-contrast-dark.always.css +1 -1
- package/css/palettes/high-contrast-dark.always.css.map +1 -1
- package/css/palettes/high-contrast-dark.class.css +1 -1
- package/css/palettes/high-contrast-dark.class.css.map +1 -1
- package/css/palettes/high-contrast-dark.system.css +1 -1
- package/css/palettes/high-contrast-dark.system.css.map +1 -1
- package/dist/cjs/ion-action-sheet.cjs.entry.js +4 -4
- package/dist/cjs/ion-app_8.cjs.entry.js +1 -1
- package/dist/cjs/ion-checkbox.cjs.entry.js +39 -32
- package/dist/cjs/ion-datetime_3.cjs.entry.js +17 -6
- package/dist/cjs/ion-input-otp.cjs.entry.js +21 -6
- package/dist/cjs/ion-modal.cjs.entry.js +99 -45
- package/dist/cjs/ion-picker-column.cjs.entry.js +4 -4
- package/dist/cjs/ion-radio_2.cjs.entry.js +13 -1
- package/dist/cjs/ion-select-modal.cjs.entry.js +18 -7
- package/dist/cjs/ion-select_3.cjs.entry.js +18 -7
- package/dist/collection/components/action-sheet/action-sheet.js +4 -4
- package/dist/collection/components/checkbox/checkbox.js +39 -32
- package/dist/collection/components/content/content.css +1 -1
- package/dist/collection/components/datetime/datetime.js +17 -6
- package/dist/collection/components/input-otp/input-otp.js +21 -6
- package/dist/collection/components/modal/modal.js +73 -44
- package/dist/collection/components/modal/safe-area-utils.js +27 -2
- package/dist/collection/components/picker-column/picker-column.js +5 -5
- package/dist/collection/components/radio-group/radio-group.js +13 -1
- package/dist/collection/components/radio-group/test/fixtures.js +2 -2
- package/dist/collection/components/select-modal/select-modal.js +18 -7
- package/dist/collection/components/select-modal/test/fixtures.js +4 -0
- package/dist/collection/components/select-popover/select-popover.js +18 -7
- package/dist/collection/components/select-popover/test/fixtures.js +4 -0
- package/dist/docs.json +1 -1
- package/dist/esm/ion-action-sheet.entry.js +4 -4
- package/dist/esm/ion-app_8.entry.js +1 -1
- package/dist/esm/ion-checkbox.entry.js +39 -32
- package/dist/esm/ion-datetime_3.entry.js +17 -6
- package/dist/esm/ion-input-otp.entry.js +21 -6
- package/dist/esm/ion-modal.entry.js +99 -45
- package/dist/esm/ion-picker-column.entry.js +5 -5
- package/dist/esm/ion-radio_2.entry.js +13 -1
- package/dist/esm/ion-select-modal.entry.js +18 -7
- package/dist/esm/ion-select_3.entry.js +18 -7
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-078037da.entry.js +4 -0
- package/dist/ionic/p-23ec35e4.entry.js +4 -0
- package/dist/ionic/p-268a3397.entry.js +4 -0
- package/dist/ionic/p-28a9e720.entry.js +4 -0
- package/dist/ionic/p-4c67ce4c.entry.js +4 -0
- package/dist/ionic/p-87125490.entry.js +4 -0
- package/dist/ionic/{p-4dd5e8e0.entry.js → p-8fda6a62.entry.js} +1 -1
- package/dist/ionic/{p-9eac4eb1.entry.js → p-aa812c4b.entry.js} +1 -1
- package/dist/ionic/p-cb27fe68.entry.js +4 -0
- package/dist/ionic/p-ce2edb36.entry.js +4 -0
- package/dist/types/components/checkbox/checkbox.d.ts +0 -1
- package/dist/types/components/datetime/datetime.d.ts +1 -0
- package/dist/types/components/modal/modal.d.ts +41 -3
- package/dist/types/components/modal/safe-area-utils.d.ts +16 -0
- package/dist/types/components/radio-group/test/fixtures.d.ts +1 -1
- package/dist/types/components/select-modal/select-modal.d.ts +1 -0
- package/dist/types/components/select-modal/test/fixtures.d.ts +1 -0
- package/dist/types/components/select-popover/select-popover.d.ts +1 -0
- package/dist/types/components/select-popover/test/fixtures.d.ts +1 -0
- package/hydrate/index.js +199 -87
- package/hydrate/index.mjs +199 -87
- package/package.json +4 -4
- package/components/p-1KVKSLu5.js +0 -4
- package/components/p-BI7WNErr.js +0 -4
- package/components/p-C7AoMl7c.js +0 -4
- package/components/p-D6pdfDIA.js +0 -4
- package/components/p-cvHphHJA.js +0 -4
- package/components/p-e-EDj2CO.js +0 -4
- package/dist/ionic/p-2d4eb1b4.entry.js +0 -4
- package/dist/ionic/p-3e143d1d.entry.js +0 -4
- package/dist/ionic/p-51c11c47.entry.js +0 -4
- package/dist/ionic/p-5681dde4.entry.js +0 -4
- package/dist/ionic/p-9fae83d8.entry.js +0 -4
- package/dist/ionic/p-c744307d.entry.js +0 -4
- package/dist/ionic/p-cb78f5a0.entry.js +0 -4
- package/dist/ionic/p-e6c5f060.entry.js +0 -4
|
@@ -15,6 +15,12 @@ import { raf } from "../../utils/helpers";
|
|
|
15
15
|
const MODAL_INSET_MIN_WIDTH = 768;
|
|
16
16
|
const MODAL_INSET_MIN_HEIGHT = 600;
|
|
17
17
|
const EDGE_THRESHOLD = 5;
|
|
18
|
+
/**
|
|
19
|
+
* CSS values for `--width` / `--height` that are treated as fullscreen
|
|
20
|
+
* (modal touches the corresponding screen edges). Empty string means the
|
|
21
|
+
* property was not overridden. See `hasCustomModalDimensions()`.
|
|
22
|
+
*/
|
|
23
|
+
const FULLSCREEN_SIZE_VALUES = new Set(['', '100%', '100vw', '100vh', '100dvw', '100dvh', '100svw', '100svh']);
|
|
18
24
|
/**
|
|
19
25
|
* Cache for resolved root safe-area-top value, invalidated once per frame.
|
|
20
26
|
*/
|
|
@@ -63,6 +69,22 @@ export const getRootSafeAreaTop = () => {
|
|
|
63
69
|
}
|
|
64
70
|
return value;
|
|
65
71
|
};
|
|
72
|
+
/**
|
|
73
|
+
* True when the modal host declares BOTH a non-fullscreen `--width` AND a
|
|
74
|
+
* non-fullscreen `--height` (i.e. a centered-dialog-like modal that doesn't
|
|
75
|
+
* touch any screen edge).
|
|
76
|
+
*
|
|
77
|
+
* The conservative "both axes" check avoids mis-zeroing safe-area for
|
|
78
|
+
* partial-custom modals where the modal still touches top/bottom edges
|
|
79
|
+
* (e.g. only `--width` overridden). Partial cases fall through to the
|
|
80
|
+
* existing position-based post-animation correction.
|
|
81
|
+
*/
|
|
82
|
+
export const hasCustomModalDimensions = (hostEl) => {
|
|
83
|
+
const styles = getComputedStyle(hostEl);
|
|
84
|
+
const width = styles.getPropertyValue('--width').trim();
|
|
85
|
+
const height = styles.getPropertyValue('--height').trim();
|
|
86
|
+
return !FULLSCREEN_SIZE_VALUES.has(width) && !FULLSCREEN_SIZE_VALUES.has(height);
|
|
87
|
+
};
|
|
66
88
|
/**
|
|
67
89
|
* Returns the initial safe-area configuration based on modal type.
|
|
68
90
|
* This is called before animation starts and uses configuration-based prediction.
|
|
@@ -97,8 +119,11 @@ export const getInitialSafeAreaConfig = (context) => {
|
|
|
97
119
|
}
|
|
98
120
|
// On viewports that meet the centered dialog media query breakpoints,
|
|
99
121
|
// regular modals render as centered dialogs (not fullscreen), so they
|
|
100
|
-
// don't touch any screen edges and don't need safe-area insets.
|
|
101
|
-
|
|
122
|
+
// don't touch any screen edges and don't need safe-area insets. Also
|
|
123
|
+
// applies to phone viewports when the modal declares custom --width and
|
|
124
|
+
// --height; these don't touch screen edges either, so the initial
|
|
125
|
+
// prediction must be zero to avoid a post-animation correction flash.
|
|
126
|
+
if (isCenteredDialogViewport() || context.hasCustomDimensions) {
|
|
102
127
|
return {
|
|
103
128
|
top: '0px',
|
|
104
129
|
bottom: '0px',
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { Host, h } from "@stencil/core";
|
|
5
5
|
import { doc } from "../../utils/browser/index";
|
|
6
|
-
import {
|
|
6
|
+
import { raf } from "../../utils/helpers";
|
|
7
7
|
import { hapticSelectionChanged, hapticSelectionEnd, hapticSelectionStart } from "../../utils/native/haptic";
|
|
8
8
|
import { isPlatform } from "../../utils/platform";
|
|
9
9
|
import { createColorClasses } from "../../utils/theme";
|
|
@@ -451,7 +451,7 @@ export class PickerColumn {
|
|
|
451
451
|
* Because this initial call to scrollActiveItemIntoView has to fire before
|
|
452
452
|
* the scroll listener is set up, we need to manage the active class manually.
|
|
453
453
|
*/
|
|
454
|
-
const oldActive =
|
|
454
|
+
const oldActive = el.querySelector(`.${PICKER_ITEM_ACTIVE_CLASS}`);
|
|
455
455
|
if (oldActive) {
|
|
456
456
|
this.setPickerItemActiveState(oldActive, false);
|
|
457
457
|
}
|
|
@@ -551,14 +551,14 @@ export class PickerColumn {
|
|
|
551
551
|
render() {
|
|
552
552
|
const { color, disabled, isActive, numericInput } = this;
|
|
553
553
|
const mode = getIonMode(this);
|
|
554
|
-
return (h(Host, { key: '
|
|
554
|
+
return (h(Host, { key: '234c96a501d7ac413b9b0ea56b33017681e25b40', class: createColorClasses(color, {
|
|
555
555
|
[mode]: true,
|
|
556
556
|
['picker-column-active']: isActive,
|
|
557
557
|
['picker-column-numeric-input']: numericInput,
|
|
558
558
|
['picker-column-disabled']: disabled,
|
|
559
|
-
}) }, h("slot", { key: '
|
|
559
|
+
}) }, h("slot", { key: '9dc15ea0601ddd2cb2e0a745e91e036a8bd96f8b', name: "prefix" }), h("div", { key: 'de4fe28ee4bc46b7c0420d6ab0df0e7809443da9', class: "picker-opts", ref: (el) => {
|
|
560
560
|
this.scrollEl = el;
|
|
561
|
-
}, role: "slider", tabindex: this.disabled ? undefined : 0, "aria-label": this.ariaLabel, "aria-valuemin": 0, "aria-valuemax": 0, "aria-valuenow": 0, "aria-valuetext": this.getOptionValueText(this.activeItem), "aria-orientation": "vertical", onKeyDown: (ev) => this.onKeyDown(ev) }, h("div", { key: '
|
|
561
|
+
}, role: "slider", tabindex: this.disabled ? undefined : 0, "aria-label": this.ariaLabel, "aria-valuemin": 0, "aria-valuemax": 0, "aria-valuenow": 0, "aria-valuetext": this.getOptionValueText(this.activeItem), "aria-orientation": "vertical", onKeyDown: (ev) => this.onKeyDown(ev) }, h("div", { key: '5297617462cc30e9444039ae032d8bdf718349af', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '55ea39ef867bcb1a11a912d52ecd20cb886c5fb3', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '3496730ce6182ebfd33e0ee4bafc130feb575a31', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("slot", { key: '44c3628aa957d60f799dc7019f72fe8b676c7843' }), h("div", { key: '5a1809f6c949678a67e0d4b5bfe93ea335c0161d', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '98fd57f1c66dbaebc2db2dd5da142671b3159fd1', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '85590708abddfa885994e549deac64866fec938f', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0")), h("slot", { key: 'bb7e674f543696a80fcbfb1f68f2e975826898a6', name: "suffix" })));
|
|
562
562
|
}
|
|
563
563
|
static get is() { return "ion-picker-column"; }
|
|
564
564
|
static get encapsulation() { return "shadow"; }
|
|
@@ -206,6 +206,18 @@ export class RadioGroup {
|
|
|
206
206
|
// to the bottom of the screen
|
|
207
207
|
ev.preventDefault();
|
|
208
208
|
}
|
|
209
|
+
// Inside a select interface, Enter commits the focused radio
|
|
210
|
+
// value (matching native <select>). The !ev.repeat guard stops
|
|
211
|
+
// a held Enter on the triggering ion-select from re-committing
|
|
212
|
+
// once focus lands in the opened popover/modal.
|
|
213
|
+
if (ev.key === 'Enter' && inSelectInterface && !ev.repeat) {
|
|
214
|
+
const previousValue = this.value;
|
|
215
|
+
this.value = current.value;
|
|
216
|
+
if (previousValue !== this.value) {
|
|
217
|
+
this.emitValueChange(ev);
|
|
218
|
+
}
|
|
219
|
+
ev.preventDefault();
|
|
220
|
+
}
|
|
209
221
|
}
|
|
210
222
|
}
|
|
211
223
|
/** @internal */
|
|
@@ -238,7 +250,7 @@ export class RadioGroup {
|
|
|
238
250
|
const { label, labelId, el, name, value } = this;
|
|
239
251
|
const mode = getIonMode(this);
|
|
240
252
|
renderHiddenInput(true, el, name, value, false);
|
|
241
|
-
return (h(Host, { key: '
|
|
253
|
+
return (h(Host, { key: '377e4aa3a656cc84b742f9d7a7d4be65d20c69f5', role: "radiogroup", "aria-labelledby": label ? labelId : null, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, onClick: this.onClick, class: mode }, this.renderHintText(), h("slot", { key: 'c3187a2497773b4f15cea3b413b036502bcec8c0' })));
|
|
242
254
|
}
|
|
243
255
|
static get is() { return "ion-radio-group"; }
|
|
244
256
|
static get originalStyleUrls() {
|
|
@@ -6,12 +6,12 @@ export class RadioFixture {
|
|
|
6
6
|
constructor(page) {
|
|
7
7
|
this.page = page;
|
|
8
8
|
}
|
|
9
|
-
async checkRadio(method, selector = 'ion-radio') {
|
|
9
|
+
async checkRadio(method, selector = 'ion-radio', key = 'Space') {
|
|
10
10
|
const { page } = this;
|
|
11
11
|
const radio = (this.radio = page.locator(selector));
|
|
12
12
|
if (method === 'keyboard') {
|
|
13
13
|
await radio.focus();
|
|
14
|
-
await page.keyboard.press(
|
|
14
|
+
await page.keyboard.press(key);
|
|
15
15
|
}
|
|
16
16
|
else {
|
|
17
17
|
await radio.click();
|
|
@@ -7,6 +7,10 @@ import { safeCall } from "../../utils/overlays";
|
|
|
7
7
|
import { getClassMap } from "../../utils/theme";
|
|
8
8
|
export class SelectModal {
|
|
9
9
|
constructor() {
|
|
10
|
+
// Tracks the option that received Enter-keydown so keyup only
|
|
11
|
+
// dismisses when the press started on the same option. Prevents
|
|
12
|
+
// Enter on the triggering ion-select from auto-dismissing.
|
|
13
|
+
this.pendingEnterTarget = null;
|
|
10
14
|
/**
|
|
11
15
|
* The text to display on the cancel button.
|
|
12
16
|
*/
|
|
@@ -56,15 +60,22 @@ export class SelectModal {
|
|
|
56
60
|
return (h("ion-radio-group", { value: checked, onIonChange: (ev) => this.callOptionHandler(ev) }, this.options.map((option) => (h("ion-item", { lines: "none", class: Object.assign({
|
|
57
61
|
// TODO FW-4784
|
|
58
62
|
'item-radio-checked': option.value === checked
|
|
59
|
-
}, getClassMap(option.cssClass)) }, h("ion-radio", { value: option.value, disabled: option.disabled, justify: "start", labelPlacement: "end", onClick: () => this.closeModal(),
|
|
63
|
+
}, getClassMap(option.cssClass)) }, h("ion-radio", { value: option.value, disabled: option.disabled, justify: "start", labelPlacement: "end", onClick: () => this.closeModal(), onKeyDown: (ev) => {
|
|
64
|
+
if (ev.key === 'Enter' && !ev.repeat) {
|
|
65
|
+
this.pendingEnterTarget = ev.currentTarget;
|
|
66
|
+
}
|
|
67
|
+
}, onKeyUp: (ev) => {
|
|
60
68
|
if (ev.key === ' ') {
|
|
61
|
-
|
|
62
|
-
* Selecting a radio option with keyboard navigation,
|
|
63
|
-
* either through the Enter or Space keys, should
|
|
64
|
-
* dismiss the modal.
|
|
65
|
-
*/
|
|
69
|
+
// Space selects and dismisses in one press.
|
|
66
70
|
this.closeModal();
|
|
67
71
|
}
|
|
72
|
+
else if (ev.key === 'Enter') {
|
|
73
|
+
const shouldClose = this.pendingEnterTarget === ev.currentTarget;
|
|
74
|
+
this.pendingEnterTarget = null;
|
|
75
|
+
if (shouldClose) {
|
|
76
|
+
this.closeModal();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
68
79
|
} }, option.text))))));
|
|
69
80
|
}
|
|
70
81
|
renderCheckboxOptions() {
|
|
@@ -79,7 +90,7 @@ export class SelectModal {
|
|
|
79
90
|
} }, option.text))));
|
|
80
91
|
}
|
|
81
92
|
render() {
|
|
82
|
-
return (h(Host, { key: '
|
|
93
|
+
return (h(Host, { key: 'fda0bf6f93cd5ec9f3c64f88a52de849e0e140a2', class: getIonMode(this) }, h("ion-header", { key: '27c0b17175a53db9ff159feeeb96451a3f011dab' }, h("ion-toolbar", { key: '91a4155ebc317fbc9f1bb3e26a7e94754b953c9b' }, this.header !== undefined && h("ion-title", { key: 'f6dae8e4e381f322cc90efefd9bb6ef81d4d2f3e' }, this.header), h("ion-buttons", { key: 'e7760532fb2e7e7385ed6e62097d92d96ff20148', slot: "end" }, h("ion-button", { key: '4999b6fc46cba138186546dca67b7950855e6fb7', onClick: () => this.closeModal() }, this.cancelText)))), h("ion-content", { key: 'c73f80a4bc25b9061ea65cf11e5d811c1a4d8704' }, h("ion-list", { key: 'b21905d15b36ad5eb45845e768918d2763cf48b1' }, this.multiple === true ? this.renderCheckboxOptions() : this.renderRadioOptions()))));
|
|
83
94
|
}
|
|
84
95
|
static get is() { return "ion-select-modal"; }
|
|
85
96
|
static get encapsulation() { return "scoped"; }
|
|
@@ -39,6 +39,10 @@ export class SelectModalPage {
|
|
|
39
39
|
const option = this.getOption(value);
|
|
40
40
|
await option.press('Space');
|
|
41
41
|
}
|
|
42
|
+
async pressEnterOnOption(value) {
|
|
43
|
+
const option = this.getOption(value);
|
|
44
|
+
await option.press('Enter');
|
|
45
|
+
}
|
|
42
46
|
getOption(value) {
|
|
43
47
|
const { multiple, selectModal } = this;
|
|
44
48
|
const selector = multiple ? 'ion-checkbox' : 'ion-radio';
|
|
@@ -10,6 +10,10 @@ import { getIonMode } from "../../global/ionic-global";
|
|
|
10
10
|
*/
|
|
11
11
|
export class SelectPopover {
|
|
12
12
|
constructor() {
|
|
13
|
+
// Tracks the option that received Enter-keydown so keyup only
|
|
14
|
+
// dismisses when the press started on the same option. Prevents
|
|
15
|
+
// Enter on the triggering ion-select from auto-dismissing.
|
|
16
|
+
this.pendingEnterTarget = null;
|
|
13
17
|
/**
|
|
14
18
|
* An array of options for the popover
|
|
15
19
|
*/
|
|
@@ -87,21 +91,28 @@ export class SelectPopover {
|
|
|
87
91
|
return (h("ion-radio-group", { value: checked, onIonChange: (ev) => this.callOptionHandler(ev) }, options.map((option) => (h("ion-item", { class: Object.assign({
|
|
88
92
|
// TODO FW-4784
|
|
89
93
|
'item-radio-checked': option.value === checked
|
|
90
|
-
}, getClassMap(option.cssClass)) }, h("ion-radio", { value: option.value, disabled: option.disabled, onClick: () => this.dismissParentPopover(),
|
|
94
|
+
}, getClassMap(option.cssClass)) }, h("ion-radio", { value: option.value, disabled: option.disabled, onClick: () => this.dismissParentPopover(), onKeyDown: (ev) => {
|
|
95
|
+
if (ev.key === 'Enter' && !ev.repeat) {
|
|
96
|
+
this.pendingEnterTarget = ev.currentTarget;
|
|
97
|
+
}
|
|
98
|
+
}, onKeyUp: (ev) => {
|
|
91
99
|
if (ev.key === ' ') {
|
|
92
|
-
|
|
93
|
-
* Selecting a radio option with keyboard navigation,
|
|
94
|
-
* either through the Enter or Space keys, should
|
|
95
|
-
* dismiss the popover.
|
|
96
|
-
*/
|
|
100
|
+
// Space selects and dismisses in one press.
|
|
97
101
|
this.dismissParentPopover();
|
|
98
102
|
}
|
|
103
|
+
else if (ev.key === 'Enter') {
|
|
104
|
+
const shouldDismiss = this.pendingEnterTarget === ev.currentTarget;
|
|
105
|
+
this.pendingEnterTarget = null;
|
|
106
|
+
if (shouldDismiss) {
|
|
107
|
+
this.dismissParentPopover();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
99
110
|
} }, option.text))))));
|
|
100
111
|
}
|
|
101
112
|
render() {
|
|
102
113
|
const { header, message, options, subHeader } = this;
|
|
103
114
|
const hasSubHeaderOrMessage = subHeader !== undefined || message !== undefined;
|
|
104
|
-
return (h(Host, { key: '
|
|
115
|
+
return (h(Host, { key: 'e7449a1ecfcdbf45a79f8e26a00253c4e146448a', class: getIonMode(this) }, h("ion-list", { key: '52abdfc8668c3429a0dcefef8ddedb6647fdd894' }, header !== undefined && h("ion-list-header", { key: '978e5c03728756feafcc60a0e10e6ec59bf2ae11' }, header), hasSubHeaderOrMessage && (h("ion-item", { key: 'e93c44e7f07a76def16e4b11f0fb4780d84ed402' }, h("ion-label", { key: 'bba1aac43b0bc7f4f00978dd8301985233f3725c', class: "ion-text-wrap" }, subHeader !== undefined && h("h3", { key: 'ad96f6017cf2cc5219540bded2c4f1ca3b532de2' }, subHeader), message !== undefined && h("p", { key: '3fd038921dc40c4d0c29734433984b279ccaeec3' }, message)))), this.renderOptions(options))));
|
|
105
116
|
}
|
|
106
117
|
static get is() { return "ion-select-popover"; }
|
|
107
118
|
static get encapsulation() { return "scoped"; }
|
|
@@ -39,6 +39,10 @@ export class SelectPopoverPage {
|
|
|
39
39
|
const option = this.getOption(value);
|
|
40
40
|
await option.press('Space');
|
|
41
41
|
}
|
|
42
|
+
async pressEnterOnOption(value) {
|
|
43
|
+
const option = this.getOption(value);
|
|
44
|
+
await option.press('Enter');
|
|
45
|
+
}
|
|
42
46
|
getOption(value) {
|
|
43
47
|
const { multiple, selectPopover } = this;
|
|
44
48
|
const selector = multiple ? 'ion-checkbox' : 'ion-radio';
|
package/dist/docs.json
CHANGED
|
@@ -471,7 +471,7 @@ const ActionSheet = class {
|
|
|
471
471
|
if (isRadio) {
|
|
472
472
|
htmlAttrs['aria-checked'] = isActiveRadio ? 'true' : 'false';
|
|
473
473
|
}
|
|
474
|
-
return (h("button", Object.assign({}, htmlAttrs, { role: isRadio ? 'radio' : undefined, type: "button", id: buttonId, class: Object.assign(Object.assign({}, buttonClass(b)), { 'action-sheet-selected': isActiveRadio }), onClick: () => {
|
|
474
|
+
return (h("button", Object.assign({}, htmlAttrs, { role: isRadio ? 'radio' : undefined, type: "button", id: buttonId, class: Object.assign(Object.assign({}, buttonClass(b)), (isRadio && { 'action-sheet-selected': isActiveRadio })), onClick: () => {
|
|
475
475
|
if (isRadio) {
|
|
476
476
|
this.selectRadioButton(b);
|
|
477
477
|
}
|
|
@@ -486,12 +486,12 @@ const ActionSheet = class {
|
|
|
486
486
|
const cancelButton = allButtons.find((b) => b.role === 'cancel');
|
|
487
487
|
const buttons = allButtons.filter((b) => b.role !== 'cancel');
|
|
488
488
|
const headerID = `action-sheet-${overlayIndex}-header`;
|
|
489
|
-
return (h(Host, Object.assign({ key: '
|
|
489
|
+
return (h(Host, Object.assign({ key: 'a56ee2ab59c763036140dbd10306a708c26e3c17', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
|
|
490
490
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
491
|
-
}, class: Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), h("ion-backdrop", { key: '
|
|
491
|
+
}, class: Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), h("ion-backdrop", { key: 'c32eb4281fd6348c7d3989a3f509c211263048e6', tappable: this.backdropDismiss }), h("div", { key: '7f0123114a876fc7cfff3cfb564aded4a7017797', tabindex: "0", "aria-hidden": "true" }), h("div", { key: '645b1d5fde39a8907f21983d66e6ecb7a99aa05d', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, h("div", { key: 'a78fb02848462d1a4f9356ac4fa1c43a2e5d90e4', class: "action-sheet-container" }, h("div", { key: '5e846f53e067b211b985d6e1512b72b9d7c1a3aa', class: "action-sheet-group", ref: (el) => (this.groupEl = el), role: hasRadioButtons ? 'radiogroup' : undefined }, header !== undefined && (h("div", { key: 'a90a0e096e1b2fa78b9adb9253c0a517f16e62cb', id: headerID, class: {
|
|
492
492
|
'action-sheet-title': true,
|
|
493
493
|
'action-sheet-has-sub-title': this.subHeader !== undefined,
|
|
494
|
-
} }, header, this.subHeader && h("div", { key: '
|
|
494
|
+
} }, header, this.subHeader && h("div", { key: '40f00b12341625c548546de1885b9c9d93bc169c', class: "action-sheet-sub-title" }, this.subHeader))), this.renderActionSheetButtons(buttons)), cancelButton && (h("div", { key: 'ef6974cb63089623df08087274b82745443cee8c', class: "action-sheet-group action-sheet-group-cancel" }, h("button", Object.assign({ key: 'b02911a6491d60f9dcb5da7d942392a9e96552c1' }, cancelButton.htmlAttributes, { type: "button", class: buttonClass(cancelButton), onClick: () => this.buttonClick(cancelButton) }), h("span", { key: '1187433e676eda55e52b5ae328a8e68bba22deb6', class: "action-sheet-button-inner" }, cancelButton.icon && (h("ion-icon", { key: '079ab2a6bd40b996950053617f1c1c8207ecb1f1', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && h("ion-ripple-effect", { key: '3bc473add8ac299f202f8c359d26708872c02f52' })))))), h("div", { key: '9b1ae7b4e3649e9b85632f0d65627ca81499e68d', tabindex: "0", "aria-hidden": "true" })));
|
|
495
495
|
}
|
|
496
496
|
get el() { return getElement(this); }
|
|
497
497
|
static get watchers() { return {
|
|
@@ -157,7 +157,7 @@ Buttons.style = {
|
|
|
157
157
|
md: buttonsMdCss()
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
-
const contentCss = () => `:host{--background:var(--ion-background-color, #fff);--color:var(--ion-text-color, #000);--padding-top:0px;--padding-bottom:0px;--padding-start:0px;--padding-end:0px;--keyboard-offset:0px;--offset-top:0px;--offset-bottom:0px;--overflow:auto;display:block;position:relative;-ms-flex:1;flex:1;width:100%;height:100%;margin:0 !important;padding:0 !important;font-family:var(--ion-font-family, inherit);contain:size style}:host(.ion-color) .inner-scroll{background:var(--ion-color-base);color:var(--ion-color-contrast)}#background-content{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);position:absolute;background:var(--background)}.inner-scroll{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:calc(var(--padding-top) + var(--offset-top));padding-bottom:calc(var(--padding-bottom) + var(--keyboard-offset) + var(--offset-bottom));position:absolute;color:var(--color);-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;-ms-touch-action:pan-x pan-y pinch-zoom;touch-action:pan-x pan-y pinch-zoom}.scroll-y,.scroll-x{-webkit-overflow-scrolling:touch;z-index:0;will-change:scroll-position}.scroll-y{overflow-y:var(--overflow);overscroll-behavior-y:contain}.scroll-x{overflow-x:var(--overflow);overscroll-behavior-x:contain}.overscroll::before,.overscroll::after{position:absolute;width:1px;height:1px;content:""}.overscroll::before{bottom:-1px}.overscroll::after{top:-1px}:host(.content-sizing){display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-height:0;contain:none}:host(.content-sizing) .inner-scroll{position:relative;top:0;bottom:0;margin-top:calc(var(--offset-top) * -1);margin-bottom:calc(var(--offset-bottom) * -1)}.transition-effect{display:none;position:absolute;width:100%;height:100vh;opacity:0;pointer-events:none}:host(.content-ltr) .transition-effect{left:-100%;}:host(.content-rtl) .transition-effect{right:-100%;}.transition-cover{position:absolute;right:0;width:100%;height:100%;background:black;opacity:0.1}.transition-shadow{display:block;position:absolute;width:100%;height:100%;-webkit-box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03);box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03)}:host(.content-ltr) .transition-shadow{right:0;}:host(.content-rtl) .transition-shadow{left:0;-webkit-transform:scaleX(-1);transform:scaleX(-1)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}`;
|
|
160
|
+
const contentCss = () => `:host{--background:var(--ion-background-color, #fff);--color:var(--ion-text-color, #000);--padding-top:0px;--padding-bottom:0px;--padding-start:0px;--padding-end:0px;--keyboard-offset:0px;--offset-top:0px;--offset-bottom:0px;--overflow:auto;display:block;position:relative;-ms-flex:1;flex:1;width:100%;height:100%;margin:0 !important;padding:0 !important;font-family:var(--ion-font-family, inherit);contain:size style}:host(.ion-color) .inner-scroll{background:var(--ion-color-base);color:var(--ion-color-contrast)}#background-content{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);position:absolute;background:var(--background)}.inner-scroll{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:calc(var(--padding-top) + var(--offset-top));padding-bottom:calc(var(--padding-bottom) + var(--keyboard-offset) + var(--offset-bottom) + var(--ion-content-safe-area-padding-bottom, 0px));position:absolute;color:var(--color);-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;-ms-touch-action:pan-x pan-y pinch-zoom;touch-action:pan-x pan-y pinch-zoom}.scroll-y,.scroll-x{-webkit-overflow-scrolling:touch;z-index:0;will-change:scroll-position}.scroll-y{overflow-y:var(--overflow);overscroll-behavior-y:contain}.scroll-x{overflow-x:var(--overflow);overscroll-behavior-x:contain}.overscroll::before,.overscroll::after{position:absolute;width:1px;height:1px;content:""}.overscroll::before{bottom:-1px}.overscroll::after{top:-1px}:host(.content-sizing){display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-height:0;contain:none}:host(.content-sizing) .inner-scroll{position:relative;top:0;bottom:0;margin-top:calc(var(--offset-top) * -1);margin-bottom:calc(var(--offset-bottom) * -1)}.transition-effect{display:none;position:absolute;width:100%;height:100vh;opacity:0;pointer-events:none}:host(.content-ltr) .transition-effect{left:-100%;}:host(.content-rtl) .transition-effect{right:-100%;}.transition-cover{position:absolute;right:0;width:100%;height:100%;background:black;opacity:0.1}.transition-shadow{display:block;position:absolute;width:100%;height:100%;-webkit-box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03);box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03)}:host(.content-ltr) .transition-shadow{right:0;}:host(.content-rtl) .transition-shadow{left:0;-webkit-transform:scaleX(-1);transform:scaleX(-1)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}`;
|
|
161
161
|
|
|
162
162
|
const Content = class {
|
|
163
163
|
constructor(hostRef) {
|
|
@@ -110,48 +110,55 @@ const Checkbox = class {
|
|
|
110
110
|
this.onDivLabelClick = (ev) => {
|
|
111
111
|
ev.stopPropagation();
|
|
112
112
|
};
|
|
113
|
-
this.onSlotChange = () => {
|
|
114
|
-
this.hasLabelContent = this.el.textContent !== '';
|
|
115
|
-
};
|
|
116
113
|
}
|
|
117
114
|
connectedCallback() {
|
|
118
115
|
const { el } = this;
|
|
119
|
-
// Watch for class changes to update validation state.
|
|
120
116
|
if (typeof MutationObserver !== 'undefined') {
|
|
121
|
-
this.validationObserver = new MutationObserver(() => {
|
|
122
|
-
|
|
123
|
-
if (
|
|
124
|
-
this.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
117
|
+
this.validationObserver = new MutationObserver((mutations) => {
|
|
118
|
+
// Watch for label content changes
|
|
119
|
+
if (mutations.some((mutation) => mutation.type === 'characterData' || mutation.type === 'childList')) {
|
|
120
|
+
this.hasLabelContent = this.el.textContent !== '';
|
|
121
|
+
}
|
|
122
|
+
// Watch for class changes to update validation state.
|
|
123
|
+
if (mutations.some((mutation) => mutation.type === 'attributes' && mutation.target === el)) {
|
|
124
|
+
const newIsInvalid = checkInvalidState(el);
|
|
125
|
+
if (this.isInvalid !== newIsInvalid) {
|
|
126
|
+
this.isInvalid = newIsInvalid;
|
|
127
|
+
/**
|
|
128
|
+
* Screen readers tend to announce changes
|
|
129
|
+
* to `aria-describedby` when the attribute
|
|
130
|
+
* is changed during a blur event for a
|
|
131
|
+
* native form control.
|
|
132
|
+
* However, the announcement can be spotty
|
|
133
|
+
* when using a non-native form control
|
|
134
|
+
* and `forceUpdate()`.
|
|
135
|
+
* This is due to `forceUpdate()` internally
|
|
136
|
+
* rescheduling the DOM update to a lower
|
|
137
|
+
* priority queue regardless if it's called
|
|
138
|
+
* inside a Promise or not, thus causing
|
|
139
|
+
* the screen reader to potentially miss the
|
|
140
|
+
* change.
|
|
141
|
+
* By using a State variable inside a Promise,
|
|
142
|
+
* it guarantees a re-render immediately at
|
|
143
|
+
* a higher priority.
|
|
144
|
+
*/
|
|
145
|
+
Promise.resolve().then(() => {
|
|
146
|
+
this.hintTextId = this.getHintTextId();
|
|
147
|
+
});
|
|
148
|
+
}
|
|
146
149
|
}
|
|
147
150
|
});
|
|
148
151
|
this.validationObserver.observe(el, {
|
|
149
152
|
attributes: true,
|
|
150
153
|
attributeFilter: ['class'],
|
|
154
|
+
characterData: true,
|
|
155
|
+
childList: true,
|
|
156
|
+
subtree: true,
|
|
151
157
|
});
|
|
152
158
|
}
|
|
153
159
|
// Always set initial state
|
|
154
160
|
this.isInvalid = checkInvalidState(el);
|
|
161
|
+
this.hasLabelContent = this.el.textContent !== '';
|
|
155
162
|
}
|
|
156
163
|
componentWillLoad() {
|
|
157
164
|
this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
|
|
@@ -201,7 +208,7 @@ const Checkbox = class {
|
|
|
201
208
|
renderHiddenInput(true, el, name, checked ? value : '', disabled);
|
|
202
209
|
// The host element must have a checkbox role to ensure proper VoiceOver
|
|
203
210
|
// support in Safari for accessibility.
|
|
204
|
-
return (h(Host, { key: '
|
|
211
|
+
return (h(Host, { key: '0da370f94c5cdf3b08bc9008395558334a300f35', role: "checkbox", "aria-checked": indeterminate ? 'mixed' : `${checked}`, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, "aria-labelledby": this.hasLabelContent ? this.inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, "aria-required": required ? 'true' : undefined, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, onFocus: this.onFocus, onBlur: this.onBlur, onClick: this.onClick, class: createColorClasses(color, {
|
|
205
212
|
[mode]: true,
|
|
206
213
|
'in-item': hostContext('ion-item', el),
|
|
207
214
|
'checkbox-checked': checked,
|
|
@@ -211,10 +218,10 @@ const Checkbox = class {
|
|
|
211
218
|
[`checkbox-justify-${justify}`]: justify !== undefined,
|
|
212
219
|
[`checkbox-alignment-${alignment}`]: alignment !== undefined,
|
|
213
220
|
[`checkbox-label-placement-${labelPlacement}`]: true,
|
|
214
|
-
}) }, h("label", { key: '
|
|
221
|
+
}) }, h("label", { key: '991f1763356671230af119a5fbdc22d0a39974e7', class: "checkbox-wrapper", htmlFor: inputId }, h("input", Object.assign({ key: '982f8a7f84d013b272b17607936355d2b6c251f4', type: "checkbox", checked: checked ? true : undefined, disabled: disabled, id: inputId, onChange: this.toggleChecked, required: required }, inheritedAttributes)), h("div", { key: 'c8f9e8baa20ac68e69fd3c6fcf0e7a26a1084d83', class: {
|
|
215
222
|
'label-text-wrapper': true,
|
|
216
223
|
'label-text-wrapper-hidden': !this.hasLabelContent,
|
|
217
|
-
}, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, h("slot", { key: '
|
|
224
|
+
}, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, h("slot", { key: '6018205e0a73dec826c7881d687f1c2ca8dcb0ab' }), this.renderHintText()), h("div", { key: '57530b9d6ff59ee7ab98f960cd65d66ee87cfd1d', class: "native-wrapper" }, h("svg", { key: '63d719154ff44459e9ca448e3f5d7de94d9ab248', class: "checkbox-icon", viewBox: "0 0 24 24", part: "container", "aria-hidden": "true" }, path)))));
|
|
218
225
|
}
|
|
219
226
|
getSVGPath(mode, indeterminate) {
|
|
220
227
|
let path = indeterminate ? (h("path", { d: "M6 12L18 12", part: "mark" })) : (h("path", { d: "M5.9,12.5l3.8,3.8l8.8-8.8", part: "mark" }));
|
|
@@ -811,6 +811,12 @@ const Datetime = class {
|
|
|
811
811
|
this.el.classList.add('datetime-ready');
|
|
812
812
|
});
|
|
813
813
|
};
|
|
814
|
+
this.loadTimeoutCleanup = () => {
|
|
815
|
+
if (this.loadTimeout) {
|
|
816
|
+
clearTimeout(this.loadTimeout);
|
|
817
|
+
this.loadTimeout = undefined;
|
|
818
|
+
}
|
|
819
|
+
};
|
|
814
820
|
this.processValue = (value) => {
|
|
815
821
|
const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
|
|
816
822
|
const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
|
|
@@ -958,9 +964,10 @@ const Datetime = class {
|
|
|
958
964
|
if (!prevMonth) {
|
|
959
965
|
return;
|
|
960
966
|
}
|
|
967
|
+
const left = prevMonth.offsetWidth * 2;
|
|
961
968
|
calendarBodyRef.scrollTo({
|
|
962
969
|
top: 0,
|
|
963
|
-
left:
|
|
970
|
+
left: left * (isRTL(this.el) ? 1 : -1),
|
|
964
971
|
behavior: 'smooth',
|
|
965
972
|
});
|
|
966
973
|
};
|
|
@@ -1082,15 +1089,16 @@ const Datetime = class {
|
|
|
1082
1089
|
}
|
|
1083
1090
|
connectedCallback() {
|
|
1084
1091
|
this.clearFocusVisible = startFocusVisible(this.el).destroy;
|
|
1092
|
+
this.loadTimeout = setTimeout(() => {
|
|
1093
|
+
this.ensureReadyIfVisible();
|
|
1094
|
+
}, 100);
|
|
1085
1095
|
}
|
|
1086
1096
|
disconnectedCallback() {
|
|
1087
1097
|
if (this.clearFocusVisible) {
|
|
1088
1098
|
this.clearFocusVisible();
|
|
1089
1099
|
this.clearFocusVisible = undefined;
|
|
1090
1100
|
}
|
|
1091
|
-
|
|
1092
|
-
clearTimeout(this.loadTimeout);
|
|
1093
|
-
}
|
|
1101
|
+
this.loadTimeoutCleanup();
|
|
1094
1102
|
}
|
|
1095
1103
|
initializeListeners() {
|
|
1096
1104
|
this.initializeCalendarListener();
|
|
@@ -1138,7 +1146,10 @@ const Datetime = class {
|
|
|
1138
1146
|
* we still initialize listeners and mark the component as ready.
|
|
1139
1147
|
*
|
|
1140
1148
|
* We schedule this after everything has had a chance to run.
|
|
1149
|
+
*
|
|
1150
|
+
* We also clean up the load timeout to ensure that we don't have multiple timeouts running.
|
|
1141
1151
|
*/
|
|
1152
|
+
this.loadTimeoutCleanup();
|
|
1142
1153
|
this.loadTimeout = setTimeout(() => {
|
|
1143
1154
|
this.ensureReadyIfVisible();
|
|
1144
1155
|
}, 100);
|
|
@@ -1897,7 +1908,7 @@ const Datetime = class {
|
|
|
1897
1908
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
1898
1909
|
const hasWheelVariant = hasDatePresentation && preferWheel;
|
|
1899
1910
|
renderHiddenInput(true, el, name, formatValue(value), disabled);
|
|
1900
|
-
return (h(Host, { key: '
|
|
1911
|
+
return (h(Host, { key: '59e0811aa273e88dfb8e4b703e6824088a457380', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
|
|
1901
1912
|
[mode]: true,
|
|
1902
1913
|
['datetime-readonly']: readonly,
|
|
1903
1914
|
['datetime-disabled']: disabled,
|
|
@@ -1907,7 +1918,7 @@ const Datetime = class {
|
|
|
1907
1918
|
[`datetime-size-${size}`]: true,
|
|
1908
1919
|
[`datetime-prefer-wheel`]: hasWheelVariant,
|
|
1909
1920
|
[`datetime-grid`]: isGridStyle,
|
|
1910
|
-
})) }, h("div", { key: '
|
|
1921
|
+
})) }, h("div", { key: '3753ff3dde3085070916c3de83687a219a49e553', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
|
|
1911
1922
|
}
|
|
1912
1923
|
get el() { return getElement(this); }
|
|
1913
1924
|
static get watchers() { return {
|
|
@@ -140,9 +140,18 @@ const InputOTP = class {
|
|
|
140
140
|
* - Tab: Allows normal tab navigation between components
|
|
141
141
|
*/
|
|
142
142
|
this.onKeyDown = (index) => (event) => {
|
|
143
|
-
const { length } = this;
|
|
143
|
+
const { disabled, length, readonly } = this;
|
|
144
144
|
const rtl = isRTL(this.el);
|
|
145
145
|
const input = event.target;
|
|
146
|
+
if (disabled) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (readonly) {
|
|
150
|
+
if (event.key === 'Backspace' || event.key === 'Delete') {
|
|
151
|
+
event.preventDefault();
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
146
155
|
// Meta shortcuts are used to copy, paste, and select text
|
|
147
156
|
// We don't want to handle these keys here
|
|
148
157
|
const metaShortcuts = ['a', 'c', 'v', 'x', 'r', 'z', 'y'];
|
|
@@ -205,10 +214,13 @@ const InputOTP = class {
|
|
|
205
214
|
*/
|
|
206
215
|
this.onInput = (index) => (event) => {
|
|
207
216
|
var _a, _b;
|
|
208
|
-
const { length, validKeyPattern } = this;
|
|
217
|
+
const { disabled, length, readonly, validKeyPattern } = this;
|
|
209
218
|
const input = event.target;
|
|
210
219
|
const value = input.value;
|
|
211
220
|
const previousValue = this.previousInputValues[index] || '';
|
|
221
|
+
if (disabled || readonly) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
212
224
|
// 1. Autofill handling
|
|
213
225
|
// If the length of the value increases by more than 1 from the previous
|
|
214
226
|
// value, treat this as autofill. This is to prevent the case where the
|
|
@@ -327,8 +339,11 @@ const InputOTP = class {
|
|
|
327
339
|
*/
|
|
328
340
|
this.onPaste = (event) => {
|
|
329
341
|
var _a, _b;
|
|
330
|
-
const { inputRefs, length, validKeyPattern } = this;
|
|
342
|
+
const { disabled, inputRefs, length, readonly, validKeyPattern } = this;
|
|
331
343
|
event.preventDefault();
|
|
344
|
+
if (disabled || readonly) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
332
347
|
const pastedText = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text');
|
|
333
348
|
// If there is no pasted text, still emit the input change event
|
|
334
349
|
// because this is how the native input element behaves
|
|
@@ -615,7 +630,7 @@ const InputOTP = class {
|
|
|
615
630
|
const tabbableIndex = this.getTabbableIndex();
|
|
616
631
|
const pattern = this.getPattern();
|
|
617
632
|
const hasDescription = ((_b = (_a = el.querySelector('.input-otp-description')) === null || _a === void 0 ? void 0 : _a.textContent) === null || _b === void 0 ? void 0 : _b.trim()) !== '';
|
|
618
|
-
return (h(Host, { key: '
|
|
633
|
+
return (h(Host, { key: '5c1386ae6b8038ec33ca94fd818c9353b1b37f75', class: createColorClasses(color, {
|
|
619
634
|
[mode]: true,
|
|
620
635
|
'has-focus': hasFocus,
|
|
621
636
|
[`input-otp-size-${size}`]: true,
|
|
@@ -623,10 +638,10 @@ const InputOTP = class {
|
|
|
623
638
|
[`input-otp-fill-${fill}`]: true,
|
|
624
639
|
'input-otp-disabled': disabled,
|
|
625
640
|
'input-otp-readonly': readonly,
|
|
626
|
-
}) }, h("div", Object.assign({ key: '
|
|
641
|
+
}) }, h("div", Object.assign({ key: '9a19129688e55095f8386826c73ef3f9744becff', role: "group", "aria-label": "One-time password input", class: "input-otp-group" }, inheritedAttributes), Array.from({ length }).map((_, index) => (h(Fragment, null, h("div", { class: "native-wrapper" }, h("input", { class: "native-input", id: `${inputId}-${index}`, "aria-label": `Input ${index + 1} of ${length}`, type: "text", autoCapitalize: autocapitalize, inputmode: inputmode, pattern: pattern, disabled: disabled, readOnly: readonly, tabIndex: index === tabbableIndex ? 0 : -1, value: inputValues[index] || '', autocomplete: "one-time-code", ref: (el) => (inputRefs[index] = el), onInput: this.onInput(index), onBlur: this.onBlur, onFocus: this.onFocus(index), onKeyDown: this.onKeyDown(index), onPaste: this.onPaste })), this.showSeparator(index) && h("div", { class: "input-otp-separator" }))))), h("div", { key: '7853819c3610c4691191f1836b947bf4ec17939d', class: {
|
|
627
642
|
'input-otp-description': true,
|
|
628
643
|
'input-otp-description-hidden': !hasDescription,
|
|
629
|
-
} }, h("slot", { key: '
|
|
644
|
+
} }, h("slot", { key: 'f4674d47d3d3991f21a0a79321ebc323968071dc' }))));
|
|
630
645
|
}
|
|
631
646
|
get el() { return getElement(this); }
|
|
632
647
|
static get watchers() { return {
|