@pathscale/ui 3.0.0 → 3.2.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 (103) hide show
  1. package/README.md +13 -2
  2. package/dist/components/accordion/Accordion.css +24 -1
  3. package/dist/components/alert/Alert.css +11 -1
  4. package/dist/components/auth-field-group/AuthFieldGroup.css +11 -3
  5. package/dist/components/button/Button.css +37 -10
  6. package/dist/components/calendar/Calendar.generated.d.ts +19 -2
  7. package/dist/components/calendar/Calendar.generated.js +30 -23
  8. package/dist/components/calendar/index.d.ts +1 -1
  9. package/dist/components/card/Card.generated.d.ts +38 -2
  10. package/dist/components/card/Card.generated.js +99 -45
  11. package/dist/components/card/Card.interactions.d.ts +70 -0
  12. package/dist/components/card/Card.interactions.js +19 -0
  13. package/dist/components/card/index.d.ts +1 -1
  14. package/dist/components/checkbox/Checkbox.generated.d.ts +23 -2
  15. package/dist/components/checkbox/Checkbox.generated.js +14 -6
  16. package/dist/components/collapsible/Collapsible.css +17 -1
  17. package/dist/components/color-wheel-flower/ColorWheelFlower.generated.d.ts +8 -0
  18. package/dist/components/color-wheel-flower/ColorWheelFlower.generated.js +14 -1
  19. package/dist/components/color-wheel-flower/colorWheelFlowerContext.d.ts +9 -2
  20. package/dist/components/color-wheel-flower/colorWheelFlowerContext.js +2 -4
  21. package/dist/components/connection-settings/ConnectionSettings.css +76 -0
  22. package/dist/components/connection-settings/ConnectionSettings.generated.d.ts +45 -0
  23. package/dist/components/connection-settings/ConnectionSettings.generated.js +300 -0
  24. package/dist/components/connection-settings/ConnectionSettings.recipe.d.ts +54 -0
  25. package/dist/components/connection-settings/ConnectionSettings.recipe.js +111 -0
  26. package/dist/components/connection-settings/index.d.ts +2 -0
  27. package/dist/components/connection-settings/index.js +1 -0
  28. package/dist/components/date-picker/DatePicker.generated.d.ts +3 -1
  29. package/dist/components/date-picker/DatePicker.generated.js +8 -5
  30. package/dist/components/date-range-picker/DateRangePicker.generated.d.ts +3 -1
  31. package/dist/components/date-range-picker/DateRangePicker.generated.js +9 -6
  32. package/dist/components/dialog/Dialog.generated.js +17 -79
  33. package/dist/components/drawer/Drawer.a11y.d.ts +1 -3
  34. package/dist/components/drawer/Drawer.a11y.js +2 -30
  35. package/dist/components/drawer/Drawer.generated.d.ts +24 -0
  36. package/dist/components/drawer/Drawer.generated.js +65 -58
  37. package/dist/components/grid/Grid.generated.js +3 -3
  38. package/dist/components/icon/Icon.generated.d.ts +15 -0
  39. package/dist/components/icon/Icon.generated.js +11 -2
  40. package/dist/components/immersive-landing/ImmersiveLanding.css +1 -1
  41. package/dist/components/immersive-landing/components/CookieConsent.interactions.d.ts +24 -0
  42. package/dist/components/immersive-landing/components/CookieConsent.interactions.js +2 -0
  43. package/dist/components/immersive-landing/components/CookieConsent.js +52 -47
  44. package/dist/components/immersive-landing/components/FirefoxPWABanner.js +10 -10
  45. package/dist/components/immersive-landing/types.d.ts +15 -0
  46. package/dist/components/input/Input.css +5 -3
  47. package/dist/components/input/Input.generated.js +6 -3
  48. package/dist/components/language-switcher/LanguageSwitcher.generated.js +1 -1
  49. package/dist/components/live-chat/LiveChatPanel.generated.js +2 -6
  50. package/dist/components/live-chat/LiveChatPanel.interactions.d.ts +21 -0
  51. package/dist/components/live-chat/LiveChatPanel.interactions.js +10 -0
  52. package/dist/components/password-field/PasswordField.generated.d.ts +9 -1
  53. package/dist/components/password-field/PasswordField.generated.js +2 -2
  54. package/dist/components/password-field/PasswordField.interactions.d.ts +2 -2
  55. package/dist/components/password-field/PasswordField.interactions.js +2 -2
  56. package/dist/components/popover/Popover.a11y.d.ts +47 -0
  57. package/dist/components/popover/Popover.a11y.js +19 -0
  58. package/dist/components/popover/Popover.generated.d.ts +26 -0
  59. package/dist/components/popover/Popover.generated.js +119 -46
  60. package/dist/components/radio/Radio.generated.d.ts +26 -2
  61. package/dist/components/radio/Radio.generated.js +9 -5
  62. package/dist/components/range-calendar/RangeCalendar.generated.d.ts +3 -1
  63. package/dist/components/range-calendar/RangeCalendar.generated.js +4 -1
  64. package/dist/components/select/Select.generated.js +5 -0
  65. package/dist/components/slider/Slider.generated.d.ts +14 -1
  66. package/dist/components/slider/Slider.generated.js +3 -2
  67. package/dist/components/switch/Switch.css +0 -3
  68. package/dist/components/switch/Switch.generated.d.ts +23 -2
  69. package/dist/components/switch/Switch.generated.js +21 -44
  70. package/dist/components/switch/Switch.recipe.d.ts +61 -38
  71. package/dist/components/switch/Switch.recipe.js +88 -68
  72. package/dist/components/table/MobileListView.generated.js +1 -1
  73. package/dist/components/text/Text.generated.d.ts +26 -1
  74. package/dist/components/text/Text.generated.js +14 -13
  75. package/dist/components/text/Text.recipe.d.ts +17 -5
  76. package/dist/components/text/Text.recipe.js +7 -13
  77. package/dist/components/text/index.d.ts +1 -1
  78. package/dist/components/theme-color-picker/ThemeColorPicker.generated.js +1 -1
  79. package/dist/hooks/connection/createConnectionSettings.d.ts +128 -0
  80. package/dist/hooks/connection/createConnectionSettings.js +211 -0
  81. package/dist/hooks/connection/index.d.ts +2 -0
  82. package/dist/hooks/connection/index.js +1 -0
  83. package/dist/hooks/date/date.names.d.ts +107 -0
  84. package/dist/hooks/date/date.names.js +74 -0
  85. package/dist/hooks/date/date.utils.d.ts +11 -1
  86. package/dist/hooks/date/date.utils.js +3 -6
  87. package/dist/hooks/date/index.d.ts +1 -0
  88. package/dist/hooks/date/index.js +1 -0
  89. package/dist/hooks/date/useCalendarState.d.ts +12 -5
  90. package/dist/hooks/date/useCalendarState.js +7 -19
  91. package/dist/hooks/form/createForm.d.ts +4 -4
  92. package/dist/hooks/form/createForm.js +7 -9
  93. package/dist/index.d.ts +8 -4
  94. package/dist/index.js +3 -1
  95. package/dist/layouts.manifest.json +4 -1
  96. package/dist/lib/focus.d.ts +31 -0
  97. package/dist/lib/focus.js +39 -0
  98. package/dist/lib/overlay.d.ts +94 -0
  99. package/dist/lib/overlay.js +72 -0
  100. package/dist/purge-manifest.json +14427 -15269
  101. package/dist/responsive-classes.txt +450 -0
  102. package/dist/styles/base/index.css +42 -0
  103. package/package.json +11 -6
@@ -3,7 +3,8 @@ import { Show, createSignal, onCleanup, onSettled } from "solid-js";
3
3
  import button_0 from "../../button/index.js";
4
4
  import flex from "../../flex/index.js";
5
5
  import { CLASSES } from "../ImmersiveLanding.recipe.js";
6
- var _tmpl$ = /*#__PURE__*/ template("<p>"), _tmpl$2 = /*#__PURE__*/ template("<button>"), _tmpl$3 = /*#__PURE__*/ template("<div><div>"), _tmpl$4 = /*#__PURE__*/ template("<h2>"), _tmpl$5 = /*#__PURE__*/ template("<label><span></span><input>"), _tmpl$6 = /*#__PURE__*/ template("<div><div><!><!><!>");
6
+ import { dismissesOnBackdropPress } from "./CookieConsent.interactions.js";
7
+ var _tmpl$ = /*#__PURE__*/ template("<p>"), _tmpl$2 = /*#__PURE__*/ template("<div><div>"), _tmpl$3 = /*#__PURE__*/ template("<h2>"), _tmpl$4 = /*#__PURE__*/ template("<label><span></span><input>"), _tmpl$5 = /*#__PURE__*/ template("<div><div><!><!><!>");
7
8
  const defaultTexts = {
8
9
  message: "We use cookies to improve your experience. You can accept all cookies or manage your preferences.",
9
10
  acceptAll: "Accept all",
@@ -79,6 +80,10 @@ const CookieConsent = (props)=>{
79
80
  const handleManageClose = ()=>{
80
81
  setShowManage(false);
81
82
  };
83
+ const handleBackdropClick = (event)=>{
84
+ if (!dismissesOnBackdropPress(event)) return;
85
+ handleManageClose();
86
+ };
82
87
  const handleManageSave = ()=>{
83
88
  localStorage.setItem(CONSENT_KEY(), "custom");
84
89
  localStorage.setItem(ANALYTICS_KEY(), analyticsEnabled().toString());
@@ -110,7 +115,7 @@ const CookieConsent = (props)=>{
110
115
  return showBanner();
111
116
  },
112
117
  get children () {
113
- var _el$ = _tmpl$3(), _el$2 = _el$.firstChild;
118
+ var _el$ = _tmpl$2(), _el$2 = _el$.firstChild;
114
119
  spread(_el$, mergeProps({
115
120
  role: "dialog",
116
121
  "aria-modal": "false",
@@ -168,18 +173,18 @@ const CookieConsent = (props)=>{
168
173
  return texts().decline;
169
174
  }
170
175
  })),
171
- (()=>{
172
- var _el$4 = _tmpl$2();
173
- spread(_el$4, mergeProps({
174
- type: "button"
175
- }, ()=>({
176
- class: CLASSES.cookie.manageButton
177
- }), {
178
- onClick: handleManageOpen
179
- }), true);
180
- insert(_el$4, ()=>texts().manage);
181
- return _el$4;
182
- })()
176
+ createComponent(button_0, mergeProps({
177
+ type: "button",
178
+ variant: "ghost",
179
+ size: "sm"
180
+ }, ()=>({
181
+ class: CLASSES.cookie.manageButton
182
+ }), {
183
+ onClick: handleManageOpen,
184
+ get children () {
185
+ return texts().manage;
186
+ }
187
+ }))
183
188
  ];
184
189
  }
185
190
  }))
@@ -194,22 +199,22 @@ const CookieConsent = (props)=>{
194
199
  return showManage();
195
200
  },
196
201
  get children () {
197
- var _el$5 = _tmpl$6(), _el$6 = _el$5.firstChild, _el$15 = _el$6.firstChild, _el$16 = _el$15.nextSibling, _el$17 = _el$16.nextSibling;
198
- spread(_el$5, mergeProps({
202
+ var _el$4 = _tmpl$5(), _el$5 = _el$4.firstChild, _el$14 = _el$5.firstChild, _el$15 = _el$14.nextSibling, _el$16 = _el$15.nextSibling;
203
+ spread(_el$4, mergeProps({
199
204
  role: "dialog",
200
205
  "aria-modal": "true",
201
206
  "aria-labelledby": "cookie-manage-title"
202
207
  }, ()=>({
203
208
  class: CLASSES.cookie.modalBackdrop
204
209
  }), {
205
- onClick: handleManageClose
210
+ onClick: handleBackdropClick
206
211
  }), true);
207
- spread(_el$6, mergeProps(()=>({
212
+ spread(_el$5, mergeProps(()=>({
208
213
  class: CLASSES.cookie.modalCard
209
214
  }), {
210
215
  onClick: (e)=>e.stopPropagation()
211
216
  }), true);
212
- insert(_el$6, createComponent(flex, mergeProps({
217
+ insert(_el$5, createComponent(flex, mergeProps({
213
218
  justify: "between",
214
219
  align: "center"
215
220
  }, ()=>({
@@ -218,14 +223,14 @@ const CookieConsent = (props)=>{
218
223
  get children () {
219
224
  return [
220
225
  (()=>{
221
- var _el$7 = _tmpl$4();
222
- spread(_el$7, mergeProps({
226
+ var _el$6 = _tmpl$3();
227
+ spread(_el$6, mergeProps({
223
228
  id: "cookie-manage-title"
224
229
  }, ()=>({
225
230
  class: CLASSES.cookie.modalTitle
226
231
  })), true);
227
- insert(_el$7, ()=>texts().manageTitle);
228
- return _el$7;
232
+ insert(_el$6, ()=>texts().manageTitle);
233
+ return _el$6;
229
234
  })(),
230
235
  createComponent(button_0, {
231
236
  size: "sm",
@@ -239,8 +244,8 @@ const CookieConsent = (props)=>{
239
244
  })
240
245
  ];
241
246
  }
242
- })), _el$15);
243
- insert(_el$6, createComponent(flex, mergeProps({
247
+ })), _el$14);
248
+ insert(_el$5, createComponent(flex, mergeProps({
244
249
  direction: "col",
245
250
  gap: "md"
246
251
  }, ()=>({
@@ -249,33 +254,33 @@ const CookieConsent = (props)=>{
249
254
  get children () {
250
255
  return [
251
256
  (()=>{
252
- var _el$8 = _tmpl$5(), _el$9 = _el$8.firstChild, _el$0 = _el$9.nextSibling;
253
- spread(_el$8, mergeProps(()=>({
257
+ var _el$7 = _tmpl$4(), _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling;
258
+ spread(_el$7, mergeProps(()=>({
254
259
  class: `${CLASSES.cookie.preferenceRow} ${CLASSES.cookie.preferenceRowLocked}`
255
260
  })), true);
256
- spread(_el$9, mergeProps(()=>({
261
+ spread(_el$8, mergeProps(()=>({
257
262
  class: CLASSES.cookie.preferenceLabel
258
263
  })), true);
259
- insert(_el$9, ()=>texts().essential);
260
- spread(_el$0, mergeProps({
264
+ insert(_el$8, ()=>texts().essential);
265
+ spread(_el$9, mergeProps({
261
266
  type: "checkbox",
262
267
  checked: true,
263
268
  disabled: true
264
269
  }, ()=>({
265
270
  class: CLASSES.cookie.toggle
266
271
  })), false);
267
- return _el$8;
272
+ return _el$7;
268
273
  })(),
269
274
  (()=>{
270
- var _el$1 = _tmpl$5(), _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling;
271
- spread(_el$1, mergeProps(()=>({
275
+ var _el$0 = _tmpl$4(), _el$1 = _el$0.firstChild, _el$10 = _el$1.nextSibling;
276
+ spread(_el$0, mergeProps(()=>({
272
277
  class: CLASSES.cookie.preferenceRow
273
278
  })), true);
274
- spread(_el$10, mergeProps(()=>({
279
+ spread(_el$1, mergeProps(()=>({
275
280
  class: CLASSES.cookie.preferenceLabel
276
281
  })), true);
277
- insert(_el$10, ()=>texts().analytics);
278
- spread(_el$11, mergeProps({
282
+ insert(_el$1, ()=>texts().analytics);
283
+ spread(_el$10, mergeProps({
279
284
  type: "checkbox",
280
285
  get checked () {
281
286
  return analyticsEnabled();
@@ -284,18 +289,18 @@ const CookieConsent = (props)=>{
284
289
  }, ()=>({
285
290
  class: CLASSES.cookie.toggle
286
291
  })), false);
287
- return _el$1;
292
+ return _el$0;
288
293
  })(),
289
294
  (()=>{
290
- var _el$12 = _tmpl$5(), _el$13 = _el$12.firstChild, _el$14 = _el$13.nextSibling;
291
- spread(_el$12, mergeProps(()=>({
295
+ var _el$11 = _tmpl$4(), _el$12 = _el$11.firstChild, _el$13 = _el$12.nextSibling;
296
+ spread(_el$11, mergeProps(()=>({
292
297
  class: CLASSES.cookie.preferenceRow
293
298
  })), true);
294
- spread(_el$13, mergeProps(()=>({
299
+ spread(_el$12, mergeProps(()=>({
295
300
  class: CLASSES.cookie.preferenceLabel
296
301
  })), true);
297
- insert(_el$13, ()=>texts().marketing);
298
- spread(_el$14, mergeProps({
302
+ insert(_el$12, ()=>texts().marketing);
303
+ spread(_el$13, mergeProps({
299
304
  type: "checkbox",
300
305
  get checked () {
301
306
  return marketingEnabled();
@@ -304,12 +309,12 @@ const CookieConsent = (props)=>{
304
309
  }, ()=>({
305
310
  class: CLASSES.cookie.toggle
306
311
  })), false);
307
- return _el$12;
312
+ return _el$11;
308
313
  })()
309
314
  ];
310
315
  }
311
- })), _el$16);
312
- insert(_el$6, createComponent(flex, mergeProps({
316
+ })), _el$15);
317
+ insert(_el$5, createComponent(flex, mergeProps({
313
318
  gap: "sm",
314
319
  justify: "end"
315
320
  }, ()=>({
@@ -338,8 +343,8 @@ const CookieConsent = (props)=>{
338
343
  }))
339
344
  ];
340
345
  }
341
- })), _el$17);
342
- return _el$5;
346
+ })), _el$16);
347
+ return _el$4;
343
348
  }
344
349
  })
345
350
  ];
@@ -1,9 +1,9 @@
1
- import { createComponent, insert, mergeProps, spread, template } from "@solidjs/web";
1
+ import { createComponent, insert, memo, mergeProps, spread, template } from "@solidjs/web";
2
2
  import { Show, createSignal, onSettled } from "solid-js";
3
3
  import button_0 from "../../button/index.js";
4
4
  import card from "../../card/index.js";
5
5
  import flex from "../../flex/index.js";
6
- import icon from "../../icon/index.js";
6
+ import icon_0 from "../../icon/index.js";
7
7
  import { CLASSES } from "../ImmersiveLanding.recipe.js";
8
8
  var _tmpl$ = /*#__PURE__*/ template("<div>"), _tmpl$2 = /*#__PURE__*/ template("<h3>"), _tmpl$3 = /*#__PURE__*/ template("<p>");
9
9
  const defaultTexts = {
@@ -89,8 +89,8 @@ const FirefoxPWABanner = (props)=>{
89
89
  return texts().closeLabel;
90
90
  },
91
91
  get children () {
92
- return createComponent(icon, {
93
- src: "icon-[mdi--close]",
92
+ return createComponent(icon_0, {
93
+ src: "icon-[lucide--x]",
94
94
  width: 16,
95
95
  height: 16
96
96
  });
@@ -115,17 +115,17 @@ const FirefoxPWABanner = (props)=>{
115
115
  })), true);
116
116
  insert(_el$2, createComponent(Show, {
117
117
  get when () {
118
- return "firefox" === browser();
118
+ return memo(()=>"firefox" === browser())() && props.icon;
119
119
  },
120
- get children () {
121
- return createComponent(icon, mergeProps({
122
- src: "icon-[mdi--firefox]",
120
+ children: (icon)=>createComponent(icon_0, mergeProps({
121
+ get src () {
122
+ return icon();
123
+ },
123
124
  width: 40,
124
125
  height: 40
125
126
  }, ()=>({
126
127
  class: CLASSES.firefoxBanner.browserIcon
127
- })));
128
- }
128
+ })))
129
129
  }));
130
130
  return _el$2;
131
131
  })(),
@@ -115,6 +115,21 @@ export interface FirefoxPWABannerProps {
115
115
  extensionUrl?: string;
116
116
  storageKey?: string;
117
117
  texts?: FirefoxPWABannerTexts;
118
+ /**
119
+ * The browser mark shown beside the text. Omit it and the banner renders
120
+ * without one.
121
+ *
122
+ * A default lived here as `icon-[mdi--firefox]`, and it was the only reason
123
+ * this library needed a second Iconify set. Everything else it draws is
124
+ * `lucide`, which has no brand glyphs, so one banner in one optional
125
+ * component obliged every consumer to install all of `-json/mdi` --
126
+ * and a consumer who installed only `lucide` got build warnings and a blank
127
+ * space, which is what happened on crates.vip.
128
+ *
129
+ * Accepts what `Icon` accepts: an Iconify class such as
130
+ * `"icon-[mdi--firefox]"`, or an inline SVG element.
131
+ */
132
+ icon?: string | JSX.Element;
118
133
  onInstall?: () => void;
119
134
  onDismiss?: () => void;
120
135
  }
@@ -88,19 +88,21 @@
88
88
  }
89
89
 
90
90
  .input-control--sm {
91
- min-height: 2rem;
91
+ /* Was 2rem, which is 0.25rem shorter than `Button` at the same declared
92
+ size. Aligned to the shared scale so a button beside an input matches. */
93
+ min-height: var(--control-h-sm);
92
94
  padding-inline: 0.625rem;
93
95
  font-size: 0.75rem;
94
96
  }
95
97
 
96
98
  .input-control--md {
97
- min-height: 2.5rem;
99
+ min-height: var(--control-h-md);
98
100
  padding-inline: 0.75rem;
99
101
  font-size: 0.875rem;
100
102
  }
101
103
 
102
104
  .input-control--lg {
103
- min-height: 2.75rem;
105
+ min-height: var(--control-h-lg);
104
106
  padding-inline: 0.875rem;
105
107
  font-size: 1rem;
106
108
  }
@@ -10,7 +10,7 @@ const InputContext = createContext(null);
10
10
  const __solidLayoutInputRoot = (_stable, p)=>{
11
11
  const others = omit(p, "children", "class", "size", "fullWidth", "state", "issues", "dataTheme");
12
12
  const baseId = createUniqueId();
13
- const size = ()=>p.size ?? "md";
13
+ const size = ()=>p.size ?? "sm";
14
14
  const isDisabled = ()=>Boolean("disabled" === p.state);
15
15
  const isInvalid = ()=>Boolean("invalid" === resolveState(p.state, p.issues));
16
16
  const fullWidth = ()=>Boolean(p.fullWidth);
@@ -54,7 +54,7 @@ const InputRoot = defineComponent({
54
54
  const __solidLayoutInputField = (_stable, p)=>{
55
55
  const ctx = useContext(InputContext);
56
56
  const others = omit(p, "class", "size", "state", "disabled", "issues", "fullWidth", "startIcon", "endIcon", "dataTheme", "id", "aria-invalid");
57
- const size = ()=>p.size ?? ctx?.size() ?? "md";
57
+ const size = ()=>p.size ?? ctx?.size() ?? "sm";
58
58
  const isDisabled = ()=>Boolean("disabled" === p.state) || Boolean(p.disabled) || Boolean(ctx?.isDisabled());
59
59
  const isInvalid = ()=>Boolean("invalid" === resolveState(p.state, p.issues)) || Boolean(p["aria-invalid"]) || Boolean(ctx?.isInvalid());
60
60
  const fullWidth = ()=>Boolean(p.fullWidth) || Boolean(ctx?.fullWidth());
@@ -204,7 +204,7 @@ const __solidLayoutInputBase = (_stable, p)=>{
204
204
  return p.fullWidth ?? true;
205
205
  },
206
206
  get state () {
207
- return isDisabled() ? "disabled" : void 0;
207
+ return memo(()=>!!isDisabled())() ? "disabled" : isInvalid() ? "invalid" : void 0;
208
208
  },
209
209
  get issues () {
210
210
  return p.issues;
@@ -220,6 +220,9 @@ const __solidLayoutInputBase = (_stable, p)=>{
220
220
  },
221
221
  get children () {
222
222
  return createComponent(InputLabel, {
223
+ get ["for"] () {
224
+ return inputId();
225
+ },
223
226
  get children () {
224
227
  return p.label;
225
228
  }
@@ -51,7 +51,7 @@ const __solidLayoutLanguageSwitcher = (_stable, p)=>{
51
51
  },
52
52
  get fallback () {
53
53
  return createComponent(icon, mergeProps({
54
- src: "icon-[mdi--loading]"
54
+ src: "icon-[lucide--loader-circle]"
55
55
  }, ()=>({
56
56
  class: CLASSES.loadingIcon
57
57
  }), {
@@ -6,6 +6,7 @@ import { twMerge } from "../../lib/twMerge.js";
6
6
  import button_0 from "../button/index.js";
7
7
  import input from "../input/index.js";
8
8
  import { CLASSES, componentRecipe } from "./LiveChat.recipe.js";
9
+ import { formatChatTime } from "./LiveChatPanel.interactions.js";
9
10
  var _tmpl$ = /*#__PURE__*/ template("<div>"), _tmpl$2 = /*#__PURE__*/ template('<div><div><div><svg><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"></path></svg><h3></h3></div><button><svg><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M6 18L18 6M6 6l12 12"></path></svg></button></div><div><!><!></div><div><!><!>'), _tmpl$3 = /*#__PURE__*/ template("<div><div></div><div><div><p></p></div><span>"), _tmpl$4 = /*#__PURE__*/ template("<span>");
10
11
  const getMockMessages = ()=>{
11
12
  const salesMessages = [
@@ -59,11 +60,6 @@ const getMockMessages = ()=>{
59
60
  ...supportMessages
60
61
  ].sort((a, b)=>a.timestamp - b.timestamp);
61
62
  };
62
- const formatTime = (timestamp)=>new Intl.DateTimeFormat("en-US", {
63
- hour: "numeric",
64
- minute: "2-digit",
65
- hour12: true
66
- }).format(new Date(timestamp));
67
63
  const __solidLayoutLiveChatPanel = (_stable, p)=>{
68
64
  const others = omit(p, "onClose", "title", "placeholder", "closeLabel", "sendLabel", "emptyMessage", "mockMode", "messages", "onSendMessage", "isSending", "autoScrollOnNewMessage", "autoScrollBehavior", "stickToBottomThreshold", "class", "style");
69
65
  const [internalMessages, setInternalMessages] = createSignal([]);
@@ -267,7 +263,7 @@ const __solidLayoutLiveChatPanel = (_stable, p)=>{
267
263
  spread(_el$18, mergeProps(()=>({
268
264
  class: CLASSES.panel.timestamp
269
265
  })), true);
270
- insert(_el$18, ()=>formatTime(message.timestamp));
266
+ insert(_el$18, ()=>formatChatTime(message.timestamp));
271
267
  return _el$13;
272
268
  }
273
269
  }), _el$0);
@@ -0,0 +1,21 @@
1
+ /**
2
+ * A chat timestamp, formatted without `Intl`.
3
+ *
4
+ * The panel used to build its timestamps with
5
+ * `new Intl.DateTimeFormat("en-US", { hour: "numeric", minute: "2-digit",
6
+ * hour12: true })`. `Intl` is not defined in the browser engine the fleet
7
+ * ships, so that constructor threw a `ReferenceError` while a message list was
8
+ * rendering. The consequence is not a wrong timestamp: the error escapes the
9
+ * render, Solid halts its reactive system, and the page keeps painting the
10
+ * frame it already had while every control on it is dead. Measured on
11
+ * pathscale.com, where opening the support chat killed the whole application,
12
+ * and this one call was the only `Intl` reference in that bundle.
13
+ *
14
+ * A clock reading of `3:07 PM` needs no locale database, so this does the
15
+ * conversion with plain `Date` accessors and keeps the `en-US` output byte for
16
+ * byte: a bare 12-hour hour, a colon, two-digit minutes, a space, and `AM` or
17
+ * `PM`. `Meter` guards its `Intl.NumberFormat` in a `try`/`catch` for the same
18
+ * reason; a fallback is not needed here because there is nothing to fall back
19
+ * from.
20
+ */
21
+ export declare const formatChatTime: (timestamp: number) => string;
@@ -0,0 +1,10 @@
1
+ const formatChatTime = (timestamp)=>{
2
+ const date = new Date(timestamp);
3
+ const hours = date.getHours();
4
+ const minutes = date.getMinutes();
5
+ const hour12 = hours % 12 === 0 ? 12 : hours % 12;
6
+ const suffix = hours < 12 ? "AM" : "PM";
7
+ const paddedMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`;
8
+ return `${hour12}:${paddedMinutes} ${suffix}`;
9
+ };
10
+ export { formatChatTime };
@@ -18,7 +18,15 @@ export type PasswordFieldProps = UIBaseProps & {
18
18
  hideLabel: string;
19
19
  value?: string;
20
20
  inputRef?: (el: HTMLInputElement) => void;
21
- onInput?: (value: string) => void;
21
+ /**
22
+ * The new value.
23
+ *
24
+ * **Breaking in 3.1.** This was `onInput`, which named the DOM event while
25
+ * delivering a `string` — so it matched neither the native `onInput` (an
26
+ * `InputEvent`) nor the rest of the library (`onChange` with a value). It is
27
+ * `onChange` now, like every other control.
28
+ */
29
+ onChange?: (value: string) => void;
22
30
  onBlur?: () => void;
23
31
  visibleIcon?: JSX.Element;
24
32
  hiddenIcon?: JSX.Element;
@@ -54,7 +54,7 @@ const __solidLayoutPasswordFieldLayout = (_stable, p)=>{
54
54
  }), {
55
55
  ref: setFieldRef,
56
56
  onInput: (event)=>{
57
- p.onInput?.(event.currentTarget.value);
57
+ p.onChange?.(event.currentTarget.value);
58
58
  },
59
59
  onBlur: ()=>p.onBlur?.(),
60
60
  get endIcon () {
@@ -105,7 +105,7 @@ const PasswordFieldLayout = defineComponent({
105
105
  "hideLabel",
106
106
  "value",
107
107
  "inputRef",
108
- "onInput",
108
+ "onChange",
109
109
  "onBlur",
110
110
  "visibleIcon",
111
111
  "hiddenIcon",
@@ -53,8 +53,8 @@ export declare const createPasswordFieldInputContract: (params: PasswordFieldInp
53
53
  autocomplete: "off" | "current-password" | "new-password" | undefined;
54
54
  "aria-describedby": string | undefined;
55
55
  value: string | undefined;
56
- isDisabled: boolean;
57
- isInvalid: boolean;
56
+ disabled: boolean;
57
+ state: "invalid" | undefined;
58
58
  startIcon: JSX.Element;
59
59
  class: string;
60
60
  };
@@ -11,8 +11,8 @@ const createPasswordFieldInputContract = (params)=>({
11
11
  autocomplete: params.autocomplete,
12
12
  "aria-describedby": params["aria-describedby"],
13
13
  value: params.value,
14
- isDisabled: Boolean(params.disabled),
15
- isInvalid: Boolean(params.invalid),
14
+ disabled: Boolean(params.disabled),
15
+ state: params.invalid ? "invalid" : void 0,
16
16
  startIcon: params.startIcon,
17
17
  class: twMerge("w-full", params.inputClass)
18
18
  });
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Which name reaches the node that carries `role="dialog"`.
3
+ *
4
+ * `role="dialog"` is on `Popover.Content`, because the content is the
5
+ * portalled overlay and `Popover.Dialog` is an optional panel inside it. A
6
+ * reader naming a dialog writes `aria-label` on `Popover.Dialog`, which is the
7
+ * part called Dialog, so the name landed on a generic inside the dialog and
8
+ * named nothing at all. Measured on two sites: every popover dialog in the
9
+ * fleet was anonymous.
10
+ *
11
+ * The name travels up to the role rather than the role travelling down to the
12
+ * name. Moving `role="dialog"` onto `Popover.Dialog` would leave a popover
13
+ * written without one with no dialog, and would make two dialogs of a popover
14
+ * written with two panels.
15
+ *
16
+ * `aria-labelledby` outranks `aria-label` in the accessible name calculation,
17
+ * so a supplied name has to *replace* the fallback reference to the trigger
18
+ * rather than sit beside it. Leaving both would keep the dialog named after
19
+ * the button that opened it while the author's own name was ignored, which is
20
+ * the same silent failure in a new place.
21
+ */
22
+ export type PopoverDialogNameInput = {
23
+ /** `aria-label` written on `Popover.Content` itself. Outranks everything. */
24
+ contentLabel?: string;
25
+ /** `aria-labelledby` written on `Popover.Content` itself. */
26
+ contentLabelledBy?: string;
27
+ /** `aria-label` written on a `Popover.Dialog` inside the content. */
28
+ dialogLabel?: string;
29
+ /** `aria-labelledby` written on a `Popover.Dialog` inside the content. */
30
+ dialogLabelledBy?: string;
31
+ /** The trigger's id, used only when nothing else names the dialog. */
32
+ triggerId?: string;
33
+ };
34
+ export type PopoverDialogName = {
35
+ "aria-label": string | undefined;
36
+ "aria-labelledby": string | undefined;
37
+ };
38
+ /**
39
+ * An ARIA attribute value as a name, or nothing.
40
+ *
41
+ * Solid types every `aria-*` attribute as `string | RemoveAttribute`, where the
42
+ * second member is `false` and means "do not emit this". A name is only ever
43
+ * the first, and the second has to become `undefined` before it can be
44
+ * compared, stored or handed to another element.
45
+ */
46
+ export declare const asAriaName: (value: unknown) => string | undefined;
47
+ export declare const resolvePopoverDialogName: (input: PopoverDialogNameInput) => PopoverDialogName;
@@ -0,0 +1,19 @@
1
+ const asAriaName = (value)=>"string" == typeof value ? value : void 0;
2
+ const firstNonEmpty = (...values)=>values.find((value)=>void 0 !== value && "" !== value);
3
+ const resolvePopoverDialogName = (input)=>{
4
+ const labelledBy = firstNonEmpty(input.contentLabelledBy, input.dialogLabelledBy);
5
+ const label = firstNonEmpty(input.contentLabel, input.dialogLabel);
6
+ if (void 0 !== labelledBy) return {
7
+ "aria-label": void 0,
8
+ "aria-labelledby": labelledBy
9
+ };
10
+ if (void 0 !== label) return {
11
+ "aria-label": label,
12
+ "aria-labelledby": void 0
13
+ };
14
+ return {
15
+ "aria-label": void 0,
16
+ "aria-labelledby": firstNonEmpty(input.triggerId)
17
+ };
18
+ };
19
+ export { asAriaName, resolvePopoverDialogName };
@@ -1,6 +1,7 @@
1
1
  import type { Component as __LayoutComponent } from "solid-js";
2
2
  import "./Popover.css";
3
3
  import { type JSX } from "@solidjs/web";
4
+ import { type ValidComponent } from "solid-js";
4
5
  import "../_shared/material.css";
5
6
  import { type OverlayAnchorRect, type OverlayPlacement } from "../_shared/overlayPosition";
6
7
  import type { Material, UIBaseProps } from "../vocabulary";
@@ -23,6 +24,31 @@ export type PopoverRootProps = UIBaseProps & Omit<JSX.HTMLAttributes<HTMLDivElem
23
24
  declare const PopoverRoot: __LayoutComponent<PopoverRootProps>;
24
25
  export type PopoverTriggerProps = UIBaseProps & Omit<JSX.ButtonHTMLAttributes<HTMLButtonElement>, "children"> & {
25
26
  children: JSX.Element;
27
+ /**
28
+ * The component to be the trigger, instead of a bare button.
29
+ *
30
+ * `Popover.Trigger` renders a `button`, which is right when the trigger is
31
+ * a word or a glyph. It is wrong when the call site hands it a control:
32
+ * `<Popover.Trigger><Button>Filters</Button></Popover.Trigger>` emitted a
33
+ * second, anonymous button wrapping the named one at identical
34
+ * coordinates. Found on three separate sites. Nested interactive content
35
+ * is invalid HTML, and a press by coordinate lands on the anonymous outer
36
+ * one rather than on the control that was written.
37
+ *
38
+ * `as` makes the control *be* the trigger, so there is one element:
39
+ *
40
+ * ```tsx
41
+ * <Popover.Trigger as={Button} flavor="primary">Filters</Popover.Trigger>
42
+ * ```
43
+ *
44
+ * The wiring -- id, `aria-haspopup`, `aria-expanded`, `aria-controls`, the
45
+ * ref and both handlers -- goes to the delegate, and anything else written
46
+ * here goes with it. The trigger's own class is a button reset and is
47
+ * dropped, because a control does not want one; so is
48
+ * `data-slot="popover-trigger"`, since the delegate's recipe owns that
49
+ * attribute. Select the delegate's own slot, or `[aria-haspopup="dialog"]`.
50
+ */
51
+ as?: ValidComponent;
26
52
  };
27
53
  declare const PopoverTrigger: __LayoutComponent<PopoverTriggerProps>;
28
54
  export type PopoverContentProps = UIBaseProps & Omit<JSX.HTMLAttributes<HTMLDivElement>, "children"> & {