@nectary/components 1.4.0 → 2.0.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 (168) 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-option/index.js +2 -2
  6. package/alert/index.js +2 -12
  7. package/avatar/index.js +1 -1
  8. package/avatar/utils.js +3 -3
  9. package/badge/index.js +41 -67
  10. package/badge/types.d.ts +0 -4
  11. package/badge/utils.d.ts +0 -3
  12. package/badge/utils.js +0 -11
  13. package/button/index.js +1 -1
  14. package/button/types.d.ts +2 -2
  15. package/card/index.js +5 -16
  16. package/card/types.d.ts +0 -6
  17. package/card-container/index.js +1 -1
  18. package/chat-block/index.js +1 -1
  19. package/chat-bubble/index.js +3 -24
  20. package/checkbox/index.js +31 -30
  21. package/checkbox/types.d.ts +0 -3
  22. package/chip/index.js +34 -27
  23. package/chip/utils.js +3 -3
  24. package/code-tag/index.js +1 -1
  25. package/color-menu/index.d.ts +0 -3
  26. package/color-menu/index.js +50 -99
  27. package/color-menu/types.d.ts +0 -4
  28. package/color-menu-option/index.d.ts +14 -0
  29. package/color-menu-option/index.js +52 -0
  30. package/color-menu-option/types.d.ts +9 -0
  31. package/color-menu-option/utils.d.ts +1 -0
  32. package/color-menu-option/utils.js +11 -0
  33. package/color-swatch/index.js +1 -1
  34. package/color-swatch/utils.js +3 -3
  35. package/date-picker/index.js +2 -21
  36. package/date-picker/types.d.ts +0 -3
  37. package/dialog/index.js +2 -5
  38. package/dialog/types.d.ts +0 -2
  39. package/emoji/index.js +1 -1
  40. package/emoji-picker/index.d.ts +1 -0
  41. package/emoji-picker/index.js +32 -23
  42. package/field/index.js +39 -32
  43. package/file-drop/index.js +1 -1
  44. package/file-status/index.js +2 -16
  45. package/flag/index.js +1 -1
  46. package/grid/index.js +1 -1
  47. package/help-tooltip/index.js +3 -12
  48. package/horizontal-stepper/index.js +1 -1
  49. package/horizontal-stepper-item/index.d.ts +2 -0
  50. package/horizontal-stepper-item/index.js +8 -12
  51. package/icon/index.js +1 -1
  52. package/icon-button/index.js +1 -1
  53. package/inline-alert/index.js +19 -29
  54. package/input/index.d.ts +0 -3
  55. package/input/index.js +12 -46
  56. package/input/types.d.ts +1 -5
  57. package/link/index.js +35 -37
  58. package/list-item/index.js +1 -1
  59. package/package.json +10 -9
  60. package/pagination/index.js +8 -21
  61. package/pagination/types.d.ts +0 -3
  62. package/pop/index.js +16 -13
  63. package/popover/index.js +44 -50
  64. package/progress/index.js +20 -15
  65. package/radio/index.js +19 -6
  66. package/radio/types.d.ts +3 -3
  67. package/radio-option/index.js +35 -27
  68. package/rich-text/index.js +1 -1
  69. package/segment/index.js +2 -3
  70. package/segment-collapse/index.js +2 -11
  71. package/segment-collapse/types.d.ts +0 -3
  72. package/segmented-control/index.js +0 -3
  73. package/segmented-control/types.d.ts +0 -3
  74. package/segmented-control-option/index.js +20 -19
  75. package/segmented-icon-control/index.js +1 -4
  76. package/segmented-icon-control/types.d.ts +0 -3
  77. package/segmented-icon-control-option/index.js +18 -14
  78. package/select-button/index.js +7 -12
  79. package/select-menu/index.js +12 -5
  80. package/select-menu-option/index.js +2 -5
  81. package/skeleton/index.js +1 -1
  82. package/skeleton-item/index.js +1 -1
  83. package/spinner/index.js +1 -1
  84. package/table/index.js +1 -1
  85. package/table-body/index.js +1 -1
  86. package/table-cell/index.js +1 -1
  87. package/table-head-cell/index.d.ts +1 -0
  88. package/table-head-cell/index.js +12 -3
  89. package/table-row/index.js +18 -2
  90. package/tabs/index.js +1 -4
  91. package/tabs/types.d.ts +0 -3
  92. package/tabs-icon-option/index.js +4 -2
  93. package/tabs-option/index.js +25 -20
  94. package/tag/index.js +16 -8
  95. package/tag/utils.js +3 -3
  96. package/text/index.js +30 -20
  97. package/textarea/index.js +10 -6
  98. package/textarea/types.d.ts +0 -3
  99. package/tile-control/index.js +23 -25
  100. package/tile-control/types.d.ts +0 -3
  101. package/tile-control-option/index.js +1 -1
  102. package/time-picker/index.js +2 -8
  103. package/time-picker/types.d.ts +0 -3
  104. package/title/index.js +30 -22
  105. package/toast/index.js +20 -30
  106. package/toggle/index.js +33 -30
  107. package/toggle/types.d.ts +0 -3
  108. package/tooltip/index.js +2 -8
  109. package/tooltip/types.d.ts +0 -12
  110. package/vertical-stepper/index.js +1 -1
  111. package/vertical-stepper-item/index.d.ts +2 -0
  112. package/vertical-stepper-item/index.js +8 -12
  113. package/logo/create-logo-class.d.ts +0 -1
  114. package/logo/create-logo-class.js +0 -52
  115. package/logo/engage-icon/index.d.ts +0 -11
  116. package/logo/engage-icon/index.js +0 -4
  117. package/logo/engage-icon-wordmark/index.d.ts +0 -11
  118. package/logo/engage-icon-wordmark/index.js +0 -4
  119. package/logo/sinch-icon/index.d.ts +0 -11
  120. package/logo/sinch-icon/index.js +0 -4
  121. package/logo/sinch-icon-wordmark/index.d.ts +0 -11
  122. package/logo/sinch-icon-wordmark/index.js +0 -4
  123. package/logo/types.d.ts +0 -11
  124. package/theme/accordion-item.css +0 -4
  125. package/theme/alert.css +0 -6
  126. package/theme/avatar.css +0 -25
  127. package/theme/badge.css +0 -15
  128. package/theme/button.css +0 -146
  129. package/theme/chat.css +0 -9
  130. package/theme/chip.css +0 -68
  131. package/theme/color-menu.css +0 -4
  132. package/theme/color-swatch.css +0 -71
  133. package/theme/colors.d.ts +0 -4
  134. package/theme/colors.js +0 -4
  135. package/theme/contextual.css +0 -40
  136. package/theme/date-picker.css +0 -7
  137. package/theme/dialog.css +0 -4
  138. package/theme/elevation.css +0 -7
  139. package/theme/emoji-picker.css +0 -13
  140. package/theme/emoji.css +0 -5
  141. package/theme/file-status.css +0 -7
  142. package/theme/flag.css +0 -4
  143. package/theme/fonts.css +0 -86
  144. package/theme/fonts.json +0 -89
  145. package/theme/help-tooltip.css +0 -5
  146. package/theme/horizontal-stepper.css +0 -5
  147. package/theme/icon-button.css +0 -68
  148. package/theme/icon.css +0 -7
  149. package/theme/index.css +0 -4
  150. package/theme/index.d.ts +0 -39
  151. package/theme/index.js +0 -39
  152. package/theme/inline-alert.css +0 -7
  153. package/theme/input.css +0 -10
  154. package/theme/link.css +0 -5
  155. package/theme/pagination.css +0 -5
  156. package/theme/palette.css +0 -90
  157. package/theme/segment.css +0 -4
  158. package/theme/select-button.css +0 -10
  159. package/theme/select-menu.css +0 -6
  160. package/theme/shapes.css +0 -8
  161. package/theme/size.css +0 -9
  162. package/theme/spinner.css +0 -7
  163. package/theme/tag.css +0 -67
  164. package/theme/time-picker.css +0 -4
  165. package/theme/toast.css +0 -7
  166. package/theme/typography.css +0 -16
  167. package/theme/vertical-stepper.css +0 -5
  168. /package/{logo → color-menu-option}/types.js +0 -0
package/link/index.js CHANGED
@@ -1,21 +1,17 @@
1
1
  import '../icon';
2
- import { defineCustomElement, getBooleanAttribute, getAttribute, updateBooleanAttribute, updateAttribute, NectaryElement, isAttrTrue, getReactEventHandler, getCssVars } from '../utils';
3
- const templateHTML = '<style>:host{display:inline}a{font:var(--sinch-font-text-m);font-size:inherit;line-height:inherit;color:var(--sinch-color-tropical-500);border-radius:.5em;white-space:nowrap;--sinch-size-icon:1em;--sinch-color-icon:var(--sinch-color-tropical-500)}a:hover{color:var(--sinch-color-tropical-600);--sinch-color-icon:var(--sinch-color-tropical-600)}a:focus-visible{outline:2px solid var(--sinch-color-border-focus);outline-offset:2px}#external-icon{display:none;margin-right:.2em;vertical-align:-.2em}#standalone-icon,#standalone-icon-prefix{display:none}:host([external]:not([external=false])) #external-icon{display:inline-block}:host([standalone]:not([standalone=false])){display:block}:host([standalone]:not([standalone=false])) a{display:block;font:var(--sinch-font-text-m);font-weight:var(--sinch-font-weight-emphasized);text-decoration:none;border-radius:var(--sinch-shape-radius-m);width:fit-content;--sinch-size-icon:24px}:host([standalone]:not([standalone=false])) #external-icon{margin-right:8px;vertical-align:-7px}:host([standalone]:not([standalone=false])) #standalone-icon-prefix{display:inline}:host([standalone]:not([standalone=false]):is([external=false],:not([external]))) #standalone-icon{display:inline-block;vertical-align:-7px}:host([disabled]:not([disabled=false])) a{color:var(--sinch-color-tropical-200);pointer-events:none;cursor:initial;--sinch-color-icon:var(--sinch-color-tropical-200)}#content{white-space:var(--sinch-text-white-space,normal)}</style><a referrerpolicy="no-referer" aria-hidden="true"><sinch-icon id="external-icon"></sinch-icon><span id="content"></span><span id="standalone-icon-prefix">&nbsp;</span><sinch-icon id="standalone-icon"></sinch-icon></a>';
2
+ import { defineCustomElement, getBooleanAttribute, getAttribute, updateBooleanAttribute, updateAttribute, NectaryElement, isAttrTrue, getReactEventHandler } from '../utils';
3
+ const templateHTML = '<style>:host{display:inline}a{font:var(--sinch-comp-link-default-font-initial);font-size:inherit;line-height:inherit;text-decoration:var(--sinch-comp-link-default-text-decoration-initial);color:var(--sinch-comp-link-color-default-text-initial);border-radius:.5em;white-space:nowrap;--sinch-global-color-icon:var(--sinch-comp-link-color-default-icon-initial)}a:hover{text-decoration:var(--sinch-comp-link-default-text-decoration-hover);color:var(--sinch-comp-link-color-default-text-hover);--sinch-global-color-icon:var(--sinch-comp-link-color-default-icon-hover)}a:focus-visible{outline:2px solid var(--sinch-comp-link-color-default-outline-focus);outline-offset:2px}:host([standalone]){display:block}:host([standalone]) a{display:block;font:var(--sinch-comp-link-standalone-font-initial);font-size:inherit;line-height:inherit;text-decoration:none;width:fit-content}#external-icon,#standalone-icon{display:none;height:1em}#standalone-icon-prefix{display:none}:host([external]:not([standalone])) #external-icon{display:inline-block;margin-right:.2em;vertical-align:-.2em;--sinch-global-size-icon:1em}:host([standalone][external]) #external-icon{display:inline-block;vertical-align:-.4em;margin-right:-.4em;--sinch-global-size-icon:1.5em}:host([standalone]) #standalone-icon-prefix{display:inline}:host([standalone]:not([external])) #standalone-icon{display:inline-block;vertical-align:-.4em;--sinch-global-size-icon:1.5em}:host([disabled]) a{color:var(--sinch-comp-link-color-disabled-text-initial);pointer-events:none;cursor:initial;text-decoration:var(--sinch-comp-link-default-text-decoration-disabled);--sinch-global-color-icon:var(--sinch-comp-link-color-disabled-icon-initial)}#content{white-space:var(--sinch-global-text-white-space,normal)}</style><a referrerpolicy="no-referer" aria-hidden="true"><sinch-icon id="external-icon" name="open_in_new"></sinch-icon><span id="content"></span><span id="standalone-icon-prefix">&nbsp;</span><sinch-icon id="standalone-icon" name="arrow_forward"></sinch-icon></a>';
4
4
  const template = document.createElement('template');
5
5
  template.innerHTML = templateHTML;
6
6
  defineCustomElement('sinch-link', class extends NectaryElement {
7
7
  #$anchor;
8
8
  #$text;
9
- #$iconStandalone;
10
- #$iconExternal;
11
9
  constructor() {
12
10
  super();
13
11
  const shadowRoot = this.attachShadow();
14
12
  shadowRoot.appendChild(template.content.cloneNode(true));
15
13
  this.#$anchor = shadowRoot.querySelector('a');
16
14
  this.#$text = shadowRoot.querySelector('#content');
17
- this.#$iconExternal = shadowRoot.querySelector('#external-icon');
18
- this.#$iconStandalone = shadowRoot.querySelector('#standalone-icon');
19
15
  }
20
16
  connectedCallback() {
21
17
  this.setAttribute('role', 'link');
@@ -25,7 +21,6 @@ defineCustomElement('sinch-link', class extends NectaryElement {
25
21
  this.addEventListener('-click', this.#onClickReactHandler);
26
22
  this.addEventListener('-focus', this.#onFocusReactHandler);
27
23
  this.addEventListener('-blur', this.#onBlurReactHandler);
28
- this.#updateIcons();
29
24
  }
30
25
  disconnectedCallback() {
31
26
  this.#$anchor.removeEventListener('click', this.#onAnchorClick);
@@ -35,6 +30,39 @@ defineCustomElement('sinch-link', class extends NectaryElement {
35
30
  this.removeEventListener('-focus', this.#onFocusReactHandler);
36
31
  this.removeEventListener('-blur', this.#onBlurReactHandler);
37
32
  }
33
+ static get observedAttributes() {
34
+ return ['text', 'href', 'external', 'standalone', 'disabled'];
35
+ }
36
+ attributeChangedCallback(name, oldVal, newVal) {
37
+ if (oldVal === newVal) {
38
+ return;
39
+ }
40
+ switch (name) {
41
+ case 'text':
42
+ {
43
+ this.#$text.textContent = newVal;
44
+ break;
45
+ }
46
+ case 'href':
47
+ {
48
+ updateAttribute(this.#$anchor, 'href', newVal);
49
+ break;
50
+ }
51
+ case 'standalone':
52
+ case 'disabled':
53
+ {
54
+ updateBooleanAttribute(this, name, isAttrTrue(newVal));
55
+ break;
56
+ }
57
+ case 'external':
58
+ {
59
+ const isExternal = isAttrTrue(newVal);
60
+ updateAttribute(this.#$anchor, 'target', isExternal ? '_blank' : null);
61
+ updateBooleanAttribute(this, name, isExternal);
62
+ break;
63
+ }
64
+ }
65
+ }
38
66
  get text() {
39
67
  return getAttribute(this, 'text', '');
40
68
  }
@@ -71,31 +99,6 @@ defineCustomElement('sinch-link', class extends NectaryElement {
71
99
  get preventDefault() {
72
100
  return getBooleanAttribute(this, 'preventdefault');
73
101
  }
74
- static get observedAttributes() {
75
- return ['text', 'href', 'external'];
76
- }
77
- attributeChangedCallback(name, oldVal, newVal) {
78
- if (oldVal === newVal) {
79
- return;
80
- }
81
- switch (name) {
82
- case 'text':
83
- {
84
- this.#$text.textContent = newVal;
85
- break;
86
- }
87
- case 'href':
88
- {
89
- updateAttribute(this.#$anchor, 'href', newVal);
90
- break;
91
- }
92
- case 'external':
93
- {
94
- updateAttribute(this.#$anchor, 'target', isAttrTrue(newVal) ? '_blank' : null);
95
- break;
96
- }
97
- }
98
- }
99
102
  get focusable() {
100
103
  return true;
101
104
  }
@@ -105,11 +108,6 @@ defineCustomElement('sinch-link', class extends NectaryElement {
105
108
  blur() {
106
109
  this.#$anchor.blur();
107
110
  }
108
- #updateIcons() {
109
- const [externalName, standaloneName] = getCssVars(this, ['--sinch-link-icon-external', '--sinch-link-icon-standalone']);
110
- updateAttribute(this.#$iconExternal, 'name', externalName);
111
- updateAttribute(this.#$iconStandalone, 'name', standaloneName);
112
- }
113
111
  #onAnchorClick = e => {
114
112
  if (this.preventDefault) {
115
113
  e.preventDefault();
@@ -1,5 +1,5 @@
1
1
  import { defineCustomElement, NectaryElement } from '../utils';
2
- const templateHTML = '<style>:host{display:block;outline:0}#wrapper{width:100%;height:100%;box-sizing:border-box;overflow:hidden;padding:8px 0;border-bottom:1px solid var(--sinch-color-snow-500)}:host(:last-child)>#wrapper{border-bottom:none}:host(:hover)>#wrapper{background-color:var(--sinch-color-snow-400)}</style><div id="wrapper"><slot name="content"></slot></div>';
2
+ const templateHTML = '<style>:host{display:block;outline:0}#wrapper{width:100%;height:100%;box-sizing:border-box;overflow:hidden;padding:8px 0;background-color:var(--sinch-comp-list-color-default-background-initial);border-bottom:1px solid var(--sinch-comp-list-color-default-border-initial)}:host(:last-child)>#wrapper{border-bottom:none}:host(:hover)>#wrapper{background-color:var(--sinch-comp-list-color-default-background-hover)}</style><div id="wrapper"><slot name="content"></slot></div>';
3
3
  const template = document.createElement('template');
4
4
  template.innerHTML = templateHTML;
5
5
  defineCustomElement('sinch-list-item', class extends NectaryElement {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nectary/components",
3
- "version": "1.4.0",
3
+ "version": "2.0.0",
4
4
  "files": [
5
5
  "**/*/*.css",
6
6
  "**/*/*.json",
@@ -13,18 +13,19 @@
13
13
  "build": "NODE_ENV=production babel . --extensions '.ts' --out-dir . && tsc --declaration --emitDeclarationOnly"
14
14
  },
15
15
  "dependencies": {
16
- "@babel/runtime": "^7.20.13",
16
+ "@babel/runtime": "^7.21.0",
17
17
  "xss": "^1.0.14"
18
18
  },
19
19
  "devDependencies": {
20
- "@babel/cli": "^7.20.7",
21
- "@babel/core": "^7.20.12",
22
- "@babel/plugin-transform-runtime": "^7.19.6",
23
- "@babel/preset-env": "^7.20.2",
24
- "@babel/preset-typescript": "^7.18.6",
25
- "@types/react": "^18.0.27",
20
+ "@babel/cli": "^7.21.0",
21
+ "@babel/core": "^7.21.4",
22
+ "@babel/plugin-transform-runtime": "^7.21.4",
23
+ "@babel/preset-env": "^7.21.4",
24
+ "@babel/preset-typescript": "^7.21.4",
25
+ "@types/node": "^18.16.0",
26
+ "@types/react": "^18.0.38",
26
27
  "babel-plugin-html-inline-minifier": "workspace:^0.0.0",
27
28
  "babel-plugin-transform-inline-environment-variables": "^0.4.4",
28
- "typescript": "^4.9.5"
29
+ "typescript": "^5.0.4"
29
30
  }
30
31
  }
@@ -1,6 +1,6 @@
1
1
  import '../icon';
2
- import { defineCustomElement, updateAttribute, getIntegerAttribute, setClass, NectaryElement, getRect, getReactEventHandler, getCssVars, isTargetEqual, getTargetIndexInParent } from '../utils';
3
- const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}#wrapper{display:flex;justify-content:center;gap:8px;width:100%;box-sizing:border-box}button{all:initial;width:28px;height:28px;box-sizing:border-box;cursor:pointer;text-align:center;contain:strict;--sinch-color-icon:var(--sinch-color-stormy-500)}button:disabled{--sinch-color-icon:var(--sinch-color-stormy-100);cursor:initial}button>*{pointer-events:none}.page{border-radius:50%;font:var(--sinch-font-text-m);color:var(--sinch-color-stormy-500)}.page.dots>span{display:none}.page.dots::after{content:"..."}.page.active{font-weight:var(--sinch-font-weight-emphasized);background-color:var(--sinch-color-snow-600);pointer-events:none;cursor:initial}.page.hidden{display:none}#left,#right{display:flex;padding:2px;--sinch-icon-size:24px}</style><div id="wrapper"><button id="left"><sinch-icon id="icon-left"></sinch-icon></button><button class="page"><span>1</span></button><button class="page active"><span>2</span></button><button class="page"><span>3</span></button><button class="page"><span>4</span></button><button class="page"><span>5</span></button><button class="page dots"><span>6</span></button><button class="page"><span>20</span></button><button id="right"><sinch-icon id="icon-right"></sinch-icon></button></div>';
2
+ import { defineCustomElement, updateAttribute, getIntegerAttribute, setClass, NectaryElement, getRect, getReactEventHandler, isTargetEqual, getTargetIndexInParent } from '../utils';
3
+ const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}#wrapper{display:flex;justify-content:center;gap:8px;width:100%;height:var(--sinch-local-size);--sinch-local-size:24px}button{all:initial;position:relative;display:flex;justify-content:center;align-items:center;width:var(--sinch-local-size);height:var(--sinch-local-size);cursor:pointer;border-radius:var(--sinch-comp-pagination-shape-radius);--sinch-global-color-icon:var(--sinch-comp-pagination-color-default-icon-default)}button:focus-visible::before{content:"";position:absolute;inset:-4px;border:2px solid var(--sinch-comp-pagination-color-default-outline-focus);border-radius:calc(var(--sinch-comp-pagination-shape-radius) + 4px);pointer-events:none}button:disabled{--sinch-global-color-icon:var(--sinch-comp-pagination-color-disabled-icon-initial);cursor:initial}button:enabled:hover{background-color:var(--sinch-comp-pagination-color-default-background-hover)}button>*{display:block;overflow:hidden;pointer-events:none}.page{font:var(--sinch-comp-pagination-font-default-page-number);color:var(--sinch-comp-pagination-color-default-text-initial);background-color:var(--sinch-comp-pagination-color-default-background-initial)}.page.dots>span{display:none}.page.dots::after{content:"..."}.page.active{font:var(--sinch-comp-pagination-font-checked-page-number);background-color:var(--sinch-comp-pagination-color-checked-background-initial);pointer-events:none;cursor:initial}.page.active:hover{background-color:var(--sinch-comp-pagination-color-checked-background-hover)}.page.hidden{display:none}#left,#right{--sinch-icon-size:24px}</style><div id="wrapper"><button id="left"><sinch-icon id="icon-left" name="keyboard_arrow_left"></sinch-icon></button><button class="page"><span>1</span></button><button class="page active"><span>2</span></button><button class="page"><span>3</span></button><button class="page"><span>4</span></button><button class="page"><span>5</span></button><button class="page dots"><span>6</span></button><button class="page"><span>20</span></button><button id="right"><sinch-icon id="icon-right" name="keyboard_arrow_right"></sinch-icon></button></div>';
4
4
  const NUM_BUTTONS = 7;
5
5
  const MIDDLE_BTN_INDEX = Math.floor(NUM_BUTTONS / 2);
6
6
  const FIRST_BTN_INDEX = 0;
@@ -11,9 +11,7 @@ const template = document.createElement('template');
11
11
  template.innerHTML = templateHTML;
12
12
  defineCustomElement('sinch-pagination', class extends NectaryElement {
13
13
  #$left;
14
- #$iconLeft;
15
14
  #$right;
16
- #$iconRight;
17
15
  #$buttons;
18
16
  #$wrapper;
19
17
  constructor() {
@@ -21,9 +19,7 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
21
19
  const shadowRoot = this.attachShadow();
22
20
  shadowRoot.appendChild(template.content.cloneNode(true));
23
21
  this.#$left = shadowRoot.querySelector('#left');
24
- this.#$iconLeft = shadowRoot.querySelector('#icon-left');
25
22
  this.#$right = shadowRoot.querySelector('#right');
26
- this.#$iconRight = shadowRoot.querySelector('#icon-right');
27
23
  this.#$buttons = shadowRoot.querySelectorAll('.page');
28
24
  this.#$wrapper = shadowRoot.querySelector('#wrapper');
29
25
  }
@@ -31,7 +27,6 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
31
27
  this.#onValueChange();
32
28
  this.#$wrapper.addEventListener('click', this.#onButtonClick);
33
29
  this.addEventListener('-change', this.#onChangeReactHandler);
34
- this.#updateIcons();
35
30
  }
36
31
  disconnectedCallback() {
37
32
  this.#$wrapper.removeEventListener('click', this.#onButtonClick);
@@ -54,9 +49,6 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
54
49
  }
55
50
  }
56
51
  }
57
- get nodeName() {
58
- return 'select';
59
- }
60
52
  set value(val) {
61
53
  updateAttribute(this, 'value', val);
62
54
  }
@@ -97,21 +89,21 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
97
89
  }
98
90
  #onButtonClick = e => {
99
91
  e.stopPropagation();
100
- const value = getIntegerAttribute(this, 'value', 0) - 1;
92
+ const value = Math.max(getIntegerAttribute(this, 'value', 0) - 1);
101
93
  const max = Math.max(0, getIntegerAttribute(this, 'max', 0));
102
94
  if (isTargetEqual(e, this.#$left)) {
103
- return this.#dispatchChangeEvent(value - 1);
95
+ return this.#dispatchChangeEvent(Math.max(value - 1, 0));
104
96
  }
105
97
  if (isTargetEqual(e, this.#$right)) {
106
- return this.#dispatchChangeEvent(value + 1);
98
+ return this.#dispatchChangeEvent(Math.min(value + 1, max));
107
99
  }
108
100
  const btnIndex = getTargetIndexInParent(e, this.#$wrapper) - 1;
109
- if (btnIndex >= 0 && btnIndex < this.#$buttons.length) {
101
+ if (btnIndex >= FIRST_BTN_INDEX && btnIndex <= LAST_BTN_INDEX) {
110
102
  if (btnIndex === FIRST_BTN_INDEX) {
111
103
  return this.#dispatchChangeEvent(0);
112
104
  }
113
- if (btnIndex === this.#$buttons.length - 1) {
114
- return this.#dispatchChangeEvent(max - 1);
105
+ if (btnIndex === LAST_BTN_INDEX) {
106
+ return this.#dispatchChangeEvent(max);
115
107
  }
116
108
  if (btnIndex === DOTS_LEFT_INDEX && max > NUM_BUTTONS && value > MIDDLE_BTN_INDEX) {
117
109
  return this.#dispatchChangeEvent(Math.floor(value / 2));
@@ -126,11 +118,6 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
126
118
  const max = getIntegerAttribute(this, 'max', 0);
127
119
  return Math.max(0, Math.min(max - 1, value)) + 1;
128
120
  }
129
- #updateIcons() {
130
- const [leftName, rightName] = getCssVars(this, ['--sinch-pagination-icon-prev', '--sinch-pagination-icon-next']);
131
- updateAttribute(this.#$iconLeft, 'name', leftName);
132
- updateAttribute(this.#$iconRight, 'name', rightName);
133
- }
134
121
  #dispatchChangeEvent(value) {
135
122
  const detail = this.#clamp(value);
136
123
  this.dispatchEvent(new CustomEvent('change', {
@@ -1,5 +1,4 @@
1
1
  import type { TRect, TSinchElementReact } from '../types';
2
- import type { SyntheticEvent } from 'react';
3
2
  export type TSinchPaginationElement = HTMLElement & {
4
3
  value: number;
5
4
  max: number;
@@ -14,7 +13,5 @@ export type TSinchPaginationElement = HTMLElement & {
14
13
  export type TSinchPaginationReact = TSinchElementReact<TSinchPaginationElement> & {
15
14
  value: number;
16
15
  max: number;
17
- /** @deprecated */
18
- onChange?: (event: SyntheticEvent<TSinchPaginationElement, CustomEvent<number>>) => void;
19
16
  'on-change': (e: CustomEvent<number>) => void;
20
17
  };
package/pop/index.js CHANGED
@@ -122,7 +122,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
122
122
  if ('production' !== 'production') {
123
123
  assertOrientation(newVal);
124
124
  }
125
- if (this.#isOpen()) {
125
+ if (this.#$dialog.open) {
126
126
  this.#updateOrientation();
127
127
  }
128
128
  break;
@@ -131,7 +131,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
131
131
  }
132
132
  #getTargetRect() {
133
133
  let item = getFirstSlotElement(this.#$targetSlot, true);
134
- if (item === null && this.#isOpen()) {
134
+ if (item === null && this.#$dialog.open) {
135
135
  item = getFirstSlotElement(this.#$targetOpenSlot, true);
136
136
  }
137
137
  if (item === null) {
@@ -150,14 +150,16 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
150
150
  return item;
151
151
  }
152
152
  #onExpand() {
153
- if (!this.isConnected || this.#isOpen()) {
153
+ if (!this.isConnected || this.#$dialog.open) {
154
154
  return;
155
155
  }
156
- this.#$targetSlot.addEventListener('blur', this.#captureActiveElement, true);
156
+ this.#$targetSlot.addEventListener('blur', this.#stopEventPropagation, true);
157
157
  this.#$focus.setAttribute('tabindex', '-1');
158
158
  this.#$focus.style.display = 'block';
159
+ this.#$focus.addEventListener('focus', this.#captureRelatedActiveElement);
159
160
  this.#$focus.focus();
160
- this.#$targetSlot.removeEventListener('blur', this.#captureActiveElement, true);
161
+ this.#$focus.removeEventListener('focus', this.#captureRelatedActiveElement);
162
+ this.#$targetSlot.removeEventListener('blur', this.#stopEventPropagation, true);
161
163
  this.#$focus.removeAttribute('tabindex');
162
164
  this.#$focus.removeAttribute('style');
163
165
  this.#$dialog.showModal();
@@ -193,7 +195,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
193
195
  this.#$targetOpenSlot.removeEventListener('focus', this.#stopEventPropagation, true);
194
196
  if (!isElementFocused(this.#targetActiveElement)) {
195
197
  requestAnimationFrame(() => {
196
- if (this.isConnected && this.#isOpen()) {
198
+ if (this.isConnected && this.#$dialog.open) {
197
199
  this.#$targetOpenSlot.addEventListener('focus', this.#stopEventPropagation, true);
198
200
  this.#targetActiveElement.focus();
199
201
  this.#$targetOpenSlot.removeEventListener('focus', this.#stopEventPropagation, true);
@@ -205,14 +207,14 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
205
207
  disableScroll();
206
208
  window.addEventListener('resize', this.#onResize);
207
209
  requestAnimationFrame(() => {
208
- if (this.isConnected && this.#isOpen()) {
210
+ if (this.isConnected && this.#$dialog.open) {
209
211
  this.#$contentSlot.addEventListener('slotchange', this.#onContentSlotChange);
210
212
  }
211
213
  });
212
214
  this.#dispatchContentVisibility(true);
213
215
  }
214
216
  #onCollapse() {
215
- if (!this.#isOpen()) {
217
+ if (!this.#$dialog.open) {
216
218
  return;
217
219
  }
218
220
  const isNonModal = !this.modal;
@@ -247,7 +249,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
247
249
  if (!isElementFocused(this.#targetActiveElement)) {
248
250
  const $targetEl = this.#targetActiveElement;
249
251
  requestAnimationFrame(() => {
250
- if (this.isConnected && !this.#isOpen()) {
252
+ if (this.isConnected && !this.#$dialog.open) {
251
253
  this.#$targetSlot.addEventListener('focus', this.#stopEventPropagation, true);
252
254
  $targetEl.focus();
253
255
  this.#$targetSlot.removeEventListener('focus', this.#stopEventPropagation, true);
@@ -262,9 +264,6 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
262
264
  window.removeEventListener('resize', this.#onResize);
263
265
  this.#$contentSlot.removeEventListener('slotchange', this.#onContentSlotChange);
264
266
  }
265
- #isOpen() {
266
- return getBooleanAttribute(this.#$dialog, 'open');
267
- }
268
267
  #onResize = () => {
269
268
  this.#resizeThrottle.fn();
270
269
  };
@@ -336,6 +335,10 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
336
335
  #dispatchCloseEvent() {
337
336
  this.dispatchEvent(new CustomEvent('-close'));
338
337
  }
338
+ #captureRelatedActiveElement = e => {
339
+ e.stopPropagation();
340
+ this.#targetActiveElement = e.relatedTarget;
341
+ };
339
342
  #captureActiveElement = e => {
340
343
  e.stopPropagation();
341
344
  this.#targetActiveElement = e.target;
@@ -361,7 +364,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
361
364
  };
362
365
  #onContentSlotChange = e => {
363
366
  e.stopPropagation();
364
- if (this.#isOpen()) {
367
+ if (this.#$dialog.open) {
365
368
  this.#updateOrientation();
366
369
  }
367
370
  };
package/popover/index.js CHANGED
@@ -1,6 +1,6 @@
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>';
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
4
  import { assertOrientation, getPopOrientation, orientationValues } from './utils';
5
5
  const TIP_SIZE = 16;
6
6
  const template = document.createElement('template');
@@ -35,19 +35,43 @@ 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
+ if ('production' !== 'production') {
49
+ assertOrientation(newVal);
50
+ }
51
+ updateAttribute(this.#$pop, 'orientation', getPopOrientation(this.orientation));
52
+ if (this.#$pop.open) {
53
+ this.#updateTipOrientation();
54
+ }
55
+ break;
56
+ }
57
+ case 'tip':
58
+ {
59
+ const hasTip = isAttrTrue(newVal);
60
+ if (hasTip && this.#$pop.open) {
61
+ this.#updateTipOrientation();
62
+ }
63
+ updateBooleanAttribute(this, name, hasTip);
64
+ break;
65
+ }
66
+ case 'modal':
67
+ case 'open':
68
+ {
69
+ updateAttribute(this.#$pop, name, newVal);
70
+ updateBooleanAttribute(this, name, isAttrTrue(newVal));
71
+ break;
72
+ }
73
+ }
74
+ }
51
75
  set modal(isModal) {
52
76
  updateBooleanAttribute(this, 'modal', isModal);
53
77
  }
@@ -78,42 +102,15 @@ defineCustomElement('sinch-popover', class extends NectaryElement {
78
102
  get popoverRect() {
79
103
  return this.#$pop.popoverRect;
80
104
  }
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
- }
105
+ #onPopClose = () => {
106
+ this.#dispatchCloseEvent();
107
+ };
108
+ #onCloseReactHandler = e => {
109
+ getReactEventHandler(this, 'onClose')?.();
110
+ getReactEventHandler(this, 'on-close')?.(e);
111
+ };
112
+ #dispatchCloseEvent() {
113
+ this.dispatchEvent(new CustomEvent('-close'));
117
114
  }
118
115
  #onContextVisibility = e => {
119
116
  if (e.detail) {
@@ -142,7 +139,4 @@ defineCustomElement('sinch-popover', class extends NectaryElement {
142
139
  this.#$tip.style.left = `${xPos}px`;
143
140
  setClass(this.#$tip, 'hidden', rectOverlap(targetRect, contentRect));
144
141
  };
145
- #isOpen() {
146
- return this.#$pop.open;
147
- }
148
142
  });
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
  };