@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.
@@ -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 _$optionSlot, _$listbox, _$popover, _onListboxKeyDown, _getFirstOption, _getLastOption, _getNextOption, _getPrevOption, _selectOption, _getOptionElements, _findSelectedOption, _getEnabledOptionElements, _onOpen, _onClose, _onReactClose;
4
+ var _$optionSlot, _$listbox, _$popover, _onListboxKeyDown, _getFirstOption, _getLastOption, _getNextOption, _getPrevOption, _selectOption, _getOptionElements, _findSelectedOption, _getEnabledOptionElements, _onClose, _onReactClose;
5
5
 
6
6
  function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
7
7
 
@@ -14,16 +14,14 @@ function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(
14
14
  import { orientationValues } from '../popover/utils';
15
15
  import '../popover';
16
16
  import { attrValueToPixels, defineCustomElement, getBooleanAttribute, getIntegerAttribute, getLiteralAttribute, getReactEventHandler, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateIntegerAttribute, updateLiteralAttribute } from '../utils';
17
- const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}sinch-popover{width:100%}</style><sinch-popover><slot name="target" slot="target"></slot><div id="listbox" slot="content"><slot name="option"></slot></div></sinch-popover>';
17
+ const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}#wrapper{width:100%;--sinch-popover-shape-radius:var(--sinch-shape-radius-s)}#listbox{overflow-y:auto}</style><sinch-popover id="wrapper"><slot name="target" slot="target"></slot><div id="listbox" slot="content"><slot name="option"></slot></div></sinch-popover>';
18
18
  const ITEM_HEIGHT = 40;
19
19
  const template = document.createElement('template');
20
20
  template.innerHTML = templateHTML;
21
- defineCustomElement('sinch-action-menu', (_$optionSlot = new WeakMap(), _$listbox = new WeakMap(), _$popover = new WeakMap(), _onListboxKeyDown = new WeakMap(), _getFirstOption = new WeakSet(), _getLastOption = new WeakSet(), _getNextOption = new WeakSet(), _getPrevOption = new WeakSet(), _selectOption = new WeakSet(), _getOptionElements = new WeakSet(), _findSelectedOption = new WeakSet(), _getEnabledOptionElements = new WeakSet(), _onOpen = new WeakSet(), _onClose = new WeakMap(), _onReactClose = new WeakMap(), class extends NectaryElement {
21
+ defineCustomElement('sinch-action-menu', (_$optionSlot = new WeakMap(), _$listbox = new WeakMap(), _$popover = new WeakMap(), _onListboxKeyDown = new WeakMap(), _getFirstOption = new WeakSet(), _getLastOption = new WeakSet(), _getNextOption = new WeakSet(), _getPrevOption = new WeakSet(), _selectOption = new WeakSet(), _getOptionElements = new WeakSet(), _findSelectedOption = new WeakSet(), _getEnabledOptionElements = new WeakSet(), _onClose = new WeakMap(), _onReactClose = new WeakMap(), class extends NectaryElement {
22
22
  constructor() {
23
23
  super();
24
24
 
25
- _classPrivateMethodInitSpec(this, _onOpen);
26
-
27
25
  _classPrivateMethodInitSpec(this, _getEnabledOptionElements);
28
26
 
29
27
  _classPrivateMethodInitSpec(this, _findSelectedOption);
@@ -59,8 +57,19 @@ defineCustomElement('sinch-action-menu', (_$optionSlot = new WeakMap(), _$listbo
59
57
  writable: true,
60
58
  value: e => {
61
59
  switch (e.code) {
60
+ case 'Enter':
61
+ {
62
+ const $opt = _classPrivateMethodGet(this, _findSelectedOption, _findSelectedOption2).call(this, _classPrivateMethodGet(this, _getEnabledOptionElements, _getEnabledOptionElements2).call(this));
63
+
64
+ if ($opt !== null) {
65
+ e.preventDefault();
66
+ $opt.click();
67
+ }
68
+
69
+ break;
70
+ }
71
+
62
72
  case 'ArrowUp':
63
- case 'ArrowLeft':
64
73
  {
65
74
  e.preventDefault();
66
75
 
@@ -70,7 +79,6 @@ defineCustomElement('sinch-action-menu', (_$optionSlot = new WeakMap(), _$listbo
70
79
  }
71
80
 
72
81
  case 'ArrowDown':
73
- case 'ArrowRight':
74
82
  {
75
83
  e.preventDefault();
76
84
 
@@ -118,7 +126,7 @@ defineCustomElement('sinch-action-menu', (_$optionSlot = new WeakMap(), _$listbo
118
126
  }
119
127
 
120
128
  static get observedAttributes() {
121
- return ['open', 'orientation', 'maxvisibleitems'];
129
+ return ['open', 'orientation', 'maxvisibleitems', 'modal'];
122
130
  }
123
131
 
124
132
  get nodeName() {
@@ -149,6 +157,14 @@ defineCustomElement('sinch-action-menu', (_$optionSlot = new WeakMap(), _$listbo
149
157
  return getBooleanAttribute(this, 'open');
150
158
  }
151
159
 
160
+ set modal(isModal) {
161
+ updateBooleanAttribute(this, 'modal', isModal);
162
+ }
163
+
164
+ get modal() {
165
+ return getBooleanAttribute(this, 'modal');
166
+ }
167
+
152
168
  get dropdownRect() {
153
169
  return _classPrivateFieldGet(this, _$popover).popoverRect;
154
170
  }
@@ -160,8 +176,6 @@ defineCustomElement('sinch-action-menu', (_$optionSlot = new WeakMap(), _$listbo
160
176
  updateAttribute(_classPrivateFieldGet(this, _$popover), 'open', newVal);
161
177
 
162
178
  if (isAttrTrue(newVal)) {
163
- _classPrivateMethodGet(this, _onOpen, _onOpen2).call(this);
164
-
165
179
  _classPrivateFieldGet(this, _$popover).addEventListener('keydown', _classPrivateFieldGet(this, _onListboxKeyDown));
166
180
 
167
181
  _classPrivateFieldGet(this, _$popover).addEventListener('close', _classPrivateFieldGet(this, _onClose));
@@ -169,6 +183,8 @@ defineCustomElement('sinch-action-menu', (_$optionSlot = new WeakMap(), _$listbo
169
183
  _classPrivateFieldGet(this, _$popover).removeEventListener('keydown', _classPrivateFieldGet(this, _onListboxKeyDown));
170
184
 
171
185
  _classPrivateFieldGet(this, _$popover).removeEventListener('close', _classPrivateFieldGet(this, _onClose));
186
+
187
+ _classPrivateMethodGet(this, _selectOption, _selectOption2).call(this, null);
172
188
  }
173
189
 
174
190
  break;
@@ -193,6 +209,12 @@ defineCustomElement('sinch-action-menu', (_$optionSlot = new WeakMap(), _$listbo
193
209
 
194
210
  break;
195
211
  }
212
+
213
+ case 'modal':
214
+ {
215
+ updateBooleanAttribute(_classPrivateFieldGet(this, _$popover), 'modal', isAttrTrue(newVal));
216
+ break;
217
+ }
196
218
  }
197
219
  }
198
220
 
@@ -235,12 +257,16 @@ function _getPrevOption2() {
235
257
  }
236
258
 
237
259
  function _selectOption2($option) {
260
+ const hasMaxVisibleItems = this.hasAttribute('maxvisibleitems');
261
+
238
262
  for (const $op of _classPrivateMethodGet(this, _getOptionElements, _getOptionElements2).call(this)) {
239
263
  const isSelected = $op === $option;
240
- updateBooleanAttribute($op, 'selected', isSelected);
264
+ updateBooleanAttribute($op, 'data-selected', isSelected);
241
265
 
242
- if (isSelected) {
243
- $op.focus();
266
+ if (isSelected && hasMaxVisibleItems) {
267
+ $op.scrollIntoView?.({
268
+ block: 'nearest'
269
+ });
244
270
  }
245
271
  }
246
272
  }
@@ -257,7 +283,7 @@ function _getOptionElements2() {
257
283
 
258
284
  function _findSelectedOption2(elements) {
259
285
  for (const el of elements) {
260
- if (getBooleanAttribute(el, 'selected')) {
286
+ if (getBooleanAttribute(el, 'data-selected')) {
261
287
  return el;
262
288
  }
263
289
  }
@@ -267,8 +293,4 @@ function _findSelectedOption2(elements) {
267
293
 
268
294
  function _getEnabledOptionElements2() {
269
295
  return _classPrivateMethodGet(this, _getOptionElements, _getOptionElements2).call(this).filter(opt => opt.disabled !== true);
270
- }
271
-
272
- function _onOpen2() {
273
- _classPrivateMethodGet(this, _selectOption, _selectOption2).call(this, _classPrivateMethodGet(this, _getFirstOption, _getFirstOption2).call(this));
274
296
  }
@@ -5,16 +5,19 @@ export declare type TSinchActionMenuElement = HTMLElement & {
5
5
  open: boolean;
6
6
  orientation: TSinchPopoverOrientation;
7
7
  maxVisibleItems: number | null;
8
+ modal: boolean;
8
9
  readonly dropdownRect: TRect;
9
10
  addEventListener(type: 'close', listener: (e: CustomEvent<void>) => void): void;
10
11
  setAttribute(name: 'open', value: ''): void;
11
12
  setAttribute(name: 'orientation', value: TSinchPopoverOrientation): void;
12
13
  setAttribute(name: 'maxvisibleitems', value: string): void;
14
+ setAttribute(name: 'modal', value: boolean): void;
13
15
  };
14
16
  export declare type TSinchActionMenuReact = TSinchElementReact<TSinchActionMenuElement> & {
15
17
  open: boolean;
16
18
  orientation?: TSinchPopoverOrientation;
17
19
  maxVisibleItems?: number;
20
+ modal?: boolean;
18
21
  'aria-label': string;
19
22
  onClose: (event: SyntheticEvent<TSinchActionMenuElement, CustomEvent<void>>) => void;
20
23
  };
@@ -1,21 +1,21 @@
1
1
  import _classPrivateFieldGet from '@babel/runtime/helpers/classPrivateFieldGet';
2
2
  import _classPrivateFieldSet from '@babel/runtime/helpers/classPrivateFieldSet';
3
3
 
4
- var _$button, _$content;
4
+ var _$wrapper, _$content, _onMouseDown;
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, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute } from '../utils';
11
- const templateHTML = '<style>:host{display:block}#wrapper{all:initial;display:flex;position:relative;box-sizing:border-box;height:40px;width:100%;padding:8px 16px;align-items:center;gap:10px;user-select:none;cursor:pointer;font:inherit;color:inherit;--sinch-size-icon:24px}#content{flex-shrink:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#wrapper:focus,:host(:hover)>#wrapper{background-color:var(--sinch-color-snow-500)}:host([disabled]:not([disabled=false]))>#wrapper{color:var(--sinch-color-stormy-100);cursor:initial;--sinch-color-icon:var(--sinch-color-stormy-100)}::slotted(*){margin-left:-6px}</style><button id="wrapper"><slot name="icon"></slot><span id="content"></span></button>';
11
+ const templateHTML = '<style>:host{display:block}#wrapper{all:initial;display:flex;position:relative;box-sizing:border-box;height:40px;width:100%;padding:8px 16px;align-items:center;gap:10px;user-select:none;cursor:pointer;font:inherit;color:inherit;--sinch-size-icon:24px}#content{flex-shrink:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host(:hover)>#wrapper,:host([data-selected])>#wrapper{background-color:var(--sinch-color-snow-500)}:host([disabled]:not([disabled=false]))>#wrapper{color:var(--sinch-color-stormy-100);cursor:initial;pointer-events:none;--sinch-color-icon:var(--sinch-color-stormy-100)}::slotted(*){margin-left:-6px}</style><div id="wrapper"><slot name="icon"></slot><span id="content"></span></div>';
12
12
  const template = document.createElement('template');
13
13
  template.innerHTML = templateHTML;
14
- defineCustomElement('sinch-action-menu-option', (_$button = new WeakMap(), _$content = new WeakMap(), class ActionMenuOption extends NectaryElement {
14
+ defineCustomElement('sinch-action-menu-option', (_$wrapper = new WeakMap(), _$content = new WeakMap(), _onMouseDown = new WeakMap(), class ActionMenuOption extends NectaryElement {
15
15
  constructor() {
16
16
  super();
17
17
 
18
- _classPrivateFieldInitSpec(this, _$button, {
18
+ _classPrivateFieldInitSpec(this, _$wrapper, {
19
19
  writable: true,
20
20
  value: void 0
21
21
  });
@@ -25,16 +25,31 @@ defineCustomElement('sinch-action-menu-option', (_$button = new WeakMap(), _$con
25
25
  value: void 0
26
26
  });
27
27
 
28
+ _classPrivateFieldInitSpec(this, _onMouseDown, {
29
+ writable: true,
30
+ value: e => {
31
+ e.preventDefault();
32
+ e.stopPropagation();
33
+ this.click();
34
+ }
35
+ });
36
+
28
37
  const shadowRoot = this.attachShadow();
29
38
  shadowRoot.appendChild(template.content.cloneNode(true));
30
39
 
31
- _classPrivateFieldSet(this, _$button, shadowRoot.querySelector('#wrapper'));
40
+ _classPrivateFieldSet(this, _$wrapper, shadowRoot.querySelector('#wrapper'));
32
41
 
33
42
  _classPrivateFieldSet(this, _$content, shadowRoot.querySelector('#content'));
34
43
  }
35
44
 
36
45
  connectedCallback() {
37
46
  this.setAttribute('role', 'option');
47
+
48
+ _classPrivateFieldGet(this, _$wrapper).addEventListener('mousedown', _classPrivateFieldGet(this, _onMouseDown));
49
+ }
50
+
51
+ disconnectedCallback() {
52
+ _classPrivateFieldGet(this, _$wrapper).removeEventListener('mousedown', _classPrivateFieldGet(this, _onMouseDown));
38
53
  }
39
54
 
40
55
  static get observedAttributes() {
@@ -55,7 +70,8 @@ defineCustomElement('sinch-action-menu-option', (_$button = new WeakMap(), _$con
55
70
 
56
71
  case 'disabled':
57
72
  {
58
- _classPrivateFieldGet(this, _$button).disabled = isAttrTrue(newVal);
73
+ updateBooleanAttribute(this, 'disabled', isAttrTrue(newVal));
74
+ break;
59
75
  }
60
76
  }
61
77
  }
@@ -76,12 +92,4 @@ defineCustomElement('sinch-action-menu-option', (_$button = new WeakMap(), _$con
76
92
  return getBooleanAttribute(this, 'disabled');
77
93
  }
78
94
 
79
- focus() {
80
- _classPrivateFieldGet(this, _$button).focus();
81
- }
82
-
83
- blur() {
84
- _classPrivateFieldGet(this, _$button).blur();
85
- }
86
-
87
95
  }));
package/dialog/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import '../icon-button';
2
2
  import '../icons/close';
3
+ import '../stop-events';
3
4
  import type { TSinchDialogElement, TSinchDialogReact } from './types';
4
5
  declare global {
5
6
  namespace JSX {
package/dialog/index.js CHANGED
@@ -14,8 +14,9 @@ function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(
14
14
  import dialogPolyfill from 'dialog-polyfill';
15
15
  import '../icon-button';
16
16
  import '../icons/close';
17
- import { defineCustomElement, getAttribute, getBooleanAttribute, getRect, isAttrTrue, updateAttribute, getReactEventHandler, NectaryElement } from '../utils';
18
- const templateHTML = '<style>dialog{position:fixed;left:0;right:0;margin:auto;display:flex;flex-direction:column;padding:24px;max-width:var(--sinch-dialog-max-width,512px);max-height:unset;border-radius:var(--sinch-shape-radius-l);box-sizing:border-box;contain:content;background-color:var(--sinch-color-snow-100);color:var(--sinch-color-text-default);font:var(--sinch-font-body);border:none;box-shadow:var(--sinch-elevation-level-3)}dialog:not([open]){display:none}dialog+.backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background-color:#000;opacity:.55}dialog::backdrop{background-color:#000;opacity:.55}._dialog_overlay{position:fixed;top:0;right:0;bottom:0;left:0}dialog.fixed{position:fixed;top:50%;transform:translate(0,-50%)}#header{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start;margin-bottom:16px}#caption{font:var(--sinch-font-title-m);color:var(--sinch-color-text-default);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}#content-wrapper{min-height:0;overflow:auto;max-height:var(--sinch-dialog-max-height,50vh)}#buttons{display:flex;flex-direction:row;justify-content:flex-end;gap:16px;margin-top:24px}sinch-icon-button{transform:translate(4px,-4px)}</style><dialog><div id="header"><span id="caption"></span><sinch-icon-button id="close" small tabindex="0"><sinch-icon-close slot="icon"></sinch-icon-close></sinch-icon-button></div><div id="content-wrapper"><slot name="content"></slot></div><div id="buttons"><slot name="buttons"></slot></div></dialog>';
17
+ import '../stop-events';
18
+ import { defineCustomElement, getAttribute, getBooleanAttribute, getRect, isAttrTrue, updateAttribute, getReactEventHandler, NectaryElement, updateBooleanAttribute } from '../utils';
19
+ const templateHTML = '<style>dialog{position:fixed;left:0;right:0;margin:auto;display:flex;flex-direction:column;padding:24px;max-width:var(--sinch-dialog-max-width,512px);max-height:unset;border-radius:var(--sinch-shape-radius-l);box-sizing:border-box;contain:content;background-color:var(--sinch-color-snow-100);color:var(--sinch-color-text-default);font:var(--sinch-font-body);border:none;box-shadow:var(--sinch-elevation-level-3)}dialog:not([open]){display:none}dialog+.backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background-color:#000;opacity:.55}dialog::backdrop{background-color:#000;opacity:.55}._dialog_overlay{position:fixed;top:0;right:0;bottom:0;left:0}dialog.fixed{position:fixed;top:50%;transform:translate(0,-50%)}#header{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start;margin-bottom:16px}#caption{font:var(--sinch-font-title-m);color:var(--sinch-color-text-default);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}#content{min-height:0;overflow:auto;max-height:var(--sinch-dialog-max-height,50vh)}#buttons{display:flex;flex-direction:row;justify-content:flex-end;gap:16px;margin-top:24px}sinch-icon-button{transform:translate(4px,-4px)}</style><dialog><div id="header"><span id="caption"></span><sinch-icon-button id="close" small tabindex="0"><sinch-icon-close slot="icon"></sinch-icon-close></sinch-icon-button></div><div id="content"><sinch-stop-events events="close"><slot name="content"></slot></sinch-stop-events></div><div id="buttons"><sinch-stop-events events="close"><slot name="buttons"></slot></sinch-stop-events></div></dialog>';
19
20
  const template = document.createElement('template');
20
21
  template.innerHTML = templateHTML;
21
22
  defineCustomElement('sinch-dialog', (_$dialog = new WeakMap(), _$closeButton = new WeakMap(), _$caption = new WeakMap(), _isConnected = new WeakMap(), _prevOverflowValue = new WeakMap(), _onCancel = new WeakMap(), _onCloseClick = new WeakMap(), _onBackdropClick = new WeakMap(), _onCloseReactHandler = new WeakMap(), _dispatchCloseEvent = new WeakSet(), _setOpen = new WeakSet(), class extends NectaryElement {
@@ -62,9 +63,7 @@ defineCustomElement('sinch-dialog', (_$dialog = new WeakMap(), _$closeButton = n
62
63
 
63
64
  _classPrivateFieldInitSpec(this, _onCloseClick, {
64
65
  writable: true,
65
- value: e => {
66
- e.stopPropagation();
67
-
66
+ value: () => {
68
67
  _classPrivateMethodGet(this, _dispatchCloseEvent, _dispatchCloseEvent2).call(this);
69
68
  }
70
69
  });
@@ -80,8 +79,6 @@ defineCustomElement('sinch-dialog', (_$dialog = new WeakMap(), _$closeButton = n
80
79
  const isInside = e.x >= rect.x && e.x < rect.x + rect.width && e.y >= rect.y && e.y < rect.y + rect.height;
81
80
 
82
81
  if (!isInside) {
83
- e.stopPropagation();
84
-
85
82
  _classPrivateMethodGet(this, _dispatchCloseEvent, _dispatchCloseEvent2).call(this);
86
83
  }
87
84
  }
@@ -106,8 +103,38 @@ defineCustomElement('sinch-dialog', (_$dialog = new WeakMap(), _$closeButton = n
106
103
  dialogPolyfill.registerDialog(_classPrivateFieldGet(this, _$dialog));
107
104
  }
108
105
 
106
+ connectedCallback() {
107
+ this.setAttribute('role', 'dialog');
108
+
109
+ _classPrivateFieldGet(this, _$closeButton).addEventListener('click', _classPrivateFieldGet(this, _onCloseClick));
110
+
111
+ _classPrivateFieldGet(this, _$dialog).addEventListener('mousedown', _classPrivateFieldGet(this, _onBackdropClick));
112
+
113
+ _classPrivateFieldGet(this, _$dialog).addEventListener('cancel', _classPrivateFieldGet(this, _onCancel));
114
+
115
+ this.addEventListener('close', _classPrivateFieldGet(this, _onCloseReactHandler));
116
+
117
+ _classPrivateFieldSet(this, _isConnected, true);
118
+
119
+ _classPrivateMethodGet(this, _setOpen, _setOpen2).call(this, getBooleanAttribute(this, 'open'));
120
+ }
121
+
122
+ disconnectedCallback() {
123
+ _classPrivateFieldGet(this, _$closeButton).removeEventListener('click', _classPrivateFieldGet(this, _onCloseClick));
124
+
125
+ _classPrivateFieldGet(this, _$dialog).removeEventListener('mousedown', _classPrivateFieldGet(this, _onBackdropClick));
126
+
127
+ _classPrivateFieldGet(this, _$dialog).removeEventListener('cancel', _classPrivateFieldGet(this, _onCancel));
128
+
129
+ this.removeEventListener('close', _classPrivateFieldGet(this, _onCloseReactHandler));
130
+
131
+ _classPrivateMethodGet(this, _setOpen, _setOpen2).call(this, false);
132
+
133
+ _classPrivateFieldSet(this, _isConnected, false);
134
+ }
135
+
109
136
  static get observedAttributes() {
110
- return ['caption', 'open'];
137
+ return ['caption', 'open', 'close-aria-label'];
111
138
  }
112
139
 
113
140
  attributeChangedCallback(name, _, newVal) {
@@ -120,10 +147,17 @@ defineCustomElement('sinch-dialog', (_$dialog = new WeakMap(), _$closeButton = n
120
147
 
121
148
  case 'open':
122
149
  {
123
- if (_classPrivateFieldGet(this, _isConnected)) {
124
- _classPrivateMethodGet(this, _setOpen, _setOpen2).call(this, isAttrTrue(newVal));
125
- }
150
+ const shouldOpen = isAttrTrue(newVal);
151
+
152
+ _classPrivateMethodGet(this, _setOpen, _setOpen2).call(this, shouldOpen);
126
153
 
154
+ updateBooleanAttribute(this, 'open', shouldOpen);
155
+ break;
156
+ }
157
+
158
+ case 'close-aria-label':
159
+ {
160
+ updateAttribute(_classPrivateFieldGet(this, _$closeButton), 'aria-label', newVal);
127
161
  break;
128
162
  }
129
163
  }
@@ -137,36 +171,6 @@ defineCustomElement('sinch-dialog', (_$dialog = new WeakMap(), _$closeButton = n
137
171
  return getAttribute(this, 'caption', '');
138
172
  }
139
173
 
140
- connectedCallback() {
141
- this.setAttribute('role', 'dialog');
142
-
143
- _classPrivateFieldGet(this, _$closeButton).addEventListener('click', _classPrivateFieldGet(this, _onCloseClick));
144
-
145
- this.addEventListener('close', _classPrivateFieldGet(this, _onCloseReactHandler));
146
-
147
- _classPrivateFieldGet(this, _$dialog).addEventListener('mousedown', _classPrivateFieldGet(this, _onBackdropClick));
148
-
149
- _classPrivateFieldGet(this, _$dialog).addEventListener('cancel', _classPrivateFieldGet(this, _onCancel));
150
-
151
- _classPrivateFieldSet(this, _isConnected, true);
152
-
153
- if (getBooleanAttribute(this, 'open')) {
154
- _classPrivateMethodGet(this, _setOpen, _setOpen2).call(this, true);
155
- }
156
- }
157
-
158
- disconnectedCallback() {
159
- _classPrivateFieldGet(this, _$closeButton).removeEventListener('click', _classPrivateFieldGet(this, _onCloseClick));
160
-
161
- this.removeEventListener('close', _classPrivateFieldGet(this, _onCloseReactHandler));
162
-
163
- _classPrivateFieldGet(this, _$dialog).removeEventListener('mousedown', _classPrivateFieldGet(this, _onBackdropClick));
164
-
165
- _classPrivateFieldGet(this, _$dialog).removeEventListener('cancel', _classPrivateFieldGet(this, _onCancel));
166
-
167
- _classPrivateFieldSet(this, _isConnected, false);
168
- }
169
-
170
174
  get dialogRect() {
171
175
  return getRect(_classPrivateFieldGet(this, _$dialog));
172
176
  }
@@ -183,14 +187,14 @@ function _dispatchCloseEvent2() {
183
187
  }));
184
188
  }
185
189
 
186
- function _setOpen2(isOpen) {
187
- if (isOpen) {
188
- if (!getBooleanAttribute(_classPrivateFieldGet(this, _$dialog), 'open')) {
189
- _classPrivateFieldGet(this, _$dialog).showModal();
190
-
190
+ function _setOpen2(shouldOpen) {
191
+ if (shouldOpen) {
192
+ if (_classPrivateFieldGet(this, _isConnected) && !getBooleanAttribute(_classPrivateFieldGet(this, _$dialog), 'open')) {
191
193
  _classPrivateFieldSet(this, _prevOverflowValue, document.body.style.overflow);
192
194
 
193
195
  document.body.style.overflow = 'hidden';
196
+
197
+ _classPrivateFieldGet(this, _$dialog).showModal();
194
198
  }
195
199
  } else {
196
200
  _classPrivateFieldGet(this, _$dialog).close?.();
package/dialog/types.d.ts CHANGED
@@ -6,10 +6,12 @@ export declare type TSinchDialogElement = HTMLElement & {
6
6
  readonly closeButtonRect: TRect;
7
7
  addEventListener(type: 'close', listener: (e: CustomEvent<void>) => void): void;
8
8
  setAttribute(name: 'caption', value: string): void;
9
+ setAttribute(name: 'close-aria-label', value: string): void;
9
10
  };
10
11
  export declare type TSinchDialogReact = TSinchElementReact<TSinchDialogElement> & {
11
12
  open: boolean;
12
13
  caption: string;
13
14
  'aria-label': string;
15
+ 'close-aria-label': string;
14
16
  onClose: (event: SyntheticEvent<TSinchDialogElement, CustomEvent<void>>) => void;
15
17
  };
package/dropdown/index.js CHANGED
@@ -14,7 +14,7 @@ function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(
14
14
  import { orientationValues } from '../popover/utils';
15
15
  import '../popover';
16
16
  import { attrValueToPixels, defineCustomElement, getAttribute, getBooleanAttribute, getCsvSet, getFirstCsvValue, getIntegerAttribute, getLiteralAttribute, getReactEventHandler, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateCsv, updateIntegerAttribute, updateLiteralAttribute } from '../utils';
17
- const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}sinch-popover{width:100%}</style><sinch-popover><slot name="target" slot="target"></slot><div id="listbox" slot="content"><slot name="option"></slot></div></sinch-popover>';
17
+ const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}#wrapper{width:100%;--sinch-popover-shape-radius:var(--sinch-shape-radius-s)}#listbox{overflow-y:auto}</style><sinch-popover id="wrapper" modal><slot name="target" slot="target"></slot><div id="listbox" slot="content"><slot name="option"></slot></div></sinch-popover>';
18
18
  const ITEM_HEIGHT = 40;
19
19
  const template = document.createElement('template');
20
20
  template.innerHTML = templateHTML;
@@ -81,9 +81,13 @@ defineCustomElement('sinch-dropdown', (_$optionSlot = new WeakMap(), _$listbox =
81
81
  case 'Space':
82
82
  case 'Enter':
83
83
  {
84
- e.preventDefault();
84
+ const $option = _classPrivateMethodGet(this, _findSelectedOption, _findSelectedOption2).call(this, _classPrivateMethodGet(this, _getEnabledOptionElements, _getEnabledOptionElements2).call(this));
85
+
86
+ if ($option !== null) {
87
+ e.preventDefault();
85
88
 
86
- _classPrivateMethodGet(this, _dispatchChangeEvent, _dispatchChangeEvent2).call(this, _classPrivateMethodGet(this, _findSelectedOption, _findSelectedOption2).call(this, _classPrivateMethodGet(this, _getEnabledOptionElements, _getEnabledOptionElements2).call(this)));
89
+ _classPrivateMethodGet(this, _dispatchChangeEvent, _dispatchChangeEvent2).call(this, $option);
90
+ }
87
91
 
88
92
  break;
89
93
  }
@@ -323,11 +327,13 @@ function _getPrevOption2() {
323
327
  }
324
328
 
325
329
  function _selectOption2($option) {
330
+ const hasMaxVisibleItems = this.hasAttribute('maxvisibleitems');
331
+
326
332
  for (const $op of _classPrivateMethodGet(this, _getOptionElements, _getOptionElements2).call(this)) {
327
333
  const isSelected = $op === $option;
328
334
  updateBooleanAttribute($op, 'data-selected', isSelected);
329
335
 
330
- if (isSelected && this.maxVisibleItems !== null) {
336
+ if (isSelected && hasMaxVisibleItems) {
331
337
  $op.scrollIntoView?.({
332
338
  block: 'nearest'
333
339
  });
@@ -389,13 +395,5 @@ function _dispatchChangeEvent2($opt) {
389
395
  function _onOpen2() {
390
396
  const $opt = _classPrivateMethodGet(this, _getOptionWithValue, _getOptionWithValue2).call(this, getFirstCsvValue(this.value));
391
397
 
392
- if ($opt !== null) {
393
- _classPrivateMethodGet(this, _selectOption, _selectOption2).call(this, $opt);
394
-
395
- $opt.scrollIntoView?.({
396
- block: 'nearest'
397
- });
398
- } else {
399
- _classPrivateMethodGet(this, _selectOption, _selectOption2).call(this, _classPrivateMethodGet(this, _getFirstOption, _getFirstOption2).call(this));
400
- }
398
+ _classPrivateMethodGet(this, _selectOption, _selectOption2).call(this, $opt ?? _classPrivateMethodGet(this, _getFirstOption, _getFirstOption2).call(this));
401
399
  }
@@ -0,0 +1,13 @@
1
+ import '../icons/check';
2
+ import '../icons/error-outline';
3
+ import type { TSinchHorizontalStepperElement, TSinchHorizontalStepperReact } from './types';
4
+ declare global {
5
+ namespace JSX {
6
+ interface IntrinsicElements {
7
+ 'sinch-horizontal-stepper': TSinchHorizontalStepperReact;
8
+ }
9
+ }
10
+ interface HTMLElementTagNameMap {
11
+ 'sinch-horizontal-stepper': TSinchHorizontalStepperElement;
12
+ }
13
+ }
@@ -0,0 +1,104 @@
1
+ import _classPrivateFieldGet from '@babel/runtime/helpers/classPrivateFieldGet';
2
+ import _classPrivateFieldSet from '@babel/runtime/helpers/classPrivateFieldSet';
3
+
4
+ var _$itemsSlot, _$progressBar, _updateItems;
5
+
6
+ function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
7
+
8
+ function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
9
+
10
+ import '../icons/check';
11
+ import '../icons/error-outline';
12
+ import { clampNumber, defineCustomElement, getAttribute, getIntegerAttribute, NectaryElement, updateAttribute } from '../utils';
13
+ const templateHTML = '<style>:host{display:block;outline:0}#wrapper{position:relative;display:flex;flex-direction:row;gap:28px;width:fit-content}#progress{position:absolute;height:1px;background-color:var(--sinch-color-snow-700);left:72px;right:72px;top:16px;transform:translateY(-50%)}#bar{position:absolute;height:1px;background-color:var(--sinch-color-stormy-400);left:0;top:0}</style><div id="wrapper"><div id="progress"><div id="bar"></div></div><slot></slot></div>';
14
+ const template = document.createElement('template');
15
+ template.innerHTML = templateHTML;
16
+ defineCustomElement('sinch-horizontal-stepper', (_$itemsSlot = new WeakMap(), _$progressBar = new WeakMap(), _updateItems = new WeakMap(), class extends NectaryElement {
17
+ constructor() {
18
+ super();
19
+
20
+ _classPrivateFieldInitSpec(this, _$itemsSlot, {
21
+ writable: true,
22
+ value: void 0
23
+ });
24
+
25
+ _classPrivateFieldInitSpec(this, _$progressBar, {
26
+ writable: true,
27
+ value: void 0
28
+ });
29
+
30
+ _classPrivateFieldInitSpec(this, _updateItems, {
31
+ writable: true,
32
+ value: () => {
33
+ const $items = _classPrivateFieldGet(this, _$itemsSlot).assignedElements();
34
+
35
+ const activeIndex = clampNumber(getIntegerAttribute(this, 'index', 0), 0, $items.length + 1);
36
+
37
+ for (let i = 0; i < $items.length; i++) {
38
+ const $el = $items[i];
39
+ const itemIndex = i + 1;
40
+ $el.setAttribute('data-index', String(itemIndex));
41
+
42
+ if (itemIndex === activeIndex) {
43
+ $el.setAttribute('data-progress', 'active');
44
+ } else if (itemIndex < activeIndex) {
45
+ $el.setAttribute('data-progress', 'done');
46
+ } else {
47
+ $el.removeAttribute('data-progress');
48
+ }
49
+ }
50
+
51
+ const valueIndex = clampNumber(activeIndex - 1, 0, $items.length - 1);
52
+ _classPrivateFieldGet(this, _$progressBar).style.width = `${Math.floor(valueIndex / Math.max(1, $items.length - 1) * 100)}%`;
53
+ this.setAttribute('aria-valuemax', String($items.length));
54
+ this.setAttribute('aria-valuenow', String(valueIndex + 1));
55
+ }
56
+ });
57
+
58
+ const shadowRoot = this.attachShadow();
59
+ shadowRoot.appendChild(template.content.cloneNode(true));
60
+
61
+ _classPrivateFieldSet(this, _$itemsSlot, shadowRoot.querySelector('slot'));
62
+
63
+ _classPrivateFieldSet(this, _$progressBar, shadowRoot.querySelector('#bar'));
64
+ }
65
+
66
+ connectedCallback() {
67
+ this.setAttribute('role', 'progressbar');
68
+ this.setAttribute('aria-valuemin', '0');
69
+
70
+ _classPrivateFieldGet(this, _$itemsSlot).addEventListener('slotchange', _classPrivateFieldGet(this, _updateItems));
71
+ }
72
+
73
+ disconnectedCallback() {
74
+ _classPrivateFieldGet(this, _$itemsSlot).removeEventListener('slotchange', _classPrivateFieldGet(this, _updateItems));
75
+ }
76
+
77
+ static get observedAttributes() {
78
+ return ['index'];
79
+ }
80
+
81
+ attributeChangedCallback(name, oldVal, newVal) {
82
+ if (oldVal === newVal) {
83
+ return;
84
+ }
85
+
86
+ switch (name) {
87
+ case 'index':
88
+ {
89
+ _classPrivateFieldGet(this, _updateItems).call(this);
90
+
91
+ break;
92
+ }
93
+ }
94
+ }
95
+
96
+ set index(value) {
97
+ updateAttribute(this, 'index', value);
98
+ }
99
+
100
+ get index() {
101
+ return getAttribute(this, 'index', '1');
102
+ }
103
+
104
+ }));
@@ -0,0 +1,9 @@
1
+ import type { TSinchElementReact } from '../types';
2
+ export declare type TSinchHorizontalStepperElement = HTMLElement & {
3
+ index: string;
4
+ setAttribute(name: 'index', value: string): void;
5
+ };
6
+ export declare type TSinchHorizontalStepperReact = TSinchElementReact<TSinchHorizontalStepperElement> & {
7
+ index: string;
8
+ 'aria-label': string;
9
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import '../icons/check';
2
+ import '../icons/exclamation';
3
+ import type { TSinchHorizontalStepperItemElement, TSinchHorizontalStepperItemReact } from './types';
4
+ declare global {
5
+ namespace JSX {
6
+ interface IntrinsicElements {
7
+ 'sinch-horizontal-stepper-item': TSinchHorizontalStepperItemReact;
8
+ }
9
+ }
10
+ interface HTMLElementTagNameMap {
11
+ 'sinch-horizontal-stepper-item': TSinchHorizontalStepperItemElement;
12
+ }
13
+ }