@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
@@ -0,0 +1,52 @@
1
+ import '../color-swatch';
2
+ import '../tooltip';
3
+ import '../icon';
4
+ import { getSwatchColorFg } from '../color-swatch/utils';
5
+ import { defineCustomElement, getAttribute, NectaryElement, updateAttribute } from '../utils';
6
+ const templateHTML = '<style>:host{display:block;outline:0}#wrapper{width:44px;height:56px;padding:12px 6px;box-sizing:border-box;--sinch-global-color-icon:var(--sinch-color-menu-color-icon)}#swatch-wrapper{position:relative;cursor:pointer;width:32px;height:32px}#swatch-wrapper::after{content:"";position:absolute;width:34px;height:34px;inset:-3px;border:2px solid transparent;border-radius:50%;pointer-events:none}:host([data-selected]:not([data-checked])) #swatch-wrapper::after{border-color:var(--sinch-comp-color-swatch-color-outline-focus)}#check{display:none;position:absolute;left:4px;top:4px;pointer-events:none;--sinch-global-size-icon:24px}:host([data-checked]) #check{display:block}</style><div id="wrapper"><sinch-tooltip id="tooltip"><div id="swatch-wrapper"><sinch-color-swatch id="swatch"></sinch-color-swatch><sinch-icon id="check" name="check"></sinch-icon></div></sinch-tooltip></div>';
7
+ const template = document.createElement('template');
8
+ template.innerHTML = templateHTML;
9
+ defineCustomElement('sinch-color-menu-option', class extends NectaryElement {
10
+ #$wrapper;
11
+ #$tooltip;
12
+ #$swatch;
13
+ constructor() {
14
+ super();
15
+ const shadowRoot = this.attachShadow();
16
+ shadowRoot.appendChild(template.content.cloneNode(true));
17
+ this.#$wrapper = shadowRoot.querySelector('#wrapper');
18
+ this.#$tooltip = shadowRoot.querySelector('#tooltip');
19
+ this.#$swatch = shadowRoot.querySelector('#swatch');
20
+ }
21
+ connectedCallback() {
22
+ this.role = 'option';
23
+ }
24
+ disconnectedCallback() {}
25
+ static get observedAttributes() {
26
+ return ['value'];
27
+ }
28
+ attributeChangedCallback(name, oldVal, newVal) {
29
+ if (oldVal === newVal) {
30
+ return;
31
+ }
32
+ switch (name) {
33
+ case 'value':
34
+ {
35
+ updateAttribute(this.#$tooltip, 'text', newVal);
36
+ updateAttribute(this.#$swatch, 'name', newVal);
37
+ if (newVal !== null) {
38
+ this.#$wrapper.style.setProperty('--sinch-global-color-icon', getSwatchColorFg(newVal));
39
+ } else {
40
+ this.#$wrapper.style.removeProperty('--sinch-global-color-icon');
41
+ }
42
+ break;
43
+ }
44
+ }
45
+ }
46
+ set value(value) {
47
+ updateAttribute(this, 'value', value);
48
+ }
49
+ get value() {
50
+ return getAttribute(this, 'value', '');
51
+ }
52
+ });
@@ -0,0 +1,9 @@
1
+ import type { TSinchElementReact } from '../types';
2
+ export type TSinchColorMenuOptionElement = HTMLElement & {
3
+ /** Value */
4
+ value: string;
5
+ };
6
+ export type TSinchColorMenuOptionReact = TSinchElementReact<TSinchColorMenuOptionElement> & {
7
+ /** Value */
8
+ value: string;
9
+ };
@@ -0,0 +1 @@
1
+ export declare const getParentOption: ($element: Element) => Element | null;
@@ -0,0 +1,11 @@
1
+ export const getParentOption = $element => {
2
+ let $el = $element;
3
+ while (!$el.hasAttribute('data-value')) {
4
+ const parent = $el.parentElement;
5
+ if (parent === null) {
6
+ return null;
7
+ }
8
+ $el = parent;
9
+ }
10
+ return $el;
11
+ };
@@ -1,6 +1,6 @@
1
1
  import '../text';
2
2
  import { defineCustomElement, NectaryElement, setClass, getAttribute, updateAttribute } from '../utils';
3
- const templateHTML = '<style>:host{display:inline-block;vertical-align:middle}#wrapper{width:var(--sinch-size-icon,32px);height:var(--sinch-size-icon,32px);border-radius:50%}#wrapper.no-color{background:linear-gradient(45deg,var(--sinch-color-swatch-color-light-orange-bg),var(--sinch-color-swatch-color-light-yellow-bg),var(--sinch-color-swatch-color-light-green-bg),var(--sinch-color-swatch-color-light-blue-bg),var(--sinch-color-swatch-color-light-violet-bg))}</style><div id="wrapper"></div>';
3
+ const templateHTML = '<style>:host{display:inline-block;vertical-align:middle}#wrapper{width:var(--sinch-global-size-icon,32px);height:var(--sinch-global-size-icon,32px);border-radius:50%}#wrapper.no-color{background:linear-gradient(45deg,var(--sinch-ref-color-complementary-orange-200),var(--sinch-ref-color-complementary-bolt-200),var(--sinch-ref-color-complementary-grass-200),var(--sinch-ref-color-complementary-night-200),var(--sinch-ref-color-complementary-violet-200))}</style><div id="wrapper"></div>';
4
4
  import { assertSwatchColor, getSwatchColorBg } from './utils';
5
5
  const template = document.createElement('template');
6
6
  template.innerHTML = templateHTML;
@@ -1,11 +1,11 @@
1
1
  export const getSwatchColorBg = id => {
2
- return `var(--sinch-color-swatch-color-${id}-bg)`;
2
+ return `var(--sinch-comp-color-swatch-color-${id}-background)`;
3
3
  };
4
4
  export const getSwatchColorFg = id => {
5
- return `var(--sinch-color-swatch-color-${id}-fg)`;
5
+ return `var(--sinch-comp-color-swatch-color-${id}-foreground)`;
6
6
  };
7
7
  export const assertSwatchColor = (root, id) => {
8
- if (id === null || window.getComputedStyle(root).getPropertyValue(`--sinch-color-swatch-color-${id}-bg`).length === 0) {
8
+ if (id === null || window.getComputedStyle(root).getPropertyValue(`--sinch-comp-color-swatch-color-${id}-background`).length === 0) {
9
9
  throw new Error(`Invalid sinch-color-swatch color name: ${id}`);
10
10
  }
11
11
  };
@@ -1,8 +1,8 @@
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>';
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
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';
7
7
  const template = document.createElement('template');
8
8
  template.innerHTML = templateHTML;
@@ -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();
@@ -162,9 +153,6 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
162
153
  }
163
154
  }
164
155
  }
165
- get nodeName() {
166
- return 'select';
167
- }
168
156
  set locale(value) {
169
157
  updateAttribute(this, 'locale', value);
170
158
  }
@@ -402,13 +390,6 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
402
390
  setClass(this.#$weeks[wi], 'empty', isEmptyWeek);
403
391
  }
404
392
  }
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
393
  #subscribeRangeHover() {
413
394
  if (!this.#isHoverSubscribed) {
414
395
  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
  };
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)}#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" tabindex="0"><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();
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,17 @@ 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;--sinch-comp-icon-font-variation-settings:"FILL" 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}</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><div id="list-wrapper"><div id="list"></div><div id="not-found"><sinch-text type="m">No results</sinch-text></div></div></div>';
15
+ const groupIconNames = ['sentiment_satisfied', 'emoji_people', 'pets', 'emoji_food_beverage', 'emoji_transportation', 'sports_tennis', 'emoji_objects', 'emoji_symbols'];
15
16
  const groupLabels = ['Emotions', 'People', 'Animals and nature', 'Food and drinks', 'Travel and places', 'Sports and activities', 'Objects', 'Symbols and flags'];
16
17
  const data = dataJson;
17
18
  const template = document.createElement('template');
@@ -20,14 +21,14 @@ const SEARCH_DEBOUNCE_TIMEOUT = 300;
20
21
  template.innerHTML = templateHTML;
21
22
  defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
22
23
  #$tabs;
23
- #$input;
24
+ #$searchInput;
25
+ #$searchClearButton;
24
26
  #$skinPopover;
25
27
  #$skinMenu;
26
28
  #$skinSwatch;
27
29
  #$skinButton;
28
30
  #$list;
29
31
  #$notFound;
30
- #$iconSearch;
31
32
  #controller = null;
32
33
  #$sh;
33
34
  #searchDebounce;
@@ -39,14 +40,14 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
39
40
  shadowRoot.appendChild(template.content.cloneNode(true));
40
41
  this.#$sh = shadowRoot;
41
42
  this.#$tabs = shadowRoot.querySelector('#tabs');
42
- this.#$input = shadowRoot.querySelector('#input');
43
+ this.#$searchInput = shadowRoot.querySelector('#search');
44
+ this.#$searchClearButton = shadowRoot.querySelector('#search-clear');
43
45
  this.#$skinPopover = shadowRoot.querySelector('#skin-popover');
44
46
  this.#$skinMenu = shadowRoot.querySelector('#skin-menu');
45
47
  this.#$skinSwatch = shadowRoot.querySelector('#skin-swatch');
46
48
  this.#$skinButton = shadowRoot.querySelector('#skin-button');
47
49
  this.#$list = shadowRoot.querySelector('#list');
48
50
  this.#$notFound = shadowRoot.querySelector('#not-found');
49
- this.#$iconSearch = shadowRoot.querySelector('#icon-search');
50
51
  this.#searchDebounce = debounceTimeout(SEARCH_DEBOUNCE_TIMEOUT)(this.#updateSearch);
51
52
  }
52
53
  connectedCallback() {
@@ -57,7 +58,10 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
57
58
  this.#$tabs.addEventListener('-change', this.#onTabsChange, {
58
59
  signal
59
60
  });
60
- this.#$input.addEventListener('-change', this.#onSearchChange, {
61
+ this.#$searchInput.addEventListener('-change', this.#onSearchChange, {
62
+ signal
63
+ });
64
+ this.#$searchClearButton.addEventListener('-click', this.#onSearchClearClick, {
61
65
  signal
62
66
  });
63
67
  this.addEventListener('keydown', this.#onListboxKeyDown, {
@@ -78,7 +82,6 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
78
82
  this.addEventListener('-change', this.#onChangeReactHandler, {
79
83
  signal
80
84
  });
81
- updateAttribute(this.#$iconSearch, 'name', getCssVar(this, '--sinch-emoji-picker-icon-search'));
82
85
  subscribeContext(this, 'keydown', this.#onContextKeyDown, signal);
83
86
  subscribeContext(this, 'visibility', this.#onContextVisibility, signal);
84
87
  this.#updateTabs();
@@ -92,10 +95,10 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
92
95
  return getRect(this.#$skinButton);
93
96
  }
94
97
  get searchInputRect() {
95
- return getRect(this.#$input);
98
+ return getRect(this.#$searchInput);
96
99
  }
97
100
  get searchClearButtonRect() {
98
- return this.#$input.clearButtonRect;
101
+ return getRect(this.#$searchClearButton);
99
102
  }
100
103
  nthSkinToneRect(index) {
101
104
  return this.#$skinMenu.nthItemRect(index);
@@ -147,12 +150,19 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
147
150
  #onTabsChange = e => {
148
151
  const value = e.detail;
149
152
  updateAttribute(this.#$tabs, 'value', value);
150
- updateAttribute(this.#$input, 'value', '');
153
+ updateAttribute(this.#$searchInput, 'value', '');
151
154
  this.#updateEmojis();
152
155
  };
153
156
  #onSearchChange = e => {
154
- this.#$input.value = e.detail;
157
+ this.#$searchInput.value = e.detail;
158
+ this.#searchDebounce.fn();
159
+ setClass(this.#$searchClearButton, 'active', e.detail.length > 0);
160
+ };
161
+ #onSearchClearClick = () => {
162
+ this.#$searchInput.value = '';
163
+ this.#$searchInput.focus();
155
164
  this.#searchDebounce.fn();
165
+ setClass(this.#$searchClearButton, 'active', false);
156
166
  };
157
167
  #onChangeReactHandler = e => {
158
168
  getReactEventHandler(this, 'on-change')?.(e);
@@ -164,7 +174,7 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
164
174
  return Reflect.has(this.#$sh, 'createElement') ? this.#$sh : document;
165
175
  }
166
176
  #updateSearch = () => {
167
- const value = this.#$input.value;
177
+ const value = this.#$searchInput.value;
168
178
  if (value.length < MIN_SEARCH_LENGTH) {
169
179
  if (this.#isSearchMode()) {
170
180
  if (this.#prevTabsValue !== null) {
@@ -185,13 +195,12 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
185
195
  const doc = this.#getDocumentRoot();
186
196
  const tabsFragment = document.createDocumentFragment();
187
197
  const activeTab = data[0].name;
188
- const iconNames = getCssVars(this, groupIconTagNames);
189
198
  for (let i = 0; i < data.length; i++) {
190
199
  const group = data[i];
191
200
  const tabOption = doc.createElement('sinch-tabs-icon-option');
192
201
  const icon = doc.createElement('sinch-icon');
193
202
  icon.setAttribute('slot', 'icon');
194
- updateAttribute(icon, 'name', iconNames[i]);
203
+ updateAttribute(icon, 'name', groupIconNames[i]);
195
204
  tabOption.setAttribute('value', group.name);
196
205
  tabOption.setAttribute('aria-label', groupLabels[i]);
197
206
  tabOption.appendChild(icon);
@@ -233,7 +242,7 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
233
242
  }
234
243
  }
235
244
  #updateSearchEmojis() {
236
- const searchValue = this.#$input.value;
245
+ const searchValue = this.#$searchInput.value;
237
246
  if (searchValue.length < MIN_SEARCH_LENGTH) {
238
247
  return;
239
248
  }
@@ -277,32 +286,32 @@ defineCustomElement('sinch-emoji-picker', class extends NectaryElement {
277
286
  this.#$skinSwatch.name = e.detail;
278
287
  this.#$skinMenu.value = e.detail;
279
288
  switch (e.detail) {
280
- case 'skin-tone-0':
289
+ case 'skintone-default':
281
290
  {
282
291
  this.#currentSkinTone = 0;
283
292
  break;
284
293
  }
285
- case 'skin-tone-10':
294
+ case 'skintone-light':
286
295
  {
287
296
  this.#currentSkinTone = 1;
288
297
  break;
289
298
  }
290
- case 'skin-tone-20':
299
+ case 'skintone-light-medium':
291
300
  {
292
301
  this.#currentSkinTone = 2;
293
302
  break;
294
303
  }
295
- case 'skin-tone-30':
304
+ case 'skintone-medium':
296
305
  {
297
306
  this.#currentSkinTone = 3;
298
307
  break;
299
308
  }
300
- case 'skin-tone-40':
309
+ case 'skintone-medium-dark':
301
310
  {
302
311
  this.#currentSkinTone = 4;
303
312
  break;
304
313
  }
305
- case 'skin-tone-50':
314
+ case 'skintone-dark':
306
315
  {
307
316
  this.#currentSkinTone = 5;
308
317
  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;