@nectary/components 1.4.0 → 2.1.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 (209) hide show
  1. package/accordion/index.js +0 -3
  2. package/accordion/types.d.ts +0 -3
  3. package/accordion-item/index.d.ts +2 -0
  4. package/accordion-item/index.js +33 -34
  5. package/action-menu/index.js +5 -1
  6. package/action-menu-option/index.js +2 -2
  7. package/alert/index.js +4 -21
  8. package/alert/utils.d.ts +0 -3
  9. package/alert/utils.js +1 -6
  10. package/avatar/index.js +5 -21
  11. package/avatar/utils.d.ts +0 -4
  12. package/avatar/utils.js +2 -15
  13. package/badge/index.js +36 -68
  14. package/badge/types.d.ts +0 -4
  15. package/badge/utils.d.ts +0 -6
  16. package/badge/utils.js +1 -17
  17. package/button/index.js +25 -27
  18. package/button/types.d.ts +2 -2
  19. package/button/utils.d.ts +0 -3
  20. package/button/utils.js +1 -9
  21. package/card/index.js +5 -16
  22. package/card/types.d.ts +0 -6
  23. package/card-container/index.js +1 -1
  24. package/chat-block/index.js +1 -1
  25. package/chat-bubble/index.d.ts +0 -1
  26. package/chat-bubble/index.js +3 -25
  27. package/checkbox/index.js +32 -33
  28. package/checkbox/types.d.ts +0 -3
  29. package/chip/index.js +54 -44
  30. package/chip/utils.d.ts +0 -1
  31. package/chip/utils.js +2 -7
  32. package/code-tag/index.js +1 -1
  33. package/color-menu/index.d.ts +0 -3
  34. package/color-menu/index.js +55 -101
  35. package/color-menu/types.d.ts +0 -4
  36. package/color-menu-option/index.d.ts +14 -0
  37. package/color-menu-option/index.js +52 -0
  38. package/color-menu-option/types.d.ts +9 -0
  39. package/color-menu-option/utils.d.ts +1 -0
  40. package/color-menu-option/utils.js +11 -0
  41. package/color-swatch/index.js +2 -5
  42. package/color-swatch/utils.d.ts +0 -1
  43. package/color-swatch/utils.js +2 -7
  44. package/date-picker/index.js +3 -40
  45. package/date-picker/types.d.ts +0 -3
  46. package/date-picker/utils.d.ts +0 -8
  47. package/date-picker/utils.js +0 -20
  48. package/dialog/index.js +2 -6
  49. package/dialog/types.d.ts +0 -2
  50. package/emoji/index.js +1 -1
  51. package/emoji-picker/index.d.ts +1 -0
  52. package/emoji-picker/index.js +36 -34
  53. package/field/index.js +39 -32
  54. package/file-drop/index.js +1 -1
  55. package/file-status/index.js +4 -25
  56. package/file-status/utils.d.ts +0 -3
  57. package/file-status/utils.js +1 -6
  58. package/flag/index.js +1 -1
  59. package/grid/index.js +1 -1
  60. package/help-tooltip/index.d.ts +0 -1
  61. package/help-tooltip/index.js +3 -13
  62. package/horizontal-stepper/index.js +1 -1
  63. package/horizontal-stepper-item/index.d.ts +2 -0
  64. package/horizontal-stepper-item/index.js +8 -12
  65. package/icon/index.js +1 -1
  66. package/icon-button/index.js +23 -27
  67. package/icon-button/utils.d.ts +0 -3
  68. package/icon-button/utils.js +1 -9
  69. package/inline-alert/index.js +20 -37
  70. package/inline-alert/utils.d.ts +0 -3
  71. package/inline-alert/utils.js +1 -6
  72. package/input/index.d.ts +0 -3
  73. package/input/index.js +22 -58
  74. package/input/types.d.ts +1 -5
  75. package/input/utils.d.ts +0 -3
  76. package/input/utils.js +1 -6
  77. package/link/index.js +35 -37
  78. package/list-item/index.js +1 -1
  79. package/package.json +11 -11
  80. package/pagination/index.js +8 -21
  81. package/pagination/types.d.ts +0 -3
  82. package/pop/index.js +39 -38
  83. package/pop/utils.d.ts +0 -3
  84. package/pop/utils.js +0 -5
  85. package/popover/index.js +42 -51
  86. package/popover/utils.d.ts +0 -3
  87. package/popover/utils.js +0 -5
  88. package/progress/index.js +20 -15
  89. package/radio/index.js +19 -6
  90. package/radio/types.d.ts +3 -3
  91. package/radio-option/index.js +35 -27
  92. package/rich-text/index.js +3 -10
  93. package/rich-text/utils.d.ts +0 -3
  94. package/rich-text/utils.js +1 -6
  95. package/segment/index.js +3 -7
  96. package/segment-collapse/index.js +2 -11
  97. package/segment-collapse/types.d.ts +0 -3
  98. package/segmented-control/index.js +0 -3
  99. package/segmented-control/types.d.ts +0 -3
  100. package/segmented-control-option/index.js +20 -19
  101. package/segmented-icon-control/index.js +1 -4
  102. package/segmented-icon-control/types.d.ts +0 -3
  103. package/segmented-icon-control-option/index.js +18 -14
  104. package/select-button/index.js +29 -31
  105. package/select-menu/index.js +18 -8
  106. package/select-menu-option/index.js +2 -5
  107. package/skeleton/index.js +1 -1
  108. package/skeleton-item/index.js +1 -1
  109. package/spinner/index.js +3 -10
  110. package/table/index.js +1 -1
  111. package/table-body/index.js +1 -1
  112. package/table-cell/index.js +1 -1
  113. package/table-head-cell/index.d.ts +1 -0
  114. package/table-head-cell/index.js +12 -3
  115. package/table-row/index.js +18 -2
  116. package/tabs/index.js +1 -4
  117. package/tabs/types.d.ts +0 -3
  118. package/tabs-icon-option/index.js +4 -2
  119. package/tabs-option/index.js +25 -20
  120. package/tag/index.js +17 -12
  121. package/tag/utils.d.ts +0 -1
  122. package/tag/utils.js +2 -7
  123. package/text/index.js +24 -21
  124. package/text/utils.d.ts +0 -3
  125. package/text/utils.js +1 -6
  126. package/textarea/index.js +10 -6
  127. package/textarea/types.d.ts +0 -3
  128. package/tile-control/index.js +23 -25
  129. package/tile-control/types.d.ts +0 -3
  130. package/tile-control-option/index.js +1 -1
  131. package/time-picker/index.js +2 -11
  132. package/time-picker/types.d.ts +0 -3
  133. package/time-picker/utils.d.ts +1 -1
  134. package/time-picker/utils.js +17 -5
  135. package/title/index.js +28 -30
  136. package/title/utils.d.ts +0 -7
  137. package/title/utils.js +1 -29
  138. package/toast/index.js +22 -39
  139. package/toast/utils.d.ts +0 -3
  140. package/toast/utils.js +1 -6
  141. package/toggle/index.js +33 -30
  142. package/toggle/types.d.ts +0 -3
  143. package/tooltip/index.js +3 -15
  144. package/tooltip/types.d.ts +0 -12
  145. package/tooltip/utils.d.ts +0 -5
  146. package/tooltip/utils.js +0 -10
  147. package/utils/dom.js +0 -5
  148. package/utils/element.js +2 -2
  149. package/utils/size.d.ts +0 -5
  150. package/utils/size.js +1 -17
  151. package/vertical-stepper/index.js +1 -1
  152. package/vertical-stepper-item/index.d.ts +2 -0
  153. package/vertical-stepper-item/index.js +8 -12
  154. package/logo/create-logo-class.d.ts +0 -1
  155. package/logo/create-logo-class.js +0 -52
  156. package/logo/engage-icon/index.d.ts +0 -11
  157. package/logo/engage-icon/index.js +0 -4
  158. package/logo/engage-icon-wordmark/index.d.ts +0 -11
  159. package/logo/engage-icon-wordmark/index.js +0 -4
  160. package/logo/sinch-icon/index.d.ts +0 -11
  161. package/logo/sinch-icon/index.js +0 -4
  162. package/logo/sinch-icon-wordmark/index.d.ts +0 -11
  163. package/logo/sinch-icon-wordmark/index.js +0 -4
  164. package/logo/types.d.ts +0 -11
  165. package/theme/accordion-item.css +0 -4
  166. package/theme/alert.css +0 -6
  167. package/theme/avatar.css +0 -25
  168. package/theme/badge.css +0 -15
  169. package/theme/button.css +0 -146
  170. package/theme/chat.css +0 -9
  171. package/theme/chip.css +0 -68
  172. package/theme/color-menu.css +0 -4
  173. package/theme/color-swatch.css +0 -71
  174. package/theme/colors.d.ts +0 -4
  175. package/theme/colors.js +0 -4
  176. package/theme/contextual.css +0 -40
  177. package/theme/date-picker.css +0 -7
  178. package/theme/dialog.css +0 -4
  179. package/theme/elevation.css +0 -7
  180. package/theme/emoji-picker.css +0 -13
  181. package/theme/emoji.css +0 -5
  182. package/theme/file-status.css +0 -7
  183. package/theme/flag.css +0 -4
  184. package/theme/fonts.css +0 -86
  185. package/theme/fonts.json +0 -89
  186. package/theme/help-tooltip.css +0 -5
  187. package/theme/horizontal-stepper.css +0 -5
  188. package/theme/icon-button.css +0 -68
  189. package/theme/icon.css +0 -7
  190. package/theme/index.css +0 -4
  191. package/theme/index.d.ts +0 -39
  192. package/theme/index.js +0 -39
  193. package/theme/inline-alert.css +0 -7
  194. package/theme/input.css +0 -10
  195. package/theme/link.css +0 -5
  196. package/theme/pagination.css +0 -5
  197. package/theme/palette.css +0 -90
  198. package/theme/segment.css +0 -4
  199. package/theme/select-button.css +0 -10
  200. package/theme/select-menu.css +0 -6
  201. package/theme/shapes.css +0 -8
  202. package/theme/size.css +0 -9
  203. package/theme/spinner.css +0 -7
  204. package/theme/tag.css +0 -67
  205. package/theme/time-picker.css +0 -4
  206. package/theme/toast.css +0 -7
  207. package/theme/typography.css +0 -16
  208. package/theme/vertical-stepper.css +0 -5
  209. /package/{logo → color-menu-option}/types.js +0 -0
package/pop/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { defineCustomElement, getBooleanAttribute, getLiteralAttribute, getRect, isAttrTrue, updateLiteralAttribute, getReactEventHandler, updateBooleanAttribute, NectaryElement, throttleAnimationFrame, isElementFocused, updateIntegerAttribute, getIntegerAttribute, getFirstFocusableElement, getFirstSlotElement, Context, subscribeContext, isTargetEqual } from '../utils';
2
2
  const templateHTML = '<style>:host{display:contents;position:relative}dialog{position:fixed;left:0;top:0;margin:0;outline:0;padding:0;border:none;box-sizing:border-box;max-width:unset;max-height:unset;z-index:1;background:0 0;overflow:visible}dialog:not([open]){display:none}dialog::backdrop{background-color:transparent}#content{position:relative;z-index:1}#target-open{display:flex;flex-direction:column;position:absolute;left:0;top:0}#focus{display:none;position:absolute;width:0;height:0}</style><slot id="target" name="target" aria-haspopup="dialog" aria-expanded="false"></slot><div id="focus"></div><dialog id="dialog"><div id="target-open"><slot name="target-open"></slot></div><div id="content"><slot name="content"></slot></div></dialog>';
3
- import { assertOrientation, disableScroll, enableScroll, orientationValues } from './utils';
3
+ import { disableScroll, enableScroll, orientationValues } from './utils';
4
4
  const template = document.createElement('template');
5
5
  template.innerHTML = templateHTML;
6
6
  defineCustomElement('sinch-pop', class extends NectaryElement {
7
- #$target;
7
+ #$targetWrapper;
8
8
  #$focus;
9
9
  #$dialog;
10
10
  #resizeThrottle;
@@ -21,7 +21,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
21
21
  super();
22
22
  const shadowRoot = this.attachShadow();
23
23
  shadowRoot.appendChild(template.content.cloneNode(true));
24
- this.#$target = shadowRoot.querySelector('#target');
24
+ this.#$targetWrapper = shadowRoot.querySelector('#target');
25
25
  this.#$focus = shadowRoot.querySelector('#focus');
26
26
  this.#$dialog = shadowRoot.querySelector('#dialog');
27
27
  this.#$targetSlot = shadowRoot.querySelector('slot[name="target"]');
@@ -119,10 +119,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
119
119
  }
120
120
  case 'orientation':
121
121
  {
122
- if ('production' !== 'production') {
123
- assertOrientation(newVal);
124
- }
125
- if (this.#isOpen()) {
122
+ if (this.#$dialog.open) {
126
123
  this.#updateOrientation();
127
124
  }
128
125
  break;
@@ -131,11 +128,11 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
131
128
  }
132
129
  #getTargetRect() {
133
130
  let item = getFirstSlotElement(this.#$targetSlot, true);
134
- if (item === null && this.#isOpen()) {
131
+ if (item === null && this.#$dialog.open) {
135
132
  item = getFirstSlotElement(this.#$targetOpenSlot, true);
136
133
  }
137
134
  if (item === null) {
138
- return getRect(this.#$target);
135
+ return getRect(this.#$targetWrapper);
139
136
  }
140
137
  if (Reflect.has(item, 'footprintRect')) {
141
138
  return item.footprintRect;
@@ -145,23 +142,25 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
145
142
  #getFirstTargetElement(slot) {
146
143
  const item = getFirstSlotElement(slot, true);
147
144
  if (item === null) {
148
- return this.#$target;
145
+ return this.#$targetWrapper;
149
146
  }
150
147
  return item;
151
148
  }
152
149
  #onExpand() {
153
- if (!this.isConnected || this.#isOpen()) {
150
+ if (!this.isConnected || this.#$dialog.open) {
154
151
  return;
155
152
  }
156
- this.#$targetSlot.addEventListener('blur', this.#captureActiveElement, true);
153
+ this.#$targetSlot.addEventListener('blur', this.#stopEventPropagation, true);
157
154
  this.#$focus.setAttribute('tabindex', '-1');
158
155
  this.#$focus.style.display = 'block';
156
+ this.#$focus.addEventListener('focus', this.#captureRelatedActiveElement);
159
157
  this.#$focus.focus();
160
- this.#$targetSlot.removeEventListener('blur', this.#captureActiveElement, true);
158
+ this.#$focus.removeEventListener('focus', this.#captureRelatedActiveElement);
159
+ this.#$targetSlot.removeEventListener('blur', this.#stopEventPropagation, true);
161
160
  this.#$focus.removeAttribute('tabindex');
162
161
  this.#$focus.removeAttribute('style');
163
162
  this.#$dialog.showModal();
164
- this.#$target.setAttribute('aria-expanded', 'true');
163
+ this.#$targetWrapper.setAttribute('aria-expanded', 'true');
165
164
  this.#updateOrientation();
166
165
  if (this.modal) {
167
166
  getFirstFocusableElement(this.#$contentSlot)?.focus();
@@ -173,9 +172,9 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
173
172
  const marginTop = parseInt(targetElComputedStyle.marginTop);
174
173
  const marginBottom = parseInt(targetElComputedStyle.marginBottom);
175
174
  const targetRect = this.#getTargetRect();
176
- this.#$target.style.setProperty('display', 'block');
177
- this.#$target.style.setProperty('width', `${targetRect.width + marginLeft + marginRight}px`);
178
- this.#$target.style.setProperty('height', `${targetRect.height + marginTop + marginBottom}px`);
175
+ this.#$targetWrapper.style.setProperty('display', 'block');
176
+ this.#$targetWrapper.style.setProperty('width', `${targetRect.width + marginLeft + marginRight}px`);
177
+ this.#$targetWrapper.style.setProperty('height', `${targetRect.height + marginTop + marginBottom}px`);
179
178
  this.#$targetOpenWrapper.style.setProperty('width', `${targetRect.width}px`);
180
179
  this.#$targetOpenWrapper.style.setProperty('height', `${targetRect.height}px`);
181
180
  this.#targetStyleValue = $targetEl.getAttribute('style');
@@ -193,7 +192,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
193
192
  this.#$targetOpenSlot.removeEventListener('focus', this.#stopEventPropagation, true);
194
193
  if (!isElementFocused(this.#targetActiveElement)) {
195
194
  requestAnimationFrame(() => {
196
- if (this.isConnected && this.#isOpen()) {
195
+ if (this.isConnected && this.#$dialog.open) {
197
196
  this.#$targetOpenSlot.addEventListener('focus', this.#stopEventPropagation, true);
198
197
  this.#targetActiveElement.focus();
199
198
  this.#$targetOpenSlot.removeEventListener('focus', this.#stopEventPropagation, true);
@@ -205,40 +204,41 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
205
204
  disableScroll();
206
205
  window.addEventListener('resize', this.#onResize);
207
206
  requestAnimationFrame(() => {
208
- if (this.isConnected && this.#isOpen()) {
207
+ if (this.isConnected && this.#$dialog.open) {
209
208
  this.#$contentSlot.addEventListener('slotchange', this.#onContentSlotChange);
210
209
  }
211
210
  });
212
211
  this.#dispatchContentVisibility(true);
213
212
  }
214
213
  #onCollapse() {
215
- if (!this.#isOpen()) {
214
+ if (!this.#$dialog.open) {
216
215
  return;
217
216
  }
218
217
  const isNonModal = !this.modal;
219
218
  this.#dispatchContentVisibility(false);
220
219
  this.#$targetOpenSlot.removeEventListener('keydown', this.#onTargetKeydown);
221
220
  if (isNonModal) {
222
- this.#targetActiveElement = null;
223
221
  this.#$targetOpenSlot.addEventListener('blur', this.#captureActiveElement, true);
224
222
  }
225
223
  this.#$dialog.close();
226
- this.#$target.setAttribute('aria-expanded', 'false');
224
+ this.#$targetWrapper.setAttribute('aria-expanded', 'false');
227
225
  if (isNonModal) {
228
226
  this.#$targetOpenSlot.removeEventListener('blur', this.#captureActiveElement, true);
229
227
  }
230
- const targetEl = this.#getFirstTargetElement(this.#$targetOpenSlot);
231
- targetEl.style.removeProperty('margin');
232
- targetEl.style.removeProperty('position');
233
- targetEl.style.removeProperty('transform');
234
- if (this.#targetStyleValue !== null) {
235
- targetEl.setAttribute('style', this.#targetStyleValue);
236
- this.#targetStyleValue = null;
228
+ if (isNonModal) {
229
+ const targetEl = this.#getFirstTargetElement(this.#$targetOpenSlot);
230
+ targetEl.style.removeProperty('margin');
231
+ targetEl.style.removeProperty('position');
232
+ targetEl.style.removeProperty('transform');
233
+ if (this.#targetStyleValue !== null) {
234
+ targetEl.setAttribute('style', this.#targetStyleValue);
235
+ this.#targetStyleValue = null;
236
+ }
237
+ getFirstSlotElement(this.#$targetOpenSlot)?.setAttribute('slot', 'target');
238
+ this.#$targetWrapper.style.removeProperty('display');
239
+ this.#$targetWrapper.style.removeProperty('width');
240
+ this.#$targetWrapper.style.removeProperty('height');
237
241
  }
238
- getFirstSlotElement(this.#$targetOpenSlot)?.setAttribute('slot', 'target');
239
- this.#$target.style.removeProperty('display');
240
- this.#$target.style.removeProperty('width');
241
- this.#$target.style.removeProperty('height');
242
242
  if (this.#targetActiveElement !== null) {
243
243
  if (!isElementFocused(this.#targetActiveElement)) {
244
244
  this.#$targetSlot.addEventListener('focus', this.#stopEventPropagation, true);
@@ -247,7 +247,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
247
247
  if (!isElementFocused(this.#targetActiveElement)) {
248
248
  const $targetEl = this.#targetActiveElement;
249
249
  requestAnimationFrame(() => {
250
- if (this.isConnected && !this.#isOpen()) {
250
+ if (this.isConnected && !this.#$dialog.open) {
251
251
  this.#$targetSlot.addEventListener('focus', this.#stopEventPropagation, true);
252
252
  $targetEl.focus();
253
253
  this.#$targetSlot.removeEventListener('focus', this.#stopEventPropagation, true);
@@ -262,9 +262,6 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
262
262
  window.removeEventListener('resize', this.#onResize);
263
263
  this.#$contentSlot.removeEventListener('slotchange', this.#onContentSlotChange);
264
264
  }
265
- #isOpen() {
266
- return getBooleanAttribute(this.#$dialog, 'open');
267
- }
268
265
  #onResize = () => {
269
266
  this.#resizeThrottle.fn();
270
267
  };
@@ -336,6 +333,10 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
336
333
  #dispatchCloseEvent() {
337
334
  this.dispatchEvent(new CustomEvent('-close'));
338
335
  }
336
+ #captureRelatedActiveElement = e => {
337
+ e.stopPropagation();
338
+ this.#targetActiveElement = e.relatedTarget;
339
+ };
339
340
  #captureActiveElement = e => {
340
341
  e.stopPropagation();
341
342
  this.#targetActiveElement = e.target;
@@ -361,7 +362,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
361
362
  };
362
363
  #onContentSlotChange = e => {
363
364
  e.stopPropagation();
364
- if (this.#isOpen()) {
365
+ if (this.#$dialog.open) {
365
366
  this.#updateOrientation();
366
367
  }
367
368
  };
package/pop/utils.d.ts CHANGED
@@ -1,7 +1,4 @@
1
1
  import type { TSinchPopOrientation } from './types';
2
2
  export declare const orientationValues: readonly TSinchPopOrientation[];
3
- type TAssertOrientation = (value: string | null) => asserts value is TSinchPopOrientation;
4
- export declare const assertOrientation: TAssertOrientation;
5
3
  export declare const disableScroll: () => void;
6
4
  export declare const enableScroll: () => void;
7
- export {};
package/pop/utils.js CHANGED
@@ -1,9 +1,4 @@
1
1
  export const orientationValues = ['top-left', 'top-right', 'bottom-left', 'bottom-right', 'bottom-stretch', 'bottom-center', 'top-stretch', 'top-center', 'center-left', 'center-right'];
2
- export const assertOrientation = value => {
3
- if (value === null || !orientationValues.includes(value)) {
4
- throw new Error(`sinch-pop: invalid orientation attribute: ${value}`);
5
- }
6
- };
7
2
  const bodyEl = document.body;
8
3
  export const disableScroll = () => {
9
4
  bodyEl.style.overflow = 'hidden';
package/popover/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import '../pop';
2
2
  import { defineCustomElement, getBooleanAttribute, getLiteralAttribute, updateLiteralAttribute, updateBooleanAttribute, NectaryElement, updateAttribute, getReactEventHandler, isAttrTrue, setClass, rectOverlap, subscribeContext } from '../utils';
3
- const templateHTML = '<style>:host{display:contents}#content-wrapper{position:relative;padding-top:4px}#content{font:var(--sinch-font-text-m);color:var(--sinch-color-text-default);background-color:var(--sinch-color-snow-100);border:1px solid var(--sinch-color-snow-500);border-radius:var(--sinch-shape-radius-m);box-shadow:var(--sinch-elevation-level-2);overflow:hidden}#tip{position:absolute;left:50%;top:13px;transform:translateX(-50%) rotate(180deg);transform-origin:top center;fill:var(--sinch-color-snow-100);stroke:var(--sinch-color-snow-500);stroke-linecap:square;pointer-events:none;display:none}:host([orientation^=top]) #tip{transform:translateX(-50%) rotate(0);top:calc(100% - 13px)}:host([tip]) #tip:not(.hidden){display:block}:host([tip]) #content{box-shadow:none}:host([tip]) #content-wrapper{padding-top:12px;filter:drop-shadow(var(--sinch-elevation-level-2))}:host([orientation^=top]) #content-wrapper{padding-top:0;padding-bottom:4px}:host([orientation^=top][tip]) #content-wrapper{padding-top:0;padding-bottom:12px}</style><sinch-pop id="pop" inset="4"><slot name="target" slot="target"></slot><div id="content-wrapper" slot="content"><div id="content"><slot name="content"></slot></div><svg id="tip" width="16" height="9" aria-hidden="true"><path d="m0 0 8 8 8 -8"/></svg></div></sinch-pop>';
4
- import { assertOrientation, getPopOrientation, orientationValues } from './utils';
3
+ const templateHTML = '<style>:host{display:contents}#content-wrapper{position:relative;padding-top:4px}:host([tip]) #content-wrapper{padding-top:12px;filter:drop-shadow(var(--sinch-comp-popover-shadow))}:host([orientation^=top]) #content-wrapper{padding-top:0;padding-bottom:4px}:host([orientation^=top][tip]) #content-wrapper{padding-top:0;padding-bottom:12px}#content{background-color:var(--sinch-comp-popover-color-default-background-initial);border:1px solid var(--sinch-comp-popover-color-default-border-initial);border-radius:var(--sinch-comp-popover-shape-radius);box-shadow:var(--sinch-comp-popover-shadow);overflow:hidden}:host([tip]) #content{box-shadow:none}#tip{position:absolute;left:50%;top:13px;transform:translateX(-50%) rotate(180deg);transform-origin:top center;fill:var(--sinch-comp-popover-color-default-background-initial);stroke:var(--sinch-comp-popover-color-default-border-initial);stroke-linecap:square;pointer-events:none;display:none}:host([orientation^=top]) #tip{transform:translateX(-50%) rotate(0);top:calc(100% - 13px)}:host([tip]) #tip:not(.hidden){display:block}</style><sinch-pop id="pop" inset="4"><slot name="target" slot="target"></slot><div id="content-wrapper" slot="content"><div id="content"><slot name="content"></slot></div><svg id="tip" width="16" height="9" aria-hidden="true"><path d="m0 0 8 8 8 -8"/></svg></div></sinch-pop>';
4
+ import { getPopOrientation, orientationValues } from './utils';
5
5
  const TIP_SIZE = 16;
6
6
  const template = document.createElement('template');
7
7
  template.innerHTML = templateHTML;
@@ -35,19 +35,40 @@ defineCustomElement('sinch-popover', class extends NectaryElement {
35
35
  disconnectedCallback() {
36
36
  this.#controller.abort();
37
37
  }
38
- #onPopClose = () => {
39
- this.#dispatchCloseEvent();
40
- };
41
- #onCloseReactHandler = e => {
42
- getReactEventHandler(this, 'onClose')?.();
43
- getReactEventHandler(this, 'on-close')?.(e);
44
- };
45
- #dispatchCloseEvent() {
46
- this.dispatchEvent(new CustomEvent('-close'));
47
- }
48
38
  static get observedAttributes() {
49
39
  return ['orientation', 'open', 'modal', 'tip'];
50
40
  }
41
+ attributeChangedCallback(name, oldVal, newVal) {
42
+ if (oldVal === newVal) {
43
+ return;
44
+ }
45
+ switch (name) {
46
+ case 'orientation':
47
+ {
48
+ updateAttribute(this.#$pop, 'orientation', getPopOrientation(this.orientation));
49
+ if (this.#$pop.open) {
50
+ this.#updateTipOrientation();
51
+ }
52
+ break;
53
+ }
54
+ case 'tip':
55
+ {
56
+ const hasTip = isAttrTrue(newVal);
57
+ if (hasTip && this.#$pop.open) {
58
+ this.#updateTipOrientation();
59
+ }
60
+ updateBooleanAttribute(this, name, hasTip);
61
+ break;
62
+ }
63
+ case 'modal':
64
+ case 'open':
65
+ {
66
+ updateAttribute(this.#$pop, name, newVal);
67
+ updateBooleanAttribute(this, name, isAttrTrue(newVal));
68
+ break;
69
+ }
70
+ }
71
+ }
51
72
  set modal(isModal) {
52
73
  updateBooleanAttribute(this, 'modal', isModal);
53
74
  }
@@ -78,42 +99,15 @@ defineCustomElement('sinch-popover', class extends NectaryElement {
78
99
  get popoverRect() {
79
100
  return this.#$pop.popoverRect;
80
101
  }
81
- attributeChangedCallback(name, oldVal, newVal) {
82
- if (oldVal === newVal) {
83
- return;
84
- }
85
- switch (name) {
86
- case 'orientation':
87
- {
88
- if ('production' !== 'production') {
89
- assertOrientation(newVal);
90
- }
91
- updateAttribute(this.#$pop, 'orientation', getPopOrientation(this.orientation));
92
- if (this.#isOpen()) {
93
- this.#updateTipOrientation();
94
- }
95
- break;
96
- }
97
- case 'tip':
98
- {
99
- updateBooleanAttribute(this, 'tip', isAttrTrue(newVal));
100
- if (newVal === '' && this.#isOpen()) {
101
- this.#updateTipOrientation();
102
- }
103
- break;
104
- }
105
- case 'open':
106
- {
107
- const isOpen = isAttrTrue(newVal);
108
- updateBooleanAttribute(this.#$pop, name, isOpen);
109
- updateBooleanAttribute(this, name, isOpen);
110
- break;
111
- }
112
- default:
113
- {
114
- updateAttribute(this.#$pop, name, newVal);
115
- }
116
- }
102
+ #onPopClose = () => {
103
+ this.#dispatchCloseEvent();
104
+ };
105
+ #onCloseReactHandler = e => {
106
+ getReactEventHandler(this, 'onClose')?.();
107
+ getReactEventHandler(this, 'on-close')?.(e);
108
+ };
109
+ #dispatchCloseEvent() {
110
+ this.dispatchEvent(new CustomEvent('-close'));
117
111
  }
118
112
  #onContextVisibility = e => {
119
113
  if (e.detail) {
@@ -142,7 +136,4 @@ defineCustomElement('sinch-popover', class extends NectaryElement {
142
136
  this.#$tip.style.left = `${xPos}px`;
143
137
  setClass(this.#$tip, 'hidden', rectOverlap(targetRect, contentRect));
144
138
  };
145
- #isOpen() {
146
- return this.#$pop.open;
147
- }
148
139
  });
@@ -2,6 +2,3 @@ import type { TSinchPopoverOrientation } from './types';
2
2
  import type { TSinchPopOrientation } from '../pop/types';
3
3
  export declare const orientationValues: readonly TSinchPopoverOrientation[];
4
4
  export declare const getPopOrientation: (orientation: TSinchPopoverOrientation) => TSinchPopOrientation;
5
- type TAssertOrientation = (value: string | null) => asserts value is TSinchPopoverOrientation;
6
- export declare const assertOrientation: TAssertOrientation;
7
- export {};
package/popover/utils.js CHANGED
@@ -7,9 +7,4 @@ export const getPopOrientation = orientation => {
7
7
  return 'bottom-stretch';
8
8
  }
9
9
  return orientation;
10
- };
11
- export const assertOrientation = value => {
12
- if (value === null || !orientationValues.includes(value)) {
13
- throw new Error(`sinch-popover: invalid orientation attribute: ${value}`);
14
- }
15
10
  };
package/progress/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import '../text';
2
- import { defineCustomElement, updateAttribute, NectaryElement, updateBooleanAttribute, getIntegerAttribute, getBooleanAttribute, attrValueToInteger } from '../utils';
3
- const templateHTML = '<style>:host{display:block}#wrapper{display:flex;align-items:center;height:24px}#bar,#progress{height:8px;border-radius:4px}#progress{background-color:var(--sinch-color-tropical-100);flex:1;min-width:0}#bar{background-color:var(--sinch-color-tropical-500);width:0}#text{display:none;width:46px}:host([detailed]:not([detailed=false])) #text{display:block}</style><div id="wrapper"><sinch-text id="text" type="m"></sinch-text><div id="progress"><div id="bar"></div></div></div>';
2
+ import { defineCustomElement, updateAttribute, NectaryElement, updateBooleanAttribute, getIntegerAttribute, getBooleanAttribute, attrValueToInteger, isAttrTrue } from '../utils';
3
+ const templateHTML = '<style>:host{display:block}#wrapper{display:flex;align-items:center;height:24px}#bar,#progress{height:8px;border-radius:4px}#progress{background-color:var(--sinch-comp-progress-color-default-background-initial);flex:1;min-width:0}#bar{background-color:var(--sinch-comp-progress-color-default-bar-initial);width:0}#text{display:none;width:46px;--sinch-global-color-text:var(--sinch-comp-progress-color-default-text-initial)}:host([detailed]) #text{display:block}</style><div id="wrapper"><sinch-text id="text" type="m"></sinch-text><div id="progress"><div id="bar"></div></div></div>';
4
4
  const template = document.createElement('template');
5
5
  template.innerHTML = templateHTML;
6
6
  defineCustomElement('sinch-progress', class extends NectaryElement {
@@ -16,20 +16,8 @@ defineCustomElement('sinch-progress', class extends NectaryElement {
16
16
  connectedCallback() {
17
17
  this.setAttribute('role', 'progressbar');
18
18
  }
19
- get value() {
20
- return getIntegerAttribute(this, 'value', 0);
21
- }
22
- set value(value) {
23
- updateAttribute(this, 'value', value);
24
- }
25
- get detailed() {
26
- return getBooleanAttribute(this, 'detailed');
27
- }
28
- set detailed(isDetailed) {
29
- updateBooleanAttribute(this, 'detailed', isDetailed);
30
- }
31
19
  static get observedAttributes() {
32
- return ['value'];
20
+ return ['value', 'detailed'];
33
21
  }
34
22
  attributeChangedCallback(name, oldVal, newVal) {
35
23
  if (oldVal === newVal) {
@@ -48,6 +36,23 @@ defineCustomElement('sinch-progress', class extends NectaryElement {
48
36
  this.setAttribute('valuenow', int !== null ? String(int) : '0');
49
37
  break;
50
38
  }
39
+ case 'detailed':
40
+ {
41
+ updateBooleanAttribute(this, name, isAttrTrue(newVal));
42
+ break;
43
+ }
51
44
  }
52
45
  }
46
+ get value() {
47
+ return getIntegerAttribute(this, 'value', 0);
48
+ }
49
+ set value(value) {
50
+ updateAttribute(this, 'value', value);
51
+ }
52
+ get detailed() {
53
+ return getBooleanAttribute(this, 'detailed');
54
+ }
55
+ set detailed(isDetailed) {
56
+ updateBooleanAttribute(this, 'detailed', isDetailed);
57
+ }
53
58
  });
package/radio/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { defineCustomElement, getAttribute, getBooleanAttribute, getReactEventHandler, NectaryElement, updateAttribute, updateBooleanAttribute } from '../utils';
1
+ import { defineCustomElement, getAttribute, getBooleanAttribute, getReactEventHandler, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute } from '../utils';
2
2
  const templateHTML = '<style>:host{display:block}#wrapper{display:flex;flex-direction:column;gap:8px;box-sizing:border-box;width:100%}</style><div id="wrapper"><slot></slot></div>';
3
3
  const template = document.createElement('template');
4
4
  template.innerHTML = templateHTML;
@@ -24,10 +24,7 @@ defineCustomElement('sinch-radio', class extends NectaryElement {
24
24
  this.removeEventListener('-change', this.#onChangeReactHandler);
25
25
  }
26
26
  static get observedAttributes() {
27
- return ['value'];
28
- }
29
- get nodeName() {
30
- return 'select';
27
+ return ['value', 'invalid'];
31
28
  }
32
29
  set value(value) {
33
30
  updateAttribute(this, 'value', value);
@@ -35,6 +32,12 @@ defineCustomElement('sinch-radio', class extends NectaryElement {
35
32
  get value() {
36
33
  return getAttribute(this, 'value', '');
37
34
  }
35
+ set invalid(isInvalid) {
36
+ updateBooleanAttribute(this, 'invalid', isInvalid);
37
+ }
38
+ get invalid() {
39
+ return getBooleanAttribute(this, 'invalid');
40
+ }
38
41
  attributeChangedCallback(name, oldVal, newVal) {
39
42
  if (oldVal === newVal) {
40
43
  return;
@@ -45,6 +48,11 @@ defineCustomElement('sinch-radio', class extends NectaryElement {
45
48
  this.#onValueChange(newVal ?? '');
46
49
  break;
47
50
  }
51
+ case 'invalid':
52
+ {
53
+ this.#updateInvalid(isAttrTrue(newVal));
54
+ break;
55
+ }
48
56
  }
49
57
  }
50
58
  #onOptionKeyDown = e => {
@@ -82,7 +90,7 @@ defineCustomElement('sinch-radio', class extends NectaryElement {
82
90
  };
83
91
  #onValueChange(value) {
84
92
  for (const $option of this.#$slot.assignedElements()) {
85
- const isChecked = !getBooleanAttribute($option, 'disabled') && value === getAttribute($option, 'value', '');
93
+ const isChecked = value === getAttribute($option, 'value', '');
86
94
  updateBooleanAttribute($option, 'checked', isChecked);
87
95
  }
88
96
  }
@@ -135,6 +143,11 @@ defineCustomElement('sinch-radio', class extends NectaryElement {
135
143
  #findSelectedOption(elements) {
136
144
  return elements.find(el => el.checked) ?? null;
137
145
  }
146
+ #updateInvalid(isInvalid) {
147
+ for (const opt of this.#$slot.assignedElements()) {
148
+ updateBooleanAttribute(opt, 'data-invalid', isInvalid);
149
+ }
150
+ }
138
151
  #onChangeReactHandler = e => {
139
152
  getReactEventHandler(this, 'on-change')?.(e);
140
153
  };
package/radio/types.d.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  import type { TSinchElementReact } from '../types';
2
- import type { SyntheticEvent } from 'react';
3
2
  export type TSinchRadioElement = HTMLElement & {
4
3
  value: string;
4
+ invalid: boolean;
5
5
  addEventListener(type: 'change', listener: (e: CustomEvent<boolean>) => void): void;
6
6
  addEventListener(type: '-change', listener: (e: CustomEvent<boolean>) => void): void;
7
7
  setAttribute(name: 'value', value: string): void;
8
+ setAttribute(name: 'invalid', value: ''): void;
8
9
  };
9
10
  export type TSinchRadioReact = TSinchElementReact<TSinchRadioElement> & {
10
11
  value: string;
12
+ invalid?: boolean;
11
13
  'aria-label': string;
12
- /** @deprecated */
13
- onChange?: (event: SyntheticEvent<TSinchRadioElement, CustomEvent<boolean>>) => void;
14
14
  'on-change'?: (e: CustomEvent<string>) => void;
15
15
  };
@@ -1,5 +1,5 @@
1
1
  import { defineCustomElement, getAttribute, getBooleanAttribute, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute } from '../utils';
2
- const templateHTML = '<style>:host{--sinch-color-radio-outer-circle:var(--sinch-color-transparent);--sinch-color-radio-background:var(--sinch-color-snow-100);--sinch-color-radio-border:var(--sinch-color-stormy-300);--sinch-color-radio-outer-circle-checked:var(--sinch-color-transparent);--sinch-color-radio-border-checked:var(--sinch-color-tropical-500);--sinch-color-radio-outer-circle-hover:var(--sinch-color-snow-500);--sinch-color-radio-border-hover:var(--sinch-color-stormy-300);--sinch-color-radio-outer-circle-hover-checked:var(--sinch-color-tropical-100);--sinch-color-radio-border-hover-checked:var(--sinch-color-tropical-500);--sinch-color-radio-outer-circle-focus:var(--sinch-color-snow-700);--sinch-color-radio-border-focus:var(--sinch-color-stormy-300);--sinch-color-radio-outer-circle-focus-checked:var(--sinch-color-tropical-200);--sinch-color-radio-border-focus-checked:var(--sinch-color-tropical-500);--sinch-color-radio-outer-circle-active:var(--sinch-color-stormy-100);--sinch-color-radio-border-active:var(--sinch-color-stormy-300);--sinch-color-radio-outer-circle-active-checked:var(--sinch-color-tropical-300);--sinch-color-radio-border-active-checked:var(--sinch-color-tropical-500);--sinch-color-radio-outer-circle-disabled:var(--sinch-color-transparent);--sinch-color-radio-border-disabled:var(--sinch-color-stormy-100);--sinch-color-radio-outer-circle-disabled-checked:var(--sinch-color-transparent);--sinch-color-radio-border-disabled-checked:var(--sinch-color-stormy-100);display:block;outline:0}#wrapper{display:flex;height:32px;box-sizing:border-box;width:100%}#input{all:initial;display:block;width:32px;height:32px;cursor:pointer}#input:disabled{cursor:initial}#icon-container{position:relative;width:32px;height:32px}#input::before{content:"";position:absolute;top:0;left:0;width:32px;height:32px;border-radius:50%;pointer-events:none;background-color:var(--sinch-color-radio-outer-circle);transition:background-color .1s linear}#input::after{content:"";position:absolute;top:6px;left:6px;width:20px;height:20px;border-radius:50%;pointer-events:none;background-color:var(--sinch-color-radio-background);border:2px solid var(--sinch-color-radio-border);transition:background-color .1s linear;box-sizing:border-box}#icon-knob{position:absolute;left:11px;top:11px;width:10px;height:10px;border-radius:50%;transition:opacity .1s linear;opacity:0;background-color:var(--sinch-color-radio-border);pointer-events:none}@media (prefers-reduced-motion){#icon-knob,#input::after,#input::before{transition:none}}#label{align-self:center;flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-left:8px;font:var(--sinch-font-text-m);color:var(--sinch-color-text-default)}:host([disabled]:not([disabled=false])) #label{color:var(--sinch-color-stormy-200)}#input:checked::before{background-color:var(--sinch-color-radio-outer-circle-checked)}#input:checked::after{border-color:var(--sinch-color-radio-border-checked)}#input:checked~#icon-knob{opacity:1;background-color:var(--sinch-color-radio-border-checked)}#input:focus::before{background-color:var(--sinch-color-radio-outer-circle-focus)}#input:focus::after{border-color:var(--sinch-color-radio-border-focus)}#input:focus~#icon-knob{background-color:var(--sinch-color-radio-border-focus)}#input:hover::before{background-color:var(--sinch-color-radio-outer-circle-hover)}#input:hover::after{border-color:var(--sinch-color-radio-border-hover)}#input:hover~#icon-knob{background-color:var(--sinch-color-radio-border-hover)}#input:active::before{background-color:var(--sinch-color-radio-outer-circle-active)}#input:active::after{border-color:var(--sinch-color-radio-border-active)}#input:active~#icon-knob{background-color:var(--sinch-color-radio-border-active)}#input:disabled::before{background-color:var(--sinch-color-radio-outer-circle-disabled)}#input:disabled::after{border-color:var(--sinch-color-radio-border-disabled)}#input:disabled~#icon-knob{background-color:var(--sinch-color-radio-border-disabled)}#input:focus:checked::before{background-color:var(--sinch-color-radio-outer-circle-focus-checked)}#input:focus:checked::after{border-color:var(--sinch-color-radio-border-focus-checked)}#input:focus:checked~#icon-knob{opacity:1;background-color:var(--sinch-color-radio-border-focus-checked)}#input:hover:checked::before{background-color:var(--sinch-color-radio-outer-circle-hover-checked)}#input:hover:checked::after{border-color:var(--sinch-color-radio-border-hover-checked)}#input:hover:checked~#icon-knob{opacity:1;background-color:var(--sinch-color-radio-border-hover-checked)}#input:active:checked::before{background-color:var(--sinch-color-radio-outer-circle-active-checked)}#input:active:checked::after{border-color:var(--sinch-color-radio-border-active-checked)}#input:active:checked~#icon-knob{opacity:1;background-color:var(--sinch-color-radio-border-active-checked)}#input:disabled:checked::before{background-color:var(--sinch-color-radio-outer-circle-disabled-checked)}#input:disabled:checked::after{border-color:var(--sinch-color-radio-border-disabled-checked)}#input:disabled:checked~#icon-knob{opacity:1;background-color:var(--sinch-color-radio-border-disabled-checked)}</style><div id="wrapper"><div id="icon-container"><input id="input" type="radio"/><div id="icon-knob"></div></div><label for="input" id="label"></label></div>';
2
+ const templateHTML = '<style>:host{display:block;outline:0}#wrapper{display:flex;flex-direction:row;box-sizing:border-box;width:100%;--sinch-local-size:24px;--sinch-local-color-background:var(--sinch-comp-radio-color-default-background-initial);--sinch-local-color-background-hover:var(--sinch-comp-radio-color-default-background-hover);--sinch-local-color-background-active:var(--sinch-comp-radio-color-default-background-active);--sinch-local-color-border:var(--sinch-comp-radio-color-default-border-initial);--sinch-local-color-border-hover:var(--sinch-comp-radio-color-default-border-hover);--sinch-local-color-border-active:var(--sinch-comp-radio-color-default-border-active);--sinch-local-color-knob:var(--sinch-comp-radio-color-checked-knob-initial);--sinch-local-color-knob-hover:var(--sinch-comp-radio-color-checked-knob-hover);--sinch-local-color-knob-active:var(--sinch-comp-radio-color-checked-knob-active);--sinch-local-color-text:var(--sinch-comp-radio-color-default-label-initial)}:host([data-invalid])>#wrapper{--sinch-local-color-border:var(--sinch-comp-radio-color-invalid-border-initial);--sinch-local-color-border-hover:var(--sinch-comp-radio-color-invalid-border-hover);--sinch-local-color-border-active:var(--sinch-comp-radio-color-invalid-border-active);--sinch-local-color-text:var(--sinch-comp-radio-color-invalid-label-initial)}:host([checked])>#wrapper{--sinch-local-color-border:var(--sinch-comp-radio-color-checked-border-initial);--sinch-local-color-border-hover:var(--sinch-comp-radio-color-checked-border-hover);--sinch-local-color-border-active:var(--sinch-comp-radio-color-checked-border-active)}:host([disabled])>#wrapper{--sinch-local-color-background:var(--sinch-comp-radio-color-disabled-background-initial);--sinch-local-color-border:var(--sinch-comp-radio-color-disabled-border-initial);--sinch-local-color-text:var(--sinch-comp-radio-color-disabled-label-initial)}:host([disabled][checked])>#wrapper{--sinch-local-color-border:var(--sinch-comp-radio-color-checked-disabled-border-initial);--sinch-local-color-knob:var(--sinch-comp-radio-color-checked-disabled-knob-initial);--sinch-local-color-text:var(--sinch-comp-radio-color-checked-disabled-label-initial)}#input{all:initial;display:block;width:var(--sinch-local-size);height:var(--sinch-local-size);cursor:pointer}#input:disabled{cursor:initial}#input::before{content:"";position:absolute;top:0;left:0;width:var(--sinch-local-size);height:var(--sinch-local-size);border:2px solid var(--sinch-comp-radio-color-default-outline-focus);border-radius:50%;transition:opacity .1s linear;opacity:0;box-sizing:border-box;pointer-events:none}#input:focus-visible::before{opacity:1}#input::after{content:"";position:absolute;width:18px;height:18px;inset:0;margin:auto;background-color:var(--sinch-local-color-background);border:1px solid var(--sinch-local-color-border);border-radius:50%;box-sizing:border-box;pointer-events:none}#input:enabled:hover::after{background-color:var(--sinch-local-color-background-hover);border-color:var(--sinch-local-color-border-hover)}#input:enabled:active::after{background-color:var(--sinch-local-color-background-active);border-color:var(--sinch-local-color-border-active)}#input-wrapper{position:relative;width:var(--sinch-local-size);height:var(--sinch-local-size);align-self:flex-start}#knob{position:absolute;width:10px;height:10px;inset:0;margin:auto;border-radius:50%;transition:opacity .1s linear;opacity:0;background-color:var(--sinch-local-color-knob);pointer-events:none}#input:checked+#knob{opacity:1}#input:enabled:hover+#knob{background-color:var(--sinch-local-color-knob-hover)}#input:enabled:active+#knob{background-color:var(--sinch-local-color-knob-active)}@media (prefers-reduced-motion){#input::after,#input::before,#knob{transition:none}}#label{flex:1;align-self:center;padding-left:8px;font:var(--sinch-comp-radio-font-label);color:var(--sinch-local-color-text);cursor:pointer}:host([disabled]) #label{cursor:initial}</style><div id="wrapper"><div id="input-wrapper"><input id="input" type="radio"/><div id="knob"></div></div><label for="input" id="label"></label></div>';
3
3
  const template = document.createElement('template');
4
4
  template.innerHTML = templateHTML;
5
5
  defineCustomElement('sinch-radio-option', class extends NectaryElement {
@@ -20,33 +20,12 @@ defineCustomElement('sinch-radio-option', class extends NectaryElement {
20
20
  this.#$input.removeEventListener('input', this.#onInput);
21
21
  }
22
22
  static get observedAttributes() {
23
- return ['checked', 'disabled', 'text', 'value'];
23
+ return ['checked', 'disabled', 'text', 'value', 'data-invalid'];
24
24
  }
25
- set checked(isChecked) {
26
- updateBooleanAttribute(this, 'checked', isChecked);
27
- }
28
- get checked() {
29
- return getBooleanAttribute(this, 'checked');
30
- }
31
- set value(value) {
32
- updateAttribute(this, 'value', value);
33
- }
34
- get value() {
35
- return getAttribute(this, 'value', '');
36
- }
37
- set disabled(isDisabled) {
38
- updateBooleanAttribute(this, 'disabled', isDisabled);
39
- }
40
- get disabled() {
41
- return getBooleanAttribute(this, 'disabled');
42
- }
43
- set text(value) {
44
- updateAttribute(this, 'text', value);
45
- }
46
- get text() {
47
- return getAttribute(this, 'text', '');
48
- }
49
- attributeChangedCallback(name, _, newVal) {
25
+ attributeChangedCallback(name, oldVal, newVal) {
26
+ if (oldVal === newVal) {
27
+ return;
28
+ }
50
29
  switch (name) {
51
30
  case 'text':
52
31
  {
@@ -66,6 +45,11 @@ defineCustomElement('sinch-radio-option', class extends NectaryElement {
66
45
  updateBooleanAttribute(this, 'disabled', isDisabled);
67
46
  break;
68
47
  }
48
+ case 'data-invalid':
49
+ {
50
+ updateBooleanAttribute(this, 'data-invalid', isAttrTrue(newVal));
51
+ break;
52
+ }
69
53
  case 'value':
70
54
  {
71
55
  this.#$input.value = newVal ?? '';
@@ -73,6 +57,30 @@ defineCustomElement('sinch-radio-option', class extends NectaryElement {
73
57
  }
74
58
  }
75
59
  }
60
+ set checked(isChecked) {
61
+ updateBooleanAttribute(this, 'checked', isChecked);
62
+ }
63
+ get checked() {
64
+ return getBooleanAttribute(this, 'checked');
65
+ }
66
+ set value(value) {
67
+ updateAttribute(this, 'value', value);
68
+ }
69
+ get value() {
70
+ return getAttribute(this, 'value', '');
71
+ }
72
+ set disabled(isDisabled) {
73
+ updateBooleanAttribute(this, 'disabled', isDisabled);
74
+ }
75
+ get disabled() {
76
+ return getBooleanAttribute(this, 'disabled');
77
+ }
78
+ set text(value) {
79
+ updateAttribute(this, 'text', value);
80
+ }
81
+ get text() {
82
+ return getAttribute(this, 'text', '');
83
+ }
76
84
  get focusable() {
77
85
  return true;
78
86
  }
@@ -1,6 +1,6 @@
1
1
  import { defineCustomElement, NectaryElement, getLiteralAttribute, updateLiteralAttribute, getAttribute, updateAttribute, parseMarkdown } from '../utils';
2
- const templateHTML = '<style>:host{display:block;font:var(--sinch-font-text-m)}:host([size="s"]){font:var(--sinch-font-text-s)}:host([size=xs]){font:var(--sinch-font-text-xs)}:host([size=xxs]){font:var(--sinch-font-text-xxs)}.em1{font-style:italic}.em2{font-weight:700}.em3{font-style:italic;font-weight:700}.strikethrough{text-decoration:line-through}.link{color:var(--sinch-color-tropical-500)}.code{border:1px solid var(--sinch-color-border-light);background-color:var(--sinch-color-bg-primary-contrast);padding:0 .25em;border-radius:var(--sinch-shape-radius-xs)}.paragraph{margin:0}.paragraph+.paragraph{margin-top:12px}</style><div id="wrapper"></div>';
3
- import { assertSize, sizeValues } from './utils';
2
+ const templateHTML = '<style>:host{display:block;--sinch-comp-rich-text-font:var(--sinch-sys-font-body-m)}:host([size="s"]){--sinch-comp-rich-text-font:var(--sinch-sys-font-body-s)}:host([size=xs]){--sinch-comp-rich-text-font:var(--sinch-sys-font-body-xs)}:host([size=xxs]){--sinch-comp-rich-text-font:var(--sinch-sys-font-body-xxs)}#wrapper{font:var(--sinch-comp-rich-text-font);color:var(--sinch-global-color-text,var(--sinch-sys-color-text-default))}.em1{font-style:italic}.em2{font-weight:var(--sinch-ref-typography-font-weight-700)}.em3{font-style:italic;font-weight:var(--sinch-ref-typography-font-weight-700)}.strikethrough{text-decoration:line-through}.link{font:var(--sinch-comp-link-default-font-initial);color:var(--sinch-comp-link-color-default-text-initial);text-decoration:underline}.link:hover{color:var(--sinch-comp-link-color-default-text-hover);text-decoration:none}.code{font:var(--sinch-comp-code-tag-font-text);line-height:inherit;font-size:inherit;border:1px solid var(--sinch-comp-code-tag-color-default-border-initial);background-color:var(--sinch-comp-code-tag-color-default-background-initial);padding:0 .25em;border-radius:var(--sinch-comp-code-tag-shape-radius)}.paragraph{margin:0}.paragraph+.paragraph{margin-top:12px}</style><div id="wrapper"></div>';
3
+ import { sizeValues } from './utils';
4
4
  const template = document.createElement('template');
5
5
  template.innerHTML = templateHTML;
6
6
  defineCustomElement('sinch-rich-text', class extends NectaryElement {
@@ -27,17 +27,10 @@ defineCustomElement('sinch-rich-text', class extends NectaryElement {
27
27
  updateAttribute(this, 'text', value);
28
28
  }
29
29
  static get observedAttributes() {
30
- return ['size', 'text'];
30
+ return ['text'];
31
31
  }
32
32
  attributeChangedCallback(name, _, newVal) {
33
33
  switch (name) {
34
- case 'size':
35
- {
36
- if ('production' !== 'production') {
37
- assertSize(newVal);
38
- }
39
- break;
40
- }
41
34
  case 'text':
42
35
  {
43
36
  this.#updateText(newVal);
@@ -1,5 +1,2 @@
1
1
  import type { TSinchTextType } from '../text/types';
2
2
  export declare const sizeValues: readonly TSinchTextType[];
3
- type TAssertSize = (value: string | null) => asserts value is TSinchTextType;
4
- export declare const assertSize: TAssertSize;
5
- export {};