@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
package/input/index.js CHANGED
@@ -1,18 +1,18 @@
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, _selectionStart, _selectionEnd, _isPendingDk, _onCompositionStart, _onInput;
4
+ var _$input, _$label, _$optionalText, _$additionalText, _$invalidText, _$iconSlot, _$iconWrapper, _$rightSlot, _$rightWrapper, _cursorPos, _isPendingDk, _onCompositionStart, _onSelectionChange, _onInput, _onIconSlotChange, _onRightSlotChange, _onEventFilter;
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
- import { defineCustomElement, getAttribute, getBooleanAttribute, getLiteralAttribute, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute, updateLiteralAttribute } 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-wrapper{display:flex;flex-direction:row;align-items:center;gap:4px;border:1px solid var(--sinch-color-stormy-200);box-sizing:border-box;border-radius:var(--sinch-shape-radius-s);width:100%;height:48px;margin:2px 0;padding:0 8px;background-color:var(--sinch-color-snow-100)}#input{all:initial;flex:1;min-width:0;height:48px;padding:0 4px;font:var(--sinch-font-body);color:var(--sinch-color-text-default);caret-color:var(--sinch-caret-color,auto)}#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)}#input[type=password]{font-size:1.5em;letter-spacing:.1em}:host([invalidtext]:not([invalidtext=""]):not([disabled])) #input-wrapper{border-color:var(--sinch-color-text-invalid)}#bottom,#top{display:flex;align-items:baseline}#top{height:24px}#bottom{height:20px}#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)}#invalid{font:var(--sinch-font-extra-small-text);color:var(--sinch-color-text-invalid)}::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><div id="input-wrapper"><input id="input" type="text"/><slot name="right"></slot></div><div id="bottom"><span id="invalid"></span> <span id="additional"></span></div></div>';
10
+ import { defineCustomElement, getAttribute, getBooleanAttribute, getLiteralAttribute, isAttrTrue, NectaryElement, setClass, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute, updateLiteralAttribute } 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-wrapper{position:relative;display:flex;flex-direction:row;align-items:center;box-sizing:border-box;border-radius:var(--sinch-shape-radius-s);width:100%;height:48px;background-color:var(--sinch-color-snow-100)}#input{all:initial;flex:1;min-width:0;height:48px;padding:0 12px 0 44px;font:var(--sinch-font-body);color:var(--sinch-color-text-default);caret-color:var(--sinch-caret-color,auto)}#input::placeholder{font:var(--sinch-font-body);color:var(--sinch-color-text-muted)}#border{position:absolute;border:1px solid var(--sinch-color-stormy-200);border-radius:var(--sinch-shape-radius-s);left:0;right:0;top:0;bottom:0;pointer-events:none}:host([invalidtext]:not([invalidtext=""]):not([disabled])) #border{border-color:var(--sinch-color-text-invalid)}#input:disabled{color:var(--sinch-color-stormy-100)}#input:disabled::placeholder{color:var(--sinch-color-snow-500)}#input:disabled+#border{border-color:var(--sinch-color-snow-500)}#input:focus+#border{border-color:var(--sinch-color-stormy-600)}#input[type=password]{font-size:1.5em;letter-spacing:.1em}#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}#icon{position:absolute;left:12px;top:12px;pointer-events:none;--sinch-icon-size:24px}#icon.empty{display:none}#icon.empty~#input{padding-left:12px}#right{display:flex;flex-direction:row;align-self:stretch;align-items:center;gap:4px;padding-right:8px}#right.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><div id="input-wrapper"><div id="icon"><slot name="icon"></slot></div><input id="input" type="text"/><div id="border"></div><div id="right"><slot name="right"></slot></div></div><div id="bottom"><div id="invalid"></div><div id="additional"></div></div></div>';
12
12
  import { inputTypes } from './utils';
13
13
  const template = document.createElement('template');
14
14
  template.innerHTML = templateHTML;
15
- defineCustomElement('sinch-input', (_$input = new WeakMap(), _$label = new WeakMap(), _$optionalText = new WeakMap(), _$additionalText = new WeakMap(), _$invalidText = new WeakMap(), _selectionStart = new WeakMap(), _selectionEnd = new WeakMap(), _isPendingDk = new WeakMap(), _onCompositionStart = new WeakMap(), _onInput = new WeakMap(), class extends NectaryElement {
15
+ defineCustomElement('sinch-input', (_$input = new WeakMap(), _$label = new WeakMap(), _$optionalText = new WeakMap(), _$additionalText = new WeakMap(), _$invalidText = new WeakMap(), _$iconSlot = new WeakMap(), _$iconWrapper = new WeakMap(), _$rightSlot = new WeakMap(), _$rightWrapper = new WeakMap(), _cursorPos = new WeakMap(), _isPendingDk = new WeakMap(), _onCompositionStart = new WeakMap(), _onSelectionChange = new WeakMap(), _onInput = new WeakMap(), _onIconSlotChange = new WeakMap(), _onRightSlotChange = new WeakMap(), _onEventFilter = new WeakMap(), class extends NectaryElement {
16
16
  constructor() {
17
17
  super();
18
18
 
@@ -41,12 +41,27 @@ defineCustomElement('sinch-input', (_$input = new WeakMap(), _$label = new WeakM
41
41
  value: void 0
42
42
  });
43
43
 
44
- _classPrivateFieldInitSpec(this, _selectionStart, {
44
+ _classPrivateFieldInitSpec(this, _$iconSlot, {
45
45
  writable: true,
46
- value: null
46
+ value: void 0
47
47
  });
48
48
 
49
- _classPrivateFieldInitSpec(this, _selectionEnd, {
49
+ _classPrivateFieldInitSpec(this, _$iconWrapper, {
50
+ writable: true,
51
+ value: void 0
52
+ });
53
+
54
+ _classPrivateFieldInitSpec(this, _$rightSlot, {
55
+ writable: true,
56
+ value: void 0
57
+ });
58
+
59
+ _classPrivateFieldInitSpec(this, _$rightWrapper, {
60
+ writable: true,
61
+ value: void 0
62
+ });
63
+
64
+ _classPrivateFieldInitSpec(this, _cursorPos, {
50
65
  writable: true,
51
66
  value: null
52
67
  });
@@ -63,6 +78,13 @@ defineCustomElement('sinch-input', (_$input = new WeakMap(), _$label = new WeakM
63
78
  }
64
79
  });
65
80
 
81
+ _classPrivateFieldInitSpec(this, _onSelectionChange, {
82
+ writable: true,
83
+ value: () => {
84
+ _classPrivateFieldSet(this, _cursorPos, _classPrivateFieldGet(this, _$input).selectionEnd);
85
+ }
86
+ });
87
+
66
88
  _classPrivateFieldInitSpec(this, _onInput, {
67
89
  writable: true,
68
90
  value: e => {
@@ -73,29 +95,23 @@ defineCustomElement('sinch-input', (_$input = new WeakMap(), _$label = new WeakM
73
95
  const prevValue = this.value;
74
96
 
75
97
  if (prevValue !== nextValue) {
76
- const nextSelectionStart = _classPrivateFieldGet(this, _$input).selectionStart;
77
-
78
- const nextSelectionEnd = _classPrivateFieldGet(this, _$input).selectionEnd;
79
-
80
- const prevSelectionStart = _classPrivateFieldGet(this, _selectionStart);
81
-
82
- const prevSelectionEnd = _classPrivateFieldGet(this, _selectionEnd);
83
-
84
- const isPrevCursorEnd = prevSelectionStart === prevSelectionEnd && prevSelectionStart === prevValue.length;
98
+ const nextCursorPos = _classPrivateFieldGet(this, _$input).selectionEnd;
85
99
 
86
100
  if (!_classPrivateFieldGet(this, _isPendingDk)) {
87
101
  _classPrivateFieldGet(this, _$input).value = prevValue;
88
- }
89
102
 
90
- _classPrivateFieldSet(this, _isPendingDk, false);
103
+ const prevCursorPos = _classPrivateFieldGet(this, _cursorPos);
104
+
105
+ const isPrevCursorEnd = prevCursorPos === null || prevCursorPos === prevValue.length;
91
106
 
92
- if (!isPrevCursorEnd) {
93
- _classPrivateFieldGet(this, _$input).setSelectionRange(prevSelectionStart, prevSelectionEnd);
107
+ if (!isPrevCursorEnd) {
108
+ _classPrivateFieldGet(this, _$input).setSelectionRange(prevCursorPos, prevCursorPos);
109
+ }
94
110
  }
95
111
 
96
- _classPrivateFieldSet(this, _selectionStart, nextSelectionStart);
112
+ _classPrivateFieldSet(this, _isPendingDk, false);
97
113
 
98
- _classPrivateFieldSet(this, _selectionEnd, nextSelectionEnd);
114
+ _classPrivateFieldSet(this, _cursorPos, nextCursorPos);
99
115
 
100
116
  this.dispatchEvent(new CustomEvent('change', {
101
117
  detail: nextValue,
@@ -105,6 +121,27 @@ defineCustomElement('sinch-input', (_$input = new WeakMap(), _$label = new WeakM
105
121
  }
106
122
  });
107
123
 
124
+ _classPrivateFieldInitSpec(this, _onIconSlotChange, {
125
+ writable: true,
126
+ value: () => {
127
+ setClass(_classPrivateFieldGet(this, _$iconWrapper), 'empty', _classPrivateFieldGet(this, _$iconSlot).assignedElements().length === 0);
128
+ }
129
+ });
130
+
131
+ _classPrivateFieldInitSpec(this, _onRightSlotChange, {
132
+ writable: true,
133
+ value: () => {
134
+ setClass(_classPrivateFieldGet(this, _$rightWrapper), 'empty', _classPrivateFieldGet(this, _$rightSlot).assignedElements().length === 0);
135
+ }
136
+ });
137
+
138
+ _classPrivateFieldInitSpec(this, _onEventFilter, {
139
+ writable: true,
140
+ value: e => {
141
+ e.stopPropagation();
142
+ }
143
+ });
144
+
108
145
  const shadowRoot = this.attachShadow();
109
146
  shadowRoot.appendChild(template.content.cloneNode(true));
110
147
 
@@ -117,6 +154,14 @@ defineCustomElement('sinch-input', (_$input = new WeakMap(), _$label = new WeakM
117
154
  _classPrivateFieldSet(this, _$additionalText, shadowRoot.querySelector('#additional'));
118
155
 
119
156
  _classPrivateFieldSet(this, _$invalidText, shadowRoot.querySelector('#invalid'));
157
+
158
+ _classPrivateFieldSet(this, _$iconSlot, shadowRoot.querySelector('slot[name="icon"]'));
159
+
160
+ _classPrivateFieldSet(this, _$iconWrapper, shadowRoot.querySelector('#icon'));
161
+
162
+ _classPrivateFieldSet(this, _$rightSlot, shadowRoot.querySelector('slot[name="right"]'));
163
+
164
+ _classPrivateFieldSet(this, _$rightWrapper, shadowRoot.querySelector('#right'));
120
165
  }
121
166
 
122
167
  connectedCallback() {
@@ -125,12 +170,48 @@ defineCustomElement('sinch-input', (_$input = new WeakMap(), _$label = new WeakM
125
170
  _classPrivateFieldGet(this, _$input).addEventListener('input', _classPrivateFieldGet(this, _onInput));
126
171
 
127
172
  _classPrivateFieldGet(this, _$input).addEventListener('compositionstart', _classPrivateFieldGet(this, _onCompositionStart));
173
+
174
+ _classPrivateFieldGet(this, _$input).addEventListener('mousedown', _classPrivateFieldGet(this, _onSelectionChange));
175
+
176
+ _classPrivateFieldGet(this, _$input).addEventListener('keydown', _classPrivateFieldGet(this, _onSelectionChange));
177
+
178
+ _classPrivateFieldGet(this, _$iconSlot).addEventListener('slotchange', _classPrivateFieldGet(this, _onIconSlotChange));
179
+
180
+ _classPrivateFieldGet(this, _$rightSlot).addEventListener('slotchange', _classPrivateFieldGet(this, _onRightSlotChange));
181
+
182
+ _classPrivateFieldGet(this, _$rightSlot).addEventListener('input', _classPrivateFieldGet(this, _onEventFilter));
183
+
184
+ _classPrivateFieldGet(this, _$rightSlot).addEventListener('change', _classPrivateFieldGet(this, _onEventFilter));
185
+
186
+ _classPrivateFieldGet(this, _$rightSlot).addEventListener('focusin', _classPrivateFieldGet(this, _onEventFilter));
187
+
188
+ _classPrivateFieldGet(this, _$rightSlot).addEventListener('focusout', _classPrivateFieldGet(this, _onEventFilter));
189
+
190
+ _classPrivateFieldGet(this, _onIconSlotChange).call(this);
191
+
192
+ _classPrivateFieldGet(this, _onRightSlotChange).call(this);
128
193
  }
129
194
 
130
195
  disconnectedCallback() {
131
196
  _classPrivateFieldGet(this, _$input).removeEventListener('input', _classPrivateFieldGet(this, _onInput));
132
197
 
133
198
  _classPrivateFieldGet(this, _$input).removeEventListener('compositionstart', _classPrivateFieldGet(this, _onCompositionStart));
199
+
200
+ _classPrivateFieldGet(this, _$input).removeEventListener('mousedown', _classPrivateFieldGet(this, _onSelectionChange));
201
+
202
+ _classPrivateFieldGet(this, _$input).removeEventListener('keydown', _classPrivateFieldGet(this, _onSelectionChange));
203
+
204
+ _classPrivateFieldGet(this, _$iconSlot).removeEventListener('slotchange', _classPrivateFieldGet(this, _onIconSlotChange));
205
+
206
+ _classPrivateFieldGet(this, _$rightSlot).removeEventListener('slotchange', _classPrivateFieldGet(this, _onRightSlotChange));
207
+
208
+ _classPrivateFieldGet(this, _$rightSlot).removeEventListener('input', _classPrivateFieldGet(this, _onEventFilter));
209
+
210
+ _classPrivateFieldGet(this, _$rightSlot).removeEventListener('change', _classPrivateFieldGet(this, _onEventFilter));
211
+
212
+ _classPrivateFieldGet(this, _$rightSlot).removeEventListener('focusin', _classPrivateFieldGet(this, _onEventFilter));
213
+
214
+ _classPrivateFieldGet(this, _$rightSlot).removeEventListener('focusout', _classPrivateFieldGet(this, _onEventFilter));
134
215
  }
135
216
 
136
217
  static get observedAttributes() {
@@ -241,12 +322,16 @@ defineCustomElement('sinch-input', (_$input = new WeakMap(), _$label = new WeakM
241
322
  {
242
323
  const nextVal = newVal ?? '';
243
324
 
244
- if (nextVal !== _classPrivateFieldGet(this, _$input).value) {
325
+ const prevVal = _classPrivateFieldGet(this, _$input).value;
326
+
327
+ if (nextVal !== prevVal) {
328
+ const prevCursorPos = _classPrivateFieldGet(this, _$input).selectionEnd;
329
+
330
+ const isPrevCursorEnd = prevCursorPos === prevVal.length;
245
331
  _classPrivateFieldGet(this, _$input).value = nextVal;
246
- const isNextCursorEnd = _classPrivateFieldGet(this, _selectionStart) === _classPrivateFieldGet(this, _selectionEnd) && (_classPrivateFieldGet(this, _selectionStart) === null || _classPrivateFieldGet(this, _selectionStart) === nextVal.length);
247
332
 
248
- if (!isNextCursorEnd) {
249
- _classPrivateFieldGet(this, _$input).setSelectionRange(_classPrivateFieldGet(this, _selectionStart), _classPrivateFieldGet(this, _selectionEnd));
333
+ if (!isPrevCursorEnd) {
334
+ _classPrivateFieldGet(this, _$input).setSelectionRange(_classPrivateFieldGet(this, _cursorPos), _classPrivateFieldGet(this, _cursorPos));
250
335
  }
251
336
  }
252
337
 
package/input/types.d.ts CHANGED
@@ -21,8 +21,6 @@ export declare type TSinchInputElement = HTMLElement & {
21
21
  selectionStart: number | null;
22
22
  selectionEnd: number | null;
23
23
  selectionDirection: 'forward' | 'backward' | 'none' | null;
24
- focus(): void;
25
- blur(): void;
26
24
  /** Change value event */
27
25
  addEventListener(type: 'change', listener: (e: CustomEvent<string>) => void): void;
28
26
  /** Text field type, `text` by default */
package/link/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import '../icons/cancel';
1
+ import '../icons/open-in-new';
2
2
  import type { TSinchLinkElement, TSinchLinkReact } from './types';
3
3
  declare global {
4
4
  namespace JSX {
package/link/index.js CHANGED
@@ -7,7 +7,7 @@ function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedec
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
- import '../icons/cancel';
10
+ import '../icons/open-in-new';
11
11
  import { defineCustomElement, getBooleanAttribute, getAttribute, updateBooleanAttribute, updateAttribute, NectaryElement, isAttrTrue } from '../utils';
12
12
  const templateHTML = '<style>:host{display:inline;outline:0}a{font:var(--sinch-font-body);font-size:inherit;line-height:inherit;color:var(--sinch-color-text-link);fill:var(--sinch-color-text-link);--sinch-size-icon:1em}#icon{display:none;margin-left:.2em;vertical-align:-.25em}a:hover{color:var(--sinch-color-tropical-600);fill:var(--sinch-color-tropical-600)}:host([disabled]:not([disabled=false])) a{color:var(--sinch-color-tropical-200);pointer-events:none;cursor:initial;fill:var(--sinch-color-tropical-200)}:host([external]:not([external=false])) #icon{display:inline-block}</style><a><span id="content"></span><sinch-icon-open-in-new id="icon"></sinch-icon-open-in-new></a>';
13
13
  const template = document.createElement('template');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nectary/components",
3
- "version": "0.31.0",
3
+ "version": "0.33.0",
4
4
  "files": [
5
5
  "theme.css",
6
6
  "**/*/*.js",
@@ -3,8 +3,6 @@ import type { SyntheticEvent } from 'react';
3
3
  export declare type TSinchPaginationElement = HTMLElement & {
4
4
  value: number;
5
5
  max: number;
6
- focus(): void;
7
- blur(): void;
8
6
  readonly prevButtonRect: TRect;
9
7
  readonly nextButtonRect: TRect;
10
8
  nthButtonRect(index: number): TRect | null;
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, _onBackdropClick, _onCancel, _onCloseReactHandler, _dispatchCloseEvent;
4
+ var _$target, _$dialog, _isConnected, _resizeThrottle, _prevOverflowValue, _onExpand, _onCollapse, _isOpen, _onResize, _updateOrientation, _updateOrientationModal, _onBackdropClick, _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, getCssVar, 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-shape-radius-s);contain:content;padding:0;box-sizing:border-box;max-width:unset;max-height:unset}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>';
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(), _onBackdropClick = new WeakMap(), _onCancel = new WeakMap(), _onCloseReactHandler = new WeakMap(), _dispatchCloseEvent = new WeakSet(), class extends NectaryElement {
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(), _onBackdropClick = 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 = 'fit-content';
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 = getCssVar(this, '--sinch-popover-expand-width') !== null;
78
- const largestWidth = Math.max(modalRect.width, targetRect.width);
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-right' || orient === 'top-right') {
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
 
@@ -134,6 +166,22 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
134
166
  }
135
167
  });
136
168
 
169
+ _classPrivateFieldInitSpec(this, _onTargetKeydown, {
170
+ writable: true,
171
+ value: e => {
172
+ switch (e.key) {
173
+ case 'Escape':
174
+ {
175
+ e.preventDefault();
176
+
177
+ _classPrivateMethodGet(this, _dispatchCloseEvent, _dispatchCloseEvent2).call(this);
178
+
179
+ break;
180
+ }
181
+ }
182
+ }
183
+ });
184
+
137
185
  const shadowRoot = this.attachShadow();
138
186
  shadowRoot.appendChild(template.content.cloneNode(true));
139
187
 
@@ -143,7 +191,7 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
143
191
 
144
192
  _classPrivateFieldSet(this, _isConnected, false);
145
193
 
146
- _classPrivateFieldSet(this, _resizeThrottle, throttleAnimationFrame(_classPrivateFieldGet(this, _updateOrientation)));
194
+ _classPrivateFieldSet(this, _resizeThrottle, throttleAnimationFrame(_classPrivateFieldGet(this, _updateOrientationModal)));
147
195
 
148
196
  dialogPolyfill.registerDialog(_classPrivateFieldGet(this, _$dialog));
149
197
  }
@@ -153,7 +201,7 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
153
201
 
154
202
  _classPrivateFieldGet(this, _$dialog).addEventListener('cancel', _classPrivateFieldGet(this, _onCancel));
155
203
 
156
- _classPrivateFieldGet(this, _$dialog).addEventListener('click', _classPrivateFieldGet(this, _onBackdropClick));
204
+ _classPrivateFieldGet(this, _$dialog).addEventListener('mousedown', _classPrivateFieldGet(this, _onBackdropClick));
157
205
 
158
206
  this.addEventListener('close', _classPrivateFieldGet(this, _onCloseReactHandler));
159
207
 
@@ -169,15 +217,25 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
169
217
  disconnectedCallback() {
170
218
  _classPrivateFieldGet(this, _$dialog).removeEventListener('cancel', _classPrivateFieldGet(this, _onCancel));
171
219
 
172
- _classPrivateFieldGet(this, _$dialog).removeEventListener('click', _classPrivateFieldGet(this, _onBackdropClick));
220
+ _classPrivateFieldGet(this, _$dialog).removeEventListener('mousedown', _classPrivateFieldGet(this, _onBackdropClick));
173
221
 
174
222
  this.removeEventListener('close', _classPrivateFieldGet(this, _onCloseReactHandler));
175
223
 
224
+ _classPrivateMethodGet(this, _onCollapse, _onCollapse2).call(this);
225
+
176
226
  _classPrivateFieldSet(this, _isConnected, false);
177
227
  }
178
228
 
179
229
  static get observedAttributes() {
180
- return ['open', 'orientation'];
230
+ return ['modal', 'orientation', 'open'];
231
+ }
232
+
233
+ set modal(isModal) {
234
+ updateBooleanAttribute(this, 'modal', isModal);
235
+ }
236
+
237
+ get modal() {
238
+ return getBooleanAttribute(this, 'modal');
181
239
  }
182
240
 
183
241
  set open(isOpen) {
@@ -189,7 +247,7 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
189
247
  }
190
248
 
191
249
  get orientation() {
192
- return getLiteralAttribute(this, orientationValues, 'orientation', 'bottom-right');
250
+ return getLiteralAttribute(this, orientationValues, 'orientation', 'bottom');
193
251
  }
194
252
 
195
253
  set orientation(value) {
@@ -201,48 +259,77 @@ defineCustomElement('sinch-popover', (_$target = new WeakMap(), _$dialog = new W
201
259
  }
202
260
 
203
261
  attributeChangedCallback(name, oldVal, newVal) {
262
+ if (oldVal === newVal) {
263
+ return;
264
+ }
265
+
204
266
  switch (name) {
205
267
  case 'open':
206
268
  {
207
- if (_classPrivateFieldGet(this, _isConnected)) {
208
- if (isAttrTrue(newVal)) {
209
- _classPrivateMethodGet(this, _onExpand, _onExpand2).call(this);
210
- } else {
211
- _classPrivateMethodGet(this, _onCollapse, _onCollapse2).call(this);
212
- }
269
+ if (isAttrTrue(newVal)) {
270
+ _classPrivateMethodGet(this, _onExpand, _onExpand2).call(this);
271
+ } else {
272
+ _classPrivateMethodGet(this, _onCollapse, _onCollapse2).call(this);
213
273
  }
214
274
 
275
+ updateBooleanAttribute(this, 'open', isAttrTrue(newVal));
215
276
  break;
216
277
  }
217
278
 
218
279
  case 'orientation':
219
280
  {
220
281
  if (_classPrivateMethodGet(this, _isOpen, _isOpen2).call(this)) {
221
- _classPrivateFieldGet(this, _updateOrientation).call(this);
282
+ if (this.modal) {
283
+ _classPrivateFieldGet(this, _updateOrientationModal).call(this);
284
+ } else {
285
+ _classPrivateFieldGet(this, _updateOrientation).call(this);
286
+ }
222
287
  }
223
288
 
224
289
  break;
225
290
  }
291
+
292
+ case 'modal':
293
+ {
294
+ if (_classPrivateMethodGet(this, _isOpen, _isOpen2).call(this)) {
295
+ _classPrivateMethodGet(this, _onCollapse, _onCollapse2).call(this);
296
+
297
+ _classPrivateMethodGet(this, _onExpand, _onExpand2).call(this);
298
+ }
299
+ }
226
300
  }
227
301
  }
228
302
 
229
303
  }));
230
304
 
231
305
  function _onExpand2() {
232
- if (_classPrivateMethodGet(this, _isOpen, _isOpen2).call(this)) {
306
+ if (!_classPrivateFieldGet(this, _isConnected) || _classPrivateMethodGet(this, _isOpen, _isOpen2).call(this)) {
233
307
  return;
234
308
  }
235
309
 
236
- _classPrivateFieldGet(this, _$target).setAttribute('aria-expanded', 'true');
310
+ if (this.modal) {
311
+ _classPrivateFieldGet(this, _$dialog).style.position = 'fixed';
312
+
313
+ _classPrivateFieldGet(this, _$dialog).showModal();
314
+
315
+ _classPrivateFieldGet(this, _updateOrientationModal).call(this);
316
+
317
+ _classPrivateFieldGet(this, _$target).setAttribute('aria-expanded', 'true');
237
318
 
238
- _classPrivateFieldGet(this, _$dialog).showModal();
319
+ _classPrivateFieldSet(this, _prevOverflowValue, document.body.style.overflow);
239
320
 
240
- _classPrivateFieldGet(this, _updateOrientation).call(this);
321
+ document.body.style.overflow = 'hidden';
322
+ window.addEventListener('resize', _classPrivateFieldGet(this, _onResize));
323
+ } else {
324
+ this.addEventListener('keydown', _classPrivateFieldGet(this, _onTargetKeydown));
325
+ _classPrivateFieldGet(this, _$dialog).style.position = 'absolute';
241
326
 
242
- _classPrivateFieldSet(this, _prevOverflowValue, document.body.style.overflow);
327
+ _classPrivateFieldGet(this, _$dialog).setAttribute('open', '');
243
328
 
244
- document.body.style.overflow = 'hidden';
245
- window.addEventListener('resize', _classPrivateFieldGet(this, _onResize));
329
+ _classPrivateFieldGet(this, _updateOrientation).call(this);
330
+
331
+ _classPrivateFieldGet(this, _$target).setAttribute('aria-expanded', 'true');
332
+ }
246
333
  }
247
334
 
248
335
  function _onCollapse2() {
@@ -250,17 +337,24 @@ function _onCollapse2() {
250
337
  return;
251
338
  }
252
339
 
340
+ if (this.modal) {
341
+ _classPrivateFieldGet(this, _$dialog).close?.();
342
+ } else {
343
+ _classPrivateFieldGet(this, _$dialog).removeAttribute('open');
344
+ }
345
+
253
346
  _classPrivateFieldGet(this, _$target).setAttribute('aria-expanded', 'false');
254
347
 
255
- _classPrivateFieldGet(this, _$dialog).close?.();
256
348
  document.body.style.overflow = _classPrivateFieldGet(this, _prevOverflowValue);
257
- window.removeEventListener('resize', _classPrivateFieldGet(this, _onResize));
258
349
 
259
350
  _classPrivateFieldGet(this, _resizeThrottle).cancel();
351
+
352
+ window.removeEventListener('resize', _classPrivateFieldGet(this, _onResize));
353
+ this.removeEventListener('keydown', _classPrivateFieldGet(this, _onTargetKeydown));
260
354
  }
261
355
 
262
356
  function _isOpen2() {
263
- return _classPrivateFieldGet(this, _isConnected) && getBooleanAttribute(_classPrivateFieldGet(this, _$dialog), 'open');
357
+ return getBooleanAttribute(_classPrivateFieldGet(this, _$dialog), 'open');
264
358
  }
265
359
 
266
360
  function _dispatchCloseEvent2() {
@@ -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
- onClose: (event: SyntheticEvent<TSinchPopoverElement, CustomEvent<void>>) => void;
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'];
@@ -4,8 +4,6 @@ export declare type TSinchRadioOptionElement = HTMLElement & {
4
4
  checked: boolean;
5
5
  disabled: boolean;
6
6
  text: string;
7
- focus(): void;
8
- blur(): void;
9
7
  setAttribute(name: 'value', value: string): void;
10
8
  setAttribute(name: 'checked', value: ''): void;
11
9
  setAttribute(name: 'disabled', value: ''): void;
package/search/types.d.ts CHANGED
@@ -9,8 +9,6 @@ export declare type TSinchSearchElement = HTMLElement & {
9
9
  selectionEnd: HTMLInputElement['selectionEnd'];
10
10
  selectionDirection: HTMLInputElement['selectionDirection'];
11
11
  readonly dropdownRect: TRect;
12
- focus(): void;
13
- blur(): void;
14
12
  addEventListener(type: 'change', listener: (e: CustomEvent<string>) => void): void;
15
13
  setAttribute(name: 'value', value: string): void;
16
14
  setAttribute(name: 'label', value: string): void;