mtrl 0.10.0-next.1 → 0.10.0-next.2
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/README.md +30 -5
- package/dist/README.md +30 -5
- package/dist/components/datepicker/constants.d.ts +1 -0
- package/dist/components/datepicker/constants.js +1 -0
- package/dist/components/datepicker/datepicker.js +70 -6
- package/dist/components/datepicker/render.js +43 -10
- package/dist/components/datepicker/types.d.ts +4 -1
- package/dist/components/datepicker/utils.d.ts +0 -7
- package/dist/components/datepicker/utils.js +0 -9
- package/dist/components/extended-fab/config.js +1 -1
- package/dist/components/extended-fab/types.d.ts +3 -2
- package/dist/components/segmented-button/segment.js +1 -1
- package/dist/components/slider/features/controller.js +6 -2
- package/dist/components/slider/features/states.d.ts +0 -3
- package/dist/components/slider/features/states.js +2 -15
- package/dist/components/textfield/constants.d.ts +11 -1
- package/dist/components/textfield/constants.js +5 -0
- package/dist/components/textfield/features/placement.js +45 -82
- package/dist/components/timepicker/api.js +47 -40
- package/dist/components/timepicker/config.js +0 -5
- package/dist/components/timepicker/dial.d.ts +30 -0
- package/dist/components/timepicker/dial.js +169 -0
- package/dist/components/timepicker/render.js +186 -275
- package/dist/components/timepicker/timepicker.d.ts +0 -5
- package/dist/components/timepicker/timepicker.js +5 -19
- package/dist/components/timepicker/types.d.ts +4 -1
- package/dist/elements/badge.d.ts +62 -0
- package/dist/elements/badge.js +33 -0
- package/dist/elements/button.d.ts +5 -8
- package/dist/elements/button.js +4 -19
- package/dist/elements/checkbox.d.ts +92 -0
- package/dist/elements/checkbox.js +49 -0
- package/dist/elements/css/checkbox.d.ts +1 -0
- package/dist/elements/css/checkbox.js +3 -0
- package/dist/elements/css/divider.d.ts +1 -0
- package/dist/elements/css/divider.js +3 -0
- package/dist/elements/css/extended-fab.d.ts +1 -0
- package/dist/elements/css/extended-fab.js +3 -0
- package/dist/elements/css/fab.d.ts +1 -0
- package/dist/elements/css/fab.js +3 -0
- package/dist/elements/css/icon-button.d.ts +1 -0
- package/dist/elements/css/icon-button.js +3 -0
- package/dist/elements/css/index.js +9 -0
- package/dist/elements/css/loading-indicator.d.ts +1 -0
- package/dist/elements/css/loading-indicator.js +3 -0
- package/dist/elements/css/radios.d.ts +1 -0
- package/dist/elements/css/radios.js +3 -0
- package/dist/elements/css/slider.d.ts +1 -0
- package/dist/elements/css/slider.js +3 -0
- package/dist/elements/css/switch.js +1 -1
- package/dist/elements/css/textfield.d.ts +1 -0
- package/dist/elements/css/textfield.js +3 -0
- package/dist/elements/define.d.ts +31 -6
- package/dist/elements/define.js +63 -11
- package/dist/elements/divider.d.ts +54 -0
- package/dist/elements/divider.js +23 -0
- package/dist/elements/extended-fab.d.ts +82 -0
- package/dist/elements/extended-fab.js +32 -0
- package/dist/elements/fab.d.ts +65 -0
- package/dist/elements/fab.js +24 -0
- package/dist/elements/form-button.d.ts +29 -0
- package/dist/elements/form-button.js +19 -0
- package/dist/elements/icon-button.d.ts +104 -0
- package/dist/elements/icon-button.js +56 -0
- package/dist/elements/index.d.ts +51 -1
- package/dist/elements/index.js +45 -0
- package/dist/elements/loading-indicator.d.ts +44 -0
- package/dist/elements/loading-indicator.js +26 -0
- package/dist/elements/progress.d.ts +90 -0
- package/dist/elements/progress.js +40 -0
- package/dist/elements/radios.d.ts +99 -0
- package/dist/elements/radios.js +126 -0
- package/dist/elements/slider.d.ts +160 -0
- package/dist/elements/slider.js +136 -0
- package/dist/elements/switch.d.ts +2 -1
- package/dist/elements/tabs.d.ts +3 -2
- package/dist/elements/tabs.js +3 -5
- package/dist/elements/textfield.d.ts +160 -0
- package/dist/elements/textfield.js +107 -0
- package/dist/index.cjs +0 -0
- package/dist/package.json +1 -1
- package/dist/react/index.d.ts +22 -1
- package/dist/react/index.js +22 -1
- package/dist/solid/index.d.ts +22 -1
- package/dist/solid/index.js +22 -1
- package/dist/styles/badge.css +1 -1
- package/dist/styles/base.css +1 -1
- package/dist/styles/bottom-app-bar.css +1 -1
- package/dist/styles/bottom-sheet.css +1 -1
- package/dist/styles/button-group.css +1 -1
- package/dist/styles/button.css +1 -1
- package/dist/styles/card.css +1 -1
- package/dist/styles/carousel.css +1 -1
- package/dist/styles/checkbox.css +1 -1
- package/dist/styles/chips.css +1 -1
- package/dist/styles/datepicker.css +2 -2
- package/dist/styles/dialog.css +1 -1
- package/dist/styles/divider.css +1 -1
- package/dist/styles/drawer.css +1 -1
- package/dist/styles/extended-fab.css +1 -1
- package/dist/styles/fab.css +1 -1
- package/dist/styles/icon-button.css +1 -1
- package/dist/styles/list.css +1 -1
- package/dist/styles/loading-indicator.css +1 -1
- package/dist/styles/menu.css +1 -1
- package/dist/styles/navigation-rail.css +1 -1
- package/dist/styles/progress.css +1 -1
- package/dist/styles/radios.css +2 -2
- package/dist/styles/search.css +1 -1
- package/dist/styles/segmented-button.css +1 -1
- package/dist/styles/select.css +1 -1
- package/dist/styles/side-sheet.css +1 -1
- package/dist/styles/slider.css +1 -1
- package/dist/styles/snackbar.css +1 -1
- package/dist/styles/split-button.css +1 -1
- package/dist/styles/switch.css +2 -2
- package/dist/styles/tabs.css +1 -1
- package/dist/styles/textfield.css +2 -2
- package/dist/styles/timepicker.css +2 -2
- package/dist/styles/tooltip.css +1 -1
- package/dist/styles/top-app-bar.css +1 -1
- package/dist/styles/utilities.css +1 -1
- package/dist/styles.css +2 -2
- package/dist/svelte/Badge.svelte +20 -0
- package/dist/svelte/Badge.svelte.d.ts +5 -0
- package/dist/svelte/Checkbox.svelte +21 -0
- package/dist/svelte/Checkbox.svelte.d.ts +5 -0
- package/dist/svelte/Divider.svelte +19 -0
- package/dist/svelte/Divider.svelte.d.ts +5 -0
- package/dist/svelte/ExtendedFab.svelte +19 -0
- package/dist/svelte/ExtendedFab.svelte.d.ts +5 -0
- package/dist/svelte/Fab.svelte +19 -0
- package/dist/svelte/Fab.svelte.d.ts +5 -0
- package/dist/svelte/IconButton.svelte +20 -0
- package/dist/svelte/IconButton.svelte.d.ts +5 -0
- package/dist/svelte/LoadingIndicator.svelte +19 -0
- package/dist/svelte/LoadingIndicator.svelte.d.ts +5 -0
- package/dist/svelte/Progress.svelte +21 -0
- package/dist/svelte/Progress.svelte.d.ts +5 -0
- package/dist/svelte/Radio.svelte +11 -0
- package/dist/svelte/Radio.svelte.d.ts +5 -0
- package/dist/svelte/Radios.svelte +20 -0
- package/dist/svelte/Radios.svelte.d.ts +5 -0
- package/dist/svelte/Slider.svelte +21 -0
- package/dist/svelte/Slider.svelte.d.ts +5 -0
- package/dist/svelte/Textfield.svelte +20 -0
- package/dist/svelte/Textfield.svelte.d.ts +5 -0
- package/dist/svelte/index.d.ts +12 -0
- package/dist/svelte/index.js +21 -0
- package/dist/themes/autumn.css +1 -1
- package/dist/themes/baseline.css +1 -1
- package/dist/themes/brownbeige.css +1 -1
- package/dist/themes/browngreen.css +1 -1
- package/dist/themes/desert.css +1 -1
- package/dist/themes/forest.css +1 -1
- package/dist/themes/highcontrast.css +1 -1
- package/dist/themes/legacy.css +1 -1
- package/dist/themes/material.css +1 -1
- package/dist/themes/ocean.css +1 -1
- package/dist/themes/sageivory.css +1 -1
- package/dist/themes/spring.css +1 -1
- package/dist/themes/summer.css +1 -1
- package/dist/themes/sunset.css +1 -1
- package/dist/themes/tealcaramel.css +1 -1
- package/dist/themes/winter.css +1 -1
- package/dist/vue/index.d.ts +22 -1
- package/dist/vue/index.js +22 -1
- package/package.json +1 -1
- package/src/styles/components/_datepicker.scss +52 -14
- package/src/styles/components/_radios.scss +2 -3
- package/src/styles/components/_switch.scss +2 -2
- package/src/styles/components/_textfield.scss +122 -70
- package/src/styles/components/_timepicker.scss +156 -67
- package/dist/components/timepicker/clockdial.d.ts +0 -34
- package/dist/components/timepicker/clockdial.js +0 -276
package/README.md
CHANGED
|
@@ -136,23 +136,48 @@ Button progress and card actions load on demand; enable code splitting in your b
|
|
|
136
136
|
|
|
137
137
|
## Web components and frameworks (experimental)
|
|
138
138
|
|
|
139
|
-
From
|
|
139
|
+
From the 0.10.0 prereleases (`npm install mtrl@next`), components also ship as custom elements, with thin adapters for React, Vue, Svelte and Solid. The API may still change.
|
|
140
|
+
|
|
141
|
+
| Element | Framework component (Vue: `M` prefix, e.g. `MTextfield`) | Kind |
|
|
142
|
+
|---------|---------------------|------|
|
|
143
|
+
| `<m-button>` | `Button` | action, submits or resets its form |
|
|
144
|
+
| `<m-icon-button>` | `IconButton` | action or toggle (`selected`) |
|
|
145
|
+
| `<m-fab>`, `<m-extended-fab>` | `Fab`, `ExtendedFab` | action |
|
|
146
|
+
| `<m-checkbox>` | `Checkbox` | form control (`checked`, `indeterminate`) |
|
|
147
|
+
| `<m-switch>` | `Switch` | form control (`checked`) |
|
|
148
|
+
| `<m-radios>` with `<m-radio>` | `Radios`, `Radio` | form control (`value`) |
|
|
149
|
+
| `<m-slider>` | `Slider` | form control (`value`, `secondValue` with `range`) |
|
|
150
|
+
| `<m-textfield>` | `Textfield` | form control (`value`) |
|
|
151
|
+
| `<m-tabs>` with `<m-tab>` | `Tabs`, `Tab` | selection (`value`) |
|
|
152
|
+
| `<m-progress>`, `<m-loading-indicator>` | `Progress`, `LoadingIndicator` | indicator |
|
|
153
|
+
| `<m-badge>`, `<m-divider>` | `Badge`, `Divider` | display |
|
|
154
|
+
|
|
155
|
+
More components follow through 0.10.x; the others are available as factories today.
|
|
140
156
|
|
|
141
157
|
```html
|
|
142
158
|
<script type="module">
|
|
143
159
|
import 'mtrl/elements/css'; // the elements' styles
|
|
144
160
|
import { defineAll } from 'mtrl/elements';
|
|
145
|
-
defineAll(); // registers <m-button>, <m-switch>,
|
|
161
|
+
defineAll(); // registers every element (<m-button>, <m-switch>, …)
|
|
146
162
|
</script>
|
|
147
163
|
|
|
148
|
-
<
|
|
164
|
+
<form>
|
|
165
|
+
<m-textfield name="email" type="email" label="Email" required></m-textfield>
|
|
166
|
+
<m-radios name="plan" value="free" aria-label="Plan">
|
|
167
|
+
<m-radio value="free">Free</m-radio>
|
|
168
|
+
<m-radio value="pro">Pro</m-radio>
|
|
169
|
+
</m-radios>
|
|
170
|
+
<m-switch name="news" checked>Newsletter</m-switch>
|
|
171
|
+
<m-button type="submit">Sign up</m-button>
|
|
172
|
+
</form>
|
|
173
|
+
|
|
149
174
|
<m-tabs value="songs">
|
|
150
175
|
<m-tab value="songs">Songs</m-tab>
|
|
151
176
|
<m-tab value="albums">Albums</m-tab>
|
|
152
177
|
</m-tabs>
|
|
153
178
|
```
|
|
154
179
|
|
|
155
|
-
The page still loads mtrl's base styles and a theme (see [Styles](#styles)); the elements render in shadow DOM and pick up the theme's tokens. Attributes are defaults and properties the live state, as on native controls
|
|
180
|
+
The page still loads mtrl's base styles and a theme (see [Styles](#styles)); the elements render in shadow DOM and pick up the theme's tokens. Attributes are defaults and properties the live state, as on native controls: a `checked` or `value` attribute sets the state until the user or a script changes it, and `form.reset()` goes back to it. Form controls take part in forms (their host's `name`), reset, validation and back-navigation restore.
|
|
156
181
|
|
|
157
182
|
| Framework | Import | Two-way binding |
|
|
158
183
|
|-----------|--------|-----------------|
|
|
@@ -161,7 +186,7 @@ The page still loads mtrl's base styles and a theme (see [Styles](#styles)); the
|
|
|
161
186
|
| Svelte 5 | `import { Switch } from 'mtrl/svelte'` | `bind:checked` |
|
|
162
187
|
| Solid | `import { Switch } from 'mtrl/solid'` | `checked` + `onChange` |
|
|
163
188
|
|
|
164
|
-
Each framework is an optional peer dependency; mtrl installs none of them. All adapters render on the server and hydrate.
|
|
189
|
+
Each framework is an optional peer dependency; mtrl installs none of them. All adapters render on the server and hydrate. Angular apps use the elements directly, with `CUSTOM_ELEMENTS_SCHEMA`.
|
|
165
190
|
|
|
166
191
|
## Building your own components
|
|
167
192
|
|
package/dist/README.md
CHANGED
|
@@ -136,23 +136,48 @@ Button progress and card actions load on demand; enable code splitting in your b
|
|
|
136
136
|
|
|
137
137
|
## Web components and frameworks (experimental)
|
|
138
138
|
|
|
139
|
-
From
|
|
139
|
+
From the 0.10.0 prereleases (`npm install mtrl@next`), components also ship as custom elements, with thin adapters for React, Vue, Svelte and Solid. The API may still change.
|
|
140
|
+
|
|
141
|
+
| Element | Framework component (Vue: `M` prefix, e.g. `MTextfield`) | Kind |
|
|
142
|
+
|---------|---------------------|------|
|
|
143
|
+
| `<m-button>` | `Button` | action, submits or resets its form |
|
|
144
|
+
| `<m-icon-button>` | `IconButton` | action or toggle (`selected`) |
|
|
145
|
+
| `<m-fab>`, `<m-extended-fab>` | `Fab`, `ExtendedFab` | action |
|
|
146
|
+
| `<m-checkbox>` | `Checkbox` | form control (`checked`, `indeterminate`) |
|
|
147
|
+
| `<m-switch>` | `Switch` | form control (`checked`) |
|
|
148
|
+
| `<m-radios>` with `<m-radio>` | `Radios`, `Radio` | form control (`value`) |
|
|
149
|
+
| `<m-slider>` | `Slider` | form control (`value`, `secondValue` with `range`) |
|
|
150
|
+
| `<m-textfield>` | `Textfield` | form control (`value`) |
|
|
151
|
+
| `<m-tabs>` with `<m-tab>` | `Tabs`, `Tab` | selection (`value`) |
|
|
152
|
+
| `<m-progress>`, `<m-loading-indicator>` | `Progress`, `LoadingIndicator` | indicator |
|
|
153
|
+
| `<m-badge>`, `<m-divider>` | `Badge`, `Divider` | display |
|
|
154
|
+
|
|
155
|
+
More components follow through 0.10.x; the others are available as factories today.
|
|
140
156
|
|
|
141
157
|
```html
|
|
142
158
|
<script type="module">
|
|
143
159
|
import 'mtrl/elements/css'; // the elements' styles
|
|
144
160
|
import { defineAll } from 'mtrl/elements';
|
|
145
|
-
defineAll(); // registers <m-button>, <m-switch>,
|
|
161
|
+
defineAll(); // registers every element (<m-button>, <m-switch>, …)
|
|
146
162
|
</script>
|
|
147
163
|
|
|
148
|
-
<
|
|
164
|
+
<form>
|
|
165
|
+
<m-textfield name="email" type="email" label="Email" required></m-textfield>
|
|
166
|
+
<m-radios name="plan" value="free" aria-label="Plan">
|
|
167
|
+
<m-radio value="free">Free</m-radio>
|
|
168
|
+
<m-radio value="pro">Pro</m-radio>
|
|
169
|
+
</m-radios>
|
|
170
|
+
<m-switch name="news" checked>Newsletter</m-switch>
|
|
171
|
+
<m-button type="submit">Sign up</m-button>
|
|
172
|
+
</form>
|
|
173
|
+
|
|
149
174
|
<m-tabs value="songs">
|
|
150
175
|
<m-tab value="songs">Songs</m-tab>
|
|
151
176
|
<m-tab value="albums">Albums</m-tab>
|
|
152
177
|
</m-tabs>
|
|
153
178
|
```
|
|
154
179
|
|
|
155
|
-
The page still loads mtrl's base styles and a theme (see [Styles](#styles)); the elements render in shadow DOM and pick up the theme's tokens. Attributes are defaults and properties the live state, as on native controls
|
|
180
|
+
The page still loads mtrl's base styles and a theme (see [Styles](#styles)); the elements render in shadow DOM and pick up the theme's tokens. Attributes are defaults and properties the live state, as on native controls: a `checked` or `value` attribute sets the state until the user or a script changes it, and `form.reset()` goes back to it. Form controls take part in forms (their host's `name`), reset, validation and back-navigation restore.
|
|
156
181
|
|
|
157
182
|
| Framework | Import | Two-way binding |
|
|
158
183
|
|-----------|--------|-----------------|
|
|
@@ -161,7 +186,7 @@ The page still loads mtrl's base styles and a theme (see [Styles](#styles)); the
|
|
|
161
186
|
| Svelte 5 | `import { Switch } from 'mtrl/svelte'` | `bind:checked` |
|
|
162
187
|
| Solid | `import { Switch } from 'mtrl/solid'` | `checked` + `onChange` |
|
|
163
188
|
|
|
164
|
-
Each framework is an optional peer dependency; mtrl installs none of them. All adapters render on the server and hydrate.
|
|
189
|
+
Each framework is an optional peer dependency; mtrl installs none of them. All adapters render on the server and hydrate. Angular apps use the elements directly, with `CUSTOM_ELEMENTS_SCHEMA`.
|
|
165
190
|
|
|
166
191
|
## Building your own components
|
|
167
192
|
|
|
@@ -101,4 +101,5 @@ export declare const DATEPICKER_ICONS: {
|
|
|
101
101
|
readonly edit: "<svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"m3 17.25 11.06-11.06 3.75 3.75L6.75 21H3v-3.75ZM20.71 7.04l-1.83 1.83-3.75-3.75 1.83-1.83a1 1 0 0 1 1.41 0l2.34 2.34a1 1 0 0 1 0 1.41Z\"/></svg>";
|
|
102
102
|
readonly previous: "<svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"m15.4 7.4-1.4-1.4-6 6 6 6 1.4-1.4-4.6-4.6Z\"/></svg>";
|
|
103
103
|
readonly next: "<svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"m8.6 7.4 1.4-1.4 6 6-6 6-1.4-1.4 4.6-4.6Z\"/></svg>";
|
|
104
|
+
readonly close: "<svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12Z\"/></svg>";
|
|
104
105
|
};
|
|
@@ -53,4 +53,5 @@ export const DATEPICKER_ICONS = {
|
|
|
53
53
|
edit: '<svg viewBox="0 0 24 24" width="24" height="24" fill="currentColor" aria-hidden="true"><path d="m3 17.25 11.06-11.06 3.75 3.75L6.75 21H3v-3.75ZM20.71 7.04l-1.83 1.83-3.75-3.75 1.83-1.83a1 1 0 0 1 1.41 0l2.34 2.34a1 1 0 0 1 0 1.41Z"/></svg>',
|
|
54
54
|
previous: '<svg viewBox="0 0 24 24" width="24" height="24" fill="currentColor" aria-hidden="true"><path d="m15.4 7.4-1.4-1.4-6 6 6 6 1.4-1.4-4.6-4.6Z"/></svg>',
|
|
55
55
|
next: '<svg viewBox="0 0 24 24" width="24" height="24" fill="currentColor" aria-hidden="true"><path d="m8.6 7.4 1.4-1.4 6 6-6 6-1.4-1.4 4.6-4.6Z"/></svg>',
|
|
56
|
+
close: '<svg viewBox="0 0 24 24" width="24" height="24" fill="currentColor" aria-hidden="true"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12Z"/></svg>',
|
|
56
57
|
};
|
|
@@ -33,10 +33,10 @@ const createDatePicker = (config = {}) => {
|
|
|
33
33
|
const today = parseDate(new Date());
|
|
34
34
|
const state = {
|
|
35
35
|
id, prefix: PREFIX, label: settings.label || "Select date", selectedDate: null, rangeEndDate: null,
|
|
36
|
-
currentView: ["month", "year"].includes(settings.initialView ?? "") ? settings.initialView : "day",
|
|
36
|
+
currentView: settings.variant !== "fullscreen" && ["month", "year"].includes(settings.initialView ?? "") ? settings.initialView : "day",
|
|
37
37
|
currentMonth: today.getMonth(), currentYear: today.getFullYear(), focusedDate: today,
|
|
38
38
|
minDate: parseDate(settings.minDate ?? null), maxDate: parseDate(settings.maxDate ?? null),
|
|
39
|
-
dateFormat: settings.dateFormat || "MM/DD/YYYY", variant: settings.variant === "modal" || settings.variant === "modal-input" ? settings.variant : "docked",
|
|
39
|
+
dateFormat: settings.dateFormat || "MM/DD/YYYY", variant: settings.variant === "modal" || settings.variant === "modal-input" || settings.variant === "fullscreen" ? settings.variant : "docked",
|
|
40
40
|
selectionMode: settings.selectionMode === "range" ? "range" : "single", inputMode: settings.variant === "modal-input",
|
|
41
41
|
specialDates: (settings.specialDates ?? []).map(item => ({ ...item })),
|
|
42
42
|
isAllowed: date => (!state.minDate || date >= state.minDate) && (!state.maxDate || date <= state.maxDate) && !state.specialDates.some(item => { const special = parseDate(item.date); return item.disabled && special && isSameDay(date, special); }),
|
|
@@ -73,6 +73,8 @@ const createDatePicker = (config = {}) => {
|
|
|
73
73
|
dialog.id = `${id}-dialog`;
|
|
74
74
|
dialog.className = cls("calendar");
|
|
75
75
|
dialog.classList.add(base.getClass(`datepicker--${modal ? "modal" : "docked"}`));
|
|
76
|
+
if (state.variant === "fullscreen")
|
|
77
|
+
dialog.classList.add(base.getClass("datepicker--fullscreen"));
|
|
76
78
|
dialog.setAttribute("aria-modal", String(modal));
|
|
77
79
|
if (settings.animate)
|
|
78
80
|
dialog.classList.add(base.getClass("datepicker--animate"));
|
|
@@ -105,11 +107,65 @@ const createDatePicker = (config = {}) => {
|
|
|
105
107
|
const element = track();
|
|
106
108
|
if (element?.clientWidth)
|
|
107
109
|
element.scrollLeft = (rtl(element) ? -1 : 1) * element.clientWidth;
|
|
110
|
+
const years = dialog.querySelector(`.${cls("years")}`);
|
|
111
|
+
const year = years?.querySelector('[aria-pressed="true"]');
|
|
112
|
+
if (years && year)
|
|
113
|
+
years.scrollTop = year.offsetTop - (years.clientHeight - year.offsetHeight) / 2;
|
|
114
|
+
};
|
|
115
|
+
const monthIndex = (date) => date.getFullYear() * 12 + date.getMonth();
|
|
116
|
+
const fromIndex = (index) => new Date(Math.floor(index / 12), index % 12, 1);
|
|
117
|
+
const list = () => dialog.querySelector(`.${cls("list")}`);
|
|
118
|
+
const limits = () => [state.minDate ? monthIndex(state.minDate) : -Infinity, state.maxDate ? monthIndex(state.maxDate) : Infinity];
|
|
119
|
+
let shiftBy = null;
|
|
120
|
+
const ensureWindow = () => {
|
|
121
|
+
if (state.variant !== "fullscreen")
|
|
122
|
+
return;
|
|
123
|
+
const focus = state.currentYear * 12 + state.currentMonth;
|
|
124
|
+
const start = state.listStart ? monthIndex(state.listStart) : NaN;
|
|
125
|
+
if (start <= focus && focus < start + (state.listLength ?? 0))
|
|
126
|
+
return;
|
|
127
|
+
const [min, max] = limits();
|
|
128
|
+
const first = Math.max(min, focus - 12), last = Math.min(max, focus + 12);
|
|
129
|
+
state.listStart = fromIndex(first);
|
|
130
|
+
state.listLength = last - first + 1;
|
|
131
|
+
};
|
|
132
|
+
const extend = (element) => {
|
|
133
|
+
const [min, max] = limits();
|
|
134
|
+
const start = monthIndex(state.listStart), end = start + state.listLength - 1;
|
|
135
|
+
const margin = element.clientHeight;
|
|
136
|
+
if (element.scrollTop < margin && start > min) {
|
|
137
|
+
const first = Math.max(min, start - 12);
|
|
138
|
+
state.listStart = fromIndex(first);
|
|
139
|
+
state.listLength = end - first + 1;
|
|
140
|
+
shiftBy = element.scrollHeight;
|
|
141
|
+
}
|
|
142
|
+
else if (element.scrollHeight - element.scrollTop - element.clientHeight < margin && end < max) {
|
|
143
|
+
state.listLength = Math.min(max, end + 12) - start + 1;
|
|
144
|
+
}
|
|
145
|
+
else
|
|
146
|
+
return;
|
|
147
|
+
const active = doc.activeElement instanceof HTMLElement ? doc.activeElement.dataset.date : undefined;
|
|
148
|
+
render();
|
|
149
|
+
if (active)
|
|
150
|
+
dialog.querySelector(`[data-date="${active}"]`)?.focus({ preventScroll: true });
|
|
151
|
+
};
|
|
152
|
+
const reveal = () => {
|
|
153
|
+
const element = list();
|
|
154
|
+
const section = element?.querySelector(`[data-month-key="${state.currentYear}-${state.currentMonth}"]`);
|
|
155
|
+
if (element && section)
|
|
156
|
+
element.scrollTop = section.offsetTop;
|
|
108
157
|
};
|
|
109
158
|
const render = (focus = false, action) => {
|
|
110
159
|
if (!opened || destroyed)
|
|
111
160
|
return;
|
|
161
|
+
ensureWindow();
|
|
162
|
+
const previous = list();
|
|
163
|
+
const kept = previous && { top: previous.scrollTop, height: previous.scrollHeight };
|
|
112
164
|
dialog.replaceChildren(renderCalendar(state), announcement);
|
|
165
|
+
const current = list();
|
|
166
|
+
if (current && kept)
|
|
167
|
+
current.scrollTop = kept.top + (shiftBy === null ? 0 : current.scrollHeight - kept.height);
|
|
168
|
+
shiftBy = null;
|
|
113
169
|
centre();
|
|
114
170
|
announcement.textContent = new Date(state.currentYear, state.currentMonth, 1).toLocaleDateString("en-US", { month: "long", year: "numeric" });
|
|
115
171
|
if (action)
|
|
@@ -150,6 +206,7 @@ const createDatePicker = (config = {}) => {
|
|
|
150
206
|
opened = true;
|
|
151
207
|
resetDraft();
|
|
152
208
|
state.inputMode = state.variant === "modal-input";
|
|
209
|
+
state.listStart = undefined;
|
|
153
210
|
let initial = committed ?? today;
|
|
154
211
|
if (state.minDate && initial < state.minDate)
|
|
155
212
|
initial = state.minDate;
|
|
@@ -169,6 +226,7 @@ const createDatePicker = (config = {}) => {
|
|
|
169
226
|
if (modal)
|
|
170
227
|
unlock = lockScroll(doc);
|
|
171
228
|
centre();
|
|
229
|
+
reveal();
|
|
172
230
|
trigger.setAttribute("aria-expanded", "true");
|
|
173
231
|
focusCurrent();
|
|
174
232
|
base.emit("open", { value: getValue() });
|
|
@@ -256,7 +314,7 @@ const createDatePicker = (config = {}) => {
|
|
|
256
314
|
render(true);
|
|
257
315
|
};
|
|
258
316
|
const navigate = (amount) => {
|
|
259
|
-
const count = state.currentView === "day" ? amount :
|
|
317
|
+
const count = state.currentView === "day" ? amount : amount * 12;
|
|
260
318
|
const anchor = new Date(state.currentYear, state.currentMonth, 1);
|
|
261
319
|
anchor.setDate(Math.min(state.focusedDate.getDate(), new Date(state.currentYear, state.currentMonth + 1, 0).getDate()));
|
|
262
320
|
setDisplayDate(addMonths(anchor, count));
|
|
@@ -363,10 +421,11 @@ const createDatePicker = (config = {}) => {
|
|
|
363
421
|
if (target?.dataset.date) {
|
|
364
422
|
const date = parseDate(target.dataset.date);
|
|
365
423
|
let next;
|
|
424
|
+
const ahead = rtl(dialog) ? -1 : 1;
|
|
366
425
|
if (event.key === "ArrowLeft")
|
|
367
|
-
next = addDays(date, -
|
|
426
|
+
next = addDays(date, -ahead);
|
|
368
427
|
else if (event.key === "ArrowRight")
|
|
369
|
-
next = addDays(date,
|
|
428
|
+
next = addDays(date, ahead);
|
|
370
429
|
else if (event.key === "ArrowUp")
|
|
371
430
|
next = addDays(date, -7);
|
|
372
431
|
else if (event.key === "ArrowDown")
|
|
@@ -395,7 +454,8 @@ const createDatePicker = (config = {}) => {
|
|
|
395
454
|
else if (target?.hasAttribute('data-month') || target?.hasAttribute('data-year')) {
|
|
396
455
|
const buttons = Array.from(dialog.querySelectorAll('[data-month], [data-year]'));
|
|
397
456
|
let index = buttons.indexOf(target);
|
|
398
|
-
const
|
|
457
|
+
const ahead = rtl(dialog) ? -1 : 1;
|
|
458
|
+
const delta = { ArrowLeft: -ahead, ArrowRight: ahead, ArrowUp: -3, ArrowDown: 3 }[event.key];
|
|
399
459
|
if (event.key === "Home")
|
|
400
460
|
index = 0;
|
|
401
461
|
else if (event.key === "End")
|
|
@@ -430,6 +490,10 @@ const createDatePicker = (config = {}) => {
|
|
|
430
490
|
render(!!active?.dataset.date, active?.dataset.action);
|
|
431
491
|
};
|
|
432
492
|
const onScroll = (event) => {
|
|
493
|
+
if (event.type === "scroll" && event.target instanceof HTMLElement && event.target === list()) {
|
|
494
|
+
extend(event.target);
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
433
497
|
if (!(event.target instanceof HTMLElement) || event.target !== track())
|
|
434
498
|
return;
|
|
435
499
|
if (event.type === "scrollend") {
|
|
@@ -2,20 +2,22 @@ import { DATEPICKER_ICONS } from "./constants.js";
|
|
|
2
2
|
import { setHTML } from "../../core/dom/html.js";
|
|
3
3
|
import { createElement } from "../../core/dom/create.js";
|
|
4
4
|
import { MONTH_NAMES, MONTH_NAMES_SHORT } from "./types.js";
|
|
5
|
-
import { formatDate, generateCalendarDates,
|
|
5
|
+
import { formatDate, generateCalendarDates, isSameDay, parseDate } from "./utils.js";
|
|
6
6
|
export function renderCalendar(state) {
|
|
7
7
|
const cls = (name) => `${state.prefix}-datepicker__${name}`;
|
|
8
8
|
const make = (tag, name, text, attributes) => createElement({ tag, className: cls(name), text, attributes });
|
|
9
9
|
const button = (name, text, action, label = text) => {
|
|
10
10
|
const element = make("button", name, text, { type: "button", "data-action": action, "aria-label": label });
|
|
11
|
-
const icon = action === "toggle-mode" ? (state.inputMode ? DATEPICKER_ICONS.calendar : DATEPICKER_ICONS.edit) : action === "prev" ? DATEPICKER_ICONS.previous : action === "next" ? DATEPICKER_ICONS.next : null;
|
|
11
|
+
const icon = name === "close" ? DATEPICKER_ICONS.close : action === "toggle-mode" ? (state.inputMode ? DATEPICKER_ICONS.calendar : DATEPICKER_ICONS.edit) : action === "prev" ? DATEPICKER_ICONS.previous : action === "next" ? DATEPICKER_ICONS.next : null;
|
|
12
12
|
if (icon)
|
|
13
13
|
setHTML(element, icon);
|
|
14
14
|
return element;
|
|
15
15
|
};
|
|
16
|
-
const monthGrid = (year, month, current) => {
|
|
16
|
+
const monthGrid = (year, month, current, list = false) => {
|
|
17
17
|
const grid = make("div", "days", undefined, { role: "grid", "aria-label": `${MONTH_NAMES[month]} ${year}`, "aria-describedby": `${state.id}-keyboard` });
|
|
18
18
|
const weekdays = make("div", "weekdays", undefined, { role: "row" });
|
|
19
|
+
if (list)
|
|
20
|
+
weekdays.classList.add(cls("sr-only"));
|
|
19
21
|
for (const name of ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"])
|
|
20
22
|
weekdays.append(make("span", "weekday", name[0], { role: "columnheader", "aria-label": name }));
|
|
21
23
|
grid.append(weekdays);
|
|
@@ -26,6 +28,10 @@ export function renderCalendar(state) {
|
|
|
26
28
|
for (const item of dates.slice(week * 7, week * 7 + 7)) {
|
|
27
29
|
const selected = !!state.selectedDate && (isSameDay(item.date, state.selectedDate) || !!state.rangeEndDate && isSameDay(item.date, state.rangeEndDate));
|
|
28
30
|
const inRange = !!state.selectedDate && !!state.rangeEndDate && item.date >= state.selectedDate && item.date <= state.rangeEndDate;
|
|
31
|
+
if (list && !item.isCurrentMonth) {
|
|
32
|
+
row.append(make("div", "cell", undefined, { role: "gridcell" }));
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
29
35
|
const cell = make("div", "cell", undefined, { role: "gridcell", "aria-selected": String(selected || inRange) });
|
|
30
36
|
if (inRange)
|
|
31
37
|
cell.classList.add(cls("cell--range"));
|
|
@@ -61,11 +67,19 @@ export function renderCalendar(state) {
|
|
|
61
67
|
};
|
|
62
68
|
const content = make("div", "content");
|
|
63
69
|
const modal = state.variant !== "docked";
|
|
70
|
+
const fullscreen = state.variant === "fullscreen";
|
|
71
|
+
const confirmDisabled = !state.selectedDate || !state.isAllowed(state.selectedDate) || state.selectionMode === "range" && (!state.rangeEndDate || !state.isAllowed(state.rangeEndDate));
|
|
64
72
|
if (modal) {
|
|
65
73
|
const header = make("div", "modal-header");
|
|
74
|
+
if (fullscreen) {
|
|
75
|
+
const save = button("save", "Save", "confirm");
|
|
76
|
+
save.disabled = confirmDisabled;
|
|
77
|
+
header.append(button("close", "", "cancel", "Close"), save);
|
|
78
|
+
}
|
|
66
79
|
header.append(make("div", "title", state.label, { id: `${state.id}-title` }));
|
|
67
|
-
const
|
|
68
|
-
|
|
80
|
+
const pattern = fullscreen ? "MMM D" : "MMM D, YYYY";
|
|
81
|
+
const headline = state.selectedDate ? formatDate(state.selectedDate, pattern) : state.selectionMode === "range" ? "Select range" : "Select date";
|
|
82
|
+
header.append(make("div", "headline", state.selectionMode === "range" && state.rangeEndDate ? `${headline} – ${formatDate(state.rangeEndDate, pattern)}` : headline));
|
|
69
83
|
header.append(button("mode-toggle", state.inputMode ? "▦" : "✎", "toggle-mode", state.inputMode ? "Switch to calendar" : "Switch to date input"));
|
|
70
84
|
content.append(header);
|
|
71
85
|
}
|
|
@@ -82,12 +96,30 @@ export function renderCalendar(state) {
|
|
|
82
96
|
}
|
|
83
97
|
content.append(fields);
|
|
84
98
|
}
|
|
99
|
+
else if (fullscreen) {
|
|
100
|
+
const weekdays = make("div", "weekdays", undefined, { "aria-hidden": "true" });
|
|
101
|
+
for (const name of ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"])
|
|
102
|
+
weekdays.append(make("span", "weekday", name[0]));
|
|
103
|
+
const list = make("div", "list");
|
|
104
|
+
const start = state.listStart ?? new Date(state.currentYear, state.currentMonth, 1);
|
|
105
|
+
for (let index = 0; index < (state.listLength ?? 1); index++) {
|
|
106
|
+
const first = new Date(start.getFullYear(), start.getMonth() + index, 1);
|
|
107
|
+
const section = make("section", "month-section", undefined, { "data-month-key": `${first.getFullYear()}-${first.getMonth()}` });
|
|
108
|
+
section.append(make("div", "subhead", `${MONTH_NAMES[first.getMonth()]} ${first.getFullYear()}`, { "aria-hidden": "true" }));
|
|
109
|
+
section.append(monthGrid(first.getFullYear(), first.getMonth(), first.getFullYear() === state.focusedDate.getFullYear() && first.getMonth() === state.focusedDate.getMonth(), true));
|
|
110
|
+
list.append(section);
|
|
111
|
+
}
|
|
112
|
+
content.append(weekdays, list, make("div", "sr-only", "Use arrow keys for days, Home and End for the week, Page Up and Page Down for months, with Shift for years.", { id: `${state.id}-keyboard` }));
|
|
113
|
+
}
|
|
85
114
|
else {
|
|
86
115
|
const header = make("div", "header");
|
|
87
116
|
const nav = make("div", "navigation");
|
|
88
117
|
nav.append(button("month-selector", MONTH_NAMES[state.currentMonth], "month", "Select month"), button("year-selector", String(state.currentYear), "year", "Select year"));
|
|
89
|
-
|
|
90
|
-
|
|
118
|
+
header.append(nav);
|
|
119
|
+
if (state.currentView !== "year") {
|
|
120
|
+
const span = state.currentView === "day" ? "month" : "year";
|
|
121
|
+
header.append(button("prev", "‹", "prev", `Previous ${span}`), button("next", "›", "next", `Next ${span}`));
|
|
122
|
+
}
|
|
91
123
|
content.append(header);
|
|
92
124
|
if (state.currentView === "day") {
|
|
93
125
|
const track = make("div", "track");
|
|
@@ -106,7 +138,8 @@ export function renderCalendar(state) {
|
|
|
106
138
|
else {
|
|
107
139
|
const months = state.currentView === "month";
|
|
108
140
|
const grid = make("div", months ? "months" : "years", undefined, { role: "group", "aria-label": months ? "Choose month" : "Choose year" });
|
|
109
|
-
|
|
141
|
+
const first = state.minDate?.getFullYear() ?? 1900, last = state.maxDate?.getFullYear() ?? 2100;
|
|
142
|
+
for (const value of months ? Array.from({ length: 12 }, (_, i) => i) : Array.from({ length: last - first + 1 }, (_, i) => first + i)) {
|
|
110
143
|
const selected = value === (months ? state.currentMonth : state.currentYear);
|
|
111
144
|
grid.append(make("button", months ? "month" : "year", months ? MONTH_NAMES_SHORT[value] : String(value), {
|
|
112
145
|
type: "button", [months ? "data-month" : "data-year"]: String(value), "aria-pressed": String(selected), tabindex: selected ? "0" : "-1",
|
|
@@ -116,10 +149,10 @@ export function renderCalendar(state) {
|
|
|
116
149
|
}
|
|
117
150
|
content.append(make("div", "sr-only", "Use arrow keys for days, Home and End for the week, Page Up and Page Down for months, with Shift for years.", { id: `${state.id}-keyboard` }));
|
|
118
151
|
}
|
|
119
|
-
if (modal) {
|
|
152
|
+
if (modal && !fullscreen) {
|
|
120
153
|
const footer = make("div", "footer");
|
|
121
154
|
const confirm = button("confirm", "OK", "confirm");
|
|
122
|
-
confirm.disabled =
|
|
155
|
+
confirm.disabled = confirmDisabled;
|
|
123
156
|
footer.append(button("cancel", "Cancel", "cancel"), confirm);
|
|
124
157
|
content.append(footer);
|
|
125
158
|
}
|
|
@@ -41,7 +41,7 @@ export interface DatePickerEvents {
|
|
|
41
41
|
* DatePicker variant types
|
|
42
42
|
* @category Components
|
|
43
43
|
*/
|
|
44
|
-
export type DatePickerVariant = 'docked' | 'modal' | 'modal-input';
|
|
44
|
+
export type DatePickerVariant = 'docked' | 'modal' | 'modal-input' | 'fullscreen';
|
|
45
45
|
/**
|
|
46
46
|
* DatePicker view types
|
|
47
47
|
* @category Components
|
|
@@ -361,4 +361,7 @@ export interface DatePickerState {
|
|
|
361
361
|
label: string;
|
|
362
362
|
specialDates: NonNullable<DatePickerConfig["specialDates"]>;
|
|
363
363
|
isAllowed(date: Date): boolean;
|
|
364
|
+
/** Full screen: the first month of the rendered list, and how many follow. FLO-276. */
|
|
365
|
+
listStart?: Date;
|
|
366
|
+
listLength?: number;
|
|
364
367
|
}
|
|
@@ -56,13 +56,6 @@ export declare const isDateInRange: (date: Date, startDate: Date, endDate: Date)
|
|
|
56
56
|
* @returns Array of calendar dates
|
|
57
57
|
*/
|
|
58
58
|
export declare const generateCalendarDates: (year: number, month: number, selectedDate?: Date | null, rangeEndDate?: Date | null, minDate?: Date | null, maxDate?: Date | null) => CalendarDate[];
|
|
59
|
-
/**
|
|
60
|
-
* Generates an array of years for year selection
|
|
61
|
-
* @param currentYear - Center year for the range
|
|
62
|
-
* @param range - Number of years before and after current year
|
|
63
|
-
* @returns Array of years
|
|
64
|
-
*/
|
|
65
|
-
export declare const generateYearRange: (currentYear: number, range?: number) => number[];
|
|
66
59
|
/**
|
|
67
60
|
* Adds days to a date
|
|
68
61
|
* @param date - Base date
|
|
@@ -162,15 +162,6 @@ export const generateCalendarDates = (year, month, selectedDate = null, rangeEnd
|
|
|
162
162
|
}
|
|
163
163
|
return result;
|
|
164
164
|
};
|
|
165
|
-
export const generateYearRange = (currentYear, range = 10) => {
|
|
166
|
-
const years = [];
|
|
167
|
-
const startYear = currentYear - range;
|
|
168
|
-
const endYear = currentYear + range;
|
|
169
|
-
for (let year = startYear; year <= endYear; year++) {
|
|
170
|
-
years.push(year);
|
|
171
|
-
}
|
|
172
|
-
return years;
|
|
173
|
-
};
|
|
174
165
|
export const addDays = (date, days) => {
|
|
175
166
|
const result = new Date(date);
|
|
176
167
|
result.setDate(result.getDate() + days);
|
|
@@ -12,7 +12,7 @@ export const createBaseConfig = (config = {}) => createComponentConfig(defaultCo
|
|
|
12
12
|
export const getElementConfig = (config) => {
|
|
13
13
|
const attributes = {
|
|
14
14
|
type: config.type || "button",
|
|
15
|
-
"aria-label": config.ariaLabel
|
|
15
|
+
"aria-label": config.ariaLabel,
|
|
16
16
|
};
|
|
17
17
|
if (config.value !== undefined) {
|
|
18
18
|
attributes.value = config.value;
|
|
@@ -237,8 +237,9 @@ export interface ExtendedFabConfig {
|
|
|
237
237
|
/**
|
|
238
238
|
* Accessible label for screen readers
|
|
239
239
|
*
|
|
240
|
-
* Sets the aria-label attribute
|
|
241
|
-
*
|
|
240
|
+
* Sets the aria-label attribute. The visible text already names the
|
|
241
|
+
* Extended FAB, so set this only when the name should differ from it or
|
|
242
|
+
* there is no text. Nothing is derived from `text` or `icon` (#232).
|
|
242
243
|
*
|
|
243
244
|
* @example
|
|
244
245
|
* ```typescript
|
|
@@ -30,7 +30,7 @@ export const createSegment = (config, container, prefix, groupDisabled = false,
|
|
|
30
30
|
ripple: options.ripple,
|
|
31
31
|
rippleConfig: options.rippleConfig,
|
|
32
32
|
class: config.class,
|
|
33
|
-
ariaLabel:
|
|
33
|
+
ariaLabel: isIconOnly ? config.value : undefined,
|
|
34
34
|
});
|
|
35
35
|
button.element.classList.add(`${prefix}-segmented-button__segment`);
|
|
36
36
|
let checkmarkElement = null;
|
|
@@ -224,13 +224,17 @@ export const withController = (config, getComponent) => (component) => {
|
|
|
224
224
|
console.error("Error initializing slider controller:", error);
|
|
225
225
|
}
|
|
226
226
|
};
|
|
227
|
-
|
|
227
|
+
initController();
|
|
228
|
+
const layout = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => updateHandlePositions()) : null;
|
|
229
|
+
layout?.observe(component.element);
|
|
228
230
|
if (component.lifecycle) {
|
|
229
231
|
const originalDestroy = component.lifecycle.destroy || (() => { });
|
|
230
232
|
component.lifecycle.destroy = () => {
|
|
231
|
-
|
|
233
|
+
layout?.disconnect();
|
|
232
234
|
if (settleTimer !== null)
|
|
233
235
|
clearTimeout(settleTimer);
|
|
236
|
+
if (state.valueHideTimer !== null)
|
|
237
|
+
clearTimeout(state.valueHideTimer);
|
|
234
238
|
handlers.cleanupEventListeners();
|
|
235
239
|
originalDestroy.call(component.lifecycle);
|
|
236
240
|
};
|
|
@@ -17,9 +17,6 @@ interface StatesHost {
|
|
|
17
17
|
structure?: Record<string, HTMLElement | undefined>;
|
|
18
18
|
formFields?: (HTMLInputElement | null)[] | null;
|
|
19
19
|
renderTracks?: (state?: unknown) => void;
|
|
20
|
-
lifecycle?: {
|
|
21
|
-
destroy: () => void;
|
|
22
|
-
};
|
|
23
20
|
}
|
|
24
21
|
export declare const withStates: (config: SliderConfig) => <C extends StatesHost>(component: C) => C & {
|
|
25
22
|
disabled: {
|
|
@@ -3,13 +3,6 @@ import { SLIDER_SIZES } from "../constants.js";
|
|
|
3
3
|
export const withStates = (config) => (component) => {
|
|
4
4
|
const handle = component.handle ?? component.structure?.handle;
|
|
5
5
|
const secondHandle = component.secondHandle ?? component.structure?.secondHandle;
|
|
6
|
-
const isDisabled = config.disabled === true;
|
|
7
|
-
let initialization = null;
|
|
8
|
-
if (isDisabled) {
|
|
9
|
-
initialization = setTimeout(() => {
|
|
10
|
-
disableComponent();
|
|
11
|
-
}, 0);
|
|
12
|
-
}
|
|
13
6
|
const setFieldsDisabled = (disabled) => {
|
|
14
7
|
for (const field of component.formFields ?? []) {
|
|
15
8
|
if (field)
|
|
@@ -56,14 +49,8 @@ export const withStates = (config) => (component) => {
|
|
|
56
49
|
const foundKey = sizeKeys.find((sizeKey) => component.element.classList.contains(`${component.getClass("slider")}--${sizeKey.toLowerCase()}`));
|
|
57
50
|
return foundKey || "XS";
|
|
58
51
|
}
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
component.lifecycle.destroy = () => {
|
|
62
|
-
if (initialization !== null)
|
|
63
|
-
clearTimeout(initialization);
|
|
64
|
-
originalDestroy.call(component.lifecycle);
|
|
65
|
-
};
|
|
66
|
-
}
|
|
52
|
+
if (config.disabled === true)
|
|
53
|
+
disableComponent();
|
|
67
54
|
return Object.assign(component, {
|
|
68
55
|
disabled: {
|
|
69
56
|
enable() {
|
|
@@ -133,8 +133,18 @@ export declare const TEXTFIELD_CLASSES: {
|
|
|
133
133
|
readonly PREFIX_TEXT: "textfield__prefix";
|
|
134
134
|
/** Suffix text class */
|
|
135
135
|
readonly SUFFIX_TEXT: "textfield__suffix";
|
|
136
|
-
/**
|
|
136
|
+
/** Outline of the outlined variant, drawn in three segments */
|
|
137
137
|
readonly OUTLINE: "textfield__outline";
|
|
138
|
+
/** Outline segment before the label (start corner) */
|
|
139
|
+
readonly OUTLINE_LEADING: "textfield__outline-leading";
|
|
140
|
+
/** Outline segment the floating label sits in */
|
|
141
|
+
readonly OUTLINE_NOTCH: "textfield__outline-notch";
|
|
142
|
+
/** Outline segment after the label */
|
|
143
|
+
readonly OUTLINE_TRAILING: "textfield__outline-trailing";
|
|
144
|
+
/** Outline whose notch is open around the floating label */
|
|
145
|
+
readonly OUTLINE_NOTCHED: "textfield__outline--notched";
|
|
146
|
+
/** Outlined field laid out right to left, from its computed direction */
|
|
147
|
+
readonly RTL: "textfield--rtl";
|
|
138
148
|
/** Multiline class */
|
|
139
149
|
readonly MULTILINE: "textfield--multiline";
|
|
140
150
|
};
|
|
@@ -59,5 +59,10 @@ export const TEXTFIELD_CLASSES = {
|
|
|
59
59
|
PREFIX_TEXT: "textfield__prefix",
|
|
60
60
|
SUFFIX_TEXT: "textfield__suffix",
|
|
61
61
|
OUTLINE: "textfield__outline",
|
|
62
|
+
OUTLINE_LEADING: "textfield__outline-leading",
|
|
63
|
+
OUTLINE_NOTCH: "textfield__outline-notch",
|
|
64
|
+
OUTLINE_TRAILING: "textfield__outline-trailing",
|
|
65
|
+
OUTLINE_NOTCHED: "textfield__outline--notched",
|
|
66
|
+
RTL: "textfield--rtl",
|
|
62
67
|
MULTILINE: "textfield--multiline",
|
|
63
68
|
};
|