@nldd/design-system 0.8.77 → 0.8.78
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/custom-elements.json +1094 -186
- package/dist/components/actions/menu/menu.js +1 -1
- package/dist/components/actions/menu/menu.js.map +1 -1
- package/dist/components/actions/menu/menu.styles.d.ts.map +1 -1
- package/dist/components/actions/menu/menu.styles.js +1 -0
- package/dist/components/actions/menu/menu.styles.js.map +1 -1
- package/dist/components/actions/menu/menu.template.js +1 -1
- package/dist/components/actions/menu/menu.template.js.map +1 -1
- package/dist/components/components.js +16 -14
- package/dist/components/content/avatar/avatar.d.ts +9 -9
- package/dist/components/content/avatar/avatar.d.ts.map +1 -1
- package/dist/components/content/avatar/avatar.js +15 -15
- package/dist/components/content/avatar/avatar.js.map +1 -1
- package/dist/components/content/code-viewer/code-viewer.styles.js +2 -2
- package/dist/components/content/icon/icon-registry.js +1 -1
- package/dist/components/content/icon/icon-registry.js.map +1 -1
- package/dist/components/content/image/image.styles.d.ts.map +1 -1
- package/dist/components/content/image/image.styles.js +4 -1
- package/dist/components/content/image/image.styles.js.map +1 -1
- package/dist/components/content/tag/tag.js +6 -6
- package/dist/components/content/tag/tag.js.map +1 -1
- package/dist/components/forms/form/form.js +1 -1
- package/dist/components/forms/form-actions/form-actions.d.ts +3 -3
- package/dist/components/forms/form-actions/form-actions.js +3 -3
- package/dist/components/forms/form-section/form-section.d.ts.map +1 -1
- package/dist/components/forms/form-section/form-section.js +11 -10
- package/dist/components/forms/form-section/form-section.js.map +1 -1
- package/dist/components/{index-DVj2pCTH.js → index-BNg_kPou.js} +1 -1
- package/dist/components/{index-FhXfLApr.js → index-BmVf8Da6.js} +1 -1
- package/dist/components/{index-9C4reCh_.js → index-CU-wlUnI.js} +3141 -1752
- package/dist/components/{index-Cor-Ak4F.js → index-CcCKQ3Dj.js} +1 -1
- package/dist/components/{index-g0CP5dPz.js → index-D03jbAoU.js} +1 -1
- package/dist/components/{index-B5S5gihT.js → index-D68oJ-Le.js} +1 -1
- package/dist/components/{index-CB4c2A6P.js → index-v6dIt9IT.js} +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/inputs/date-field/date-field.d.ts +3 -3
- package/dist/components/inputs/date-field/date-field.d.ts.map +1 -1
- package/dist/components/inputs/date-field/date-field.i18n.js +7 -7
- package/dist/components/inputs/date-field/date-field.i18n.js.map +1 -1
- package/dist/components/inputs/date-field/date-field.js +3 -3
- package/dist/components/inputs/date-field/date-field.js.map +1 -1
- package/dist/components/inputs/date-field/date-field.styles.d.ts.map +1 -1
- package/dist/components/inputs/date-field/date-field.styles.js +31 -29
- package/dist/components/inputs/date-field/date-field.styles.js.map +1 -1
- package/dist/components/inputs/date-picker/date-picker.d.ts +5 -5
- package/dist/components/inputs/date-picker/date-picker.d.ts.map +1 -1
- package/dist/components/inputs/date-picker/date-picker.i18n.js +18 -18
- package/dist/components/inputs/date-picker/date-picker.i18n.js.map +1 -1
- package/dist/components/inputs/date-picker/date-picker.js +6 -6
- package/dist/components/inputs/date-picker/date-picker.js.map +1 -1
- package/dist/components/inputs/date-picker/date-picker.styles.js +1 -1
- package/dist/components/inputs/number-field/number-field.d.ts +1 -1
- package/dist/components/inputs/number-field/number-field.js +1 -1
- package/dist/components/inputs/search-field/search-field.d.ts.map +1 -1
- package/dist/components/inputs/search-field/search-field.js +9 -0
- package/dist/components/inputs/search-field/search-field.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.markdown.js +3 -3
- package/dist/components/inputs/text-editor/text-editor.markdown.js.map +1 -1
- package/dist/components/inputs/time-field/time-field.d.ts +242 -0
- package/dist/components/inputs/time-field/time-field.d.ts.map +1 -0
- package/dist/components/inputs/time-field/time-field.i18n.d.ts +8 -0
- package/dist/components/inputs/time-field/time-field.i18n.d.ts.map +1 -0
- package/dist/components/inputs/time-field/time-field.i18n.js +14 -0
- package/dist/components/inputs/time-field/time-field.i18n.js.map +1 -0
- package/dist/components/inputs/time-field/time-field.js +641 -0
- package/dist/components/inputs/time-field/time-field.js.map +1 -0
- package/dist/components/inputs/time-field/time-field.styles.d.ts +2 -0
- package/dist/components/inputs/time-field/time-field.styles.d.ts.map +1 -0
- package/dist/components/inputs/time-field/time-field.styles.js +192 -0
- package/dist/components/inputs/time-field/time-field.styles.js.map +1 -0
- package/dist/components/inputs/time-field/time-field.template.d.ts +20 -0
- package/dist/components/inputs/time-field/time-field.template.d.ts.map +1 -0
- package/dist/components/inputs/time-field/time-field.template.js +126 -0
- package/dist/components/inputs/time-field/time-field.template.js.map +1 -0
- package/dist/components/inputs/time-picker/time-picker.d.ts +135 -0
- package/dist/components/inputs/time-picker/time-picker.d.ts.map +1 -0
- package/dist/components/inputs/time-picker/time-picker.i18n.d.ts +7 -0
- package/dist/components/inputs/time-picker/time-picker.i18n.d.ts.map +1 -0
- package/dist/components/inputs/time-picker/time-picker.i18n.js +10 -0
- package/dist/components/inputs/time-picker/time-picker.i18n.js.map +1 -0
- package/dist/components/inputs/time-picker/time-picker.js +386 -0
- package/dist/components/inputs/time-picker/time-picker.js.map +1 -0
- package/dist/components/inputs/time-picker/time-picker.styles.d.ts +2 -0
- package/dist/components/inputs/time-picker/time-picker.styles.d.ts.map +1 -0
- package/dist/components/inputs/time-picker/time-picker.styles.js +183 -0
- package/dist/components/inputs/time-picker/time-picker.styles.js.map +1 -0
- package/dist/components/inputs/time-picker/time-picker.template.d.ts +4 -0
- package/dist/components/inputs/time-picker/time-picker.template.d.ts.map +1 -0
- package/dist/components/inputs/time-picker/time-picker.template.js +87 -0
- package/dist/components/inputs/time-picker/time-picker.template.js.map +1 -0
- package/dist/components/layout/box/box.styles.js +1 -1
- package/dist/components/layout/page/page.styles.d.ts.map +1 -1
- package/dist/components/layout/page/page.styles.js +6 -0
- package/dist/components/layout/page/page.styles.js.map +1 -1
- package/dist/components/layout/popover/popover.d.ts +2 -2
- package/dist/components/layout/popover/popover.d.ts.map +1 -1
- package/dist/components/layout/popover/popover.js +67 -71
- package/dist/components/layout/popover/popover.js.map +1 -1
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.styles.d.ts.map +1 -1
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.styles.js +14 -0
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.styles.js.map +1 -1
- package/dist/components/layout/window/window.js +6 -6
- package/dist/components/layout/window/window.js.map +1 -1
- package/dist/components/lists-and-tables/list/list.d.ts +1 -1
- package/dist/components/lists-and-tables/list/list.js +1 -1
- package/dist/components/lists-and-tables/list/list.styles.js +1 -1
- package/dist/components/lists-and-tables/list-item/list-item.d.ts +1 -1
- package/dist/components/lists-and-tables/list-item/list-item.js +1 -1
- package/dist/components/navigation/top-navigation-bar/top-navigation-bar.styles.js +3 -3
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.styles.js +1 -1
- package/dist/components/status-and-feedback/banner/banner.d.ts +3 -0
- package/dist/components/status-and-feedback/banner/banner.d.ts.map +1 -1
- package/dist/components/status-and-feedback/banner/banner.i18n.js +1 -1
- package/dist/components/status-and-feedback/banner/banner.i18n.js.map +1 -1
- package/dist/components/status-and-feedback/banner/banner.js +5 -0
- package/dist/components/status-and-feedback/banner/banner.js.map +1 -1
- package/dist/components/status-and-feedback/banner/banner.styles.d.ts.map +1 -1
- package/dist/components/status-and-feedback/banner/banner.styles.js +27 -10
- package/dist/components/status-and-feedback/banner/banner.styles.js.map +1 -1
- package/dist/components/status-and-feedback/banner/banner.template.js +1 -1
- package/dist/components/status-and-feedback/banner/banner.template.js.map +1 -1
- package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.i18n.js +1 -1
- package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.i18n.js.map +1 -1
- package/dist/components/status-and-feedback/progress-bar/progress-bar.styles.d.ts.map +1 -1
- package/dist/components/status-and-feedback/progress-bar/progress-bar.styles.js +8 -2
- package/dist/components/status-and-feedback/progress-bar/progress-bar.styles.js.map +1 -1
- package/dist/components/status-and-feedback/progress-circle/progress-circle.styles.d.ts.map +1 -1
- package/dist/components/status-and-feedback/progress-circle/progress-circle.styles.js +4 -1
- package/dist/components/status-and-feedback/progress-circle/progress-circle.styles.js.map +1 -1
- package/dist/css/variables.css +4 -1
- package/dist/nldd.min.js +22269 -0
- package/dist/palettes.html +245 -0
- package/dist/sample-images/butterfly-1200.jpg +0 -0
- package/dist/sample-images/butterfly-1600.jpg +0 -0
- package/dist/sample-images/butterfly-480.jpg +0 -0
- package/dist/sample-images/butterfly-960.jpg +0 -0
- package/dist/types/vue.d.ts +90 -3
- package/package.json +16 -4
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NLDD Design System Time Picker Component (Lit + TypeScript)
|
|
3
|
+
*
|
|
4
|
+
* Twee kolommen, uren en minuten, die als een wiel langs de selectie in het midden
|
|
5
|
+
* schuiven. Het component is zelfstandig bruikbaar (inline op een pagina, in een
|
|
6
|
+
* filterpaneel) en zit ook in de popover van nldd-time-field. Waarden zijn altijd
|
|
7
|
+
* 24-uurs `HH:mm`.
|
|
8
|
+
*
|
|
9
|
+
* Scrollen ís kiezen: wat in het midden tot stilstand komt, is de waarde. Met het
|
|
10
|
+
* toetsenbord bedien je de selectie, want dat is wat een wiel is: uur en minuut zijn
|
|
11
|
+
* er elk een spinbutton. De kolommen eronder staan op aria-hidden, zodat dezelfde
|
|
12
|
+
* waarden niet twee keer worden voorgelezen.
|
|
13
|
+
*
|
|
14
|
+
* @element nldd-time-picker
|
|
15
|
+
*
|
|
16
|
+
* @attr {string} value - De gekozen tijd als `HH:mm` (24-uurs).
|
|
17
|
+
* @attr {string} min - Vroegst toegestane tijd als `HH:mm`. Is tevens de basis waarvandaan `step` telt.
|
|
18
|
+
* @attr {string} max - Laatst toegestane tijd als `HH:mm`.
|
|
19
|
+
* @attr {number} step - Minutenstap (standaard 1). Bepaalt welke minuten in de kolom staan.
|
|
20
|
+
* @attr {number} rows - Hoogte van de kolommen in rijen (standaard 7, minimaal 3). De gekozen waarde staat altijd in het midden, dus een oneven aantal toont hele rijen en een even aantal kapt boven en onder een halve rij af.
|
|
21
|
+
* @attr {string} width - Breedte: `full` vult de container, of geef een eigen CSS-lengte.
|
|
22
|
+
* @attr {string} accessible-label - Toegankelijke naam van de picker.
|
|
23
|
+
* @attr {object} translations - Vertalingen; niet opgegeven sleutels vallen terug op het Nederlands.
|
|
24
|
+
*
|
|
25
|
+
* @fires input - Bij elke wijziging: scrollen, de pijltjestoetsen. detail: { value } met `HH:mm`.
|
|
26
|
+
* @fires change - Wanneer de keuze is bevestigd: een klik op een waarde of op de selectie, of Enter. detail: { value } met `HH:mm`. Scrollen geeft alleen `input`, want anders zou een veld dat de picker in een popover toont al vastleggen zodra je stopt met scrollen.
|
|
27
|
+
*/
|
|
28
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
29
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
30
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
31
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
32
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
33
|
+
};
|
|
34
|
+
import { LitElement } from 'lit';
|
|
35
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
|
36
|
+
import { timePickerStyles } from './time-picker.styles.js';
|
|
37
|
+
import { timePickerTemplate } from './time-picker.template.js';
|
|
38
|
+
import { nlddTimePickerTranslations } from './time-picker.i18n.js';
|
|
39
|
+
const LAST_MINUTE_OF_DAY = 23 * 60 + 59;
|
|
40
|
+
export function toMinutes(time) {
|
|
41
|
+
const [hours, minutes] = time.split(':');
|
|
42
|
+
return Number(hours) * 60 + Number(minutes);
|
|
43
|
+
}
|
|
44
|
+
export function fromMinutes(total) {
|
|
45
|
+
return `${String(Math.floor(total / 60)).padStart(2, '0')}:${String(total % 60).padStart(2, '0')}`;
|
|
46
|
+
}
|
|
47
|
+
function isTime(value) {
|
|
48
|
+
return /^([01]\d|2[0-3]):[0-5]\d$/.test(value);
|
|
49
|
+
}
|
|
50
|
+
let NLDDTimePicker = class NLDDTimePicker extends LitElement {
|
|
51
|
+
constructor() {
|
|
52
|
+
super(...arguments);
|
|
53
|
+
this.value = '';
|
|
54
|
+
this.min = '';
|
|
55
|
+
this.max = '';
|
|
56
|
+
this.step = 1;
|
|
57
|
+
this.rows = 7;
|
|
58
|
+
this.width = '';
|
|
59
|
+
this.accessibleLabel = '';
|
|
60
|
+
this.translations = {};
|
|
61
|
+
/**
|
|
62
|
+
* Where scrolling has landed, per column, for as long as it is not recorded.
|
|
63
|
+
* Kept apart from `value`, which only records once scrolling comes to rest.
|
|
64
|
+
* Were the selection to show the recorded value, digits would slide past
|
|
65
|
+
* behind it while the number in the selection stayed put, and then it lies
|
|
66
|
+
* about where you are.
|
|
67
|
+
*/
|
|
68
|
+
this._scrolledTo = { hours: null, minutes: null };
|
|
69
|
+
/**
|
|
70
|
+
* While we scroll ourselves (on opening, or after a choice) the scrolling must
|
|
71
|
+
* not pick something again: that would overwrite the choice just made with
|
|
72
|
+
* whatever happens to pass by.
|
|
73
|
+
*/
|
|
74
|
+
this._scrollingSelf = false;
|
|
75
|
+
this._scrollTimers = { hours: 0, minutes: 0 };
|
|
76
|
+
this._selfScrollTimer = 0;
|
|
77
|
+
}
|
|
78
|
+
_t(key) {
|
|
79
|
+
return this.translations[key] ?? nlddTimePickerTranslations[key];
|
|
80
|
+
}
|
|
81
|
+
get _label() {
|
|
82
|
+
return this.accessibleLabel || this._t('components.time-picker.default-label');
|
|
83
|
+
}
|
|
84
|
+
get _minMinutes() {
|
|
85
|
+
return isTime(this.min) ? toMinutes(this.min) : 0;
|
|
86
|
+
}
|
|
87
|
+
get _maxMinutes() {
|
|
88
|
+
return isTime(this.max) ? toMinutes(this.max) : LAST_MINUTE_OF_DAY;
|
|
89
|
+
}
|
|
90
|
+
get _stepMinutes() {
|
|
91
|
+
return Math.max(1, Math.round(this.step));
|
|
92
|
+
}
|
|
93
|
+
/** Every valid time: from `min` (or midnight) in increments of `step`, up to
|
|
94
|
+
* and including `max`. One list, because the two columns are projections of
|
|
95
|
+
* it. That way an hour can never appear in its column without a valid minute
|
|
96
|
+
* to go with it. */
|
|
97
|
+
get _slots() {
|
|
98
|
+
const out = [];
|
|
99
|
+
for (let m = this._minMinutes; m <= this._maxMinutes; m += this._stepMinutes)
|
|
100
|
+
out.push(m);
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
/** The hours for which at least one valid minute exists. */
|
|
104
|
+
get _hours() {
|
|
105
|
+
return [...new Set(this._slots.map((m) => Math.floor(m / 60)))];
|
|
106
|
+
}
|
|
107
|
+
/** The minutes within the chosen hour. Without a chosen hour, those of the
|
|
108
|
+
* first hour, so the column never looks empty before anything is picked. */
|
|
109
|
+
get _minutes() {
|
|
110
|
+
const hour = this._selected === null ? this._hours[0] : Math.floor(this._selected / 60);
|
|
111
|
+
return this._slots.filter((m) => Math.floor(m / 60) === hour).map((m) => m % 60);
|
|
112
|
+
}
|
|
113
|
+
/** The chosen time in minutes, or null while there is no valid value. */
|
|
114
|
+
get _selected() {
|
|
115
|
+
if (!isTime(this.value))
|
|
116
|
+
return null;
|
|
117
|
+
const minutes = toMinutes(this.value);
|
|
118
|
+
return minutes >= this._minMinutes && minutes <= this._maxMinutes ? minutes : null;
|
|
119
|
+
}
|
|
120
|
+
get _selectedHour() {
|
|
121
|
+
return this._selected === null ? null : Math.floor(this._selected / 60);
|
|
122
|
+
}
|
|
123
|
+
get _selectedMinute() {
|
|
124
|
+
return this._selected === null ? null : this._selected % 60;
|
|
125
|
+
}
|
|
126
|
+
/** The number now standing in the selection: whatever lies in the middle while
|
|
127
|
+
* scrolling, and otherwise simply the chosen value. */
|
|
128
|
+
get _centeredHour() {
|
|
129
|
+
return this._scrolledTo.hours ?? this._selectedHour;
|
|
130
|
+
}
|
|
131
|
+
get _centeredMinute() {
|
|
132
|
+
return this._scrolledTo.minutes ?? this._selectedMinute;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Pick an hour or a minute. The hour holds on to the chosen minute when it
|
|
136
|
+
* fits inside it, so moving the hour keeps you on the same minute instead of
|
|
137
|
+
* jumping back to the start every time. When it does not fit (because of
|
|
138
|
+
* `min`, `max` or a step that does not work out), the first possible minute
|
|
139
|
+
* in that hour.
|
|
140
|
+
*/
|
|
141
|
+
_select(column, number, commit = false) {
|
|
142
|
+
const slots = this._slots;
|
|
143
|
+
if (slots.length === 0)
|
|
144
|
+
return;
|
|
145
|
+
let next;
|
|
146
|
+
if (column === 'hours') {
|
|
147
|
+
const wanted = this._selected === null ? null : this._selected % 60;
|
|
148
|
+
const inHour = slots.filter((m) => Math.floor(m / 60) === number);
|
|
149
|
+
if (inHour.length === 0)
|
|
150
|
+
return;
|
|
151
|
+
next = wanted !== null && inHour.includes(number * 60 + wanted)
|
|
152
|
+
? number * 60 + wanted
|
|
153
|
+
: inHour[0];
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
const hour = this._selected === null ? this._hours[0] : Math.floor(this._selected / 60);
|
|
157
|
+
next = hour * 60 + number;
|
|
158
|
+
if (!slots.includes(next))
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const changed = fromMinutes(next) !== this.value;
|
|
162
|
+
this.value = fromMinutes(next);
|
|
163
|
+
if (changed)
|
|
164
|
+
this._emit('input');
|
|
165
|
+
// change is the confirmation, not the change: a field showing the picker in
|
|
166
|
+
// a popover records on it, and that must not happen the moment you stop
|
|
167
|
+
// scrolling.
|
|
168
|
+
if (commit)
|
|
169
|
+
this._emit('change');
|
|
170
|
+
}
|
|
171
|
+
_emit(type) {
|
|
172
|
+
this.dispatchEvent(new CustomEvent(type, {
|
|
173
|
+
detail: { value: this.value },
|
|
174
|
+
bubbles: true,
|
|
175
|
+
composed: true,
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Arrow keys within a column, plus Home and End. The column is a single tab
|
|
180
|
+
* stop (roving tabindex), so Tab takes you to the next column instead of to
|
|
181
|
+
* the next value.
|
|
182
|
+
*/
|
|
183
|
+
_handleKeydown(e, column) {
|
|
184
|
+
const numbers = column === 'hours' ? this._hours : this._minutes;
|
|
185
|
+
if (numbers.length === 0)
|
|
186
|
+
return;
|
|
187
|
+
const current = column === 'hours' ? this._selectedHour : this._selectedMinute;
|
|
188
|
+
const index = current === null ? -1 : numbers.indexOf(current);
|
|
189
|
+
// Enter and space confirm what stands in the selection, the way a click does.
|
|
190
|
+
// With the arrow keys you are still adjusting.
|
|
191
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
192
|
+
e.preventDefault();
|
|
193
|
+
this._emit('change');
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
// Horizontal switches column, vertical moves the value: that way the arrows
|
|
197
|
+
// move in the direction you see them point. Same split as the segments of a
|
|
198
|
+
// native <input type="time">.
|
|
199
|
+
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
|
|
200
|
+
e.preventDefault();
|
|
201
|
+
this._focusColumn(e.key === 'ArrowLeft' ? 'hours' : 'minutes');
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
let next = null;
|
|
205
|
+
switch (e.key) {
|
|
206
|
+
case 'ArrowDown':
|
|
207
|
+
next = numbers[Math.min(index + 1, numbers.length - 1)];
|
|
208
|
+
break;
|
|
209
|
+
case 'ArrowUp':
|
|
210
|
+
next = numbers[index <= 0 ? 0 : index - 1];
|
|
211
|
+
break;
|
|
212
|
+
case 'Home':
|
|
213
|
+
next = numbers[0];
|
|
214
|
+
break;
|
|
215
|
+
case 'End':
|
|
216
|
+
next = numbers[numbers.length - 1];
|
|
217
|
+
break;
|
|
218
|
+
default:
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
e.preventDefault();
|
|
222
|
+
if (next !== null)
|
|
223
|
+
this._select(column, next);
|
|
224
|
+
}
|
|
225
|
+
/** Move focus to the spinbutton of the other column. */
|
|
226
|
+
_focusColumn(column) {
|
|
227
|
+
this.shadowRoot
|
|
228
|
+
?.querySelectorAll('.time-picker__value')[column === 'hours' ? 0 : 1]
|
|
229
|
+
?.focus();
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Focus lands on the hour, the way nldd-date-picker focuses a day. The host
|
|
233
|
+
* itself forwards nowhere, so an overlay that focuses this picker would leave
|
|
234
|
+
* the arrow keys dead until the user tabbed into the selection themselves.
|
|
235
|
+
*/
|
|
236
|
+
focus(options) {
|
|
237
|
+
const hour = this.shadowRoot?.querySelector('.time-picker__value');
|
|
238
|
+
if (hour)
|
|
239
|
+
hour.focus(options);
|
|
240
|
+
else
|
|
241
|
+
super.focus(options);
|
|
242
|
+
}
|
|
243
|
+
disconnectedCallback() {
|
|
244
|
+
// A settle timer that outlives the element still runs _select on it, which
|
|
245
|
+
// dispatches input and change from something no longer in the document.
|
|
246
|
+
clearTimeout(this._scrollTimers.hours);
|
|
247
|
+
clearTimeout(this._scrollTimers.minutes);
|
|
248
|
+
clearTimeout(this._selfScrollTimer);
|
|
249
|
+
super.disconnectedCallback();
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Scrolling is choosing: whatever comes to rest in the middle is the value.
|
|
253
|
+
* There is a `scrollend` event, but not everywhere, so this waits until
|
|
254
|
+
* scrolling has been still for 120ms. Short enough to feel immediate, long
|
|
255
|
+
* enough not to pick halfway through a swipe.
|
|
256
|
+
*/
|
|
257
|
+
_handleScroll(e, column) {
|
|
258
|
+
if (this._scrollingSelf)
|
|
259
|
+
return;
|
|
260
|
+
// Clearing the timers on disconnect is not enough on its own: a scroll event
|
|
261
|
+
// the browser had already queued still arrives afterwards and would set a
|
|
262
|
+
// fresh one on an element that is no longer in the document.
|
|
263
|
+
if (!this.isConnected)
|
|
264
|
+
return;
|
|
265
|
+
const el = e.currentTarget;
|
|
266
|
+
// The selection follows every movement, the value only records once at rest.
|
|
267
|
+
const centered = this._centeredOption(el);
|
|
268
|
+
if (centered !== null)
|
|
269
|
+
this._scrolledTo = { ...this._scrolledTo, [column]: centered };
|
|
270
|
+
// As an attribute and not as reactive state: this happens every scroll
|
|
271
|
+
// frame, and re-rendering eighty values per frame is a waste.
|
|
272
|
+
this.toggleAttribute('data-scrolling', true);
|
|
273
|
+
clearTimeout(this._scrollTimers[column]);
|
|
274
|
+
this._scrollTimers[column] = window.setTimeout(() => {
|
|
275
|
+
this._selectCentred(column, el);
|
|
276
|
+
this.toggleAttribute('data-scrolling', false);
|
|
277
|
+
}, 120);
|
|
278
|
+
}
|
|
279
|
+
/** The number of the option closest to the middle of the column. */
|
|
280
|
+
_centeredOption(el) {
|
|
281
|
+
const centre = el.scrollTop + el.clientHeight / 2;
|
|
282
|
+
let best = null;
|
|
283
|
+
let bestDistance = Infinity;
|
|
284
|
+
for (const option of el.querySelectorAll('.time-picker__list-item')) {
|
|
285
|
+
const distance = Math.abs(option.offsetTop + option.offsetHeight / 2 - centre);
|
|
286
|
+
if (distance < bestDistance) {
|
|
287
|
+
bestDistance = distance;
|
|
288
|
+
best = option;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return best === null ? null : Number(best.textContent);
|
|
292
|
+
}
|
|
293
|
+
/** Records whatever came to rest in the middle. */
|
|
294
|
+
_selectCentred(column, el) {
|
|
295
|
+
const centered = this._centeredOption(el);
|
|
296
|
+
if (centered !== null)
|
|
297
|
+
this._select(column, centered);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Put the chosen value in the middle of the view. The column is seven values
|
|
301
|
+
* tall, so `center` lands it on the fourth row with three above and three
|
|
302
|
+
* below.
|
|
303
|
+
*
|
|
304
|
+
* Public because a hidden element cannot be scrolled: with the picker in a
|
|
305
|
+
* popover it has no dimensions yet when the value is set, and scrollIntoView
|
|
306
|
+
* does nothing. The field therefore calls this as soon as the popover
|
|
307
|
+
* opens.
|
|
308
|
+
*/
|
|
309
|
+
scrollSelectedIntoView() {
|
|
310
|
+
this._scrollingSelf = true;
|
|
311
|
+
for (const name of ['hours', 'minutes']) {
|
|
312
|
+
const column = this.shadowRoot?.querySelector(`[data-column="${name}"]`);
|
|
313
|
+
const option = column?.querySelector('[data-selected]');
|
|
314
|
+
if (!column || !option)
|
|
315
|
+
continue;
|
|
316
|
+
// Doing the math ourselves instead of scrollIntoView: that negotiates with
|
|
317
|
+
// the snap points and with every scrollable ancestor, and does so
|
|
318
|
+
// differently per browser. This is the exact inverse of _centeredOption, so
|
|
319
|
+
// what we put down is also what we read back later.
|
|
320
|
+
column.scrollTop = option.offsetTop + option.offsetHeight / 2 - column.clientHeight / 2;
|
|
321
|
+
}
|
|
322
|
+
// A little longer than the debounce above, so the scroll events from this
|
|
323
|
+
// movement have all been ignored before we listen again.
|
|
324
|
+
this._selfScrollTimer = window.setTimeout(() => { this._scrollingSelf = false; }, 200);
|
|
325
|
+
}
|
|
326
|
+
updated(changed) {
|
|
327
|
+
if (changed.has('rows')) {
|
|
328
|
+
// Odd or even makes no difference: the chosen value is centered, so with
|
|
329
|
+
// an odd count you see whole rows and with an even one half a row runs off
|
|
330
|
+
// the top and bottom. At least 3, because with 1 you only see the chosen
|
|
331
|
+
// value and there is nothing to scroll.
|
|
332
|
+
this.style.setProperty('--_rows', String(Math.max(3, Math.round(this.rows))));
|
|
333
|
+
}
|
|
334
|
+
if (changed.has('width')) {
|
|
335
|
+
const w = this.width;
|
|
336
|
+
if (w === 'full')
|
|
337
|
+
this.style.setProperty('--_width', '100%');
|
|
338
|
+
else if (w && CSS.supports('width', w))
|
|
339
|
+
this.style.setProperty('--_width', w);
|
|
340
|
+
else
|
|
341
|
+
this.style.removeProperty('--_width');
|
|
342
|
+
}
|
|
343
|
+
if (changed.has('value') || changed.has('min') || changed.has('max') || changed.has('step')) {
|
|
344
|
+
// The selection follows the value again: it was just set from outside or
|
|
345
|
+
// recorded, and in both cases it lines up with the middle.
|
|
346
|
+
this._scrolledTo = { hours: null, minutes: null };
|
|
347
|
+
this.scrollSelectedIntoView();
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
render() {
|
|
351
|
+
return timePickerTemplate(this);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
NLDDTimePicker.styles = timePickerStyles;
|
|
355
|
+
__decorate([
|
|
356
|
+
property({ type: String })
|
|
357
|
+
], NLDDTimePicker.prototype, "value", void 0);
|
|
358
|
+
__decorate([
|
|
359
|
+
property({ type: String })
|
|
360
|
+
], NLDDTimePicker.prototype, "min", void 0);
|
|
361
|
+
__decorate([
|
|
362
|
+
property({ type: String })
|
|
363
|
+
], NLDDTimePicker.prototype, "max", void 0);
|
|
364
|
+
__decorate([
|
|
365
|
+
property({ type: Number })
|
|
366
|
+
], NLDDTimePicker.prototype, "step", void 0);
|
|
367
|
+
__decorate([
|
|
368
|
+
property({ type: Number, reflect: true })
|
|
369
|
+
], NLDDTimePicker.prototype, "rows", void 0);
|
|
370
|
+
__decorate([
|
|
371
|
+
property({ type: String, reflect: true })
|
|
372
|
+
], NLDDTimePicker.prototype, "width", void 0);
|
|
373
|
+
__decorate([
|
|
374
|
+
property({ type: String, attribute: 'accessible-label' })
|
|
375
|
+
], NLDDTimePicker.prototype, "accessibleLabel", void 0);
|
|
376
|
+
__decorate([
|
|
377
|
+
property({ type: Object })
|
|
378
|
+
], NLDDTimePicker.prototype, "translations", void 0);
|
|
379
|
+
__decorate([
|
|
380
|
+
state()
|
|
381
|
+
], NLDDTimePicker.prototype, "_scrolledTo", void 0);
|
|
382
|
+
NLDDTimePicker = __decorate([
|
|
383
|
+
customElement('nldd-time-picker')
|
|
384
|
+
], NLDDTimePicker);
|
|
385
|
+
export { NLDDTimePicker };
|
|
386
|
+
//# sourceMappingURL=time-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time-picker.js","sourceRoot":"","sources":["../../../../src/components/inputs/time-picker/time-picker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time-picker.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/inputs/time-picker/time-picker.styles.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,yBAmL5B,CAAC"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
import { inheritedTextReset } from '../../../assets/styles/shadow-resets.js';
|
|
3
|
+
export const timePickerStyles = css `
|
|
4
|
+
:host {
|
|
5
|
+
box-sizing: border-box;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/* # Host */
|
|
10
|
+
|
|
11
|
+
:host {
|
|
12
|
+
--_control-min-size: var(--semantics-controls-md-min-size);
|
|
13
|
+
--_control-corner-radius: var(--semantics-controls-md-corner-radius);
|
|
14
|
+
--_list-item-font: var(--primitives-font-body-md-medium-flat);
|
|
15
|
+
--_list-item-is-hovered-background-color: light-dark(var(--primitives-color-neutral-100), var(--primitives-color-neutral-150));
|
|
16
|
+
--_selection-background-color: var(--semantics-controls-is-highlighted-indicator-color);
|
|
17
|
+
--_selection-content-color: var(--semantics-controls-is-highlighted-contrast-color);
|
|
18
|
+
--_list-width: calc(var(--_control-min-size) * 1.5);
|
|
19
|
+
--_rows: 7;
|
|
20
|
+
--_list-height: calc(var(--_control-min-size) * var(--_rows));
|
|
21
|
+
--_list-gap: var(--primitives-space-4);
|
|
22
|
+
/* initial keeps it guaranteed-invalid, so width lands on auto as long as
|
|
23
|
+
the attribute sets nothing. */
|
|
24
|
+
--_width: initial;
|
|
25
|
+
|
|
26
|
+
@media (pointer: fine) {
|
|
27
|
+
--_control-min-size: var(--semantics-controls-sm-min-size);
|
|
28
|
+
--_control-corner-radius: var(--semantics-controls-sm-corner-radius);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
${inheritedTextReset}
|
|
32
|
+
display: inline-block;
|
|
33
|
+
width: var(--_width);
|
|
34
|
+
max-width: 100%;
|
|
35
|
+
font: var(--_list-item-font);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
:host([hidden]) {
|
|
39
|
+
display: none;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
/* # Block */
|
|
44
|
+
|
|
45
|
+
.time-picker {
|
|
46
|
+
display: flex;
|
|
47
|
+
position: relative;
|
|
48
|
+
height: var(--_list-height);
|
|
49
|
+
gap: var(--_list-gap);
|
|
50
|
+
align-items: stretch;
|
|
51
|
+
justify-content: center;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
/* # Lists */
|
|
56
|
+
|
|
57
|
+
.time-picker__list {
|
|
58
|
+
display: flex;
|
|
59
|
+
width: var(--_list-width);
|
|
60
|
+
overflow-y: auto;
|
|
61
|
+
flex-direction: column;
|
|
62
|
+
flex-grow: 1;
|
|
63
|
+
flex-shrink: 1;
|
|
64
|
+
/* Without this the values of a short list stretch to the full height. */
|
|
65
|
+
justify-content: flex-start;
|
|
66
|
+
scrollbar-width: none;
|
|
67
|
+
/* Not mandatory: then the browser always has to land on a snap point, and a
|
|
68
|
+
short list can refuse to scroll. */
|
|
69
|
+
scroll-snap-type: y proximity;
|
|
70
|
+
mask-image: linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.time-picker__list::-webkit-scrollbar {
|
|
74
|
+
display: none;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Room for the first and last value to reach the middle. As empty boxes and
|
|
78
|
+
not as padding-block: Safari does not count the bottom padding of a scroll
|
|
79
|
+
container towards the scrollable overflow, and on a short list that wipes
|
|
80
|
+
out all overflow. */
|
|
81
|
+
.time-picker__list::before,
|
|
82
|
+
.time-picker__list::after {
|
|
83
|
+
content: '';
|
|
84
|
+
display: block;
|
|
85
|
+
flex-shrink: 0;
|
|
86
|
+
height: calc((var(--_list-height) - var(--_control-min-size)) / 2);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.time-picker__list-item {
|
|
90
|
+
box-sizing: border-box;
|
|
91
|
+
display: flex;
|
|
92
|
+
border-radius: var(--_control-corner-radius);
|
|
93
|
+
min-height: var(--_control-min-size);
|
|
94
|
+
flex-shrink: 0;
|
|
95
|
+
align-items: center;
|
|
96
|
+
justify-content: center;
|
|
97
|
+
color: var(--semantics-content-color);
|
|
98
|
+
font: var(--_list-item-font);
|
|
99
|
+
font-variant-numeric: tabular-nums;
|
|
100
|
+
scroll-snap-align: center;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.time-picker__list-item:hover {
|
|
104
|
+
background-color: var(--_list-item-is-hovered-background-color);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* While scrolling, the values slide past under a stationary cursor and a
|
|
108
|
+
different one would light up every time. A tap halfway through a swipe
|
|
109
|
+
should also stop the scroll, not pick a value.
|
|
110
|
+
Turning the background off separately: pointer-events only holds off new
|
|
111
|
+
hover, and a :hover already in place stays until the browser redoes the
|
|
112
|
+
hit test. */
|
|
113
|
+
:host([data-scrolling]) .time-picker__list-item {
|
|
114
|
+
pointer-events: none;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
:host([data-scrolling]) .time-picker__list-item:hover {
|
|
118
|
+
background-color: transparent;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.time-picker__gap {
|
|
122
|
+
flex-shrink: 0;
|
|
123
|
+
width: 1ch;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
/* # Selection */
|
|
128
|
+
|
|
129
|
+
/* The lists have a mask-image and therefore their own stacking context, and
|
|
130
|
+
they come after this in the DOM: without z-index their digits paint over
|
|
131
|
+
it. */
|
|
132
|
+
.time-picker__selection {
|
|
133
|
+
display: flex;
|
|
134
|
+
z-index: 1;
|
|
135
|
+
position: absolute;
|
|
136
|
+
top: 50%;
|
|
137
|
+
right: 0;
|
|
138
|
+
left: 0;
|
|
139
|
+
border-radius: var(--_control-corner-radius);
|
|
140
|
+
background-color: var(--_selection-background-color);
|
|
141
|
+
/* Otherwise this surface catches the swipe meant to scroll the list beneath
|
|
142
|
+
it, exactly where you put the mouse down. */
|
|
143
|
+
pointer-events: none;
|
|
144
|
+
height: var(--_control-min-size);
|
|
145
|
+
gap: var(--_list-gap);
|
|
146
|
+
align-items: center;
|
|
147
|
+
color: var(--_selection-content-color);
|
|
148
|
+
font-variant-numeric: tabular-nums;
|
|
149
|
+
transform: translateY(-50%);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.time-picker__value {
|
|
153
|
+
display: flex;
|
|
154
|
+
outline: none;
|
|
155
|
+
border-radius: var(--_control-corner-radius);
|
|
156
|
+
width: var(--_list-width);
|
|
157
|
+
height: 100%;
|
|
158
|
+
flex-grow: 1;
|
|
159
|
+
flex-shrink: 1;
|
|
160
|
+
align-items: center;
|
|
161
|
+
justify-content: center;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.time-picker__value:focus-visible {
|
|
165
|
+
outline: var(--semantics-focus-ring-outline);
|
|
166
|
+
outline-offset: var(--semantics-focus-ring-outline-offset);
|
|
167
|
+
box-shadow: var(--semantics-focus-ring-box-shadow);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.time-picker__value-separator {
|
|
171
|
+
flex-shrink: 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
/* # High Contrast */
|
|
176
|
+
|
|
177
|
+
@media (forced-colors: active) {
|
|
178
|
+
.time-picker__selection {
|
|
179
|
+
outline: 2px solid CanvasText;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
`;
|
|
183
|
+
//# sourceMappingURL=time-picker.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time-picker.styles.js","sourceRoot":"","sources":["../../../../src/components/inputs/time-picker/time-picker.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAE7E,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4B/B,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuJrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time-picker.template.d.ts","sourceRoot":"","sources":["../../../../src/components/inputs/time-picker/time-picker.template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,cAAc,EAAE,MAAM,KAAK,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AA8EvD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,cAAc,GAAG,cAAc,CAgC5E"}
|