@nectary/components 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/accordion-item/types.d.ts +0 -2
  2. package/action-menu/index.js +40 -18
  3. package/action-menu/types.d.ts +3 -0
  4. package/action-menu-option/index.js +22 -14
  5. package/action-menu-option/types.d.ts +0 -2
  6. package/alert-button/types.d.ts +0 -2
  7. package/alert-close/types.d.ts +1 -4
  8. package/button/types.d.ts +0 -2
  9. package/card-button/types.d.ts +0 -2
  10. package/card-link/types.d.ts +0 -2
  11. package/checkbox/types.d.ts +0 -2
  12. package/date-picker/index.js +1 -1
  13. package/date-picker/types.d.ts +16 -1
  14. package/dialog/index.js +47 -40
  15. package/dialog/types.d.ts +2 -0
  16. package/dropdown/index.js +11 -13
  17. package/dropdown/types.d.ts +0 -2
  18. package/icon-button/index.js +1 -1
  19. package/icon-button/types.d.ts +0 -2
  20. package/input/index.js +111 -26
  21. package/input/types.d.ts +0 -2
  22. package/link/index.d.ts +1 -1
  23. package/link/index.js +1 -1
  24. package/package.json +1 -1
  25. package/pagination/types.d.ts +0 -2
  26. package/popover/index.js +127 -33
  27. package/popover/types.d.ts +17 -2
  28. package/popover/utils.js +1 -1
  29. package/radio-option/types.d.ts +0 -2
  30. package/search/types.d.ts +0 -2
  31. package/segment/index.js +30 -3
  32. package/segment-collapse/types.d.ts +0 -2
  33. package/segmented-control-option/index.js +1 -1
  34. package/segmented-control-option/types.d.ts +0 -2
  35. package/segmented-icon-control-option/types.d.ts +0 -2
  36. package/select/index.js +1 -1
  37. package/select/types.d.ts +0 -2
  38. package/tabs-option/types.d.ts +0 -2
  39. package/tag-close/types.d.ts +1 -4
  40. package/text/index.js +1 -3
  41. package/textarea/index.js +36 -28
  42. package/textarea/types.d.ts +0 -2
  43. package/time-picker/index.d.ts +17 -0
  44. package/time-picker/index.js +525 -0
  45. package/time-picker/types.d.ts +31 -0
  46. package/time-picker/types.js +1 -0
  47. package/time-picker/utils.d.ts +11 -0
  48. package/time-picker/utils.js +94 -0
  49. package/toggle/types.d.ts +0 -2
  50. package/utils.js +1 -1
@@ -0,0 +1,525 @@
1
+ import _classPrivateFieldGet from '@babel/runtime/helpers/classPrivateFieldGet';
2
+ import _classPrivateFieldSet from '@babel/runtime/helpers/classPrivateFieldSet';
3
+
4
+ var _$pickerHours, _$pickerMinutes, _$pickerTouch, _$needleHour, _$needleMinute, _$headerHours, _$headerHoursText, _$headerMinutes, _$headerMinutesText, _$ampm, _$submitButton, _hour, _minute, _getClickDegree, _onPickerClick, _render, _selectHour, _selectMinute, _onAmPmChange, _onSubmitButtonClick, _onHoursKeydown, _onMinutesKeydown;
5
+
6
+ function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
7
+
8
+ function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
9
+
10
+ function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
11
+
12
+ function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
13
+
14
+ import '../icon-button';
15
+ import '../icons/done';
16
+ import '../icons/arrow-drop-up';
17
+ import '../icons/arrow-drop-down';
18
+ import '../segmented-control';
19
+ import '../segmented-control-option';
20
+ import { defineCustomElement, getAttribute, getBooleanAttribute, getRect, isAttrTrue, NectaryElement, setClass, updateAttribute, updateBooleanAttribute } from '../utils';
21
+ const templateHTML = '<style>:host{display:block;outline:0}#wrapper{display:flex;flex-direction:column;width:248px;padding:16px;box-sizing:border-box;gap:16px}#header{position:relative;width:100%;height:48px;font:var(--sinch-font-title-xl);line-height:48px}#footer{display:flex;justify-content:center;width:100%;height:32px}#picker{position:relative;width:216px;height:216px;border-radius:50%;box-sizing:border-box;border:1px solid var(--sinch-color-stormy-500)}#digit-minutes,#picker-hours{position:absolute;left:0;top:0;width:100%;height:100%;border-radius:50%}.digit-hour-12,.digit-hour-24,.digit-minute{position:absolute;width:28px;height:28px;font:var(--sinch-font-text-s);line-height:28px;text-align:center;color:var(--sinch-color-text-default);top:calc(50% - 14px);left:calc(50% - 14px);z-index:1;cursor:pointer}.digit-hour-24{font:var(--sinch-font-text-xs);line-height:28px;color:var(--sinch-color-text-muted)}.digit-minute{font:var(--sinch-font-text-xs);line-height:28px;color:var(--sinch-color-text-muted)}.digit-hour-12:hover,.digit-hour-24:hover,.digit-minute:hover{color:var(--sinch-color-tropical-500)}.digit-hour-12.selected,.digit-hour-24.selected,.digit-minute.selected{color:var(--sinch-color-tropical-500)}.digit-hour-12.selected{font-size:16px}.digit-hour-24.selected{font-size:16px}.digit-minute.selected{font-size:16px}#picker-touch{position:absolute;left:0;top:0;width:100%;height:100%;cursor:pointer;border-radius:50%}#needle-hour,#needle-minute,#picker-touch::after{background-color:var(--sinch-color-stormy-500)}#needle-hour,#needle-minute{position:absolute;transform-origin:bottom center;transform:rotate(0);bottom:50%;height:50px;transition-duration:.25s;transition-timing-function:ease-in-out;transition-property:transform height;z-index:2}@media (prefers-reduced-motion){#needle-hour,#needle-minute{transition:none}}#needle-hour{width:4px;left:calc(50% - 2px);border-radius:2px}#needle-minute{width:2px;left:calc(50% - 1px);border-radius:1px}#needle-minute:not(.selected)::after{content:"";position:absolute;transform:translateX(-50%);left:0;top:-16px;width:4px;height:4px;border-radius:50%;background-color:var(--sinch-color-tropical-500)}#picker-touch::after{content:"";position:absolute;top:50%;left:50%;width:12px;height:12px;border-radius:50%;transform:translate(-50%,-50%)}#header-hours,#header-minutes{position:absolute;padding:0 4px;width:50px;outline:0;--sinch-icon-size:24px}#header-hours{right:calc(50% + 8px);text-align:right}#header-minutes{left:calc(50% + 8px)}#header-hours::before,#header-minutes::before{content:"";display:none;position:absolute;border-radius:12px;left:50%;top:50%;width:100%;height:100%;transform:translate(-50%,-50%);padding:1px;border:1px solid var(--sinch-color-aqua-400)}#header-hours-down,#header-hours-up,#header-minutes-down,#header-minutes-up{display:none;position:absolute;left:50%;transform:translateX(-50%)}#header-hours-up,#header-minutes-up{top:-18px}#header-hours-down,#header-minutes-down{bottom:-18px}#header-hours:focus #header-hours-down,#header-hours:focus #header-hours-up,#header-hours:focus::before{display:block}#header-minutes:focus #header-minutes-down,#header-minutes:focus #header-minutes-up,#header-minutes:focus::before{display:block}#header-colon{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)}#submit{position:absolute;right:0;top:50%;transform:translateY(-50%)}:host([ampm]) .digit-hour-24{display:none}:host(:not([ampm])) #footer{display:none}</style><div id="wrapper"><div id="header"><div id="header-hours" tabindex="0" role="meter" aria-valuemin="0" aria-valuemax="23" aria-valuenow="0" aria-valuetext="0"><span>00</span><sinch-icon-arrow-drop-up id="header-hours-up"></sinch-icon-arrow-drop-up><sinch-icon-arrow-drop-down id="header-hours-down"></sinch-icon-arrow-drop-down></div><div id="header-colon">&colon;</div><div id="header-minutes" tabindex="0" role="meter" aria-valuemin="0" aria-valuemax="59" aria-valuenow="0" aria-valuetext="0"><span>00</span><sinch-icon-arrow-drop-up id="header-minutes-up"></sinch-icon-arrow-drop-up><sinch-icon-arrow-drop-down id="header-minutes-down"></sinch-icon-arrow-drop-down></div><sinch-icon-button id="submit" small aria-label="Submit"><sinch-icon-done slot="icon"></sinch-icon-done></sinch-icon-button></div><div id="picker" aria-hidden="true"><div id="picker-hours"></div><div id="picker-minutes"></div><div id="picker-touch"><div id="needle-hour"></div><div id="needle-minute"></div></div></div><div id="footer"><sinch-segmented-control id="ampm"><sinch-segmented-control-option value="am" text="AM" aria-label="AM"></sinch-segmented-control-option><sinch-segmented-control-option value="pm" text="PM" aria-label="PM"></sinch-segmented-control-option></sinch-segmented-control></div></div>';
22
+ import { getNeedleRotationDeg, getShortestCssDeg, hourToIndex, parseTime, stringifyHour, stringifyHourFace, stringifyMinute, stringifyTime } from './utils';
23
+ const template = document.createElement('template');
24
+ template.innerHTML = templateHTML;
25
+ const PICKER_RADIUS = 216 / 2;
26
+ const MINUTE_DIGIT_SIZE = 30;
27
+ const HOUR_12_DIGIT_SIZE = 26;
28
+ const HOUR_24_DIGIT_SIZE = 26;
29
+ const MINUTE_RADIUS = PICKER_RADIUS - MINUTE_DIGIT_SIZE;
30
+ const HOUR_12_RADIUS = MINUTE_RADIUS - HOUR_12_DIGIT_SIZE;
31
+ const HOUR_24_RADIUS = HOUR_12_RADIUS - HOUR_24_DIGIT_SIZE;
32
+ const NEEDLE_HOUR_12_LENGTH = HOUR_12_RADIUS;
33
+ const NEEDLE_HOUR_24_LENGTH = HOUR_24_RADIUS;
34
+ const NEEDLE_MINUTE_LENGTH = MINUTE_RADIUS;
35
+ defineCustomElement('sinch-time-picker', (_$pickerHours = new WeakMap(), _$pickerMinutes = new WeakMap(), _$pickerTouch = new WeakMap(), _$needleHour = new WeakMap(), _$needleMinute = new WeakMap(), _$headerHours = new WeakMap(), _$headerHoursText = new WeakMap(), _$headerMinutes = new WeakMap(), _$headerMinutesText = new WeakMap(), _$ampm = new WeakMap(), _$submitButton = new WeakMap(), _hour = new WeakMap(), _minute = new WeakMap(), _getClickDegree = new WeakSet(), _onPickerClick = new WeakMap(), _render = new WeakSet(), _selectHour = new WeakSet(), _selectMinute = new WeakSet(), _onAmPmChange = new WeakMap(), _onSubmitButtonClick = new WeakMap(), _onHoursKeydown = new WeakMap(), _onMinutesKeydown = new WeakMap(), class extends NectaryElement {
36
+ constructor() {
37
+ super();
38
+
39
+ _classPrivateMethodInitSpec(this, _selectMinute);
40
+
41
+ _classPrivateMethodInitSpec(this, _selectHour);
42
+
43
+ _classPrivateMethodInitSpec(this, _render);
44
+
45
+ _classPrivateMethodInitSpec(this, _getClickDegree);
46
+
47
+ _classPrivateFieldInitSpec(this, _$pickerHours, {
48
+ writable: true,
49
+ value: void 0
50
+ });
51
+
52
+ _classPrivateFieldInitSpec(this, _$pickerMinutes, {
53
+ writable: true,
54
+ value: void 0
55
+ });
56
+
57
+ _classPrivateFieldInitSpec(this, _$pickerTouch, {
58
+ writable: true,
59
+ value: void 0
60
+ });
61
+
62
+ _classPrivateFieldInitSpec(this, _$needleHour, {
63
+ writable: true,
64
+ value: void 0
65
+ });
66
+
67
+ _classPrivateFieldInitSpec(this, _$needleMinute, {
68
+ writable: true,
69
+ value: void 0
70
+ });
71
+
72
+ _classPrivateFieldInitSpec(this, _$headerHours, {
73
+ writable: true,
74
+ value: void 0
75
+ });
76
+
77
+ _classPrivateFieldInitSpec(this, _$headerHoursText, {
78
+ writable: true,
79
+ value: void 0
80
+ });
81
+
82
+ _classPrivateFieldInitSpec(this, _$headerMinutes, {
83
+ writable: true,
84
+ value: void 0
85
+ });
86
+
87
+ _classPrivateFieldInitSpec(this, _$headerMinutesText, {
88
+ writable: true,
89
+ value: void 0
90
+ });
91
+
92
+ _classPrivateFieldInitSpec(this, _$ampm, {
93
+ writable: true,
94
+ value: void 0
95
+ });
96
+
97
+ _classPrivateFieldInitSpec(this, _$submitButton, {
98
+ writable: true,
99
+ value: void 0
100
+ });
101
+
102
+ _classPrivateFieldInitSpec(this, _hour, {
103
+ writable: true,
104
+ value: 0
105
+ });
106
+
107
+ _classPrivateFieldInitSpec(this, _minute, {
108
+ writable: true,
109
+ value: 0
110
+ });
111
+
112
+ _classPrivateFieldInitSpec(this, _onPickerClick, {
113
+ writable: true,
114
+ value: e => {
115
+ const [cssDeg, rowIndex] = _classPrivateMethodGet(this, _getClickDegree, _getClickDegree2).call(this, e.x, e.y);
116
+
117
+ const isHourRowClick = rowIndex > 0;
118
+ const isHour24RowClick = rowIndex > 1;
119
+
120
+ if (isHourRowClick) {
121
+ const digitIndex = Math.round(cssDeg / 30) % 12;
122
+ const is24 = getBooleanAttribute(this, 'ampm') === false;
123
+
124
+ if (is24) {
125
+ if (isHour24RowClick) {
126
+ _classPrivateFieldSet(this, _hour, digitIndex === 0 ? 0 : digitIndex + 12);
127
+ } else {
128
+ _classPrivateFieldSet(this, _hour, digitIndex === 0 ? 12 : digitIndex);
129
+ }
130
+ } else {
131
+ _classPrivateFieldSet(this, _hour, digitIndex + (_classPrivateFieldGet(this, _$ampm).value === 'pm' ? 12 : 0));
132
+ }
133
+
134
+ _classPrivateFieldGet(this, _$headerHours).focus();
135
+ } else {
136
+ _classPrivateFieldSet(this, _minute, Math.round(cssDeg / 6) % 60);
137
+
138
+ _classPrivateFieldGet(this, _$headerMinutes).focus();
139
+ }
140
+
141
+ _classPrivateMethodGet(this, _render, _render2).call(this);
142
+ }
143
+ });
144
+
145
+ _classPrivateFieldInitSpec(this, _onAmPmChange, {
146
+ writable: true,
147
+ value: e => {
148
+ e.stopPropagation();
149
+ const value = e.detail;
150
+
151
+ switch (value) {
152
+ case 'am':
153
+ {
154
+ if (_classPrivateFieldGet(this, _hour) >= 12) {
155
+ _classPrivateFieldSet(this, _hour, _classPrivateFieldGet(this, _hour) - 12);
156
+
157
+ _classPrivateMethodGet(this, _render, _render2).call(this);
158
+ }
159
+
160
+ break;
161
+ }
162
+
163
+ case 'pm':
164
+ {
165
+ if (_classPrivateFieldGet(this, _hour) < 12) {
166
+ _classPrivateFieldSet(this, _hour, _classPrivateFieldGet(this, _hour) + 12);
167
+
168
+ _classPrivateMethodGet(this, _render, _render2).call(this);
169
+ }
170
+
171
+ break;
172
+ }
173
+ }
174
+ }
175
+ });
176
+
177
+ _classPrivateFieldInitSpec(this, _onSubmitButtonClick, {
178
+ writable: true,
179
+ value: () => {
180
+ const value = stringifyTime(_classPrivateFieldGet(this, _hour), _classPrivateFieldGet(this, _minute));
181
+ this.dispatchEvent(new CustomEvent('change', {
182
+ bubbles: true,
183
+ detail: value
184
+ }));
185
+ }
186
+ });
187
+
188
+ _classPrivateFieldInitSpec(this, _onHoursKeydown, {
189
+ writable: true,
190
+ value: e => {
191
+ switch (e.key) {
192
+ case 'ArrowUp':
193
+ {
194
+ _classPrivateFieldSet(this, _hour, (_classPrivateFieldGet(this, _hour) + 1) % 24);
195
+
196
+ _classPrivateMethodGet(this, _render, _render2).call(this);
197
+
198
+ break;
199
+ }
200
+
201
+ case 'ArrowDown':
202
+ {
203
+ _classPrivateFieldSet(this, _hour, (_classPrivateFieldGet(this, _hour) + 23) % 24);
204
+
205
+ _classPrivateMethodGet(this, _render, _render2).call(this);
206
+
207
+ break;
208
+ }
209
+ }
210
+ }
211
+ });
212
+
213
+ _classPrivateFieldInitSpec(this, _onMinutesKeydown, {
214
+ writable: true,
215
+ value: e => {
216
+ switch (e.key) {
217
+ case 'ArrowUp':
218
+ {
219
+ _classPrivateFieldSet(this, _minute, (_classPrivateFieldGet(this, _minute) + 1) % 60);
220
+
221
+ _classPrivateMethodGet(this, _render, _render2).call(this);
222
+
223
+ break;
224
+ }
225
+
226
+ case 'ArrowDown':
227
+ {
228
+ _classPrivateFieldSet(this, _minute, (_classPrivateFieldGet(this, _minute) + 59) % 60);
229
+
230
+ _classPrivateMethodGet(this, _render, _render2).call(this);
231
+
232
+ break;
233
+ }
234
+ }
235
+ }
236
+ });
237
+
238
+ const shadowRoot = this.attachShadow();
239
+ shadowRoot.appendChild(template.content.cloneNode(true));
240
+
241
+ _classPrivateFieldSet(this, _$pickerHours, shadowRoot.querySelector('#picker-hours'));
242
+
243
+ _classPrivateFieldSet(this, _$pickerMinutes, shadowRoot.querySelector('#picker-minutes'));
244
+
245
+ _classPrivateFieldSet(this, _$pickerTouch, shadowRoot.querySelector('#picker'));
246
+
247
+ _classPrivateFieldSet(this, _$needleHour, shadowRoot.querySelector('#needle-hour'));
248
+
249
+ _classPrivateFieldSet(this, _$needleMinute, shadowRoot.querySelector('#needle-minute'));
250
+
251
+ _classPrivateFieldSet(this, _$headerHours, shadowRoot.querySelector('#header-hours'));
252
+
253
+ _classPrivateFieldSet(this, _$headerMinutes, shadowRoot.querySelector('#header-minutes'));
254
+
255
+ _classPrivateFieldSet(this, _$headerHoursText, shadowRoot.querySelector('#header-hours > span'));
256
+
257
+ _classPrivateFieldSet(this, _$headerMinutesText, shadowRoot.querySelector('#header-minutes > span'));
258
+
259
+ _classPrivateFieldSet(this, _$ampm, shadowRoot.querySelector('#ampm'));
260
+
261
+ _classPrivateFieldSet(this, _$submitButton, shadowRoot.querySelector('#submit'));
262
+
263
+ _classPrivateFieldGet(this, _$needleMinute).style.height = `${NEEDLE_MINUTE_LENGTH}px`;
264
+ _classPrivateFieldGet(this, _$needleHour).style.height = `${NEEDLE_HOUR_12_LENGTH}px`;
265
+ const MINUTE_DIGIT_RADIUS = MINUTE_RADIUS + MINUTE_DIGIT_SIZE / 2;
266
+ const HOUR_12_DIGIT_RADIUS = HOUR_12_RADIUS + HOUR_12_DIGIT_SIZE / 2;
267
+ const HOUR_24_DIGIT_RADIUS = HOUR_24_RADIUS + HOUR_24_DIGIT_SIZE / 2;
268
+ const hours12Frag = document.createDocumentFragment();
269
+
270
+ for (let i = 0; i < 12; i++) {
271
+ const rad = Math.PI / 6 * (i - 3);
272
+ const el = document.createElement('div');
273
+ const x = Math.cos(rad) * HOUR_12_DIGIT_RADIUS;
274
+ const y = Math.sin(rad) * HOUR_12_DIGIT_RADIUS;
275
+ const hourDisplayValue = stringifyHourFace(i);
276
+ el.className = 'digit-hour-12';
277
+ el.style.transform = `translate(${x}px, ${y}px)`;
278
+ el.textContent = hourDisplayValue;
279
+ hours12Frag.appendChild(el);
280
+ }
281
+
282
+ _classPrivateFieldGet(this, _$pickerHours).appendChild(hours12Frag);
283
+
284
+ const hours24Frag = document.createDocumentFragment();
285
+
286
+ for (let i = 12; i < 24; i++) {
287
+ const rad = Math.PI / 6 * (i - 3);
288
+ const el = document.createElement('div');
289
+ const x = Math.cos(rad) * HOUR_24_DIGIT_RADIUS;
290
+ const y = Math.sin(rad) * HOUR_24_DIGIT_RADIUS;
291
+ const hourDisplayValue = stringifyHourFace(i);
292
+ el.className = 'digit-hour-24';
293
+ el.style.transform = `translate(${x}px, ${y}px)`;
294
+ el.textContent = hourDisplayValue;
295
+ hours24Frag.appendChild(el);
296
+ }
297
+
298
+ _classPrivateFieldGet(this, _$pickerHours).appendChild(hours24Frag);
299
+
300
+ const minutesFrag = document.createDocumentFragment();
301
+
302
+ for (let i = 0; i < 60; i += 5) {
303
+ const rad = Math.PI / 30 * (i - 15);
304
+ const el = document.createElement('div');
305
+ const x = Math.cos(rad) * MINUTE_DIGIT_RADIUS;
306
+ const y = Math.sin(rad) * MINUTE_DIGIT_RADIUS;
307
+ el.className = 'digit-minute';
308
+ el.style.transform = `translate(${x}px, ${y}px)`;
309
+ el.textContent = stringifyMinute(i);
310
+ minutesFrag.appendChild(el);
311
+ }
312
+
313
+ _classPrivateFieldGet(this, _$pickerMinutes).appendChild(minutesFrag);
314
+ }
315
+
316
+ connectedCallback() {
317
+ _classPrivateFieldGet(this, _$pickerTouch).addEventListener('click', _classPrivateFieldGet(this, _onPickerClick));
318
+
319
+ _classPrivateFieldGet(this, _$ampm).addEventListener('change', _classPrivateFieldGet(this, _onAmPmChange));
320
+
321
+ _classPrivateFieldGet(this, _$submitButton).addEventListener('click', _classPrivateFieldGet(this, _onSubmitButtonClick));
322
+
323
+ _classPrivateFieldGet(this, _$headerHours).addEventListener('keydown', _classPrivateFieldGet(this, _onHoursKeydown));
324
+
325
+ _classPrivateFieldGet(this, _$headerMinutes).addEventListener('keydown', _classPrivateFieldGet(this, _onMinutesKeydown));
326
+ }
327
+
328
+ disconnectedCallback() {
329
+ _classPrivateFieldGet(this, _$pickerTouch).removeEventListener('click', _classPrivateFieldGet(this, _onPickerClick));
330
+
331
+ _classPrivateFieldGet(this, _$ampm).removeEventListener('change', _classPrivateFieldGet(this, _onAmPmChange));
332
+
333
+ _classPrivateFieldGet(this, _$submitButton).removeEventListener('click', _classPrivateFieldGet(this, _onSubmitButtonClick));
334
+
335
+ _classPrivateFieldGet(this, _$headerHours).removeEventListener('keydown', _classPrivateFieldGet(this, _onHoursKeydown));
336
+
337
+ _classPrivateFieldGet(this, _$headerMinutes).removeEventListener('keydown', _classPrivateFieldGet(this, _onMinutesKeydown));
338
+ }
339
+
340
+ static get observedAttributes() {
341
+ return ['value', 'ampm', 'submit-aria-label'];
342
+ }
343
+
344
+ attributeChangedCallback(name, prevValue, newVal) {
345
+ if (newVal === prevValue) {
346
+ return;
347
+ }
348
+
349
+ switch (name) {
350
+ case 'value':
351
+ {
352
+ if (newVal === null) {
353
+ throw new Error('Missing "value" attribute');
354
+ }
355
+
356
+ const {
357
+ hours,
358
+ minutes
359
+ } = parseTime(newVal);
360
+
361
+ _classPrivateFieldSet(this, _hour, hours);
362
+
363
+ _classPrivateFieldSet(this, _minute, minutes);
364
+
365
+ _classPrivateMethodGet(this, _render, _render2).call(this);
366
+
367
+ break;
368
+ }
369
+
370
+ case 'ampm':
371
+ {
372
+ const isAmpm = isAttrTrue(newVal);
373
+ updateBooleanAttribute(this, 'ampm', isAmpm);
374
+
375
+ _classPrivateMethodGet(this, _render, _render2).call(this);
376
+
377
+ break;
378
+ }
379
+
380
+ case 'submit-aria-label':
381
+ {
382
+ _classPrivateFieldGet(this, _$submitButton).ariaLabel = newVal;
383
+ break;
384
+ }
385
+ }
386
+ }
387
+
388
+ get nodeName() {
389
+ return 'select';
390
+ }
391
+
392
+ set value(value) {
393
+ updateAttribute(this, 'value', value);
394
+ }
395
+
396
+ get value() {
397
+ return getAttribute(this, 'value', '');
398
+ }
399
+
400
+ set ampm(value) {
401
+ updateBooleanAttribute(this, 'ampm', value);
402
+ }
403
+
404
+ get ampm() {
405
+ return getBooleanAttribute(this, 'ampm');
406
+ }
407
+
408
+ get submitButtonRect() {
409
+ return getRect(_classPrivateFieldGet(this, _$submitButton));
410
+ }
411
+
412
+ get amButtonRect() {
413
+ if (!this.ampm) {
414
+ return null;
415
+ }
416
+
417
+ const $am = _classPrivateFieldGet(this, _$ampm).querySelector('[value="am"]');
418
+
419
+ return $am != null ? getRect($am) : null;
420
+ }
421
+
422
+ get pmButtonRect() {
423
+ if (!this.ampm) {
424
+ return null;
425
+ }
426
+
427
+ const $pm = _classPrivateFieldGet(this, _$ampm).querySelector('[value="pm"]');
428
+
429
+ return $pm != null ? getRect($pm) : null;
430
+ }
431
+
432
+ hourDigitRect(hour) {
433
+ const $digit = _classPrivateFieldGet(this, _$pickerHours).children[hourToIndex(hour, !this.ampm)];
434
+
435
+ return $digit != null ? getRect($digit) : null;
436
+ }
437
+
438
+ minuteDigitRect(minute) {
439
+ const $digit = _classPrivateFieldGet(this, _$pickerMinutes).children[Math.round(minute / 5)];
440
+
441
+ return $digit != null ? getRect($digit) : null;
442
+ }
443
+
444
+ }));
445
+
446
+ function _getClickDegree2(x, y) {
447
+ const touchRect = _classPrivateFieldGet(this, _$pickerTouch).getBoundingClientRect();
448
+
449
+ const cx = touchRect.width / 2;
450
+ const cy = touchRect.height / 2;
451
+ const px = x - touchRect.x;
452
+ const py = touchRect.height - y + touchRect.y;
453
+ const dx = px - cx;
454
+ const dy = py - cy;
455
+ const len = Math.sqrt(dx * dx + dy * dy);
456
+ const cosRad = dx / len;
457
+ const rad = Math.acos(cosRad * (dy < 0 ? -1 : 1));
458
+ const deg = rad * (180 / Math.PI);
459
+ let cssDeg = (deg - 90 - 360) % 360 * -1;
460
+
461
+ if (dy < 0) {
462
+ cssDeg += 180;
463
+ }
464
+
465
+ const rowIndex = len > MINUTE_RADIUS ? 0 : len > HOUR_12_RADIUS ? 1 : 2;
466
+ return [cssDeg, rowIndex];
467
+ }
468
+
469
+ function _render2() {
470
+ const is24 = getBooleanAttribute(this, 'ampm') === false;
471
+
472
+ _classPrivateMethodGet(this, _selectHour, _selectHour2).call(this, is24);
473
+
474
+ _classPrivateMethodGet(this, _selectMinute, _selectMinute2).call(this);
475
+
476
+ _classPrivateFieldGet(this, _$headerHoursText).textContent = stringifyHour(_classPrivateFieldGet(this, _hour), is24);
477
+ _classPrivateFieldGet(this, _$headerMinutesText).textContent = stringifyMinute(_classPrivateFieldGet(this, _minute));
478
+ updateAttribute(_classPrivateFieldGet(this, _$headerHours), 'aria-valuenow', _classPrivateFieldGet(this, _hour));
479
+ updateAttribute(_classPrivateFieldGet(this, _$headerHours), 'aria-valuetext', _classPrivateFieldGet(this, _hour));
480
+ updateAttribute(_classPrivateFieldGet(this, _$headerMinutes), 'aria-valuenow', _classPrivateFieldGet(this, _minute));
481
+ updateAttribute(_classPrivateFieldGet(this, _$headerMinutes), 'aria-valuetext', _classPrivateFieldGet(this, _minute));
482
+ }
483
+
484
+ function _selectHour2(is24) {
485
+ const $hours = _classPrivateFieldGet(this, _$pickerHours).children;
486
+
487
+ const hourDigitIndex = _classPrivateFieldGet(this, _hour) % 12;
488
+ const selectedIndex = hourToIndex(_classPrivateFieldGet(this, _hour), is24);
489
+ const currentCssDeg = getNeedleRotationDeg(_classPrivateFieldGet(this, _$needleHour));
490
+ const hourCssDeg = getShortestCssDeg(currentCssDeg, hourDigitIndex * 30);
491
+
492
+ for (let i = 0; i < $hours.length; i++) {
493
+ setClass($hours[i], 'selected', i === selectedIndex);
494
+ }
495
+
496
+ _classPrivateFieldGet(this, _$needleHour).style.transform = `rotate(${hourCssDeg}deg)`;
497
+
498
+ if (is24) {
499
+ if (_classPrivateFieldGet(this, _hour) > 0 && _classPrivateFieldGet(this, _hour) <= 12) {
500
+ _classPrivateFieldGet(this, _$needleHour).style.height = `${NEEDLE_HOUR_12_LENGTH}px`;
501
+ } else {
502
+ _classPrivateFieldGet(this, _$needleHour).style.height = `${NEEDLE_HOUR_24_LENGTH}px`;
503
+ }
504
+ } else {
505
+ _classPrivateFieldGet(this, _$needleHour).style.height = `${NEEDLE_HOUR_12_LENGTH}px`;
506
+ }
507
+
508
+ _classPrivateFieldGet(this, _$ampm).setAttribute('value', _classPrivateFieldGet(this, _hour) >= 0 && _classPrivateFieldGet(this, _hour) < 12 ? 'am' : 'pm');
509
+ }
510
+
511
+ function _selectMinute2() {
512
+ const $minutes = _classPrivateFieldGet(this, _$pickerMinutes).children;
513
+
514
+ const isNeedleSelected = _classPrivateFieldGet(this, _minute) % 5 === 0;
515
+ const selectedIndex = _classPrivateFieldGet(this, _minute) / 5;
516
+ const currentCssDeg = getNeedleRotationDeg(_classPrivateFieldGet(this, _$needleMinute));
517
+ const minuteCssDeg = getShortestCssDeg(currentCssDeg, _classPrivateFieldGet(this, _minute) * 6);
518
+
519
+ for (let i = 0; i < $minutes.length; i++) {
520
+ setClass($minutes[i], 'selected', selectedIndex === i);
521
+ }
522
+
523
+ setClass(_classPrivateFieldGet(this, _$needleMinute), 'selected', isNeedleSelected);
524
+ _classPrivateFieldGet(this, _$needleMinute).style.transform = `rotate(${minuteCssDeg}deg)`;
525
+ }
@@ -0,0 +1,31 @@
1
+ import type { TRect, TSinchElementReact } from '../types';
2
+ import type { SyntheticEvent } from 'react';
3
+ export declare type TSinchTimePickerElement = HTMLElement & {
4
+ /** Time value in ISO 8601 format */
5
+ value: string;
6
+ /** AM/PM 12-hour clock system, `false` by default */
7
+ ampm: boolean;
8
+ readonly submitButtonRect: TRect;
9
+ readonly amButtonRect: TRect | null;
10
+ readonly pmButtonRect: TRect | null;
11
+ hourDigitRect(hour: number): TRect | null;
12
+ minuteDigitRect(minute: number): TRect | null;
13
+ /** Change value handler, return time in ISO 8601 format */
14
+ addEventListener(type: 'change', listener: (e: CustomEvent<string>) => void): void;
15
+ /** Time value in ISO 8601 format */
16
+ setAttribute(name: 'value', value: string): void;
17
+ /** AM/PM 12-hour clock system, `false` by default */
18
+ setAttribute(name: 'ampm', value: boolean): void;
19
+ };
20
+ export declare type TSinchTimePickerReact = TSinchElementReact<TSinchTimePickerElement> & {
21
+ /** Time value in ISO 8601 format */
22
+ value: string;
23
+ /** AM/PM 12-hour clock system, `false` by default */
24
+ ampm?: boolean;
25
+ /** Label that is used for a11y */
26
+ 'aria-label': string;
27
+ /** Submit button label that is used for a11y */
28
+ 'submit-aria-label': string;
29
+ /** Change value handler, return time in ISO 8601 format */
30
+ onChange: (e: SyntheticEvent<TSinchTimePickerElement, CustomEvent<string>>) => void;
31
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ export declare const parseTime: (value: string) => {
2
+ hours: number;
3
+ minutes: number;
4
+ };
5
+ export declare const stringifyTime: (hour: number, minute: number) => string;
6
+ export declare const stringifyHour: (hour: number, is24: boolean) => string;
7
+ export declare const stringifyHourFace: (hour: number) => string;
8
+ export declare const stringifyMinute: (minute: number) => string;
9
+ export declare const hourToIndex: (hour: number, is24: boolean) => number;
10
+ export declare const getNeedleRotationDeg: (elem: HTMLElement) => number;
11
+ export declare const getShortestCssDeg: (currentDeg: number, nextDeg: number) => number;
@@ -0,0 +1,94 @@
1
+ export const parseTime = value => {
2
+ if (value === '') {
3
+ return {
4
+ hours: 0,
5
+ minutes: 0
6
+ };
7
+ }
8
+
9
+ const timeParts = value.split(':');
10
+
11
+ if (timeParts.length < 3) {
12
+ throw new Error(`Incorrect time format: ${value}. Should be "hh:mm:ss"`);
13
+ }
14
+
15
+ const hours = parseInt(timeParts[0]);
16
+ const minutes = parseInt(timeParts[1]);
17
+ const seconds = parseInt(timeParts[2]);
18
+
19
+ if (isNaN(hours) || hours > 23 || hours < 0) {
20
+ throw new Error(`Invalid hours value: ${value}`);
21
+ }
22
+
23
+ if (isNaN(minutes) || minutes > 59 || minutes < 0) {
24
+ throw new Error(`Invalid minutes value: ${value}`);
25
+ }
26
+
27
+ if (isNaN(seconds) || seconds > 59 || seconds < 0) {
28
+ throw new Error(`Invalid seconds value: ${value}`);
29
+ }
30
+
31
+ return {
32
+ hours,
33
+ minutes
34
+ };
35
+ };
36
+
37
+ const pad = value => {
38
+ return value.toString().padStart(2, '0');
39
+ };
40
+
41
+ export const stringifyTime = (hour, minute) => {
42
+ return `${pad(hour)}:${pad(minute)}:00`;
43
+ };
44
+ export const stringifyHour = (hour, is24) => {
45
+ if (is24) {
46
+ return pad(hour);
47
+ }
48
+
49
+ if (hour === 0 || hour === 12) {
50
+ return '12';
51
+ }
52
+
53
+ return pad(hour % 12);
54
+ };
55
+ export const stringifyHourFace = hour => {
56
+ return hour === 0 ? '12' : hour === 12 ? '24' : String(hour);
57
+ };
58
+ export const stringifyMinute = minute => {
59
+ return pad(minute);
60
+ };
61
+ export const hourToIndex = (hour, is24) => {
62
+ if (is24) {
63
+ if (hour === 0) {
64
+ return 12;
65
+ }
66
+
67
+ if (hour === 12) {
68
+ return 0;
69
+ }
70
+
71
+ return hour;
72
+ }
73
+
74
+ return hour % 12;
75
+ };
76
+ export const getNeedleRotationDeg = elem => {
77
+ const match = elem.style.transform.match(/^rotate\((-?\d+)deg\)$/);
78
+
79
+ if (match === null) {
80
+ return 0;
81
+ }
82
+
83
+ return Number(match[1]);
84
+ };
85
+ export const getShortestCssDeg = (currentDeg, nextDeg) => {
86
+ const angle = currentDeg % 360;
87
+ const diff = (360 - (angle - nextDeg)) % 360;
88
+
89
+ if (diff > 180) {
90
+ return currentDeg - 360 + diff;
91
+ }
92
+
93
+ return currentDeg + diff;
94
+ };
package/toggle/types.d.ts CHANGED
@@ -6,8 +6,6 @@ export declare type TSinchToggleElement = HTMLElement & {
6
6
  labeled: boolean;
7
7
  disabled: boolean;
8
8
  text: string | null;
9
- focus(): void;
10
- blur(): void;
11
9
  addEventListener(type: 'change', listener: (e: CustomEvent<boolean>) => void): void;
12
10
  setAttribute(name: 'checked', value: ''): void;
13
11
  setAttribute(name: 'small', value: ''): void;
package/utils.js CHANGED
@@ -30,7 +30,7 @@ export class NectaryElement extends HTMLElement {
30
30
  attachShadow(options) {
31
31
  return super.attachShadow({
32
32
  mode: 'closed',
33
- delegatesFocus: true,
33
+ delegatesFocus: false,
34
34
  customElements: nectaryRegistry,
35
35
  ...options
36
36
  });