@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
@@ -1,9 +1,9 @@
1
1
  import '../icon-button';
2
2
  import '../icon';
3
3
  import '../text';
4
- import { defineCustomElement, getAttribute, getBooleanAttribute, getCssVars, getReactEventHandler, getRect, getTargetAttribute, isAttrTrue, NectaryElement, packCsv, setClass, unpackCsv, updateAttribute, updateBooleanAttribute } from '../utils';
5
- const templateHTML = '<style>:host{display:block;outline:0}#content{width:fit-content;box-sizing:border-box;padding:16px;display:flex;flex-direction:column;gap:8px}#month{display:flex;flex-direction:column;row-gap:8px}.week{display:flex;flex-direction:row;column-gap:8px}.week.empty{display:none}.day{all:initial;font:var(--sinch-font-text-xs);color:var(--sinch-color-text-default);text-align:center;border-radius:var(--sinch-shape-radius-s);width:24px;height:24px;line-height:22px;cursor:pointer;border:1px solid transparent;background-color:transparent;box-sizing:border-box;user-select:none}.day.today{border:1px solid var(--sinch-color-tropical-500)}.day:disabled{cursor:initial;color:var(--sinch-color-snow-700)}.day:focus-visible{outline:1px solid var(--sinch-color-border-focus);outline-offset:1px}.day.range{background-color:var(--sinch-color-tropical-100)}.day.selected{background-color:var(--sinch-color-tropical-500);color:var(--sinch-color-snow-100)}.day:hover:enabled:not(.selected){background-color:var(--sinch-color-tropical-200)}#week-day-names{display:flex;flex-direction:row;gap:8px;height:24px}.week-day-name{font:var(--sinch-font-text-xs);font-weight:var(--sinch-font-weight-emphasized);color:var(--sinch-color-text-default);text-align:center;width:24px;height:24px;line-height:24px;user-select:none;text-transform:uppercase}#content-header{display:flex;flex-direction:row;height:32px;align-items:center}#date{flex:1;text-align:center;text-transform:capitalize}#prev-year{margin-left:-4px}#next-year{margin-right:-4px}</style><div id="content"><div id="content-header"><sinch-icon-button id="prev-year" size="s"><sinch-icon id="icon-prev-year" slot="icon"></sinch-icon></sinch-icon-button><sinch-icon-button id="prev-month" size="s"><sinch-icon id="icon-prev-month" slot="icon"></sinch-icon></sinch-icon-button><sinch-text id="date" type="m" emphasized aria-live="polite"></sinch-text><sinch-icon-button id="next-month" size="s"><sinch-icon id="icon-next-month" slot="icon"></sinch-icon></sinch-icon-button><sinch-icon-button id="next-year" size="s"><sinch-icon id="icon-next-year" slot="icon"></sinch-icon></sinch-icon-button></div><div id="week-day-names"><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div></div><div id="month"><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div></div></div>';
6
- import { areDatesEqual, assertDate, assertLocale, assertMinMax, assertValue, canGoNextMonth, canGoNextYear, canGoPrevMonth, canGoPrevYear, clampMaxDate, clampMinDate, cloneDate, dateToIso, decMonth, decYear, getCalendarMonth, getDayNames, getMonthNames, incMonth, incYear, isDateBetween, isoToDate, isValidDate, sortDates, today } from './utils';
4
+ import { defineCustomElement, getAttribute, getBooleanAttribute, getReactEventHandler, getRect, getTargetAttribute, isAttrTrue, NectaryElement, packCsv, setClass, unpackCsv, updateAttribute, updateBooleanAttribute } from '../utils';
5
+ const templateHTML = '<style>:host{display:block;outline:0}#content{width:fit-content;box-sizing:border-box;padding:16px;display:flex;flex-direction:column;gap:8px}#month{display:flex;flex-direction:column;row-gap:8px}.week{display:flex;flex-direction:row;column-gap:8px}.week.empty{display:none}.day{all:initial;font:var(--sinch-comp-date-picker-font-day);width:24px;height:24px;line-height:22px;color:var(--sinch-comp-date-picker-day-color-default-text-initial);background-color:var(--sinch-comp-date-picker-day-color-default-background-initial);border:1px solid var(--sinch-comp-date-picker-day-color-default-border-initial);border-radius:var(--sinch-comp-date-picker-day-shape-radius);text-align:center;box-sizing:border-box;user-select:none;cursor:pointer}.day:focus-visible{outline:1px solid var(--sinch-comp-date-picker-day-color-default-outline-focus);outline-offset:1px}.day:disabled{cursor:initial;color:var(--sinch-comp-date-picker-day-color-disabled-text-initial)}.day:enabled:hover{background-color:var(--sinch-comp-date-picker-day-color-default-background-hover)}.day:enabled.range{background-color:var(--sinch-comp-date-picker-day-color-default-range-background)}.day:enabled.selected{color:var(--sinch-comp-date-picker-day-color-checked-text-initial);background-color:var(--sinch-comp-date-picker-day-color-checked-background-initial);border-color:var(--sinch-comp-date-picker-day-color-checked-border-initial)}.day.today{font:var(--sinch-comp-date-picker-font-today);color:var(--sinch-comp-date-picker-today-color-default-text-initial);background-color:var(--sinch-comp-date-picker-today-color-default-background-initial);border-color:var(--sinch-comp-date-picker-today-color-default-border-initial)}.day.today:hover{background-color:var(--sinch-comp-date-picker-today-color-default-background-hover)}.day.today:disabled{color:var(--sinch-comp-date-picker-today-color-disabled-text-initial);border-color:var(--sinch-comp-date-picker-today-color-disabled-border-initial)}.day.today.selected{color:var(--sinch-comp-date-picker-today-color-checked-text-initial);background-color:var(--sinch-comp-date-picker-today-color-checked-background-initial);border-color:var(--sinch-comp-date-picker-today-color-checked-border-initial)}#week-day-names{display:flex;flex-direction:row;gap:8px;height:24px}.week-day-name{font:var(--sinch-comp-date-picker-font-weekday);color:var(--sinch-comp-date-picker-weekday-color-default-text-initial);text-align:center;width:24px;height:24px;line-height:24px;user-select:none;text-transform:uppercase}#content-header{display:flex;flex-direction:row;height:32px;align-items:center}#date{flex:1;text-align:center;text-transform:capitalize;--sinch-com-text-font:var(--sinch-comp-date-picker-font-header);--sinch-global-color-text:var(--sinch-comp-date-picker-header-color-default-text-initial)}#prev-year{margin-left:-4px}#next-year{margin-right:-4px}</style><div id="content"><div id="content-header"><sinch-icon-button id="prev-year" size="s"><sinch-icon id="icon-prev-year" slot="icon" name="keyboard_double_arrow_left"></sinch-icon></sinch-icon-button><sinch-icon-button id="prev-month" size="s"><sinch-icon id="icon-prev-month" slot="icon" name="keyboard_arrow_left"></sinch-icon></sinch-icon-button><sinch-text id="date" type="m" emphasized aria-live="polite"></sinch-text><sinch-icon-button id="next-month" size="s"><sinch-icon id="icon-next-month" slot="icon" name="keyboard_arrow_right"></sinch-icon></sinch-icon-button><sinch-icon-button id="next-year" size="s"><sinch-icon id="icon-next-year" slot="icon" name="keyboard_double_arrow_right"></sinch-icon></sinch-icon-button></div><div id="week-day-names"><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div></div><div id="month"><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div></div></div>';
6
+ import { areDatesEqual, canGoNextMonth, canGoNextYear, canGoPrevMonth, canGoPrevYear, clampMaxDate, clampMinDate, cloneDate, dateToIso, decMonth, decYear, getCalendarMonth, getDayNames, getMonthNames, incMonth, incYear, isDateBetween, isoToDate, isValidDate, sortDates, today } from './utils';
7
7
  const template = document.createElement('template');
8
8
  template.innerHTML = templateHTML;
9
9
  defineCustomElement('sinch-date-picker', class extends NectaryElement {
@@ -20,10 +20,6 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
20
20
  #$nextMonth;
21
21
  #$prevYear;
22
22
  #$nextYear;
23
- #$iconPrevMonth;
24
- #$iconNextMonth;
25
- #$iconPrevYear;
26
- #$iconNextYear;
27
23
  #$date;
28
24
  #monthNames;
29
25
  #controller = null;
@@ -38,10 +34,6 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
38
34
  this.#$nextYear = shadowRoot.querySelector('#next-year');
39
35
  this.#$date = shadowRoot.querySelector('#date');
40
36
  this.#$month = shadowRoot.querySelector('#month');
41
- this.#$iconPrevMonth = shadowRoot.querySelector('#icon-prev-month');
42
- this.#$iconNextMonth = shadowRoot.querySelector('#icon-next-month');
43
- this.#$iconPrevYear = shadowRoot.querySelector('#icon-prev-year');
44
- this.#$iconNextYear = shadowRoot.querySelector('#icon-next-year');
45
37
  this.#$days = [];
46
38
  this.#$weeks = [];
47
39
  this.#monthNames = [];
@@ -65,7 +57,6 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
65
57
  this.#$nextYear.addEventListener('click', this.#onNextYearClick, options);
66
58
  this.#$month.addEventListener('click', this.#onDateClick, options);
67
59
  this.addEventListener('-change', this.#onChangeReactHandler, options);
68
- this.#updateIcons();
69
60
  }
70
61
  disconnectedCallback() {
71
62
  this.#controller.abort();
@@ -81,21 +72,12 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
81
72
  switch (name) {
82
73
  case 'value':
83
74
  {
84
- if ('production' !== 'production') {
85
- assertValue(newVal);
86
- }
87
75
  this.#onValueChange();
88
76
  break;
89
77
  }
90
78
  case 'min':
91
79
  {
92
- if ('production' !== 'production') {
93
- assertMinMax(newVal, name);
94
- }
95
80
  this.#minDate = isoToDate(newVal);
96
- if ('production' !== 'production') {
97
- assertDate(this.#minDate, name, newVal);
98
- }
99
81
  if (this.#uiDate !== null) {
100
82
  clampMinDate(this.#uiDate, this.#minDate);
101
83
  }
@@ -104,13 +86,7 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
104
86
  }
105
87
  case 'max':
106
88
  {
107
- if ('production' !== 'production') {
108
- assertMinMax(newVal, name);
109
- }
110
89
  this.#maxDate = isoToDate(newVal);
111
- if ('production' !== 'production') {
112
- assertDate(this.#maxDate, name, newVal);
113
- }
114
90
  if (this.#uiDate !== null) {
115
91
  clampMaxDate(this.#uiDate, this.#maxDate);
116
92
  }
@@ -119,9 +95,6 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
119
95
  }
120
96
  case 'locale':
121
97
  {
122
- if ('production' !== 'production') {
123
- assertLocale(newVal);
124
- }
125
98
  const names = getDayNames(newVal);
126
99
  this.#$weekDayNames.forEach(($day, i) => {
127
100
  $day.textContent = names[i];
@@ -162,9 +135,6 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
162
135
  }
163
136
  }
164
137
  }
165
- get nodeName() {
166
- return 'select';
167
- }
168
138
  set locale(value) {
169
139
  updateAttribute(this, 'locale', value);
170
140
  }
@@ -402,13 +372,6 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
402
372
  setClass(this.#$weeks[wi], 'empty', isEmptyWeek);
403
373
  }
404
374
  }
405
- #updateIcons() {
406
- const names = getCssVars(this, ['--sinch-date-picker-icon-prev-month', '--sinch-date-picker-icon-next-month', '--sinch-date-picker-icon-prev-year', '--sinch-date-picker-icon-next-year']);
407
- updateAttribute(this.#$iconPrevMonth, 'name', names[0]);
408
- updateAttribute(this.#$iconNextMonth, 'name', names[1]);
409
- updateAttribute(this.#$iconPrevYear, 'name', names[2]);
410
- updateAttribute(this.#$iconNextYear, 'name', names[3]);
411
- }
412
375
  #subscribeRangeHover() {
413
376
  if (!this.#isHoverSubscribed) {
414
377
  this.#$month.addEventListener('mouseover', this.#onDateMouseEnter);
@@ -1,5 +1,4 @@
1
1
  import type { TRect, TSinchElementReact } from '../types';
2
- import type { SyntheticEvent } from 'react';
3
2
  export type TSinchDatePickerElement = HTMLElement & {
4
3
  /** Date value in ISO 8601 format */
5
4
  value: string;
@@ -66,8 +65,6 @@ export type TSinchDatePickerReact = TSinchElementReact<TSinchDatePickerElement>
66
65
  'prev-month-aria-label': string;
67
66
  /** Label that is used for a11y */
68
67
  'next-month-aria-label': string;
69
- /** @deprecated Change value handler, return date in ISO 8601 format */
70
- onChange?: (e: SyntheticEvent<TSinchDatePickerElement, CustomEvent<string>>) => void;
71
68
  /** Change value handler, return date in ISO 8601 format */
72
69
  'on-change'?: (e: CustomEvent<string>) => void;
73
70
  };
@@ -8,15 +8,7 @@ export declare const isoToDate: (value: string) => Date;
8
8
  export declare const today: () => Date;
9
9
  export declare const getDayNames: (locale: string) => string[];
10
10
  export declare const getMonthNames: (locale: string) => string[];
11
- type TAssertMinMax = (value: string | null, attrName: string) => asserts value is string;
12
- export declare const assertMinMax: TAssertMinMax;
13
- type TAssertValue = (value: string | null) => asserts value is string;
14
- export declare const assertValue: TAssertValue;
15
- type TAssertLocale = (value: string | null) => asserts value is string;
16
- export declare const assertLocale: TAssertLocale;
17
- type TAssertDate = (value: any, attrName: string, attrValue: string) => asserts value is Date;
18
11
  export declare const isValidDate: (value: any) => value is Date;
19
- export declare const assertDate: TAssertDate;
20
12
  export declare const compareDates: (a: Date, b: Date) => number;
21
13
  export declare const clampMinDate: (date: Date, min: Date) => void;
22
14
  export declare const clampMaxDate: (date: Date, max: Date) => void;
@@ -63,29 +63,9 @@ export const getMonthNames = locale => {
63
63
  return formatter.format(date);
64
64
  });
65
65
  };
66
- export const assertMinMax = (value, attrName) => {
67
- if (value == null || value === '') {
68
- throw new Error(`sinch-date-picker: missing or empty "${attrName}" attribute`);
69
- }
70
- };
71
- export const assertValue = value => {
72
- if (value == null) {
73
- throw new Error(`sinch-date-picker: missing "value" attribute`);
74
- }
75
- };
76
- export const assertLocale = value => {
77
- if (value === null || value.length === 0) {
78
- throw new Error(`sinch-date-picker: invalid locale attribute: ${value}`);
79
- }
80
- };
81
66
  export const isValidDate = value => {
82
67
  return value instanceof Date && !isNaN(value);
83
68
  };
84
- export const assertDate = (value, attrName, attrValue) => {
85
- if (!isValidDate(value)) {
86
- throw new Error(`sinch-date-picker: invalid "${attrName}" attribute: ${attrValue}`);
87
- }
88
- };
89
69
  export const compareDates = (a, b) => {
90
70
  return a.getTime() - b.getTime();
91
71
  };
package/dialog/index.js CHANGED
@@ -3,12 +3,11 @@ import '../icon';
3
3
  import '../stop-events';
4
4
  import '../title';
5
5
  import { disableScroll, enableScroll } from '../pop/utils';
6
- import { defineCustomElement, getAttribute, getBooleanAttribute, getRect, isAttrTrue, updateAttribute, getReactEventHandler, NectaryElement, updateBooleanAttribute, getCssVar, setClass, isTargetEqual } from '../utils';
7
- const templateHTML = '<style>:host{display:contents}#dialog{position:fixed;left:0;right:0;margin:auto;display:flex;flex-direction:column;padding:24px 0;max-width:var(--sinch-dialog-max-width,512px);max-height:unset;border-radius:var(--sinch-shape-radius-l);box-sizing:border-box;contain:content;background-color:var(--sinch-color-snow-100);color:var(--sinch-color-text-default);font:var(--sinch-font-text-m);border:none;box-shadow:var(--sinch-elevation-level-3)}#dialog:not([open]){display:none}dialog::backdrop{background-color:#000;opacity:.55}#header{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start;margin-bottom:12px;padding:0 24px}#caption{color:var(--sinch-color-text-default)}#content{min-height:0;overflow:auto;max-height:var(--sinch-dialog-max-height,50vh);padding:4px 24px}#action{display:flex;flex-direction:row;justify-content:flex-end;gap:16px;margin-top:20px;padding:0 24px}#action.empty{display:none}#close{transform:translate(4px,-4px)}</style><dialog id="dialog"><div id="header"><sinch-title id="caption" type="m" level="3" ellipsis></sinch-title><sinch-icon-button id="close" size="s" tabindex="0"><sinch-icon id="icon-close" slot="icon"></sinch-icon></sinch-icon-button></div><div id="content"><sinch-stop-events events="close"><slot name="content"></slot></sinch-stop-events></div><div id="action"><sinch-stop-events events="close"><slot name="buttons"></slot></sinch-stop-events></div></dialog>';
6
+ import { defineCustomElement, getAttribute, getBooleanAttribute, getRect, isAttrTrue, updateAttribute, getReactEventHandler, NectaryElement, updateBooleanAttribute, setClass, isTargetEqual } from '../utils';
7
+ const templateHTML = '<style>:host{display:contents;--sinch-comp-dialog-max-width:512px;--sinch-comp-dialog-max-height:50vh}#dialog{position:fixed;left:0;right:0;margin:auto;display:flex;flex-direction:column;padding:24px 0;max-width:var(--sinch-comp-dialog-max-width);max-height:unset;border-radius:var(--sinch-comp-dialog-shape-radius);box-sizing:border-box;contain:content;background-color:var(--sinch-comp-dialog-color-default-background-initial);border:none;box-shadow:var(--sinch-comp-dialog-shadow);outline:0}#dialog:not([open]){display:none}dialog::backdrop{background-color:#000;opacity:.55}#header{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start;margin-bottom:12px;padding:0 24px}#caption{--sinch-global-color-text:var(--sinch-comp-dialog-color-default-title-initial);--sinch-comp-title-font:var(--sinch-comp-dialog-font-title)}#content{min-height:0;overflow:auto;max-height:var(--sinch-comp-dialog-max-height);padding:4px 24px}#action{display:flex;flex-direction:row;justify-content:flex-end;gap:16px;margin-top:20px;padding:0 24px}#action.empty{display:none}#close{position:relative;left:4px;top:-4px;--sinch-global-color-icon:var(--sinch-comp-dialog-color-default-icon-initial)}</style><dialog id="dialog"><div id="header"><sinch-title id="caption" type="m" level="3" ellipsis></sinch-title><sinch-icon-button id="close" size="s"><sinch-icon id="icon-close" slot="icon" name="close"></sinch-icon></sinch-icon-button></div><div id="content"><sinch-stop-events events="close"><slot name="content"></slot></sinch-stop-events></div><div id="action"><sinch-stop-events events="close"><slot name="buttons"></slot></sinch-stop-events></div></dialog>';
8
8
  const template = document.createElement('template');
9
9
  template.innerHTML = templateHTML;
10
10
  defineCustomElement('sinch-dialog', class extends NectaryElement {
11
- #$iconClose;
12
11
  #$dialog;
13
12
  #$closeButton;
14
13
  #$caption;
@@ -22,7 +21,6 @@ defineCustomElement('sinch-dialog', class extends NectaryElement {
22
21
  this.#$dialog = shadowRoot.querySelector('#dialog');
23
22
  this.#$closeButton = shadowRoot.querySelector('#close');
24
23
  this.#$caption = shadowRoot.querySelector('#caption');
25
- this.#$iconClose = shadowRoot.querySelector('#icon-close');
26
24
  this.#$actionWrapper = shadowRoot.querySelector('#action');
27
25
  this.#$actionSlot = shadowRoot.querySelector('slot[name="buttons"]');
28
26
  }
@@ -38,7 +36,6 @@ defineCustomElement('sinch-dialog', class extends NectaryElement {
38
36
  this.#$dialog.addEventListener('cancel', this.#onCancel, options);
39
37
  this.#$actionSlot.addEventListener('slotchange', this.#onActionSlotChange, options);
40
38
  this.addEventListener('-close', this.#onCloseReactHandler, options);
41
- updateAttribute(this.#$iconClose, 'name', getCssVar(this, '--sinch-dialog-icon-close'));
42
39
  this.#onActionSlotChange();
43
40
  if (getBooleanAttribute(this, 'open')) {
44
41
  this.#onExpand();
@@ -110,7 +107,6 @@ defineCustomElement('sinch-dialog', class extends NectaryElement {
110
107
  }
111
108
  };
112
109
  #onCloseReactHandler = e => {
113
- getReactEventHandler(this, 'onClose')?.(e);
114
110
  getReactEventHandler(this, 'on-close')?.(e);
115
111
  };
116
112
  #dispatchCloseEvent(detail) {
package/dialog/types.d.ts CHANGED
@@ -21,8 +21,6 @@ export type TSinchDialogReact = TSinchElementReact<TSinchDialogElement> & {
21
21
  'aria-label': string;
22
22
  /** Close button label that is used for a11y */
23
23
  'close-aria-label': string;
24
- /** @deprecated close event handler */
25
- onClose?: (e: CustomEvent<TSinchDialogCloseDetail>) => void;
26
24
  /** close event handler */
27
25
  'on-close'?: (e: CustomEvent<TSinchDialogCloseDetail>) => void;
28
26
  };
package/emoji/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { defineCustomElement, getAttribute, NectaryElement, updateAttribute } from '../utils';
2
- const templateHTML = '<style>:host{display:contents}#image{pointer-events:none;width:var(--sinch-size-icon,48px);height:var(--sinch-size-icon,48px)}</style><img id="image" src="" alt="" loading="lazy"/>';
2
+ const templateHTML = '<style>:host{display:contents}#image{pointer-events:none;width:var(--sinch-global-size-icon,48px);height:var(--sinch-global-size-icon,48px)}</style><img id="image" src="" alt="" loading="lazy"/>';
3
3
  import { getEmojiUrl } from './utils';
4
4
  const template = document.createElement('template');
5
5
  template.innerHTML = templateHTML;
@@ -2,6 +2,7 @@ import '../input';
2
2
  import '../icon-button';
3
3
  import '../color-swatch';
4
4
  import '../color-menu';
5
+ import '../color-menu-option';
5
6
  import '../popover';
6
7
  import '../tabs';
7
8
  import '../tabs-icon-option';
@@ -2,16 +2,16 @@ import '../input';
2
2
  import '../icon-button';
3
3
  import '../color-swatch';
4
4
  import '../color-menu';
5
+ import '../color-menu-option';
5
6
  import '../popover';
6
7
  import '../tabs';
7
8
  import '../tabs-icon-option';
8
9
  import '../emoji';
9
10
  import '../text';
10
11
  import '../icon';
11
- import { defineCustomElement, getAttribute, getBooleanAttribute, NectaryElement, updateAttribute, updateBooleanAttribute, getReactEventHandler, getRect, subscribeContext, debounceTimeout, setClass, getCssVar, getCssVars } from '../utils';
12
+ import { defineCustomElement, getAttribute, getBooleanAttribute, NectaryElement, updateAttribute, updateBooleanAttribute, getReactEventHandler, getRect, subscribeContext, debounceTimeout, setClass } from '../utils';
12
13
  import dataJson from './data.json';
13
- const templateHTML = '<style>:host{display:block}#wrapper{width:384px;max-height:504px;display:flex;flex-direction:column;gap:8px;padding:12px 0;--sinch-icon-font-variation-settings:var(--sinch-emoji-picker-icon-font-variation-settings)}#toolbar{display:flex;gap:8px;padding:0 12px}#input{flex:1}#list-wrapper{overflow-y:auto;overflow-x:hidden;width:384px;box-sizing:border-box;scrollbar-gutter:stable}#list{display:flex;flex-wrap:wrap;gap:8px;padding:4px 12px 0;width:384px;box-sizing:border-box}#not-found{display:none;width:100%;height:48px;align-items:center;justify-content:center;color:var(--sinch-color-text-muted);pointer-events:none;user-select:none}#not-found.active{display:flex}</style><div id="wrapper"><div id="toolbar"><sinch-input id="input" size="l" aria-label="Search emojis"><sinch-icon id="icon-search" slot="icon"></sinch-icon></sinch-input><sinch-popover id="skin-popover" orientation="bottom-left" aria-label="Emoji skin tone select"><sinch-icon-button id="skin-button" slot="target" size="l" aria-label="Select emoji skin tones"><sinch-color-swatch id="skin-swatch" slot="icon" name="skin-tone-0"></sinch-color-swatch></sinch-icon-button><sinch-color-menu id="skin-menu" slot="content" cols="1" value="skin-tone-0" colors="skin-tone-0,skin-tone-10,skin-tone-20,skin-tone-30,skin-tone-40,skin-tone-50" aria-label="Emoji skin tone menu"></sinch-color-menu></sinch-popover></div><sinch-tabs id="tabs" aria-label="Emoji groups"></sinch-tabs><div id="list-wrapper"><div id="list"></div><div id="not-found"><sinch-text type="m">No results</sinch-text></div></div></div>';
14
- const groupIconTagNames = ['--sinch-emoji-picker-icon-emoji-emotions', '--sinch-emoji-picker-icon-emoji-people', '--sinch-emoji-picker-icon-emoji-animals-nature', '--sinch-emoji-picker-icon-emoji-food-drinks', '--sinch-emoji-picker-icon-emoji-travel-places', '--sinch-emoji-picker-icon-emoji-sports-activities', '--sinch-emoji-picker-icon-emoji-objects', '--sinch-emoji-picker-icon-emoji-symbols-flags'];
14
+ const templateHTML = '<style>:host{display:block}#wrapper{width:384px;max-height:504px;display:flex;flex-direction:column;gap:8px;padding:12px 0}#toolbar{display:flex;gap:8px;padding:0 12px}#search{flex:1;min-width:0}#search-clear:not(.active){display:none}#list-wrapper{overflow-y:auto;overflow-x:hidden;width:384px;box-sizing:border-box;scrollbar-gutter:stable}#list{display:flex;flex-wrap:wrap;gap:8px;padding:4px 12px 0;width:384px;box-sizing:border-box}#not-found{display:none;width:100%;height:48px;align-items:center;justify-content:center;pointer-events:none;user-select:none;--sinch-global-color-text:var(--sinch-comp-emoji-picker-color-default-text-not-found);--sinch-comp-text-font:var(--sinch-comp-emoji-picker-font-not-found)}#not-found.active{display:flex}#tabs svg{pointer-events:none;height:var(--sinch-global-size-icon);fill:var(--sinch-global-color-icon)}</style><div id="wrapper"><div id="toolbar"><sinch-input id="search" size="l" aria-label="Search emojis"><sinch-icon id="icon-search" slot="icon" name="search"></sinch-icon><sinch-icon-button id="search-clear" slot="right" aria-label="Clear"><sinch-icon slot="icon" name="close"></sinch-icon></sinch-icon-button></sinch-input><sinch-popover id="skin-popover" orientation="bottom-left" aria-label="Emoji skin tone select"><sinch-icon-button id="skin-button" slot="target" size="l" aria-label="Select emoji skin tones"><sinch-color-swatch id="skin-swatch" slot="icon" name="skintone-default"></sinch-color-swatch></sinch-icon-button><sinch-color-menu id="skin-menu" slot="content" cols="1" value="skintone-default" aria-label="Emoji skin tone menu"><sinch-color-menu-option value="skintone-default"></sinch-color-menu-option><sinch-color-menu-option value="skintone-light"></sinch-color-menu-option><sinch-color-menu-option value="skintone-light-medium"></sinch-color-menu-option><sinch-color-menu-option value="skintone-medium"></sinch-color-menu-option><sinch-color-menu-option value="skintone-medium-dark"></sinch-color-menu-option><sinch-color-menu-option value="skintone-dark"></sinch-color-menu-option></sinch-color-menu></sinch-popover></div><sinch-tabs id="tabs" aria-label="Emoji groups"><sinch-tabs-icon-option id="tab-emotions"><svg slot="icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M15.5 11a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm-7 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"/><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2ZM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8Zm4.41-6.11a.745.745 0 0 0-1.03.24A3.98 3.98 0 0 1 12 16c-1.38 0-2.64-.7-3.38-1.88a.747.747 0 1 0-1.27.79A5.446 5.446 0 0 0 12 17.5c1.9 0 3.63-.97 4.65-2.58.22-.35.11-.81-.24-1.03Z"/></svg></sinch-tabs-icon-option><sinch-tabs-icon-option id="tab-people"><svg slot="icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 6a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z"/><path d="M15.89 8.11C15.5 7.72 14.83 7 13.53 7h-2.54a5.023 5.023 0 0 1-4.92-4.15.998.998 0 0 0-.98-.85c-.61 0-1.09.54-1 1.14A7.037 7.037 0 0 0 9 8.71V21c0 .55.45 1 1 1s1-.45 1-1v-5h2v5c0 .55.45 1 1 1s1-.45 1-1V10.05l3.24 3.24a.996.996 0 1 0 1.41-1.41l-3.76-3.77Z"/></svg></sinch-tabs-icon-option><sinch-tabs-icon-option id="tab-animals"><svg slot="icon" viewBox="0 0 24 24"><path d="M17 14c-.24-.24-.44-.49-.65-.75C17.51 11.5 19 8.56 19 5c0-1.95-.74-3-2-3-1.54 0-3.96 2.06-5 5.97C10.96 4.06 8.54 2 7 2 5.74 2 5 3.05 5 5c0 3.56 1.49 6.5 2.65 8.25-.21.26-.41.51-.65.75-.25.25-2 1.39-2 3.5C5 19.98 7.02 22 9.5 22c1.5 0 2.5-.5 2.5-.5s1 .5 2.5.5c2.48 0 4.5-2.02 4.5-4.5 0-2.11-1.75-3.25-2-3.5Zm-.12-9.97c.06.17.12.48.12.97 0 2.84-1.11 5.24-2.07 6.78-.38-.26-.83-.48-1.4-.62.24-4.52 2.44-6.83 3.35-7.13ZM7 5c0-.49.06-.8.12-.97.91.3 3.11 2.61 3.36 7.13-.58.14-1.03.35-1.4.62C8.11 10.24 7 7.84 7 5Zm7.5 15c-1 0-1.8-.33-2.22-.56.42-.18.72-.71.72-.94 0-.28-.45-.5-1-.5s-1 .22-1 .5c0 .23.3.76.72.94-.42.23-1.22.56-2.22.56A2.5 2.5 0 0 1 7 17.5c0-.7.43-1.24 1-1.73.44-.36.61-.52 1.3-1.37.76-.95 1.09-1.4 2.7-1.4s1.94.45 2.7 1.4c.69.85.86 1.01 1.3 1.37.57.49 1 1.03 1 1.73a2.5 2.5 0 0 1-2.5 2.5Zm-.5-4c0 .41-.22.75-.5.75s-.5-.34-.5-.75.22-.75.5-.75.5.34.5.75Zm-3 0c0 .41-.22.75-.5.75s-.5-.34-.5-.75.22-.75.5-.75.5.34.5.75Z"/></svg></sinch-tabs-icon-option><sinch-tabs-icon-option id="tab-food"><svg slot="icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M19 19H3c-.55 0-1 .45-1 1s.45 1 1 1h16c.55 0 1-.45 1-1s-.45-1-1-1Zm1-16H9v2.4l1.81 1.45c.12.09.19.24.19.39v4.26c0 .28-.22.5-.5.5h-4c-.28 0-.5-.22-.5-.5V7.24c0-.15.07-.3.19-.39L8 5.4V3H6c-1.1 0-2 .9-2 2v8c0 2.21 1.79 4 4 4h6c2.21 0 4-1.79 4-4v-3h2c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2Zm0 5h-2V5h2v3Z"/></svg></sinch-tabs-icon-option><sinch-tabs-icon-option id="tab-travel"><svg slot="icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="m21.99 14.77-1.43-4.11c-.14-.4-.52-.66-.97-.66H12.4c-.46 0-.83.26-.98.66L10 14.77v5.24c0 .55.45.99 1 .99s1-.45 1-1v-1h8v1a1 1 0 0 0 2 .01l-.01-5.24Zm-10.38-1.43.69-2c.05-.2.24-.34.46-.34h6.48c.21 0 .4.14.47.34l.69 2a.5.5 0 0 1-.47.66h-7.85a.5.5 0 0 1-.47-.66Zm.38 3.66c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1Zm8 0c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1Z"/><path d="M14 4.5V9h1V4c0-.55-.45-1-1-1H8c-.55 0-1 .45-1 1v4H3c-.55 0-1 .45-1 1v12h1V9.5c0-.28.22-.5.5-.5h4c.28 0 .5-.22.5-.5v-4c0-.28.22-.5.5-.5h5c.28 0 .5.22.5.5Z"/><path d="M7 11H5v2h2v-2Zm5-6h-2v2h2V5ZM7 15H5v2h2v-2Zm0 4H5v2h2v-2Z"/></svg></sinch-tabs-icon-option><sinch-tabs-icon-option id="tab-sports"><svg slot="icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M19.52 2.49C17.18.15 12.9.62 9.97 3.55c-1.6 1.6-2.52 3.87-2.54 5.46-.02 1.58.26 3.89-1.35 5.5l-3.54 3.53c-.39.39-.39 1.02 0 1.42.39.39 1.02.39 1.42 0l3.53-3.54c1.61-1.61 3.92-1.33 5.5-1.35 1.58-.02 3.86-.94 5.46-2.54 2.93-2.92 3.41-7.2 1.07-9.54Zm-9.2 9.19c-1.53-1.53-1.05-4.61 1.06-6.72 2.11-2.11 5.18-2.59 6.72-1.06 1.53 1.53 1.05 4.61-1.06 6.72-2.11 2.11-5.18 2.59-6.72 1.06ZM18 17c.53 0 1.04.21 1.41.59.78.78.78 2.05 0 2.83-.37.37-.88.58-1.41.58-.53 0-1.04-.21-1.41-.59-.78-.78-.78-2.05 0-2.83.37-.37.88-.58 1.41-.58Zm0-2a3.998 3.998 0 0 0-2.83 6.83c.78.78 1.81 1.17 2.83 1.17a3.998 3.998 0 0 0 2.83-6.83A3.998 3.998 0 0 0 18 15Z"/></svg></sinch-tabs-icon-option><sinch-tabs-icon-option id="tab-objects"><svg slot="icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 3c-.46 0-.93.04-1.4.14-2.76.53-4.96 2.76-5.48 5.52-.48 2.61.48 5.01 2.22 6.56.43.38.66.91.66 1.47V19c0 1.1.9 2 2 2h.28a1.98 1.98 0 0 0 3.44 0H14c1.1 0 2-.9 2-2v-2.31c0-.55.22-1.09.64-1.46A6.956 6.956 0 0 0 19 10c0-3.87-3.13-7-7-7Zm.5 11h-1v-2.59L9.67 9.59l.71-.71L12 10.5l1.62-1.62.71.71-1.83 1.83V14Zm1 5c-.01 0-.02-.01-.03-.01V19h-2.94v-.01c-.01 0-.02.01-.03.01-.28 0-.5-.22-.5-.5s.22-.5.5-.5c.01 0 .02.01.03.01V18h2.94v.01c.01 0 .02-.01.03-.01.28 0 .5.22.5.5s-.22.5-.5.5Zm0-2h-3c-.28 0-.5-.22-.5-.5s.22-.5.5-.5h3c.28 0 .5.22.5.5s-.22.5-.5.5Z"/></svg></sinch-tabs-icon-option><sinch-tabs-icon-option id="tab-symbols"><svg slot="icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M10 5H4c-.55 0-1 .45-1 1s.45 1 1 1h2v3c0 .55.45 1 1 1s1-.45 1-1V7h2c.55 0 1-.45 1-1s-.45-1-1-1Zm0-3H4c-.55 0-1 .45-1 1s.45 1 1 1h6c.55 0 1-.45 1-1s-.45-1-1-1Zm10.89 11.11a.996.996 0 0 0-1.41 0l-6.36 6.36a.996.996 0 1 0 1.41 1.41l6.36-6.36a.996.996 0 0 0 0-1.41ZM14.5 16a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm5 5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm-4-10A2.5 2.5 0 0 0 18 8.5V4h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1v3.51c-.42-.32-.93-.51-1.5-.51a2.5 2.5 0 0 0 0 5Zm-5.05 7.09a.996.996 0 1 0-1.41-1.41l-.71.71-.71-.71.35-.35a2.499 2.499 0 0 0-1.77-4.27 2.499 2.499 0 0 0-1.77 4.27l.35.35-1.06 1.06c-.98.98-.98 2.56 0 3.54.5.48 1.14.72 1.78.72.64 0 1.28-.24 1.77-.73l1.06-1.06.71.71a.996.996 0 1 0 1.41-1.41l-.71-.71.71-.71Zm-4.6-3.89a.5.5 0 0 1 .35-.15.5.5 0 0 1 .35.15c.19.2.19.51 0 .71l-.35.35-.35-.36a.5.5 0 0 1-.15-.35.5.5 0 0 1 .15-.35Zm0 5.65a.5.5 0 0 1-.35.15.5.5 0 0 1-.35-.15.5.5 0 0 1-.15-.35.5.5 0 0 1 .15-.35l1.06-1.06.71.71-1.07 1.05Z"/></svg></sinch-tabs-icon-option></sinch-tabs><div id="list-wrapper"><div id="list"></div><div id="not-found"><sinch-text type="m">No results</sinch-text></div></div></div>';
15
15
  const groupLabels = ['Emotions', 'People', 'Animals and nature', 'Food and drinks', 'Travel and places', 'Sports and activities', 'Objects', 'Symbols and flags'];
16
16
  const data = dataJson;
17
17
  const template = document.createElement('template');
@@ -20,14 +20,14 @@ const SEARCH_DEBOUNCE_TIMEOUT = 300;
20
20
  template.innerHTML = templateHTML;
21
21
  defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
22
22
  #$tabs;
23
- #$input;
23
+ #$searchInput;
24
+ #$searchClearButton;
24
25
  #$skinPopover;
25
26
  #$skinMenu;
26
27
  #$skinSwatch;
27
28
  #$skinButton;
28
29
  #$list;
29
30
  #$notFound;
30
- #$iconSearch;
31
31
  #controller = null;
32
32
  #$sh;
33
33
  #searchDebounce;
@@ -39,14 +39,14 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
39
39
  shadowRoot.appendChild(template.content.cloneNode(true));
40
40
  this.#$sh = shadowRoot;
41
41
  this.#$tabs = shadowRoot.querySelector('#tabs');
42
- this.#$input = shadowRoot.querySelector('#input');
42
+ this.#$searchInput = shadowRoot.querySelector('#search');
43
+ this.#$searchClearButton = shadowRoot.querySelector('#search-clear');
43
44
  this.#$skinPopover = shadowRoot.querySelector('#skin-popover');
44
45
  this.#$skinMenu = shadowRoot.querySelector('#skin-menu');
45
46
  this.#$skinSwatch = shadowRoot.querySelector('#skin-swatch');
46
47
  this.#$skinButton = shadowRoot.querySelector('#skin-button');
47
48
  this.#$list = shadowRoot.querySelector('#list');
48
49
  this.#$notFound = shadowRoot.querySelector('#not-found');
49
- this.#$iconSearch = shadowRoot.querySelector('#icon-search');
50
50
  this.#searchDebounce = debounceTimeout(SEARCH_DEBOUNCE_TIMEOUT)(this.#updateSearch);
51
51
  }
52
52
  connectedCallback() {
@@ -57,7 +57,10 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
57
57
  this.#$tabs.addEventListener('-change', this.#onTabsChange, {
58
58
  signal
59
59
  });
60
- this.#$input.addEventListener('-change', this.#onSearchChange, {
60
+ this.#$searchInput.addEventListener('-change', this.#onSearchChange, {
61
+ signal
62
+ });
63
+ this.#$searchClearButton.addEventListener('-click', this.#onSearchClearClick, {
61
64
  signal
62
65
  });
63
66
  this.addEventListener('keydown', this.#onListboxKeyDown, {
@@ -78,7 +81,6 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
78
81
  this.addEventListener('-change', this.#onChangeReactHandler, {
79
82
  signal
80
83
  });
81
- updateAttribute(this.#$iconSearch, 'name', getCssVar(this, '--sinch-emoji-picker-icon-search'));
82
84
  subscribeContext(this, 'keydown', this.#onContextKeyDown, signal);
83
85
  subscribeContext(this, 'visibility', this.#onContextVisibility, signal);
84
86
  this.#updateTabs();
@@ -92,10 +94,10 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
92
94
  return getRect(this.#$skinButton);
93
95
  }
94
96
  get searchInputRect() {
95
- return getRect(this.#$input);
97
+ return getRect(this.#$searchInput);
96
98
  }
97
99
  get searchClearButtonRect() {
98
- return this.#$input.clearButtonRect;
100
+ return getRect(this.#$searchClearButton);
99
101
  }
100
102
  nthSkinToneRect(index) {
101
103
  return this.#$skinMenu.nthItemRect(index);
@@ -147,12 +149,19 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
147
149
  #onTabsChange = e => {
148
150
  const value = e.detail;
149
151
  updateAttribute(this.#$tabs, 'value', value);
150
- updateAttribute(this.#$input, 'value', '');
152
+ updateAttribute(this.#$searchInput, 'value', '');
151
153
  this.#updateEmojis();
152
154
  };
153
155
  #onSearchChange = e => {
154
- this.#$input.value = e.detail;
156
+ this.#$searchInput.value = e.detail;
155
157
  this.#searchDebounce.fn();
158
+ setClass(this.#$searchClearButton, 'active', e.detail.length > 0);
159
+ };
160
+ #onSearchClearClick = () => {
161
+ this.#$searchInput.value = '';
162
+ this.#$searchInput.focus();
163
+ this.#searchDebounce.fn();
164
+ setClass(this.#$searchClearButton, 'active', false);
156
165
  };
157
166
  #onChangeReactHandler = e => {
158
167
  getReactEventHandler(this, 'on-change')?.(e);
@@ -164,7 +173,7 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
164
173
  return Reflect.has(this.#$sh, 'createElement') ? this.#$sh : document;
165
174
  }
166
175
  #updateSearch = () => {
167
- const value = this.#$input.value;
176
+ const value = this.#$searchInput.value;
168
177
  if (value.length < MIN_SEARCH_LENGTH) {
169
178
  if (this.#isSearchMode()) {
170
179
  if (this.#prevTabsValue !== null) {
@@ -182,23 +191,16 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
182
191
  this.#updateSearchEmojis();
183
192
  };
184
193
  #updateTabs() {
185
- const doc = this.#getDocumentRoot();
186
- const tabsFragment = document.createDocumentFragment();
187
- const activeTab = data[0].name;
188
- const iconNames = getCssVars(this, groupIconTagNames);
189
- for (let i = 0; i < data.length; i++) {
194
+ const tabOptions = this.#$tabs.querySelectorAll('sinch-tabs-icon-option');
195
+ const activeTabName = data[0].name;
196
+ const numTabs = Math.min(data.length, tabOptions.length);
197
+ for (let i = 0; i < numTabs; i++) {
190
198
  const group = data[i];
191
- const tabOption = doc.createElement('sinch-tabs-icon-option');
192
- const icon = doc.createElement('sinch-icon');
193
- icon.setAttribute('slot', 'icon');
194
- updateAttribute(icon, 'name', iconNames[i]);
199
+ const tabOption = tabOptions[i];
195
200
  tabOption.setAttribute('value', group.name);
196
201
  tabOption.setAttribute('aria-label', groupLabels[i]);
197
- tabOption.appendChild(icon);
198
- tabsFragment.appendChild(tabOption);
199
202
  }
200
- this.#$tabs.replaceChildren(tabsFragment);
201
- updateAttribute(this.#$tabs, 'value', activeTab);
203
+ updateAttribute(this.#$tabs, 'value', activeTabName);
202
204
  }
203
205
  *#iterateSearchEmojis(searchValue, skinTone) {
204
206
  for (const group of data) {
@@ -233,7 +235,7 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
233
235
  }
234
236
  }
235
237
  #updateSearchEmojis() {
236
- const searchValue = this.#$input.value;
238
+ const searchValue = this.#$searchInput.value;
237
239
  if (searchValue.length < MIN_SEARCH_LENGTH) {
238
240
  return;
239
241
  }
@@ -277,32 +279,32 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
277
279
  this.#$skinSwatch.name = e.detail;
278
280
  this.#$skinMenu.value = e.detail;
279
281
  switch (e.detail) {
280
- case 'skin-tone-0':
282
+ case 'skintone-default':
281
283
  {
282
284
  this.#currentSkinTone = 0;
283
285
  break;
284
286
  }
285
- case 'skin-tone-10':
287
+ case 'skintone-light':
286
288
  {
287
289
  this.#currentSkinTone = 1;
288
290
  break;
289
291
  }
290
- case 'skin-tone-20':
292
+ case 'skintone-light-medium':
291
293
  {
292
294
  this.#currentSkinTone = 2;
293
295
  break;
294
296
  }
295
- case 'skin-tone-30':
297
+ case 'skintone-medium':
296
298
  {
297
299
  this.#currentSkinTone = 3;
298
300
  break;
299
301
  }
300
- case 'skin-tone-40':
302
+ case 'skintone-medium-dark':
301
303
  {
302
304
  this.#currentSkinTone = 4;
303
305
  break;
304
306
  }
305
- case 'skin-tone-50':
307
+ case 'skintone-dark':
306
308
  {
307
309
  this.#currentSkinTone = 5;
308
310
  break;
package/field/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { defineCustomElement, getAttribute, getBooleanAttribute, getFirstSlotElement, NectaryElement, setClass, updateAttribute, updateBooleanAttribute } from '../utils';
2
- const templateHTML = '<style>:host{display:inline-block;vertical-align:middle}#wrapper{display:flex;flex-direction:column;width:100%}#bottom,#top{display:flex;align-items:baseline}#top{height:24px;margin-bottom:2px;--sinch-color-icon:var(--sinch-color-stormy-500)}#additional,#invalid,#label,#optional{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#label{font:var(--sinch-font-title-s);color:var(--sinch-color-text-default)}#optional{flex:1;text-align:right;font:var(--sinch-font-text-s);color:var(--sinch-color-text-muted)}#additional{flex:1;text-align:right;font:var(--sinch-font-text-xs);color:var(--sinch-color-text-muted);line-height:20px;margin-top:2px}#additional:empty{display:none}#invalid{font:var(--sinch-font-text-xs);color:var(--sinch-color-text-invalid);line-height:20px;margin-top:2px}#invalid:empty{display:none}#tooltip{align-self:center;margin:0 8px;display:flex}#tooltip.empty{display:none}:host([disabled]:not([disabled=false])) :is(#label,#additional,#optional,#invalid){color:var(--sinch-color-stormy-100)}:host([disabled]:not([disabled=false])) #top{--sinch-color-icon:var(--sinch-color-stormy-100)}</style><div id="wrapper"><div id="top"><label id="label" for="input"></label><div id="tooltip"><slot name="tooltip"></slot></div><span id="optional"></span></div><slot name="input"></slot><div id="bottom"><div id="invalid"></div><div id="additional"></div></div></div>';
1
+ import { defineCustomElement, getAttribute, getBooleanAttribute, getFirstSlotElement, isAttrTrue, NectaryElement, setClass, updateAttribute, updateBooleanAttribute } from '../utils';
2
+ const templateHTML = '<style>:host{display:inline-block;vertical-align:middle}#wrapper{display:flex;flex-direction:column;width:100%}#bottom,#top{display:flex;align-items:baseline}#top{height:24px;margin-bottom:2px}#additional,#invalid,#label,#optional{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#label{font:var(--sinch-comp-field-font-label);color:var(--sinch-comp-field-color-default-label-initial)}#optional{flex:1;font:var(--sinch-comp-field-font-optional);color:var(--sinch-comp-field-color-default-optional-initial);text-align:right}#additional{flex:1;text-align:right;font:var(--sinch-comp-field-font-additional);color:var(--sinch-comp-field-color-default-additional-initial);line-height:20px;margin-top:2px}#additional:empty{display:none}#invalid{font:var(--sinch-comp-field-font-invalid);color:var(--sinch-comp-field-color-invalid-text-initial);line-height:20px;margin-top:2px}#invalid:empty{display:none}#tooltip{align-self:center;margin:0 8px;display:flex}#tooltip.empty{display:none}:host([disabled]) #label{color:var(--sinch-comp-field-color-disabled-label-initial)}:host([disabled]) #additional{color:var(--sinch-comp-field-color-disabled-additional-initial)}:host([disabled]) #optional{color:var(--sinch-comp-field-color-disabled-optional-initial)}</style><div id="wrapper"><div id="top"><label id="label" for="input"></label><div id="tooltip"><slot name="tooltip"></slot></div><span id="optional"></span></div><slot name="input"></slot><div id="bottom"><div id="invalid"></div><div id="additional"></div></div></div>';
3
3
  const template = document.createElement('template');
4
4
  template.innerHTML = templateHTML;
5
5
  defineCustomElement('sinch-field', class extends NectaryElement {
@@ -28,18 +28,49 @@ defineCustomElement('sinch-field', class extends NectaryElement {
28
28
  const {
29
29
  signal
30
30
  } = this.#controller;
31
- this.#$label.addEventListener('click', this.#onLabelClick, {
31
+ const options = {
32
32
  signal
33
- });
34
- this.#$tooltipSlot.addEventListener('slotchange', this.#onTooltipSlotChange, {
35
- signal
36
- });
33
+ };
34
+ this.#$label.addEventListener('click', this.#onLabelClick, options);
35
+ this.#$tooltipSlot.addEventListener('slotchange', this.#onTooltipSlotChange, options);
37
36
  }
38
37
  disconnectedCallback() {
39
38
  this.#controller.abort();
40
39
  }
41
40
  static get observedAttributes() {
42
- return ['label', 'optionaltext', 'additionaltext', 'invalidtext'];
41
+ return ['label', 'optionaltext', 'additionaltext', 'invalidtext', 'disabled'];
42
+ }
43
+ attributeChangedCallback(name, oldVal, newVal) {
44
+ if (oldVal === newVal) {
45
+ return;
46
+ }
47
+ switch (name) {
48
+ case 'label':
49
+ {
50
+ this.#$label.textContent = newVal;
51
+ break;
52
+ }
53
+ case 'optionaltext':
54
+ {
55
+ this.#$optionalText.textContent = newVal;
56
+ break;
57
+ }
58
+ case 'additionaltext':
59
+ {
60
+ this.#$additionalText.textContent = newVal;
61
+ break;
62
+ }
63
+ case 'invalidtext':
64
+ {
65
+ this.#$invalidText.textContent = newVal;
66
+ break;
67
+ }
68
+ case 'disabled':
69
+ {
70
+ updateBooleanAttribute(this, name, isAttrTrue(newVal));
71
+ break;
72
+ }
73
+ }
43
74
  }
44
75
  set label(value) {
45
76
  updateAttribute(this, 'label', value);
@@ -71,30 +102,6 @@ defineCustomElement('sinch-field', class extends NectaryElement {
71
102
  get disabled() {
72
103
  return getBooleanAttribute(this, 'disabled');
73
104
  }
74
- attributeChangedCallback(name, _, newVal) {
75
- switch (name) {
76
- case 'label':
77
- {
78
- this.#$label.textContent = newVal;
79
- break;
80
- }
81
- case 'optionaltext':
82
- {
83
- this.#$optionalText.textContent = newVal;
84
- break;
85
- }
86
- case 'additionaltext':
87
- {
88
- this.#$additionalText.textContent = newVal;
89
- break;
90
- }
91
- case 'invalidtext':
92
- {
93
- this.#$invalidText.textContent = newVal;
94
- break;
95
- }
96
- }
97
- }
98
105
  #onLabelClick = () => {
99
106
  getFirstSlotElement(this.#$inputSlot)?.focus?.();
100
107
  };
@@ -1,7 +1,7 @@
1
1
  import '../text';
2
2
  import '../file-picker';
3
3
  import { defineCustomElement, getAttribute, getBooleanAttribute, getIntegerAttribute, getReactEventHandler, isAttrTrue, NectaryElement, setClass, updateAttribute, updateBooleanAttribute } from '../utils';
4
- const templateHTML = '<style>:host{display:block}#wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;align-content:center;gap:8px;height:148px;min-width:148px;box-sizing:border-box;padding:16px;border-radius:var(--sinch-shape-radius-m);background-color:var(--sinch-color-bg-primary-contrast)}#wrapper.drop.valid{background-color:var(--sinch-color-bg-secondary-blue)}#wrapper::after{content:"";position:absolute;top:0;left:0;right:0;bottom:0;border:1px dashed var(--sinch-color-stormy-100);border-radius:var(--sinch-shape-radius-m);pointer-events:none}#placeholder{align-self:center;text-align:center}:host([invalid]) #wrapper::after{border-color:var(--sinch-color-text-invalid);border-width:1px}#wrapper.drop::after{pointer-events:all}#wrapper.drop.valid::after{border-color:var(--sinch-color-border-focus);border-width:2px}#wrapper.drop #placeholder{color:var(--sinch-color-text-muted)}:host([disabled]) #wrapper #placeholder{color:var(--sinch-color-stormy-100)}:host([disabled]) #wrapper{background-color:var(--sinch-color-snow-100)}:host([disabled]) #wrapper::after{border-color:var(--sinch-color-stormy-100);border-width:1px}</style><div id="wrapper"><sinch-text id="placeholder" type="m" aria-hidden="true"></sinch-text><sinch-file-picker id="file-picker"><slot></slot></sinch-file-picker></div>';
4
+ const templateHTML = '<style>:host{display:block}#wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;align-content:center;gap:8px;height:148px;min-width:148px;box-sizing:border-box;padding:16px;border-radius:var(--sinch-comp-file-drop-shape-radius);background-color:var(--sinch-comp-file-drop-color-default-background-initial)}#wrapper::after{content:"";position:absolute;top:0;left:0;right:0;bottom:0;border:1px dashed var(--sinch-comp-file-drop-color-default-border-initial);border-radius:var(--sinch-comp-file-drop-shape-radius);pointer-events:none}#placeholder{align-self:center;text-align:center;--sinch-global-color-text:var(--sinch-comp-file-drop-color-default-placeholder-initial);--sinch-comp-text-font:var(--sinch-comp-file-drop-font-placeholder)}:host([invalid]) #wrapper{background-color:var(--sinch-comp-file-drop-color-invalid-background-initial)}:host([invalid]) #wrapper::after{border-color:var(--sinch-comp-file-drop-color-invalid-border-initial);border-width:1px}#wrapper.drop::after{pointer-events:all}#wrapper.drop.valid{background-color:var(--sinch-comp-file-drop-color-default-background-active)}#wrapper.drop.valid::after{border-color:var(--sinch-comp-file-drop-color-default-border-active);border-width:2px}#wrapper.drop.valid>#placeholder{--sinch-global-color-text:var(--sinch-comp-file-drop-color-default-placeholder-active)}:host([disabled])>#wrapper>#placeholder{--sinch-global-color-text:var(--sinch-comp-file-drop-color-disabled-placeholder-initial)}:host([disabled])>#wrapper{background-color:var(--sinch-comp-file-drop-color-disabled-background-initial)}:host([disabled])>#wrapper::after{border-color:var(--sinch-comp-file-drop-color-disabled-border-initial);border-width:1px}</style><div id="wrapper"><sinch-text id="placeholder" type="m" aria-hidden="true"></sinch-text><sinch-file-picker id="file-picker"><slot></slot></sinch-file-picker></div>';
5
5
  import { areFilesAccepted, doFilesSatisfySize } from './utils';
6
6
  const template = document.createElement('template');
7
7
  template.innerHTML = templateHTML;