@vonage/vivid 5.4.0 → 5.5.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 (161) hide show
  1. package/bundled/base-color-picker.cjs +18 -13
  2. package/bundled/base-color-picker.js +98 -81
  3. package/bundled/calendar-picker.template.cjs +1 -1
  4. package/bundled/calendar-picker.template.js +2 -2
  5. package/bundled/char-count.cjs +1 -1
  6. package/bundled/char-count.js +1 -1
  7. package/bundled/definition10.cjs +1 -1
  8. package/bundled/definition10.js +2 -2
  9. package/bundled/definition11.cjs +12 -19
  10. package/bundled/definition11.js +73 -204
  11. package/bundled/definition12.cjs +19 -10
  12. package/bundled/definition12.js +217 -36
  13. package/bundled/definition13.cjs +10 -1
  14. package/bundled/definition13.js +38 -14
  15. package/bundled/definition14.cjs +1 -5
  16. package/bundled/definition14.js +15 -24
  17. package/bundled/definition15.cjs +5 -30
  18. package/bundled/definition15.js +22 -73
  19. package/bundled/definition16.cjs +30 -19
  20. package/bundled/definition16.js +74 -97
  21. package/bundled/definition17.cjs +19 -13
  22. package/bundled/definition17.js +83 -117
  23. package/bundled/definition18.cjs +13 -12
  24. package/bundled/definition18.js +114 -71
  25. package/bundled/definition19.cjs +16 -16
  26. package/bundled/definition19.js +87 -84
  27. package/bundled/definition2.cjs +9 -9
  28. package/bundled/definition2.js +84 -129
  29. package/bundled/definition3.cjs +1 -1
  30. package/bundled/definition3.js +1 -1
  31. package/bundled/listbox.cjs +1 -1
  32. package/bundled/listbox.js +1 -1
  33. package/bundled/localized.cjs +1 -1
  34. package/bundled/localized.js +48 -35
  35. package/bundled/mixins.cjs +1 -1
  36. package/bundled/mixins.js +1 -1
  37. package/bundled/picker-field.template.cjs +14 -14
  38. package/bundled/picker-field.template.js +35 -56
  39. package/bundled/time-selection-picker.template.cjs +12 -12
  40. package/bundled/time-selection-picker.template.js +13 -12
  41. package/bundled/trapped-focus.cjs +1 -0
  42. package/bundled/trapped-focus.js +26 -0
  43. package/bundled/vivid-element.cjs +1 -1
  44. package/bundled/vivid-element.js +1 -1
  45. package/calendar/index.cjs +13 -13
  46. package/calendar/index.js +172 -144
  47. package/color-picker/definition.cjs +208 -112
  48. package/color-picker/definition.js +208 -112
  49. package/color-picker/index.cjs +104 -75
  50. package/color-picker/index.js +412 -326
  51. package/combobox/index.cjs +1 -1
  52. package/combobox/index.js +1 -1
  53. package/contextual-help/index.cjs +1 -1
  54. package/contextual-help/index.js +1 -1
  55. package/custom-elements.json +49 -0
  56. package/data-grid/index.cjs +1 -1
  57. package/data-grid/index.js +1 -1
  58. package/date-picker/index.cjs +1 -1
  59. package/date-picker/index.js +2 -2
  60. package/date-range-picker/index.cjs +1 -1
  61. package/date-range-picker/index.js +2 -2
  62. package/date-time-picker/index.cjs +1 -1
  63. package/date-time-picker/index.js +2 -2
  64. package/dial-pad/definition.cjs +139 -0
  65. package/dial-pad/definition.js +139 -0
  66. package/dial-pad/index.cjs +27 -20
  67. package/dial-pad/index.js +177 -100
  68. package/divider/index.cjs +1 -1
  69. package/divider/index.js +1 -1
  70. package/icon/definition.cjs +56 -22
  71. package/icon/definition.js +56 -22
  72. package/lib/color-picker/color-picker.d.ts +390 -12
  73. package/lib/color-picker/locale.d.ts +4 -0
  74. package/lib/date-picker/date-picker.d.ts +38 -38
  75. package/lib/date-range-picker/date-range-picker.d.ts +20 -20
  76. package/lib/date-time-picker/date-time-picker.d.ts +40 -40
  77. package/lib/dial-pad/dial-pad.d.ts +1 -0
  78. package/lib/icon/icon.d.ts +1 -0
  79. package/lib/simple-color-picker/simple-color-picker.d.ts +2 -1
  80. package/lib/time-picker/time-picker.d.ts +20 -20
  81. package/locales/de-DE.cjs +16 -3
  82. package/locales/de-DE.js +16 -3
  83. package/locales/en-GB.cjs +17 -4
  84. package/locales/en-GB.js +17 -4
  85. package/locales/en-US.cjs +17 -4
  86. package/locales/en-US.js +17 -4
  87. package/locales/ja-JP.cjs +16 -3
  88. package/locales/ja-JP.js +16 -3
  89. package/locales/zh-CN.cjs +15 -2
  90. package/locales/zh-CN.js +15 -2
  91. package/number-field/index.cjs +1 -1
  92. package/number-field/index.js +3 -3
  93. package/option/index.cjs +1 -1
  94. package/option/index.js +1 -1
  95. package/package.json +1 -1
  96. package/progress-ring/index.cjs +1 -1
  97. package/progress-ring/index.js +1 -1
  98. package/radio/index.cjs +1 -1
  99. package/radio/index.js +1 -1
  100. package/radio-group/index.cjs +1 -1
  101. package/radio-group/index.js +1 -1
  102. package/rich-text-editor/index.cjs +1 -1
  103. package/rich-text-editor/index.js +3 -3
  104. package/searchable-select/index.cjs +1 -1
  105. package/searchable-select/index.js +3 -3
  106. package/select/definition.cjs +6 -3
  107. package/select/definition.js +6 -3
  108. package/selectable-box/index.cjs +1 -1
  109. package/selectable-box/index.js +1 -1
  110. package/shared/color-picker/base-color-picker.d.ts +2 -1
  111. package/shared/picker-field/mixins/calendar-picker.d.ts +10 -10
  112. package/shared/picker-field/mixins/calendar-picker.template.d.ts +10 -10
  113. package/shared/picker-field/mixins/min-max-calendar-picker.d.ts +20 -20
  114. package/shared/picker-field/mixins/single-date-picker.d.ts +28 -28
  115. package/shared/picker-field/mixins/single-value-picker.d.ts +8 -8
  116. package/shared/picker-field/mixins/time-selection-picker.d.ts +20 -20
  117. package/shared/picker-field/mixins/time-selection-picker.template.d.ts +20 -20
  118. package/simple-color-picker/definition.cjs +8 -6
  119. package/simple-color-picker/definition.js +8 -6
  120. package/simple-color-picker/index.cjs +6 -6
  121. package/simple-color-picker/index.js +41 -39
  122. package/styles/core/all.css +1 -1
  123. package/styles/core/theme.css +1 -1
  124. package/styles/core/typography.css +1 -1
  125. package/styles/tokens/theme-dark.css +4 -4
  126. package/styles/tokens/theme-light.css +4 -4
  127. package/styles/tokens/vivid-2-compat.css +1 -1
  128. package/tag/definition.cjs +34 -14
  129. package/tag/definition.js +34 -14
  130. package/tag/index.cjs +25 -12
  131. package/tag/index.js +64 -47
  132. package/tag-group/definition.cjs +1 -2
  133. package/tag-group/definition.js +1 -2
  134. package/tag-group/index.cjs +1 -1
  135. package/tag-group/index.js +11 -12
  136. package/text-area/index.cjs +1 -1
  137. package/text-area/index.js +2 -2
  138. package/time-picker/index.cjs +1 -1
  139. package/time-picker/index.js +1 -1
  140. package/toggletip/index.cjs +1 -1
  141. package/toggletip/index.js +1 -1
  142. package/tooltip/definition.cjs +2 -2
  143. package/tooltip/definition.js +2 -2
  144. package/tooltip/index.cjs +1 -1
  145. package/tooltip/index.js +1 -1
  146. package/unbundled/base-color-picker.cjs +36 -18
  147. package/unbundled/base-color-picker.js +36 -18
  148. package/unbundled/calendar-picker.template.cjs +1 -1
  149. package/unbundled/calendar-picker.template.js +1 -1
  150. package/unbundled/picker-field.template.cjs +2 -35
  151. package/unbundled/picker-field.template.js +2 -34
  152. package/unbundled/time-selection-picker.template.cjs +2 -1
  153. package/unbundled/time-selection-picker.template.js +2 -1
  154. package/unbundled/trapped-focus.cjs +37 -0
  155. package/unbundled/trapped-focus.js +34 -0
  156. package/unbundled/vivid-element.cjs +1 -1
  157. package/unbundled/vivid-element.js +1 -1
  158. package/visually-hidden/index.cjs +1 -1
  159. package/visually-hidden/index.js +1 -1
  160. package/bundled/_has.cjs +0 -1
  161. package/bundled/_has.js +0 -34
package/dial-pad/index.js CHANGED
@@ -1,23 +1,23 @@
1
1
  import { B as h, b as m } from "../bundled/definition3.js";
2
- import { T as g, t as _ } from "../bundled/definition10.js";
3
- import { V as $, a as i, o as y, h as d, c as L, d as A } from "../bundled/vivid-element.js";
4
- import { I as x, i as w } from "../bundled/definition2.js";
5
- import { V as F, v as E } from "../bundled/definition13.js";
6
- import { L as k } from "../bundled/localized.js";
2
+ import { T as _, t as $ } from "../bundled/definition10.js";
3
+ import { V as L, a as i, o as y, h as d, c as w, d as k } from "../bundled/vivid-element.js";
4
+ import { I as P, i as T } from "../bundled/definition2.js";
5
+ import { V as A, v as x } from "../bundled/definition14.js";
6
+ import { L as C } from "../bundled/localized.js";
7
7
  import { w as p } from "../bundled/when.js";
8
- import { r as D } from "../bundled/repeat.js";
9
- import { r as T } from "../bundled/ref.js";
10
- import { c as B } from "../bundled/class-names.js";
11
- import { f as C } from "../bundled/key-codes.js";
12
- const I = ":host{display:inline-block;margin:16px;inline-size:230px}.base{display:grid;box-sizing:border-box;grid-template-rows:80px 1fr auto}.base.no-input{grid-template-rows:1fr auto}.digits{display:grid;gap:16px;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(4,1fr);inline-size:100%}.phone-field{align-self:flex-start;grid-column:1/-1}.digit-btn{--_appearance-color-text: var(--_connotation-color-firm-all);--_appearance-color-fill: transparent;--_appearance-color-outline: var(--_connotation-color-pale)}@media (hover: hover){.digit-btn:hover:where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text: var(--_connotation-color-firm-all);--_appearance-color-fill: transparent;--_appearance-color-outline: var(--_connotation-color-firm-all)}}.digit-btn.hover:where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text: var(--_connotation-color-firm-all);--_appearance-color-fill: transparent;--_appearance-color-outline: var(--_connotation-color-firm-all)}.digit-btn:disabled{--_appearance-color-text: var(--vvd-color-neutral-300);--_appearance-color-fill: transparent;--_appearance-color-outline: var(--vvd-color-neutral-100)}.digit-btn.disabled{--_appearance-color-text: var(--vvd-color-neutral-300);--_appearance-color-fill: transparent;--_appearance-color-outline: var(--vvd-color-neutral-100)}.digit-btn{--_connotation-color-contrast: var(--vvd-dial-pad-accent-contrast, var(--vvd-color-neutral-800));--_connotation-color-soft: var(--vvd-dial-pad-accent-soft, var(--vvd-color-neutral-100));--_connotation-color-pale: var(--vvd-dial-pad-accent-pale, var(--vvd-color-neutral-300));--_connotation-color-fierce: var(--vvd-dial-pad-accent-fierce, var(--vvd-color-neutral-700));--_connotation-color-firm-all: var(--vvd-dial-pad-accent-firm-all, var(--vvd-color-neutral-600));--_connotation-color-faint: var(--vvd-dial-pad-accent-faint, var(--vvd-color-neutral-50));--_connotation-color-dim: var(--vvd-dial-pad-accent-dim, var(--vvd-color-neutral-200))}.digit-btn{--vvd-button-accent-firm: var(--_appearance-color-text);display:flex;overflow:hidden;flex-direction:column;border-radius:16px;box-shadow:0 0 0 1px var(--_appearance-color-outline);inline-size:100%}.digit-btn:not(.disabled) .digit-btn-num{color:var(--vvd-color-canvas-text)}.digit-btn:focus-within{--focus-stroke-gap-color: transparent;box-shadow:0 0 0 4px color-mix(in srgb,var(--vvd-color-cta-500),transparent 85%),inset 0 0 0 3px var(--focus-stroke-gap-color, currentColor);outline:1px solid var(--focus-stroke-color, var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset, 0px))}.call-btn{margin-top:32px;grid-column:1/-1}";
13
- var V = Object.defineProperty, n = (a, t, e, o) => {
14
- for (var c = void 0, s = a.length - 1, u; s >= 0; s--)
15
- (u = a[s]) && (c = u(t, e, c) || c);
16
- return c && V(t, e, c), c;
8
+ import { r as E } from "../bundled/repeat.js";
9
+ import { r as D } from "../bundled/ref.js";
10
+ import { c as F } from "../bundled/class-names.js";
11
+ import { f as I } from "../bundled/key-codes.js";
12
+ const B = ":host{display:inline-block;margin:16px;inline-size:230px}.base{display:grid;box-sizing:border-box;grid-template-rows:80px 1fr auto}.base.no-input{grid-template-rows:1fr auto}.digits{display:grid;gap:16px;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(4,1fr);inline-size:100%}.phone-field{align-self:flex-start;grid-column:1/-1}.digit-btn{--_appearance-color-text: var(--_connotation-color-firm-all);--_appearance-color-fill: transparent;--_appearance-color-outline: var(--_connotation-color-pale)}@media (hover: hover){.digit-btn:hover:where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text: var(--_connotation-color-firm-all);--_appearance-color-fill: transparent;--_appearance-color-outline: var(--_connotation-color-firm-all)}}.digit-btn.hover:where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text: var(--_connotation-color-firm-all);--_appearance-color-fill: transparent;--_appearance-color-outline: var(--_connotation-color-firm-all)}.digit-btn:disabled{--_appearance-color-text: var(--vvd-color-neutral-300);--_appearance-color-fill: transparent;--_appearance-color-outline: var(--vvd-color-neutral-100)}.digit-btn.disabled{--_appearance-color-text: var(--vvd-color-neutral-300);--_appearance-color-fill: transparent;--_appearance-color-outline: var(--vvd-color-neutral-100)}.digit-btn{--_connotation-color-contrast: var(--vvd-dial-pad-accent-contrast, var(--vvd-color-neutral-800));--_connotation-color-soft: var(--vvd-dial-pad-accent-soft, var(--vvd-color-neutral-100));--_connotation-color-pale: var(--vvd-dial-pad-accent-pale, var(--vvd-color-neutral-300));--_connotation-color-fierce: var(--vvd-dial-pad-accent-fierce, var(--vvd-color-neutral-700));--_connotation-color-firm-all: var(--vvd-dial-pad-accent-firm-all, var(--vvd-color-neutral-600));--_connotation-color-faint: var(--vvd-dial-pad-accent-faint, var(--vvd-color-neutral-50));--_connotation-color-dim: var(--vvd-dial-pad-accent-dim, var(--vvd-color-neutral-200))}.digit-btn{--vvd-button-accent-firm: var(--_appearance-color-text);display:flex;overflow:hidden;flex-direction:column;border-radius:16px;box-shadow:0 0 0 1px var(--_appearance-color-outline);inline-size:100%}.digit-btn:not(.disabled) .digit-btn-num{color:var(--vvd-color-canvas-text)}.digit-btn:focus-within{--focus-stroke-gap-color: transparent;box-shadow:0 0 0 4px color-mix(in srgb,var(--vvd-color-cta-500),transparent 85%),inset 0 0 0 3px var(--focus-stroke-gap-color, currentColor);outline:1px solid var(--focus-stroke-color, var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset, 0px))}.call-btn{margin-top:32px;grid-column:1/-1}";
13
+ var V = Object.defineProperty, l = (n, t, e, a) => {
14
+ for (var s = void 0, c = n.length - 1, u; c >= 0; c--)
15
+ (u = n[c]) && (s = u(t, e, s) || s);
16
+ return s && V(t, e, s), s;
17
17
  };
18
- class l extends k($) {
18
+ class o extends C(L) {
19
19
  constructor() {
20
- super(...arguments), this.helperText = null, this.placeholder = null, this.value = "", this.pattern = "^[0-9#*]*$", this.disabled = !1, this.pending = !1, this.callActive = !1, this.noCall = !1, this.noInput = !1, this.endCallButtonLabel = null, this.callButtonLabel = null, this.deleteAriaLabel = null, this._onDial = () => {
20
+ super(...arguments), this.helperText = null, this.placeholder = null, this.value = "", this.pattern = "^[0-9#*]*$", this.disabled = !1, this.pending = !1, this.callActive = !1, this.noCall = !1, this.noInput = !1, this.endCallButtonLabel = null, this.callButtonLabel = null, this.deleteAriaLabel = null, this._longPressTimeoutId = null, this._suppressNextClick = !1, this._keyboardLongPressCompleted = !1, this._onDial = () => {
21
21
  !this._textFieldEl.checkValidity() ? this._announceValidationError(
22
22
  this._textFieldEl.errorValidationMessage ?? ""
23
23
  ) : this._clearErrorAnnouncement(), this.callActive ? this.$emit("end-call") : this.$emit("dial");
@@ -26,6 +26,52 @@ class l extends k($) {
26
26
  valueChanged(t, e) {
27
27
  e != null && this._textFieldEl && e !== this._textFieldEl.value && (this._textFieldEl.value = e, this._textFieldEl.reportValidity());
28
28
  }
29
+ /**
30
+ * @internal
31
+ */
32
+ _startLongPress(t, e) {
33
+ if (this.disabled || this.callActive || t !== "0") return;
34
+ this._clearLongPressTimer();
35
+ const a = e.currentTarget;
36
+ this._longPressTimeoutId = window.setTimeout(() => {
37
+ this._suppressNextClick = !0, this.value += "+", this.$emit("keypad-click", a), this.$emit("input"), this.$emit("change");
38
+ }, 600);
39
+ }
40
+ /**
41
+ * @internal
42
+ */
43
+ _startKeyboardLongPress() {
44
+ this.disabled || this.callActive || this._longPressTimeoutId === null && (this._keyboardLongPressCompleted = !1, this._longPressTimeoutId = window.setTimeout(() => {
45
+ this._keyboardLongPressCompleted = !0, this.value += "+", this.$emit("input"), this.$emit("change");
46
+ }, 650));
47
+ }
48
+ /**
49
+ * @internal
50
+ */
51
+ _endLongPress() {
52
+ this._clearLongPressTimer(), window.setTimeout(() => {
53
+ this._suppressNextClick && (this._suppressNextClick = !1);
54
+ }, 0);
55
+ }
56
+ /**
57
+ * @internal
58
+ * @returns true if long press completed (timer fired), false otherwise
59
+ */
60
+ _endKeyboardLongPress() {
61
+ const t = this._keyboardLongPressCompleted;
62
+ return this._clearLongPressTimer(), window.setTimeout(() => {
63
+ this._keyboardLongPressCompleted = !1;
64
+ }, 0), t;
65
+ }
66
+ /**
67
+ * @internal
68
+ */
69
+ _cancelLongPress() {
70
+ this._clearLongPressTimer();
71
+ }
72
+ _clearLongPressTimer() {
73
+ this._longPressTimeoutId !== null && (clearTimeout(this._longPressTimeoutId), this._longPressTimeoutId = null);
74
+ }
29
75
  /**
30
76
  * Moves focus into the diapl-pad.
31
77
  *
@@ -50,54 +96,54 @@ class l extends k($) {
50
96
  this._errorAnnouncement = "", this._forceAnnouncementToggle = !1;
51
97
  }
52
98
  }
53
- n([
99
+ l([
54
100
  i({ attribute: "helper-text" })
55
- ], l.prototype, "helperText");
56
- n([
101
+ ], o.prototype, "helperText");
102
+ l([
57
103
  i
58
- ], l.prototype, "placeholder");
59
- n([
104
+ ], o.prototype, "placeholder");
105
+ l([
60
106
  i({ mode: "fromView" })
61
- ], l.prototype, "value");
62
- n([
107
+ ], o.prototype, "value");
108
+ l([
63
109
  i({ mode: "fromView" })
64
- ], l.prototype, "pattern");
65
- n([
110
+ ], o.prototype, "pattern");
111
+ l([
66
112
  i({ mode: "boolean" })
67
- ], l.prototype, "disabled");
68
- n([
113
+ ], o.prototype, "disabled");
114
+ l([
69
115
  i({ mode: "boolean" })
70
- ], l.prototype, "pending");
71
- n([
116
+ ], o.prototype, "pending");
117
+ l([
72
118
  i({ attribute: "call-active", mode: "boolean" })
73
- ], l.prototype, "callActive");
74
- n([
119
+ ], o.prototype, "callActive");
120
+ l([
75
121
  i({ mode: "boolean", attribute: "no-call" })
76
- ], l.prototype, "noCall");
77
- n([
122
+ ], o.prototype, "noCall");
123
+ l([
78
124
  i({ mode: "boolean", attribute: "no-input" })
79
- ], l.prototype, "noInput");
80
- n([
125
+ ], o.prototype, "noInput");
126
+ l([
81
127
  i({ attribute: "end-call-button-label" })
82
- ], l.prototype, "endCallButtonLabel");
83
- n([
128
+ ], o.prototype, "endCallButtonLabel");
129
+ l([
84
130
  i({ attribute: "call-button-label" })
85
- ], l.prototype, "callButtonLabel");
86
- n([
131
+ ], o.prototype, "callButtonLabel");
132
+ l([
87
133
  i({ attribute: "delete-aria-label" })
88
- ], l.prototype, "deleteAriaLabel");
89
- n([
134
+ ], o.prototype, "deleteAriaLabel");
135
+ l([
90
136
  i({ mode: "boolean" })
91
- ], l.prototype, "autofocus");
92
- n([
137
+ ], o.prototype, "autofocus");
138
+ l([
93
139
  y
94
- ], l.prototype, "_errorAnnouncement");
140
+ ], o.prototype, "_errorAnnouncement");
95
141
  class r {
96
- constructor(t, e, o, c, s) {
97
- this.value = t, this.label = e, this.ariaLabel = o, this.icon = c, this.id = s;
142
+ constructor(t, e, a, s, c) {
143
+ this.value = t, this.label = e, this.ariaLabel = a, this.icon = s, this.id = c;
98
144
  }
99
145
  }
100
- const f = [
146
+ const b = [
101
147
  new r("1", " ", "digitOneLabel", "one-solid", "btn1"),
102
148
  new r("2", "ABC", "digitTwoLabel", "two-solid", "btn2"),
103
149
  new r("3", "DEF", "digitThreeLabel", "three-solid", "btn3"),
@@ -122,42 +168,57 @@ const f = [
122
168
  "hashtag-solid",
123
169
  "btnHashtag"
124
170
  )
125
- ], P = ({ noInput: a }) => B("base", ["no-input", !!a]);
126
- function z(a, t) {
127
- if (t.key === C && !a.pending && !a.disabled && !a.callActive && !a.noCall && a.value.length > 0 && t.target instanceof HTMLInputElement)
128
- a._onDial();
171
+ ], K = ({ noInput: n }) => F("base", ["no-input", !!n]);
172
+ function N(n, t) {
173
+ if (t.key === I && !n.pending && !n.disabled && !n.callActive && !n.noCall && n.value.length > 0 && t.target instanceof HTMLInputElement)
174
+ n._onDial();
175
+ else if (t.key === " " || t.key === "Space")
176
+ t.target instanceof HTMLInputElement && (t.preventDefault(), t.repeat || n._startKeyboardLongPress());
129
177
  else {
130
- const e = f.findIndex((o) => o.value === t.key);
178
+ const e = b.findIndex((a) => a.value === t.key);
131
179
  if (e > -1) {
132
- const o = a.shadowRoot.querySelector(".digits").children[e];
133
- o && (o.active = !0, setTimeout(() => {
134
- o.active = !1;
180
+ const a = n.shadowRoot.querySelector(".digits").children[e];
181
+ a && (a.active = !0, setTimeout(() => {
182
+ a.active = !1;
135
183
  }, 200));
136
184
  }
137
185
  }
138
186
  return !0;
139
187
  }
140
- function v(a) {
141
- a.value = a._textFieldEl.value;
188
+ function S(n, t) {
189
+ return (t.key === " " || t.key === "Space") && t.target instanceof HTMLInputElement && (t.preventDefault(), !n._endKeyboardLongPress() && !n.disabled && !n.callActive && (n.value += " ", n.$emit("input"), n.$emit("change"))), !0;
190
+ }
191
+ function z(n, { parent: t, event: e }) {
192
+ return (e.key === " " || e.key === "Space") && n.value === "0" && (e.preventDefault(), e.repeat || t._startKeyboardLongPress()), !0;
142
193
  }
143
- function b(a, { event: t }) {
194
+ function H(n, { parent: t, event: e }) {
195
+ return (e.key === " " || e.key === "Space") && n.value === "0" && (e.preventDefault(), !t._endKeyboardLongPress() && !t.disabled && !t.callActive && g(n, {
196
+ parent: t,
197
+ event: new MouseEvent("click", { bubbles: !0 })
198
+ })), !0;
199
+ }
200
+ function v(n) {
201
+ n.value = n._textFieldEl.value;
202
+ }
203
+ function f(n, { event: t }) {
144
204
  t.stopImmediatePropagation();
145
205
  }
146
- function H(a) {
147
- a.value = a.value.slice(0, -1), a.$emit("input"), a.$emit("change"), a.value === "" && a._textFieldEl?.focus();
206
+ function M(n) {
207
+ n.value = n.value.slice(0, -1), n.$emit("input"), n.$emit("change"), n.value === "" && n._textFieldEl?.focus();
148
208
  }
149
- function S(a, t) {
150
- return d`<${a} ${T(
209
+ function O(n, t) {
210
+ return d`<${n} ${D(
151
211
  "_textFieldEl"
152
212
  )} class="phone-field" internal-part type="tel"
153
213
  value="${(e) => e.value}" placeholder="${(e) => e.placeholder}"
154
214
  ?disabled="${(e) => e.disabled}" helper-text="${(e) => e.helperText}" pattern="${(e) => e.pattern}"
155
215
  aria-label="${(e) => e.locale.dialPad.inputLabel}"
156
- @keydown="${(e, o) => z(e, o.event)}"
216
+ @keydown="${(e, a) => N(e, a.event)}"
217
+ @keyup="${(e, a) => S(e, a.event)}"
157
218
  @input="${v}"
158
219
  @change="${v}"
159
- @focus="${b}"
160
- @blur="${b}"
220
+ @focus="${f}"
221
+ @blur="${f}"
161
222
  ?autofocus="${(e) => e.autofocus}"
162
223
  >
163
224
  ${p(
@@ -169,20 +230,24 @@ function S(a, t) {
169
230
  aria-label="${(e) => e.deleteAriaLabel || e.locale.dialPad.deleteButtonLabel}"
170
231
  appearance='ghost'
171
232
  ?disabled="${(e) => e.disabled || e.callActive}"
172
- @click="${(e) => H(e)}">
233
+ @click="${(e) => M(e)}">
173
234
  </${t}>`
174
235
  )}
175
- </${a}>`;
236
+ </${n}>`;
176
237
  }
177
- function M(a, { parent: t, event: e }) {
178
- t.value += a.value, t.$emit("keypad-click", e.currentTarget), t.$emit("input"), t.$emit("change");
238
+ function g(n, { parent: t, event: e }) {
239
+ if (t._suppressNextClick) {
240
+ t._suppressNextClick = !1;
241
+ return;
242
+ }
243
+ t.value += n.value, t.$emit("keypad-click", e.currentTarget), t.$emit("input"), t.$emit("change");
179
244
  }
180
- function N(a, t) {
245
+ function R(n, t) {
181
246
  return d`
182
- ${D(
183
- (e) => f,
247
+ ${E(
248
+ (e) => b,
184
249
  d`
185
- <${a}
250
+ <${n}
186
251
  id="${(e) => e.id}"
187
252
  value="${(e) => e.value}"
188
253
  stacked
@@ -191,14 +256,26 @@ function N(a, t) {
191
256
  label="${(e) => e.label === "&nbsp;" ? " " : e.label}"
192
257
  size='condensed'
193
258
  class="digit-btn"
194
- ?autofocus="${(e, o) => o.parent.autofocus && o.parent.noInput && o.index === 0}"
195
- aria-label="${(e, o) => o.parent.locale.dialPad[e.ariaLabel]}"
196
- ?disabled="${(e, o) => o.parent.disabled}"
197
- @click="${M}">
259
+ ?autofocus="${(e, a) => a.parent.autofocus && a.parent.noInput && a.index === 0}"
260
+ aria-label="${(e, a) => a.parent.locale.dialPad[e.ariaLabel]}"
261
+ ?disabled="${(e, a) => a.parent.disabled}"
262
+ @pointerdown="${(e, a) => a.parent._startLongPress(e.value, a.event)}"
263
+ @pointerup="${(e, a) => a.parent._endLongPress()}"
264
+ @pointercancel="${(e, a) => a.parent._cancelLongPress()}"
265
+ @pointerleave="${(e, a) => a.parent._cancelLongPress()}"
266
+ @keydown="${(e, a) => z(e, {
267
+ parent: a.parent,
268
+ event: a.event
269
+ })}"
270
+ @keyup="${(e, a) => H(e, {
271
+ parent: a.parent,
272
+ event: a.event
273
+ })}"
274
+ @click="${g}">
198
275
  <${t} slot="icon"
199
276
  name="${(e) => e.icon}"
200
277
  class="digit-btn-num"></${t}>
201
- </${a}>
278
+ </${n}>
202
279
  `,
203
280
  {
204
281
  positioning: !0
@@ -206,8 +283,8 @@ function N(a, t) {
206
283
  )}
207
284
  `;
208
285
  }
209
- function O(a) {
210
- return d`<${a} class="call-btn"
286
+ function U(n) {
287
+ return d`<${n} class="call-btn"
211
288
  size="expanded"
212
289
  appearance="filled"
213
290
  icon="${(t) => t.callActive ? "disable-call-line" : "call-line"}"
@@ -216,33 +293,33 @@ function O(a) {
216
293
  ?pending="${(t) => t.pending}"
217
294
  @click="${(t) => t._onDial()}"
218
295
  label="${(t) => t.callActive ? t.endCallButtonLabel || t.locale.dialPad.endCallButtonLabel : t.callButtonLabel || t.locale.dialPad.callButtonLabel}">
219
- </${a}>`;
296
+ </${n}>`;
220
297
  }
221
- function R(a) {
222
- return d`<${a} role="alert" aria-atomic="true">
298
+ function q(n) {
299
+ return d`<${n} role="alert" aria-atomic="true">
223
300
  ${(t) => `${t.locale.dialPad.errorLabel} ${t._errorAnnouncement}`}
224
- </${a}>`;
301
+ </${n}>`;
225
302
  }
226
- const q = (a) => {
227
- const t = a.tagFor(h), e = a.tagFor(x), o = a.tagFor(g), c = a.tagFor(F);
228
- return d` <div class="${P}">
229
- ${p((s) => !s.noInput, S(o, t))}
230
- <div class="digits">${N(t, e)}</div>
231
- ${p((s) => !s.noCall, O(t))}
232
- ${R(c)}
303
+ const Z = (n) => {
304
+ const t = n.tagFor(h), e = n.tagFor(P), a = n.tagFor(_), s = n.tagFor(A);
305
+ return d` <div class="${K}">
306
+ ${p((c) => !c.noInput, O(a, t))}
307
+ <div class="digits">${R(t, e)}</div>
308
+ ${p((c) => !c.noCall, U(t))}
309
+ ${q(s)}
233
310
  </div>`;
234
- }, K = A(
311
+ }, j = k(
235
312
  "dial-pad",
236
- l,
237
- q,
313
+ o,
314
+ Z,
238
315
  [
239
316
  m,
240
- _,
241
- w,
242
- E
317
+ $,
318
+ T,
319
+ x
243
320
  ],
244
321
  {
245
- styles: I
322
+ styles: B
246
323
  }
247
- ), U = L(K);
248
- U();
324
+ ), G = w(j);
325
+ G();
package/divider/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";const i=require("../bundled/definition14.cjs");i.registerDivider();
1
+ "use strict";const i=require("../bundled/definition15.cjs");i.registerDivider();
package/divider/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { r } from "../bundled/definition14.js";
1
+ import { r } from "../bundled/definition15.js";
2
2
  r();
@@ -5,7 +5,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5
5
  const vividElement = require('../unbundled/vivid-element.cjs');
6
6
  const visuallyHidden_definition = require('../visually-hidden/definition.cjs');
7
7
  const fastElement = require('@microsoft/fast-element');
8
- const ramda = require('ramda');
9
8
  const fastWebUtilities = require('@microsoft/fast-web-utilities');
10
9
 
11
10
  const styles = ":host{display:inline-block;vertical-align:sub}.control.connotation-accent{--_connotation-color-primary: var(--vvd-icon-accent-primary, var(--vvd-color-canvas-text))}.control.connotation-announcement{--_connotation-color-primary: var(--vvd-icon-announcement-primary, var(--vvd-color-announcement-500))}.control.connotation-cta{--_connotation-color-primary: var(--vvd-icon-cta-primary, var(--vvd-color-cta-500))}.control.connotation-success{--_connotation-color-primary: var(--vvd-icon-success-primary, var(--vvd-color-success-500))}.control.connotation-warning{--_connotation-color-primary: var(--vvd-icon-warning-primary, var(--vvd-color-warning-300))}.control.connotation-alert{--_connotation-color-primary: var(--vvd-icon-alert-primary, var(--vvd-color-alert-500))}.control.connotation-information{--_connotation-color-primary: var(--vvd-icon-information-primary, var(--vvd-color-information-500))}.control.size--6{--_icon-block-size: calc(1px*(40 + 4*clamp(-1, var(--vvd-size-density, 0), 2)) - (1px*(24 + 4*clamp(-1, var(--vvd-size-density, 0), 2)))) }.control.size--5{--_icon-block-size: calc(1px*(20 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size--4{--_icon-block-size: calc(1px*(24 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size--3{--_icon-block-size: calc(1px*(28 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size--2{--_icon-block-size: calc(1px*(32 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size--1{--_icon-block-size: calc(1px*(36 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-0{--_icon-block-size: calc(1px*(40 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-1{--_icon-block-size: calc(1px*(44 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-2{--_icon-block-size: calc(1px*(48 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-3{--_icon-block-size: calc(1px*(52 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-4{--_icon-block-size: calc(1px*(56 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-5{--_icon-block-size: calc(1px*(60 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control:not(.size--6,.size--5,.size--4,.size--3,.size--2,.size--1,.size-0,.size-1,.size-2,.size-3,.size-4,.size-5){--_icon-block-size: 1em}.control{display:flex;margin:unset;block-size:var(--_icon-block-size);color:currentColor;contain:strict;inline-size:var(--_icon-block-size)}.control[class*=connotation]{color:var(--_connotation-color-primary)}slot,svg,::slotted(:where(svg,img)){margin:auto;block-size:inherit;inline-size:inherit}";
@@ -66,24 +65,50 @@ const extractSvg = (response) => {
66
65
  assertIsValidResponse(response);
67
66
  return response.text();
68
67
  };
69
- const loadSvg = (iconId, signal) => fetch(baseUrlTemplate([iconId, "svg"].join("."), ICONS_VERSION), {
70
- signal
71
- }).then(extractSvg);
72
- const resolveIcon = ramda.memoizeWith(
73
- ramda.identity,
74
- (iconId, signal) => iconId.trim() ? loadSvg(iconId, signal) : Promise.resolve("")
68
+ const loadSvg = (iconId, signal) => fetch(baseUrlTemplate(`${iconId}.svg`, ICONS_VERSION), { signal }).then(
69
+ extractSvg
75
70
  );
71
+ const normalizeKey = (iconId) => (iconId ?? "").trim();
72
+ const iconCache = /* @__PURE__ */ new Map();
73
+ const resolveIcon = (iconId, signal) => {
74
+ const key = normalizeKey(iconId);
75
+ if (!key) return Promise.resolve("");
76
+ const cached = iconCache.get(key);
77
+ if (cached && !cached.signal?.aborted) {
78
+ return cached.promise;
79
+ }
80
+ const promise = loadSvg(key, signal).then((svg) => {
81
+ const entry = iconCache.get(key);
82
+ if (entry && entry.promise === promise && signal.aborted) {
83
+ iconCache.delete(key);
84
+ throw signal.reason ?? new DOMException("Aborted", "AbortError");
85
+ }
86
+ return svg;
87
+ }).catch((err) => {
88
+ const entry = iconCache.get(key);
89
+ if (entry && entry.promise === promise) {
90
+ iconCache.delete(key);
91
+ }
92
+ throw err;
93
+ });
94
+ iconCache.set(key, { promise, signal });
95
+ return promise;
96
+ };
76
97
  class Icon extends vividElement.VividElement {
77
98
  constructor() {
78
99
  super(...arguments);
79
100
  this.iconLoaded = false;
101
+ this.#currentRequestId = 0;
80
102
  this.#abortController = null;
81
103
  }
104
+ #currentRequestId;
82
105
  get iconUrl() {
83
- return !this.name ? this._svg : baseUrlTemplate(`${this.name}.svg`, ICONS_VERSION);
106
+ const key = normalizeKey(this.name);
107
+ return key ? baseUrlTemplate(`${key}.svg`, ICONS_VERSION) : this._svg;
84
108
  }
85
109
  #abortController;
86
110
  async nameChanged() {
111
+ const requestId = ++this.#currentRequestId;
87
112
  if (this.#abortController) {
88
113
  this.#abortController.abort();
89
114
  }
@@ -91,21 +116,30 @@ class Icon extends vividElement.VividElement {
91
116
  this._svg = void 0;
92
117
  this.iconLoaded = false;
93
118
  let timeout = setTimeout(() => {
94
- this._svg = PLACEHOLDER_ICON;
95
- timeout = setTimeout(() => {
96
- if (this._svg === PLACEHOLDER_ICON) {
97
- this._svg = void 0;
98
- }
99
- }, PLACEHOLDER_TIMEOUT);
119
+ if (this.#currentRequestId === requestId) {
120
+ this._svg = PLACEHOLDER_ICON;
121
+ timeout = setTimeout(() => {
122
+ if (this.#currentRequestId === requestId && this._svg === PLACEHOLDER_ICON) {
123
+ this._svg = void 0;
124
+ }
125
+ }, PLACEHOLDER_TIMEOUT);
126
+ }
100
127
  }, PLACEHOLDER_DELAY);
101
- await resolveIcon(this.name ? this.name : "", this.#abortController.signal).then((svg) => {
102
- this._svg = svg;
103
- }).catch(() => {
104
- this._svg = void 0;
105
- }).finally(() => {
106
- clearTimeout(timeout);
107
- this.iconLoaded = true;
108
- });
128
+ try {
129
+ const svg = await resolveIcon(this.name, this.#abortController.signal);
130
+ if (this.#currentRequestId === requestId) {
131
+ this._svg = svg;
132
+ }
133
+ } catch {
134
+ if (this.#currentRequestId === requestId) {
135
+ this._svg = void 0;
136
+ }
137
+ } finally {
138
+ if (this.#currentRequestId === requestId) {
139
+ clearTimeout(timeout);
140
+ this.iconLoaded = true;
141
+ }
142
+ }
109
143
  }
110
144
  }
111
145
  __decorateClass([
@@ -1,7 +1,6 @@
1
1
  import { V as VividElement, d as defineVividComponent, c as createRegisterFunction } from '../unbundled/vivid-element.js';
2
2
  import { VwcVisuallyHiddenElement as VisuallyHidden, visuallyHiddenDefinition } from '../visually-hidden/definition.js';
3
3
  import { attr, observable, volatile, when, html } from '@microsoft/fast-element';
4
- import { memoizeWith, identity } from 'ramda';
5
4
  import { classNames } from '@microsoft/fast-web-utilities';
6
5
 
7
6
  const styles = ":host{display:inline-block;vertical-align:sub}.control.connotation-accent{--_connotation-color-primary: var(--vvd-icon-accent-primary, var(--vvd-color-canvas-text))}.control.connotation-announcement{--_connotation-color-primary: var(--vvd-icon-announcement-primary, var(--vvd-color-announcement-500))}.control.connotation-cta{--_connotation-color-primary: var(--vvd-icon-cta-primary, var(--vvd-color-cta-500))}.control.connotation-success{--_connotation-color-primary: var(--vvd-icon-success-primary, var(--vvd-color-success-500))}.control.connotation-warning{--_connotation-color-primary: var(--vvd-icon-warning-primary, var(--vvd-color-warning-300))}.control.connotation-alert{--_connotation-color-primary: var(--vvd-icon-alert-primary, var(--vvd-color-alert-500))}.control.connotation-information{--_connotation-color-primary: var(--vvd-icon-information-primary, var(--vvd-color-information-500))}.control.size--6{--_icon-block-size: calc(1px*(40 + 4*clamp(-1, var(--vvd-size-density, 0), 2)) - (1px*(24 + 4*clamp(-1, var(--vvd-size-density, 0), 2)))) }.control.size--5{--_icon-block-size: calc(1px*(20 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size--4{--_icon-block-size: calc(1px*(24 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size--3{--_icon-block-size: calc(1px*(28 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size--2{--_icon-block-size: calc(1px*(32 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size--1{--_icon-block-size: calc(1px*(36 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-0{--_icon-block-size: calc(1px*(40 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-1{--_icon-block-size: calc(1px*(44 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-2{--_icon-block-size: calc(1px*(48 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-3{--_icon-block-size: calc(1px*(52 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-4{--_icon-block-size: calc(1px*(56 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control.size-5{--_icon-block-size: calc(1px*(60 + 4*clamp(-1, var(--vvd-size-density, 0), 2))) }.control:not(.size--6,.size--5,.size--4,.size--3,.size--2,.size--1,.size-0,.size-1,.size-2,.size-3,.size-4,.size-5){--_icon-block-size: 1em}.control{display:flex;margin:unset;block-size:var(--_icon-block-size);color:currentColor;contain:strict;inline-size:var(--_icon-block-size)}.control[class*=connotation]{color:var(--_connotation-color-primary)}slot,svg,::slotted(:where(svg,img)){margin:auto;block-size:inherit;inline-size:inherit}";
@@ -62,24 +61,50 @@ const extractSvg = (response) => {
62
61
  assertIsValidResponse(response);
63
62
  return response.text();
64
63
  };
65
- const loadSvg = (iconId, signal) => fetch(baseUrlTemplate([iconId, "svg"].join("."), ICONS_VERSION), {
66
- signal
67
- }).then(extractSvg);
68
- const resolveIcon = memoizeWith(
69
- identity,
70
- (iconId, signal) => iconId.trim() ? loadSvg(iconId, signal) : Promise.resolve("")
64
+ const loadSvg = (iconId, signal) => fetch(baseUrlTemplate(`${iconId}.svg`, ICONS_VERSION), { signal }).then(
65
+ extractSvg
71
66
  );
67
+ const normalizeKey = (iconId) => (iconId ?? "").trim();
68
+ const iconCache = /* @__PURE__ */ new Map();
69
+ const resolveIcon = (iconId, signal) => {
70
+ const key = normalizeKey(iconId);
71
+ if (!key) return Promise.resolve("");
72
+ const cached = iconCache.get(key);
73
+ if (cached && !cached.signal?.aborted) {
74
+ return cached.promise;
75
+ }
76
+ const promise = loadSvg(key, signal).then((svg) => {
77
+ const entry = iconCache.get(key);
78
+ if (entry && entry.promise === promise && signal.aborted) {
79
+ iconCache.delete(key);
80
+ throw signal.reason ?? new DOMException("Aborted", "AbortError");
81
+ }
82
+ return svg;
83
+ }).catch((err) => {
84
+ const entry = iconCache.get(key);
85
+ if (entry && entry.promise === promise) {
86
+ iconCache.delete(key);
87
+ }
88
+ throw err;
89
+ });
90
+ iconCache.set(key, { promise, signal });
91
+ return promise;
92
+ };
72
93
  class Icon extends VividElement {
73
94
  constructor() {
74
95
  super(...arguments);
75
96
  this.iconLoaded = false;
97
+ this.#currentRequestId = 0;
76
98
  this.#abortController = null;
77
99
  }
100
+ #currentRequestId;
78
101
  get iconUrl() {
79
- return !this.name ? this._svg : baseUrlTemplate(`${this.name}.svg`, ICONS_VERSION);
102
+ const key = normalizeKey(this.name);
103
+ return key ? baseUrlTemplate(`${key}.svg`, ICONS_VERSION) : this._svg;
80
104
  }
81
105
  #abortController;
82
106
  async nameChanged() {
107
+ const requestId = ++this.#currentRequestId;
83
108
  if (this.#abortController) {
84
109
  this.#abortController.abort();
85
110
  }
@@ -87,21 +112,30 @@ class Icon extends VividElement {
87
112
  this._svg = void 0;
88
113
  this.iconLoaded = false;
89
114
  let timeout = setTimeout(() => {
90
- this._svg = PLACEHOLDER_ICON;
91
- timeout = setTimeout(() => {
92
- if (this._svg === PLACEHOLDER_ICON) {
93
- this._svg = void 0;
94
- }
95
- }, PLACEHOLDER_TIMEOUT);
115
+ if (this.#currentRequestId === requestId) {
116
+ this._svg = PLACEHOLDER_ICON;
117
+ timeout = setTimeout(() => {
118
+ if (this.#currentRequestId === requestId && this._svg === PLACEHOLDER_ICON) {
119
+ this._svg = void 0;
120
+ }
121
+ }, PLACEHOLDER_TIMEOUT);
122
+ }
96
123
  }, PLACEHOLDER_DELAY);
97
- await resolveIcon(this.name ? this.name : "", this.#abortController.signal).then((svg) => {
98
- this._svg = svg;
99
- }).catch(() => {
100
- this._svg = void 0;
101
- }).finally(() => {
102
- clearTimeout(timeout);
103
- this.iconLoaded = true;
104
- });
124
+ try {
125
+ const svg = await resolveIcon(this.name, this.#abortController.signal);
126
+ if (this.#currentRequestId === requestId) {
127
+ this._svg = svg;
128
+ }
129
+ } catch {
130
+ if (this.#currentRequestId === requestId) {
131
+ this._svg = void 0;
132
+ }
133
+ } finally {
134
+ if (this.#currentRequestId === requestId) {
135
+ clearTimeout(timeout);
136
+ this.iconLoaded = true;
137
+ }
138
+ }
105
139
  }
106
140
  }
107
141
  __decorateClass([