@nectary/components 0.32.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/action-menu/index.js +40 -18
- package/action-menu/types.d.ts +3 -0
- package/action-menu-option/index.js +22 -14
- package/dialog/index.d.ts +1 -0
- package/dialog/index.js +50 -46
- package/dialog/types.d.ts +2 -0
- package/dropdown/index.js +11 -13
- package/horizontal-stepper/index.d.ts +13 -0
- package/horizontal-stepper/index.js +104 -0
- package/horizontal-stepper/types.d.ts +9 -0
- package/horizontal-stepper/types.js +1 -0
- package/horizontal-stepper-item/index.d.ts +13 -0
- package/horizontal-stepper-item/index.js +100 -0
- package/horizontal-stepper-item/types.d.ts +15 -0
- package/horizontal-stepper-item/types.js +1 -0
- package/horizontal-stepper-item/utils.d.ts +2 -0
- package/horizontal-stepper-item/utils.js +1 -0
- package/icons/exclamation/index.d.ts +11 -0
- package/icons/exclamation/index.js +4 -0
- package/input/index.d.ts +1 -0
- package/input/index.js +89 -26
- package/package.json +1 -1
- package/popover/index.js +128 -36
- package/popover/types.d.ts +17 -2
- package/popover/utils.js +1 -1
- package/select/index.js +1 -1
- package/select/types.d.ts +33 -5
- package/stop-events/index.d.ts +1 -0
- package/stop-events/index.js +40 -0
- package/textarea/index.js +36 -28
- package/utils.d.ts +1 -0
- package/utils.js +3 -0
package/popover/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _classPrivateFieldGet from '@babel/runtime/helpers/classPrivateFieldGet';
|
|
2
2
|
import _classPrivateFieldSet from '@babel/runtime/helpers/classPrivateFieldSet';
|
|
3
3
|
|
|
4
|
-
var _$target, _$dialog, _isConnected, _resizeThrottle, _prevOverflowValue, _onExpand, _onCollapse, _isOpen, _onResize, _updateOrientation,
|
|
4
|
+
var _$target, _$dialog, _isConnected, _resizeThrottle, _prevOverflowValue, _onExpand, _onCollapse, _isOpen, _onResize, _updateOrientation, _updateOrientationModal, _onBackdropMouseDown, _onCancel, _onCloseReactHandler, _onTargetKeydown, _dispatchCloseEvent;
|
|
5
5
|
|
|
6
6
|
function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
|
|
7
7
|
|
|
@@ -12,13 +12,13 @@ function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollect
|
|
|
12
12
|
function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
|
|
13
13
|
|
|
14
14
|
import dialogPolyfill from 'dialog-polyfill';
|
|
15
|
-
import { defineCustomElement, getBooleanAttribute, getLiteralAttribute, getRect, isAttrTrue, updateLiteralAttribute, getReactEventHandler, updateBooleanAttribute, NectaryElement,
|
|
16
|
-
const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}#wrapper{position:relative}dialog{position:fixed;top:0;left:0;margin:0;outline:0;font:var(--sinch-font-body);color:var(--sinch-color-text-default);background-color:var(--sinch-color-snow-100);box-shadow:var(--sinch-elevation-level-2);border:1px solid var(--sinch-color-snow-500);border-radius:var(--sinch-shape-radius-
|
|
15
|
+
import { defineCustomElement, getBooleanAttribute, getLiteralAttribute, getRect, isAttrTrue, updateLiteralAttribute, getReactEventHandler, updateBooleanAttribute, NectaryElement, throttleAnimationFrame } from '../utils';
|
|
16
|
+
const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}#wrapper{position:relative}dialog{position:fixed;top:0;left:0;margin:0;outline:0;font:var(--sinch-font-body);color:var(--sinch-color-text-default);background-color:var(--sinch-color-snow-100);box-shadow:var(--sinch-elevation-level-2);border:1px solid var(--sinch-color-snow-500);border-radius:var(--sinch-popover-shape-radius,var(--sinch-shape-radius-l));contain:content;padding:0;box-sizing:border-box;max-width:unset;max-height:unset;z-index:1}dialog:not([open]){display:none}dialog::backdrop{background-color:transparent}dialog+.backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background-color:transparent}dialog.fixed{position:fixed;top:50%;transform:translate(0,-50%)}._dialog_overlay{position:fixed;top:0;right:0;bottom:0;left:0}#target{display:flex;flex-direction:column}</style><div id="wrapper"><div id="target" aria-haspopup="dialog" aria-expanded="false"><slot name="target"></slot></div><dialog id="dialog" tabindex="-1"><slot name="content"></slot></dialog></div>';
|
|
17
17
|
import { orientationValues } from './utils';
|
|
18
18
|
const template = document.createElement('template');
|
|
19
19
|
template.innerHTML = templateHTML;
|
|
20
20
|
const POPOVER_OFFSET = 4;
|
|
21
|
-
defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new WeakMap(), _isConnected = new WeakMap(), _resizeThrottle = new WeakMap(), _prevOverflowValue = new WeakMap(), _onExpand = new WeakSet(), _onCollapse = new WeakSet(), _isOpen = new WeakSet(), _onResize = new WeakMap(), _updateOrientation = new WeakMap(),
|
|
21
|
+
defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new WeakMap(), _isConnected = new WeakMap(), _resizeThrottle = new WeakMap(), _prevOverflowValue = new WeakMap(), _onExpand = new WeakSet(), _onCollapse = new WeakSet(), _isOpen = new WeakSet(), _onResize = new WeakMap(), _updateOrientation = new WeakMap(), _updateOrientationModal = new WeakMap(), _onBackdropMouseDown = new WeakMap(), _onCancel = new WeakMap(), _onCloseReactHandler = new WeakMap(), _onTargetKeydown = new WeakMap(), _dispatchCloseEvent = new WeakSet(), class extends NectaryElement {
|
|
22
22
|
constructor() {
|
|
23
23
|
super();
|
|
24
24
|
|
|
@@ -65,7 +65,7 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
|
|
|
65
65
|
_classPrivateFieldInitSpec(this, _updateOrientation, {
|
|
66
66
|
writable: true,
|
|
67
67
|
value: () => {
|
|
68
|
-
_classPrivateFieldGet(this, _$dialog).style.width = '
|
|
68
|
+
_classPrivateFieldGet(this, _$dialog).style.width = 'max-content';
|
|
69
69
|
|
|
70
70
|
const targetRect = _classPrivateFieldGet(this, _$target).getBoundingClientRect();
|
|
71
71
|
|
|
@@ -74,11 +74,43 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
|
|
|
74
74
|
let leftPos = 0;
|
|
75
75
|
let topPos = 0;
|
|
76
76
|
const orient = this.orientation;
|
|
77
|
-
const shouldExpandWidthToTarget =
|
|
78
|
-
const
|
|
79
|
-
const resultWidth = shouldExpandWidthToTarget ? largestWidth : modalRect.width;
|
|
77
|
+
const shouldExpandWidthToTarget = orient === 'top' || orient === 'bottom';
|
|
78
|
+
const resultWidth = shouldExpandWidthToTarget ? Math.max(modalRect.width, targetRect.width) : modalRect.width;
|
|
80
79
|
|
|
81
|
-
if (orient === 'bottom-
|
|
80
|
+
if (orient === 'bottom-left' || orient === 'top-left') {
|
|
81
|
+
leftPos = targetRect.width - resultWidth;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (orient === 'bottom-left' || orient === 'bottom-right' || orient === 'bottom') {
|
|
85
|
+
topPos = targetRect.height + POPOVER_OFFSET;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (orient === 'top-left' || orient === 'top-right' || orient === 'top') {
|
|
89
|
+
topPos = -(modalRect.height + POPOVER_OFFSET);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
_classPrivateFieldGet(this, _$dialog).style.left = `${leftPos}px`;
|
|
93
|
+
_classPrivateFieldGet(this, _$dialog).style.top = `${topPos}px`;
|
|
94
|
+
_classPrivateFieldGet(this, _$dialog).style.width = `${resultWidth}px`;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
_classPrivateFieldInitSpec(this, _updateOrientationModal, {
|
|
99
|
+
writable: true,
|
|
100
|
+
value: () => {
|
|
101
|
+
_classPrivateFieldGet(this, _$dialog).style.width = 'max-content';
|
|
102
|
+
|
|
103
|
+
const targetRect = _classPrivateFieldGet(this, _$target).getBoundingClientRect();
|
|
104
|
+
|
|
105
|
+
const modalRect = _classPrivateFieldGet(this, _$dialog).getBoundingClientRect();
|
|
106
|
+
|
|
107
|
+
let leftPos = 0;
|
|
108
|
+
let topPos = 0;
|
|
109
|
+
const orient = this.orientation;
|
|
110
|
+
const shouldExpandWidthToTarget = orient === 'top' || orient === 'bottom';
|
|
111
|
+
const resultWidth = shouldExpandWidthToTarget ? Math.max(modalRect.width, targetRect.width) : modalRect.width;
|
|
112
|
+
|
|
113
|
+
if (orient === 'bottom-right' || orient === 'top-right' || orient === 'top' || orient === 'bottom') {
|
|
82
114
|
leftPos = Math.max(POPOVER_OFFSET, Math.min(targetRect.x, window.innerWidth - resultWidth - POPOVER_OFFSET));
|
|
83
115
|
}
|
|
84
116
|
|
|
@@ -86,11 +118,11 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
|
|
|
86
118
|
leftPos = Math.max(POPOVER_OFFSET, targetRect.right - resultWidth);
|
|
87
119
|
}
|
|
88
120
|
|
|
89
|
-
if (orient === 'bottom-left' || orient === 'bottom-right') {
|
|
121
|
+
if (orient === 'bottom-left' || orient === 'bottom-right' || orient === 'bottom') {
|
|
90
122
|
topPos = Math.max(POPOVER_OFFSET, Math.min(targetRect.bottom + POPOVER_OFFSET, window.innerHeight - modalRect.height - POPOVER_OFFSET));
|
|
91
123
|
}
|
|
92
124
|
|
|
93
|
-
if (orient === 'top-left' || orient === 'top-right') {
|
|
125
|
+
if (orient === 'top-left' || orient === 'top-right' || orient === 'top') {
|
|
94
126
|
topPos = Math.max(POPOVER_OFFSET, targetRect.top - POPOVER_OFFSET - modalRect.height);
|
|
95
127
|
}
|
|
96
128
|
|
|
@@ -100,7 +132,7 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
|
|
|
100
132
|
}
|
|
101
133
|
});
|
|
102
134
|
|
|
103
|
-
_classPrivateFieldInitSpec(this,
|
|
135
|
+
_classPrivateFieldInitSpec(this, _onBackdropMouseDown, {
|
|
104
136
|
writable: true,
|
|
105
137
|
value: e => {
|
|
106
138
|
if (e.target !== _classPrivateFieldGet(this, _$dialog)) {
|
|
@@ -111,8 +143,6 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
|
|
|
111
143
|
const isInside = e.x >= rect.x && e.x < rect.x + rect.width && e.y >= rect.y && e.y < rect.y + rect.height;
|
|
112
144
|
|
|
113
145
|
if (!isInside) {
|
|
114
|
-
e.stopPropagation();
|
|
115
|
-
|
|
116
146
|
_classPrivateMethodGet(this, _dispatchCloseEvent, _dispatchCloseEvent2).call(this);
|
|
117
147
|
}
|
|
118
148
|
}
|
|
@@ -134,6 +164,22 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
|
|
|
134
164
|
}
|
|
135
165
|
});
|
|
136
166
|
|
|
167
|
+
_classPrivateFieldInitSpec(this, _onTargetKeydown, {
|
|
168
|
+
writable: true,
|
|
169
|
+
value: e => {
|
|
170
|
+
switch (e.key) {
|
|
171
|
+
case 'Escape':
|
|
172
|
+
{
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
|
|
175
|
+
_classPrivateMethodGet(this, _dispatchCloseEvent, _dispatchCloseEvent2).call(this);
|
|
176
|
+
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
137
183
|
const shadowRoot = this.attachShadow();
|
|
138
184
|
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
139
185
|
|
|
@@ -143,7 +189,7 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
|
|
|
143
189
|
|
|
144
190
|
_classPrivateFieldSet(this, _isConnected, false);
|
|
145
191
|
|
|
146
|
-
_classPrivateFieldSet(this, _resizeThrottle, throttleAnimationFrame(_classPrivateFieldGet(this,
|
|
192
|
+
_classPrivateFieldSet(this, _resizeThrottle, throttleAnimationFrame(_classPrivateFieldGet(this, _updateOrientationModal)));
|
|
147
193
|
|
|
148
194
|
dialogPolyfill.registerDialog(_classPrivateFieldGet(this, _$dialog));
|
|
149
195
|
}
|
|
@@ -153,7 +199,7 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
|
|
|
153
199
|
|
|
154
200
|
_classPrivateFieldGet(this, _$dialog).addEventListener('cancel', _classPrivateFieldGet(this, _onCancel));
|
|
155
201
|
|
|
156
|
-
_classPrivateFieldGet(this, _$dialog).addEventListener('mousedown', _classPrivateFieldGet(this,
|
|
202
|
+
_classPrivateFieldGet(this, _$dialog).addEventListener('mousedown', _classPrivateFieldGet(this, _onBackdropMouseDown));
|
|
157
203
|
|
|
158
204
|
this.addEventListener('close', _classPrivateFieldGet(this, _onCloseReactHandler));
|
|
159
205
|
|
|
@@ -169,15 +215,25 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
|
|
|
169
215
|
disconnectedCallback() {
|
|
170
216
|
_classPrivateFieldGet(this, _$dialog).removeEventListener('cancel', _classPrivateFieldGet(this, _onCancel));
|
|
171
217
|
|
|
172
|
-
_classPrivateFieldGet(this, _$dialog).removeEventListener('mousedown', _classPrivateFieldGet(this,
|
|
218
|
+
_classPrivateFieldGet(this, _$dialog).removeEventListener('mousedown', _classPrivateFieldGet(this, _onBackdropMouseDown));
|
|
173
219
|
|
|
174
220
|
this.removeEventListener('close', _classPrivateFieldGet(this, _onCloseReactHandler));
|
|
175
221
|
|
|
222
|
+
_classPrivateMethodGet(this, _onCollapse, _onCollapse2).call(this);
|
|
223
|
+
|
|
176
224
|
_classPrivateFieldSet(this, _isConnected, false);
|
|
177
225
|
}
|
|
178
226
|
|
|
179
227
|
static get observedAttributes() {
|
|
180
|
-
return ['
|
|
228
|
+
return ['modal', 'orientation', 'open'];
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
set modal(isModal) {
|
|
232
|
+
updateBooleanAttribute(this, 'modal', isModal);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
get modal() {
|
|
236
|
+
return getBooleanAttribute(this, 'modal');
|
|
181
237
|
}
|
|
182
238
|
|
|
183
239
|
set open(isOpen) {
|
|
@@ -189,7 +245,7 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
|
|
|
189
245
|
}
|
|
190
246
|
|
|
191
247
|
get orientation() {
|
|
192
|
-
return getLiteralAttribute(this, orientationValues, 'orientation', 'bottom
|
|
248
|
+
return getLiteralAttribute(this, orientationValues, 'orientation', 'bottom');
|
|
193
249
|
}
|
|
194
250
|
|
|
195
251
|
set orientation(value) {
|
|
@@ -201,48 +257,77 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
|
|
|
201
257
|
}
|
|
202
258
|
|
|
203
259
|
attributeChangedCallback(name, oldVal, newVal) {
|
|
260
|
+
if (oldVal === newVal) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
204
264
|
switch (name) {
|
|
205
265
|
case 'open':
|
|
206
266
|
{
|
|
207
|
-
if (
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
_classPrivateMethodGet(this, _onCollapse, _onCollapse2).call(this);
|
|
212
|
-
}
|
|
267
|
+
if (isAttrTrue(newVal)) {
|
|
268
|
+
_classPrivateMethodGet(this, _onExpand, _onExpand2).call(this);
|
|
269
|
+
} else {
|
|
270
|
+
_classPrivateMethodGet(this, _onCollapse, _onCollapse2).call(this);
|
|
213
271
|
}
|
|
214
272
|
|
|
273
|
+
updateBooleanAttribute(this, 'open', isAttrTrue(newVal));
|
|
215
274
|
break;
|
|
216
275
|
}
|
|
217
276
|
|
|
218
277
|
case 'orientation':
|
|
219
278
|
{
|
|
220
279
|
if (_classPrivateMethodGet(this, _isOpen, _isOpen2).call(this)) {
|
|
221
|
-
|
|
280
|
+
if (this.modal) {
|
|
281
|
+
_classPrivateFieldGet(this, _updateOrientationModal).call(this);
|
|
282
|
+
} else {
|
|
283
|
+
_classPrivateFieldGet(this, _updateOrientation).call(this);
|
|
284
|
+
}
|
|
222
285
|
}
|
|
223
286
|
|
|
224
287
|
break;
|
|
225
288
|
}
|
|
289
|
+
|
|
290
|
+
case 'modal':
|
|
291
|
+
{
|
|
292
|
+
if (_classPrivateMethodGet(this, _isOpen, _isOpen2).call(this)) {
|
|
293
|
+
_classPrivateMethodGet(this, _onCollapse, _onCollapse2).call(this);
|
|
294
|
+
|
|
295
|
+
_classPrivateMethodGet(this, _onExpand, _onExpand2).call(this);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
226
298
|
}
|
|
227
299
|
}
|
|
228
300
|
|
|
229
301
|
}));
|
|
230
302
|
|
|
231
303
|
function _onExpand2() {
|
|
232
|
-
if (_classPrivateMethodGet(this, _isOpen, _isOpen2).call(this)) {
|
|
304
|
+
if (!_classPrivateFieldGet(this, _isConnected) || _classPrivateMethodGet(this, _isOpen, _isOpen2).call(this)) {
|
|
233
305
|
return;
|
|
234
306
|
}
|
|
235
307
|
|
|
236
|
-
|
|
308
|
+
if (this.modal) {
|
|
309
|
+
_classPrivateFieldGet(this, _$dialog).style.position = 'fixed';
|
|
310
|
+
|
|
311
|
+
_classPrivateFieldGet(this, _$dialog).showModal();
|
|
312
|
+
|
|
313
|
+
_classPrivateFieldGet(this, _updateOrientationModal).call(this);
|
|
314
|
+
|
|
315
|
+
_classPrivateFieldGet(this, _$target).setAttribute('aria-expanded', 'true');
|
|
237
316
|
|
|
238
|
-
|
|
317
|
+
_classPrivateFieldSet(this, _prevOverflowValue, document.body.style.overflow);
|
|
239
318
|
|
|
240
|
-
|
|
319
|
+
document.body.style.overflow = 'hidden';
|
|
320
|
+
window.addEventListener('resize', _classPrivateFieldGet(this, _onResize));
|
|
321
|
+
} else {
|
|
322
|
+
this.addEventListener('keydown', _classPrivateFieldGet(this, _onTargetKeydown));
|
|
323
|
+
_classPrivateFieldGet(this, _$dialog).style.position = 'absolute';
|
|
241
324
|
|
|
242
|
-
|
|
325
|
+
_classPrivateFieldGet(this, _$dialog).setAttribute('open', '');
|
|
243
326
|
|
|
244
|
-
|
|
245
|
-
|
|
327
|
+
_classPrivateFieldGet(this, _updateOrientation).call(this);
|
|
328
|
+
|
|
329
|
+
_classPrivateFieldGet(this, _$target).setAttribute('aria-expanded', 'true');
|
|
330
|
+
}
|
|
246
331
|
}
|
|
247
332
|
|
|
248
333
|
function _onCollapse2() {
|
|
@@ -250,17 +335,24 @@ function _onCollapse2() {
|
|
|
250
335
|
return;
|
|
251
336
|
}
|
|
252
337
|
|
|
338
|
+
if (this.modal) {
|
|
339
|
+
_classPrivateFieldGet(this, _$dialog).close?.();
|
|
340
|
+
} else {
|
|
341
|
+
_classPrivateFieldGet(this, _$dialog).removeAttribute('open');
|
|
342
|
+
}
|
|
343
|
+
|
|
253
344
|
_classPrivateFieldGet(this, _$target).setAttribute('aria-expanded', 'false');
|
|
254
345
|
|
|
255
|
-
_classPrivateFieldGet(this, _$dialog).close?.();
|
|
256
346
|
document.body.style.overflow = _classPrivateFieldGet(this, _prevOverflowValue);
|
|
257
|
-
window.removeEventListener('resize', _classPrivateFieldGet(this, _onResize));
|
|
258
347
|
|
|
259
348
|
_classPrivateFieldGet(this, _resizeThrottle).cancel();
|
|
349
|
+
|
|
350
|
+
window.removeEventListener('resize', _classPrivateFieldGet(this, _onResize));
|
|
351
|
+
this.removeEventListener('keydown', _classPrivateFieldGet(this, _onTargetKeydown));
|
|
260
352
|
}
|
|
261
353
|
|
|
262
354
|
function _isOpen2() {
|
|
263
|
-
return
|
|
355
|
+
return getBooleanAttribute(_classPrivateFieldGet(this, _$dialog), 'open');
|
|
264
356
|
}
|
|
265
357
|
|
|
266
358
|
function _dispatchCloseEvent2() {
|
package/popover/types.d.ts
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
import type { TRect, TSinchElementReact } from '../types';
|
|
2
2
|
import type { SyntheticEvent } from 'react';
|
|
3
|
-
export declare type TSinchPopoverOrientation = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
3
|
+
export declare type TSinchPopoverOrientation = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'bottom' | 'top';
|
|
4
4
|
export declare type TSinchPopoverElement = HTMLElement & {
|
|
5
|
+
/** Open/close state */
|
|
5
6
|
open: boolean;
|
|
7
|
+
/** Orientation, where it *points to* from origin */
|
|
6
8
|
orientation: TSinchPopoverOrientation;
|
|
9
|
+
/** Modal/non-modal mode */
|
|
10
|
+
modal: boolean;
|
|
7
11
|
readonly popoverRect: TRect;
|
|
12
|
+
/** Close event */
|
|
8
13
|
addEventListener(type: 'close', listener: (e: CustomEvent<void>) => void): void;
|
|
14
|
+
/** Open/close state */
|
|
9
15
|
setAttribute(name: 'open', value: ''): void;
|
|
16
|
+
/** Orientation, where it *points to* from origin */
|
|
10
17
|
setAttribute(name: 'orientation', value: TSinchPopoverOrientation): void;
|
|
18
|
+
/** Modal/non-modal mode */
|
|
19
|
+
setAttribute(name: 'modal', value: boolean): void;
|
|
11
20
|
};
|
|
12
21
|
export declare type TSinchPopoverReact = TSinchElementReact<TSinchPopoverElement> & {
|
|
22
|
+
/** Open/close state */
|
|
13
23
|
open: boolean;
|
|
24
|
+
/** Orientation, where it *points to* from origin */
|
|
14
25
|
orientation?: TSinchPopoverOrientation;
|
|
26
|
+
/** Modal/non-modal mode */
|
|
27
|
+
modal?: boolean;
|
|
28
|
+
/** Label that is used for a11y */
|
|
15
29
|
'aria-label': string;
|
|
16
|
-
|
|
30
|
+
/** Close event handler */
|
|
31
|
+
onClose?: (event: SyntheticEvent<TSinchPopoverElement, CustomEvent<void>>) => void;
|
|
17
32
|
};
|
package/popover/utils.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const orientationValues = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];
|
|
1
|
+
export const orientationValues = ['top-left', 'top-right', 'bottom-left', 'bottom-right', 'bottom', 'top'];
|
package/select/index.js
CHANGED
|
@@ -13,7 +13,7 @@ function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(
|
|
|
13
13
|
|
|
14
14
|
import '../dropdown';
|
|
15
15
|
import { defineCustomElement, getAttribute, getBooleanAttribute, getIntegerAttribute, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute, updateIntegerAttribute } from '../utils';
|
|
16
|
-
const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0;--sinch-color-icon:var(--sinch-color-stormy-500)}#wrapper{position:relative
|
|
16
|
+
const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0;--sinch-color-icon:var(--sinch-color-stormy-500)}#wrapper{position:relative}sinch-dropdown{display:block}#button{all:initial;display:flex;align-items:center;gap:8px;border:1px solid var(--sinch-color-stormy-200);border-radius:var(--sinch-shape-radius-s);box-sizing:border-box;width:100%;height:48px;padding:8px 12px;font:var(--sinch-font-body);color:var(--sinch-color-text-default);background-color:var(--sinch-color-snow-100);cursor:pointer}#button:focus{border-color:var(--sinch-color-stormy-600)}#dropdown-icon{fill:var(--sinch-color-stormy-500)}#button>*{pointer-events:none}#button[data-unselected]{color:var(--sinch-color-text-muted)}#button:disabled{border-color:var(--sinch-color-snow-500);color:var(--sinch-color-stormy-100);cursor:initial}#button:disabled #dropdown-icon{fill:var(--sinch-color-stormy-100)}:host([invalidtext]:not([invalidtext=""])) #button:not(:disabled){border-color:var(--sinch-color-text-invalid)}#content{flex:1;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}#bottom,#top{display:flex;align-items:baseline}#top{height:24px;margin-bottom:2px}#additional,#invalid,#label,#optional{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#label{font:var(--sinch-font-title-s);color:var(--sinch-color-text-default)}#optional{flex:1;text-align:right;font:var(--sinch-font-small-text);color:var(--sinch-color-text-muted)}#additional{flex:1;text-align:right;font:var(--sinch-font-extra-small-text);color:var(--sinch-color-text-muted);line-height:20px;margin-top:2px}#additional:empty{display:none}#invalid{font:var(--sinch-font-extra-small-text);color:var(--sinch-color-text-invalid);line-height:20px;margin-top:2px}#invalid:empty{display:none}::slotted(sinch-help-tooltip){align-self:center;margin:0 8px}:host([disabled]:not([disabled=false])) :is(#label,#additional,#optional,#invalid){color:var(--sinch-color-stormy-100)}:host([disabled]:not([disabled=false])){--sinch-color-icon:var(--sinch-color-stormy-100)}</style><div id="wrapper"><div id="top"><label id="label" for="button"></label><slot name="tooltip"></slot><span id="optional"></span></div><sinch-dropdown id="dropdown" modal orientation="bottom"><button slot="target" id="button"><span id="content"></span> <svg id="dropdown-icon" width="12" height="8" aria-hidden="true"><path d="M1.41.59 6 5.17 10.59.59 12 2 6 8 0 2 1.41.59Z"/></svg></button><slot name="option" slot="option"></slot></sinch-dropdown><div id="bottom"><span id="invalid"></span> <span id="additional"></span></div></div>';
|
|
17
17
|
const template = document.createElement('template');
|
|
18
18
|
template.innerHTML = templateHTML;
|
|
19
19
|
defineCustomElement('sinch-select', (_$button = new WeakMap(), _$buttonContent = new WeakMap(), _$label = new WeakMap(), _$optionalText = new WeakMap(), _$additionalText = new WeakMap(), _$invalidText = new WeakMap(), _$dropdown = new WeakMap(), _$optionSlot = new WeakMap(), _$sh = new WeakMap(), _createElement = new WeakSet(), _updateButtonContent = new WeakSet(), _onValueChange = new WeakMap(), _getOptionWithValue = new WeakSet(), _onLabelClick = new WeakMap(), _onDropdownClick = new WeakMap(), _onDropdownClose = new WeakMap(), class extends NectaryElement {
|
package/select/types.d.ts
CHANGED
|
@@ -1,33 +1,61 @@
|
|
|
1
1
|
import type { TRect, TSinchElementReact } from '../types';
|
|
2
2
|
import type { SyntheticEvent } from 'react';
|
|
3
3
|
export declare type TSinchSelectElement = HTMLElement & {
|
|
4
|
+
/** Value that matches one of the options `value` */
|
|
4
5
|
value: string;
|
|
6
|
+
/** Label */
|
|
5
7
|
label: string;
|
|
8
|
+
/** Text that appears when it has no value set */
|
|
6
9
|
placeholder: string | null;
|
|
10
|
+
/** Optional text */
|
|
7
11
|
optionalText: string | null;
|
|
8
|
-
|
|
12
|
+
/** Additional text */
|
|
9
13
|
additionalText: string | null;
|
|
10
|
-
|
|
14
|
+
/** Invalid text, controls the overall invalid state */
|
|
15
|
+
invalidText: string | null;
|
|
16
|
+
/** Disabled */
|
|
11
17
|
disabled: boolean;
|
|
18
|
+
/** Number of visible at the same time options in the list */
|
|
19
|
+
maxVisibleItems: number | null;
|
|
12
20
|
readonly dropdownRect: TRect;
|
|
21
|
+
/** Change value event */
|
|
13
22
|
addEventListener(type: 'change', listener: (e: CustomEvent<string>) => void): void;
|
|
23
|
+
/** Value that matches one of the options `value` */
|
|
14
24
|
setAttribute(name: 'value', value: string): void;
|
|
25
|
+
/** Label */
|
|
15
26
|
setAttribute(name: 'label', value: string): void;
|
|
27
|
+
/** Text that appears when it has no value set */
|
|
16
28
|
setAttribute(name: 'placeholder', value: string): void;
|
|
29
|
+
/** Optional text */
|
|
17
30
|
setAttribute(name: 'optionaltext', value: string): void;
|
|
31
|
+
/** Additional text */
|
|
18
32
|
setAttribute(name: 'additionaltext', value: string): void;
|
|
19
|
-
|
|
33
|
+
/** Invalid text, controls the overall invalid state */
|
|
34
|
+
setAttribute(name: 'invalidtext', value: string): void;
|
|
35
|
+
/** Disabled */
|
|
20
36
|
setAttribute(name: 'disabled', value: ''): void;
|
|
37
|
+
/** Number of visible at the same time options in the list */
|
|
38
|
+
setAttribute(name: 'maxvisibleitems', value: string): void;
|
|
21
39
|
};
|
|
22
40
|
export declare type TSinchSelectReact = TSinchElementReact<TSinchSelectElement> & {
|
|
41
|
+
/** Value that matches one of the options `value` */
|
|
23
42
|
value: string;
|
|
43
|
+
/** Label */
|
|
24
44
|
label: string;
|
|
45
|
+
/** Label that is used for a11y – might be different from `label` */
|
|
46
|
+
'aria-label': string;
|
|
47
|
+
/** Text that appears when it has no value set */
|
|
25
48
|
placeholder?: string;
|
|
49
|
+
/** Optional text */
|
|
26
50
|
optionalText?: string;
|
|
27
|
-
|
|
51
|
+
/** Additional text */
|
|
28
52
|
additionalText?: string;
|
|
53
|
+
/** Invalid text, controls the overall invalid state */
|
|
54
|
+
invalidText?: string;
|
|
55
|
+
/** Disabled */
|
|
29
56
|
disabled?: boolean;
|
|
57
|
+
/** Number of visible at the same time options in the list */
|
|
30
58
|
maxVisibleItems?: number;
|
|
31
|
-
|
|
59
|
+
/** Change value handler */
|
|
32
60
|
onChange: (e: SyntheticEvent<TSinchSelectElement, CustomEvent<string>>) => void;
|
|
33
61
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import _classPrivateFieldGet from '@babel/runtime/helpers/classPrivateFieldGet';
|
|
2
|
+
|
|
3
|
+
var _stopEvent;
|
|
4
|
+
|
|
5
|
+
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
|
|
6
|
+
|
|
7
|
+
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
8
|
+
|
|
9
|
+
import { defineCustomElement, getCsvSet } from '../utils';
|
|
10
|
+
defineCustomElement('sinch-stop-events', (_stopEvent = new WeakMap(), class extends HTMLElement {
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
|
|
14
|
+
_classPrivateFieldInitSpec(this, _stopEvent, {
|
|
15
|
+
writable: true,
|
|
16
|
+
value: e => {
|
|
17
|
+
e.stopPropagation();
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
this.style.display = 'contents';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
connectedCallback() {
|
|
25
|
+
const events = getCsvSet(this.getAttribute('events'));
|
|
26
|
+
|
|
27
|
+
for (const event of events) {
|
|
28
|
+
this.addEventListener(event, _classPrivateFieldGet(this, _stopEvent));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
disconnectedCallback() {
|
|
33
|
+
const events = getCsvSet(this.getAttribute('events'));
|
|
34
|
+
|
|
35
|
+
for (const event of events) {
|
|
36
|
+
this.removeEventListener(event, _classPrivateFieldGet(this, _stopEvent));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
}));
|
package/textarea/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import _classPrivateFieldGet from '@babel/runtime/helpers/classPrivateFieldGet';
|
|
2
2
|
import _classPrivateFieldSet from '@babel/runtime/helpers/classPrivateFieldSet';
|
|
3
3
|
|
|
4
|
-
var _$input, _$label, _$optionalText, _$additionalText, _$invalidText,
|
|
4
|
+
var _$input, _$label, _$optionalText, _$additionalText, _$invalidText, _cursorPos, _isPendingDk, _onCompositionStart, _onSelectionChange, _onInput;
|
|
5
5
|
|
|
6
6
|
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
|
|
7
7
|
|
|
8
8
|
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
9
9
|
|
|
10
10
|
import { defineCustomElement, getAttribute, getBooleanAttribute, getIntegerAttribute, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute } from '../utils';
|
|
11
|
-
const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0;--sinch-color-icon:var(--sinch-color-stormy-500)}#wrapper{width:100%;box-sizing:border-box}#input{all:initial;border:1px solid var(--sinch-color-stormy-200);box-sizing:border-box;border-radius:var(--sinch-shape-radius-s);width:100%;
|
|
11
|
+
const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0;--sinch-color-icon:var(--sinch-color-stormy-500)}#wrapper{width:100%;box-sizing:border-box}#input{all:initial;border:1px solid var(--sinch-color-stormy-200);box-sizing:border-box;border-radius:var(--sinch-shape-radius-s);width:100%;padding:8px 12px;font:var(--sinch-font-body);color:var(--sinch-color-text-default);caret-color:var(--sinch-caret-color,auto);background-color:var(--sinch-color-snow-100);resize:none}#input::placeholder{font:var(--sinch-font-body);color:var(--sinch-color-text-muted)}#input:disabled{border-color:var(--sinch-color-snow-500);color:var(--sinch-color-stormy-100)}#input:disabled::placeholder{color:var(--sinch-color-snow-500)}#input:focus{border-color:var(--sinch-color-stormy-600)}:host([resizable]:not([resizable=false])) #input{resize:vertical}:host([invalidtext]:not([invalidtext=""])) #input:not(:disabled){border-color:var(--sinch-color-text-invalid)}#bottom,#top{display:flex;align-items:baseline}#top{height:24px;margin-bottom:2px}#additional,#invalid,#label,#optional{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#label{font:var(--sinch-font-title-s);color:var(--sinch-color-text-default)}#optional{flex:1;text-align:right;font:var(--sinch-font-small-text);color:var(--sinch-color-text-muted)}#additional{flex:1;text-align:right;font:var(--sinch-font-extra-small-text);color:var(--sinch-color-text-muted);line-height:20px;margin-top:2px}#additional:empty{display:none}#invalid{font:var(--sinch-font-extra-small-text);color:var(--sinch-color-text-invalid);line-height:20px;margin-top:2px}#invalid:empty{display:none}::slotted(sinch-help-tooltip){align-self:center;margin:0 8px}:host([disabled]:not([disabled=false])) :is(#label,#additional,#optional,#invalid){color:var(--sinch-color-stormy-100)}:host([disabled]:not([disabled=false])){--sinch-color-icon:var(--sinch-color-stormy-100)}</style><div id="wrapper"><div id="top"><label id="label" for="input"></label><slot name="tooltip"></slot><span id="optional"></span></div><textarea id="input"></textarea><div id="bottom"><span id="invalid"></span> <span id="additional"></span></div></div>';
|
|
12
12
|
const template = document.createElement('template');
|
|
13
13
|
template.innerHTML = templateHTML;
|
|
14
|
-
defineCustomElement('sinch-textarea', (_$input = new WeakMap(), _$label = new WeakMap(), _$optionalText = new WeakMap(), _$additionalText = new WeakMap(), _$invalidText = new WeakMap(),
|
|
14
|
+
defineCustomElement('sinch-textarea', (_$input = new WeakMap(), _$label = new WeakMap(), _$optionalText = new WeakMap(), _$additionalText = new WeakMap(), _$invalidText = new WeakMap(), _cursorPos = new WeakMap(), _isPendingDk = new WeakMap(), _onCompositionStart = new WeakMap(), _onSelectionChange = new WeakMap(), _onInput = new WeakMap(), class extends NectaryElement {
|
|
15
15
|
constructor() {
|
|
16
16
|
super();
|
|
17
17
|
|
|
@@ -40,12 +40,7 @@ defineCustomElement('sinch-textarea', (_$input = new WeakMap(), _$label = new We
|
|
|
40
40
|
value: void 0
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
_classPrivateFieldInitSpec(this,
|
|
44
|
-
writable: true,
|
|
45
|
-
value: null
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
_classPrivateFieldInitSpec(this, _selectionEnd, {
|
|
43
|
+
_classPrivateFieldInitSpec(this, _cursorPos, {
|
|
49
44
|
writable: true,
|
|
50
45
|
value: null
|
|
51
46
|
});
|
|
@@ -62,6 +57,13 @@ defineCustomElement('sinch-textarea', (_$input = new WeakMap(), _$label = new We
|
|
|
62
57
|
}
|
|
63
58
|
});
|
|
64
59
|
|
|
60
|
+
_classPrivateFieldInitSpec(this, _onSelectionChange, {
|
|
61
|
+
writable: true,
|
|
62
|
+
value: () => {
|
|
63
|
+
_classPrivateFieldSet(this, _cursorPos, _classPrivateFieldGet(this, _$input).selectionEnd);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
65
67
|
_classPrivateFieldInitSpec(this, _onInput, {
|
|
66
68
|
writable: true,
|
|
67
69
|
value: e => {
|
|
@@ -72,29 +74,23 @@ defineCustomElement('sinch-textarea', (_$input = new WeakMap(), _$label = new We
|
|
|
72
74
|
const prevValue = this.value;
|
|
73
75
|
|
|
74
76
|
if (prevValue !== nextValue) {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
const nextSelectionEnd = _classPrivateFieldGet(this, _$input).selectionEnd;
|
|
78
|
-
|
|
79
|
-
const prevSelectionStart = _classPrivateFieldGet(this, _selectionStart);
|
|
80
|
-
|
|
81
|
-
const prevSelectionEnd = _classPrivateFieldGet(this, _selectionEnd);
|
|
82
|
-
|
|
83
|
-
const isPrevCursorEnd = prevSelectionStart === prevSelectionEnd && prevSelectionStart === prevValue.length;
|
|
77
|
+
const nextCursorPos = _classPrivateFieldGet(this, _$input).selectionEnd;
|
|
84
78
|
|
|
85
79
|
if (!_classPrivateFieldGet(this, _isPendingDk)) {
|
|
86
80
|
_classPrivateFieldGet(this, _$input).value = prevValue;
|
|
87
|
-
}
|
|
88
81
|
|
|
89
|
-
|
|
82
|
+
const prevCursorPos = _classPrivateFieldGet(this, _cursorPos);
|
|
90
83
|
|
|
91
|
-
|
|
92
|
-
|
|
84
|
+
const isPrevCursorEnd = prevCursorPos === null || prevCursorPos === prevValue.length;
|
|
85
|
+
|
|
86
|
+
if (!isPrevCursorEnd) {
|
|
87
|
+
_classPrivateFieldGet(this, _$input).setSelectionRange(prevCursorPos, prevCursorPos);
|
|
88
|
+
}
|
|
93
89
|
}
|
|
94
90
|
|
|
95
|
-
_classPrivateFieldSet(this,
|
|
91
|
+
_classPrivateFieldSet(this, _isPendingDk, false);
|
|
96
92
|
|
|
97
|
-
_classPrivateFieldSet(this,
|
|
93
|
+
_classPrivateFieldSet(this, _cursorPos, nextCursorPos);
|
|
98
94
|
|
|
99
95
|
this.dispatchEvent(new CustomEvent('change', {
|
|
100
96
|
detail: nextValue,
|
|
@@ -125,12 +121,20 @@ defineCustomElement('sinch-textarea', (_$input = new WeakMap(), _$label = new We
|
|
|
125
121
|
_classPrivateFieldGet(this, _$input).addEventListener('input', _classPrivateFieldGet(this, _onInput));
|
|
126
122
|
|
|
127
123
|
_classPrivateFieldGet(this, _$input).addEventListener('compositionstart', _classPrivateFieldGet(this, _onCompositionStart));
|
|
124
|
+
|
|
125
|
+
_classPrivateFieldGet(this, _$input).addEventListener('mousedown', _classPrivateFieldGet(this, _onSelectionChange));
|
|
126
|
+
|
|
127
|
+
_classPrivateFieldGet(this, _$input).addEventListener('keydown', _classPrivateFieldGet(this, _onSelectionChange));
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
disconnectedCallback() {
|
|
131
131
|
_classPrivateFieldGet(this, _$input).removeEventListener('input', _classPrivateFieldGet(this, _onInput));
|
|
132
132
|
|
|
133
133
|
_classPrivateFieldGet(this, _$input).removeEventListener('compositionstart', _classPrivateFieldGet(this, _onCompositionStart));
|
|
134
|
+
|
|
135
|
+
_classPrivateFieldGet(this, _$input).removeEventListener('mousedown', _classPrivateFieldGet(this, _onSelectionChange));
|
|
136
|
+
|
|
137
|
+
_classPrivateFieldGet(this, _$input).removeEventListener('keydown', _classPrivateFieldGet(this, _onSelectionChange));
|
|
134
138
|
}
|
|
135
139
|
|
|
136
140
|
static get observedAttributes() {
|
|
@@ -143,12 +147,16 @@ defineCustomElement('sinch-textarea', (_$input = new WeakMap(), _$label = new We
|
|
|
143
147
|
{
|
|
144
148
|
const nextVal = newVal ?? '';
|
|
145
149
|
|
|
146
|
-
|
|
150
|
+
const prevVal = _classPrivateFieldGet(this, _$input).value;
|
|
151
|
+
|
|
152
|
+
if (nextVal !== prevVal) {
|
|
153
|
+
const prevCursorPos = _classPrivateFieldGet(this, _$input).selectionEnd;
|
|
154
|
+
|
|
155
|
+
const isPrevCursorEnd = prevCursorPos === prevVal.length;
|
|
147
156
|
_classPrivateFieldGet(this, _$input).value = nextVal;
|
|
148
|
-
const isNextCursorEnd = _classPrivateFieldGet(this, _selectionStart) === _classPrivateFieldGet(this, _selectionEnd) && (_classPrivateFieldGet(this, _selectionStart) === null || _classPrivateFieldGet(this, _selectionStart) === nextVal.length);
|
|
149
157
|
|
|
150
|
-
if (!
|
|
151
|
-
_classPrivateFieldGet(this, _$input).setSelectionRange(_classPrivateFieldGet(this,
|
|
158
|
+
if (!isPrevCursorEnd) {
|
|
159
|
+
_classPrivateFieldGet(this, _$input).setSelectionRange(_classPrivateFieldGet(this, _cursorPos), _classPrivateFieldGet(this, _cursorPos));
|
|
152
160
|
}
|
|
153
161
|
}
|
|
154
162
|
|
package/utils.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export declare const updateLiteralAttribute: <T extends readonly string[]>($elem
|
|
|
23
23
|
export declare function getLiteralAttribute<T extends readonly string[]>($element: Element, literals: T, attrName: string): T[number];
|
|
24
24
|
export declare function getLiteralAttribute<T extends readonly string[]>($element: Element, literals: T, attrName: string, defaultValue: null): T[number] | null;
|
|
25
25
|
export declare function getLiteralAttribute<T extends readonly string[]>($element: Element, literals: T, attrName: string, defaultValue: T[number]): T[number];
|
|
26
|
+
export declare const clampNumber: (value: number, min: number, max: number) => number;
|
|
26
27
|
declare type TRange = {
|
|
27
28
|
min?: number;
|
|
28
29
|
max?: number;
|
package/utils.js
CHANGED
|
@@ -99,6 +99,9 @@ export function getLiteralAttribute($element, literals, attrName, defaultValue)
|
|
|
99
99
|
|
|
100
100
|
return defaultValue;
|
|
101
101
|
}
|
|
102
|
+
export const clampNumber = (value, min, max) => {
|
|
103
|
+
return Math.min(max, Math.max(min, value));
|
|
104
|
+
};
|
|
102
105
|
|
|
103
106
|
const applyRange = (value, range) => {
|
|
104
107
|
let result = value;
|