@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
@@ -1,10 +1,12 @@
1
- import { createComponent, insert, mergeProps, spread, template } from "@solidjs/web";
1
+ import { claimElement, createComponent, insert, mergeProps, spread, template } from "@solidjs/web";
2
2
  import { defineComponent } from "solid-layouts/solid-2/application-boundary";
3
3
  import "../_shared/material.css";
4
4
  import "./Card.css";
5
5
  import { Show } from "solid-js";
6
+ import { buttonHref, buttonRel } from "../button/Button.interactions.js";
7
+ import { cardSemantics } from "./Card.interactions.js";
6
8
  import { card, cardBody, cardFooter, cardHeader } from "./Card.recipe.js";
7
- var _tmpl$ = /*#__PURE__*/ template("<div>"), _tmpl$2 = /*#__PURE__*/ template("<div><!><!><!>");
9
+ var _tmpl$ = /*#__PURE__*/ template("<div>"), _tmpl$2 = /*#__PURE__*/ template("<a>");
8
10
  const __solidLayoutCardHeaderLayout = (_stable, p)=>(()=>{
9
11
  var _el$ = _tmpl$();
10
12
  spread(_el$, mergeProps(()=>_stable.slot.root), true);
@@ -48,62 +50,111 @@ const CardFooterLayout = defineComponent({
48
50
  ]
49
51
  });
50
52
  const __solidLayoutCardLayout = (_stable, p)=>{
53
+ const semantics = ()=>cardSemantics({
54
+ href: p.href,
55
+ isInteractive: p.isInteractive,
56
+ hasActivation: null != p.onClick,
57
+ role: p.role,
58
+ tabindex: p.tabindex
59
+ });
51
60
  const handleKeyDown = (event)=>{
52
- if (!p.isInteractive) return;
61
+ if (!semantics().handlesKeyboardActivation) return;
53
62
  if ("Enter" !== event.key && " " !== event.key) return;
54
63
  if (event.target !== event.currentTarget) return;
55
64
  event.preventDefault();
56
65
  event.currentTarget.click();
57
66
  };
58
- var _el$4 = _tmpl$2(), _el$5 = _el$4.firstChild, _el$6 = _el$5.nextSibling, _el$7 = _el$6.nextSibling;
59
- spread(_el$4, mergeProps(()=>_stable.slot.root, {
60
- get role () {
61
- return p.role ?? (p.isInteractive ? "button" : void 0);
62
- },
63
- get tabindex () {
64
- return p.tabindex ?? (p.isInteractive ? 0 : void 0);
65
- },
66
- onKeyDown: handleKeyDown,
67
- get ["data-flavor"] () {
68
- return p.flavor ?? "neutral";
69
- },
70
- get ["data-material"] () {
71
- return p.material ?? "solid";
72
- },
73
- get ["data-material-explicit"] () {
74
- return p.material ? "" : void 0;
75
- }
76
- }), true);
77
- insert(_el$4, createComponent(Show, {
78
- get when () {
79
- return p.header;
80
- },
81
- get children () {
82
- return createComponent(CardHeaderLayout, {
83
- get children () {
67
+ const body = ()=>[
68
+ createComponent(Show, {
69
+ get when () {
84
70
  return p.header;
71
+ },
72
+ get children () {
73
+ return createComponent(CardHeaderLayout, {
74
+ get children () {
75
+ return p.header;
76
+ }
77
+ });
85
78
  }
86
- });
87
- }
88
- }), _el$5);
89
- insert(_el$4, createComponent(CardBodyLayout, {
90
- get children () {
91
- return _stable.children;
92
- }
93
- }), _el$6);
94
- insert(_el$4, createComponent(Show, {
79
+ }),
80
+ createComponent(CardBodyLayout, {
81
+ get children () {
82
+ return _stable.children;
83
+ }
84
+ }),
85
+ createComponent(Show, {
86
+ get when () {
87
+ return p.footer;
88
+ },
89
+ get children () {
90
+ return createComponent(CardFooterLayout, {
91
+ get children () {
92
+ return p.footer;
93
+ }
94
+ });
95
+ }
96
+ })
97
+ ];
98
+ return createComponent(Show, {
95
99
  get when () {
96
- return p.footer;
100
+ return "a" === semantics().element;
101
+ },
102
+ get fallback () {
103
+ var _el$5 = _tmpl$();
104
+ spread(_el$5, mergeProps(()=>_stable.slot.root, {
105
+ get role () {
106
+ return semantics().role;
107
+ },
108
+ get tabindex () {
109
+ return semantics().tabindex;
110
+ },
111
+ onKeyDown: handleKeyDown,
112
+ get ["data-flavor"] () {
113
+ return p.flavor ?? "neutral";
114
+ },
115
+ get ["data-material"] () {
116
+ return p.material ?? "solid";
117
+ },
118
+ get ["data-material-explicit"] () {
119
+ return p.material ? "" : void 0;
120
+ }
121
+ }), true);
122
+ insert(_el$5, body);
123
+ return _el$5;
97
124
  },
98
125
  get children () {
99
- return createComponent(CardFooterLayout, {
100
- get children () {
101
- return p.footer;
126
+ var _el$4 = _tmpl$2();
127
+ claimElement(_el$4);
128
+ spread(_el$4, mergeProps(()=>_stable.slot.root, {
129
+ get href () {
130
+ return buttonHref(p.href, false);
131
+ },
132
+ get target () {
133
+ return p.target;
134
+ },
135
+ get rel () {
136
+ return buttonRel(p.rel, p.target);
137
+ },
138
+ get role () {
139
+ return semantics().role;
140
+ },
141
+ get tabindex () {
142
+ return semantics().tabindex;
143
+ },
144
+ get ["data-flavor"] () {
145
+ return p.flavor ?? "neutral";
146
+ },
147
+ get ["data-material"] () {
148
+ return p.material ?? "solid";
149
+ },
150
+ get ["data-material-explicit"] () {
151
+ return p.material ? "" : void 0;
102
152
  }
103
- });
153
+ }), true);
154
+ insert(_el$4, body);
155
+ return _el$4;
104
156
  }
105
- }), _el$7);
106
- return _el$4;
157
+ });
107
158
  };
108
159
  const CardLayout = defineComponent({
109
160
  recipe: card,
@@ -118,6 +169,9 @@ const CardLayout = defineComponent({
118
169
  "padding",
119
170
  "radius",
120
171
  "isInteractive",
172
+ "href",
173
+ "target",
174
+ "rel",
121
175
  "header",
122
176
  "footer",
123
177
  "children"
@@ -0,0 +1,70 @@
1
+ /**
2
+ * What an interactive card *is*, as one function.
3
+ *
4
+ * `isInteractive` gave a card `role="button"` and `tabindex="0"` with no way
5
+ * off either. That is right for a card that is the only activatable thing in
6
+ * its box, and wrong the moment a card is put inside a link, which is the
7
+ * ordinary way to make a whole card navigate. Measured on one site: every card
8
+ * on it was a `button` inside a `link`, same name, same box. Nested
9
+ * interactive content is invalid HTML, a reader hears the card twice, and a
10
+ * press by coordinate lands on whichever of the two is on top.
11
+ *
12
+ * Three things come out of this, and the first is what fixes the sites without
13
+ * anyone editing a call site. A card is announced as a button when it looks
14
+ * pressable *and has something to press*: `<a href><Card isInteractive /></a>`
15
+ * hands the card no handler, because the anchor is what navigates, so the card
16
+ * stops claiming to be a button and the nesting goes away where it stands.
17
+ * `isInteractive` was doing two jobs at once and only one of them survives
18
+ * inside a link: it is how a card asks for hover and press affordance, which is
19
+ * exactly what a card inside a link wants, and all it wants.
20
+ *
21
+ * The second is `href`: a card that navigates should *be* the anchor rather
22
+ * than sit inside one, exactly as `Button` already does. The third is an
23
+ * explicit `role`, which was accepted and then half-ignored --
24
+ * `role="presentation"` left `tabindex="0"` behind, so the escape hatch
25
+ * produced a presentational element that was still in the tab order and still
26
+ * announced as focusable.
27
+ *
28
+ * A `.layout.tsx` binds free identifiers to props, so the rule lives beside
29
+ * the markup rather than inside it, and the repository's tests are pure.
30
+ */
31
+ import type { JSX } from "@solidjs/web";
32
+ type RoleAttribute = JSX.HTMLAttributes<HTMLElement>["role"];
33
+ type TabIndexAttribute = JSX.HTMLAttributes<HTMLElement>["tabindex"];
34
+ type Role = Exclude<RoleAttribute, false | undefined>;
35
+ type TabIndex = Exclude<TabIndexAttribute, false | undefined>;
36
+ export type CardSemanticsInput = {
37
+ href?: string | false;
38
+ isInteractive?: boolean;
39
+ /**
40
+ * Whether the card has an activation of its own.
41
+ *
42
+ * This is the half that fixes the fleet without anyone editing a call site.
43
+ * `<a href><Card isInteractive /></a>` gives the card no handler: the anchor
44
+ * is what navigates. A card with nothing to activate is not a button, so it
45
+ * stops claiming to be one, and the nesting goes away where it is.
46
+ *
47
+ * `isInteractive` alone was read as "announce this as a button", and it
48
+ * cannot be: it is also how a card asks for hover and press *affordance*,
49
+ * which is exactly what a card inside a link wants and all it wants.
50
+ */
51
+ hasActivation?: boolean;
52
+ /** An explicit `role` from the call site. Wins outright. */
53
+ role?: RoleAttribute;
54
+ /** An explicit `tabindex` from the call site. Wins outright. */
55
+ tabindex?: TabIndexAttribute;
56
+ };
57
+ export type CardSemantics = {
58
+ element: "a" | "div";
59
+ role: Role | undefined;
60
+ tabindex: TabIndex | undefined;
61
+ /**
62
+ * Whether the card has to implement Enter and Space itself.
63
+ *
64
+ * Only a `div` wearing `role="button"` does. An anchor activates on Enter
65
+ * natively, and a presentational card activates on nothing.
66
+ */
67
+ handlesKeyboardActivation: boolean;
68
+ };
69
+ export declare const cardSemantics: (input: CardSemanticsInput) => CardSemantics;
70
+ export {};
@@ -0,0 +1,19 @@
1
+ const given = (value)=>false === value || void 0 === value ? void 0 : value;
2
+ const cardSemantics = (input)=>{
3
+ const role = given(input.role);
4
+ const tabindex = given(input.tabindex);
5
+ if ("string" == typeof input.href) return {
6
+ element: "a",
7
+ role,
8
+ tabindex,
9
+ handlesKeyboardActivation: false
10
+ };
11
+ const resolvedRole = role ?? (input.isInteractive && input.hasActivation ? "button" : void 0);
12
+ return {
13
+ element: "div",
14
+ role: resolvedRole,
15
+ tabindex: tabindex ?? ("button" === resolvedRole ? 0 : void 0),
16
+ handlesKeyboardActivation: "button" === resolvedRole
17
+ };
18
+ };
19
+ export { cardSemantics };
@@ -11,6 +11,6 @@ declare const Card: import("solid-js").Component<import("./Card.generated").Card
11
11
  Content: import("solid-js").Component<import("./Card.generated").CardSectionProps>;
12
12
  Footer: import("solid-js").Component<import("./Card.generated").CardSectionProps>;
13
13
  };
14
- export type { CardElevation, CardMaterial, CardProps, CardSectionProps, } from "./Card.generated";
14
+ export type { CardElevation, CardMaterial, CardState, CardProps, CardSectionProps, } from "./Card.generated";
15
15
  export { card, cardBody, cardFooter, cardHeader } from "./Card.recipe";
16
16
  export { Card as default, Card, CardBodyLayout as CardBody, CardFooterLayout as CardFooter, CardHeaderLayout as CardHeader, };
@@ -1,9 +1,9 @@
1
1
  import type { Component as __LayoutComponent } from "solid-js";
2
2
  import "./Checkbox.css";
3
3
  import type { JSX } from "@solidjs/web";
4
- import type { UIBaseProps, State, Issue } from "../vocabulary";
4
+ import type { Issue, State, UIBaseProps } from "../vocabulary";
5
5
  export type CheckboxVariant = "primary" | "secondary";
6
- export type CheckboxProps = Omit<JSX.InputHTMLAttributes<HTMLInputElement>, "type" | "children"> & UIBaseProps & {
6
+ export type CheckboxProps = Omit<JSX.InputHTMLAttributes<HTMLInputElement>, "type" | "children" | "onChange"> & UIBaseProps & {
7
7
  defaultChecked?: boolean;
8
8
  children?: JSX.Element;
9
9
  description?: JSX.Element;
@@ -12,6 +12,27 @@ export type CheckboxProps = Omit<JSX.InputHTMLAttributes<HTMLInputElement>, "typ
12
12
  isIndeterminate?: boolean;
13
13
  indeterminate?: boolean;
14
14
  variant?: CheckboxVariant;
15
+ /**
16
+ * The new checked state.
17
+ *
18
+ * **Breaking in 3.1.** This was the input's native `onChange`, handing you
19
+ * an `Event`, while `Slider`, `RadioGroup` and `CheckboxGroup` handed you a
20
+ * value under the same name. Every control now reports its value here.
21
+ *
22
+ * Fires for a checkbox inside a `CheckboxGroup` too, reporting this box's
23
+ * own state; the group separately reports the whole selection through its
24
+ * own `onChange`.
25
+ *
26
+ * The native handler is {@link onNativeChange}.
27
+ */
28
+ onChange?: (checked: boolean) => void;
29
+ /**
30
+ * The underlying `change` event, before the toggle is applied.
31
+ *
32
+ * `preventDefault()` here leaves the box as it was, suppresses
33
+ * {@link onChange}, and does not notify an enclosing group.
34
+ */
35
+ onNativeChange?: JSX.EventHandlerUnion<HTMLInputElement, Event>;
15
36
  };
16
37
  declare const Checkbox: __LayoutComponent<CheckboxProps>;
17
38
  export default Checkbox;
@@ -4,8 +4,8 @@ import "./Checkbox.css";
4
4
  import { Show, createSignal, createTrackedEffect, omit, useContext } from "solid-js";
5
5
  import { twMerge } from "../../lib/twMerge.js";
6
6
  import { CheckboxGroupContext } from "../checkbox-group/context.js";
7
- import { CLASSES, componentRecipe } from "./Checkbox.recipe.js";
8
7
  import { resolveState } from "../vocabulary.js";
8
+ import { CLASSES, componentRecipe } from "./Checkbox.recipe.js";
9
9
  var _tmpl$ = /*#__PURE__*/ template('<svg aria-hidden=true data-slot=checkbox-default-indicator--indeterminate fill=none role=presentation stroke=currentColor stroke-linecap=round stroke-width=3 viewBox="0 0 24 24"><line x1=21 x2=3 y1=12 y2=12>'), _tmpl$2 = /*#__PURE__*/ template("<span data-slot=label>"), _tmpl$3 = /*#__PURE__*/ template("<span>"), _tmpl$4 = /*#__PURE__*/ template("<span><!><!>"), _tmpl$5 = /*#__PURE__*/ template("<label><input><span><span>"), _tmpl$6 = /*#__PURE__*/ template('<svg aria-hidden=true data-slot=checkbox-default-indicator--checkmark fill=none role=presentation stroke=currentColor stroke-linecap=round stroke-linejoin=round stroke-width=2 viewBox="0 0 17 18"><polyline points="1 9 7 14 15 4">');
10
10
  const invokeEventHandler = (handler, event)=>{
11
11
  if ("function" == typeof handler) return void handler(event);
@@ -14,7 +14,7 @@ const invokeEventHandler = (handler, event)=>{
14
14
  const __solidLayoutCheckbox = (_stable, p)=>{
15
15
  let inputRef;
16
16
  const group = useContext(CheckboxGroupContext);
17
- const others = omit(p, "class", "children", "description", "state", "issues", "isIndeterminate", "indeterminate", "variant", "checked", "defaultChecked", "value", "name", "disabled", "onChange", "dataTheme", "aria-invalid");
17
+ const others = omit(p, "class", "children", "description", "state", "issues", "isIndeterminate", "indeterminate", "variant", "checked", "defaultChecked", "value", "name", "disabled", "onChange", "onNativeChange", "dataTheme", "aria-invalid");
18
18
  const [internalSelected, setInternalSelected] = createSignal(Boolean(p.defaultChecked));
19
19
  const isControlled = ()=>void 0 !== p.checked;
20
20
  const optionValue = ()=>null != p.value ? String(p.value) : void 0;
@@ -31,11 +31,17 @@ const __solidLayoutCheckbox = (_stable, p)=>{
31
31
  inputRef.indeterminate = isIndeterminate();
32
32
  });
33
33
  const handleChange = (event)=>{
34
- invokeEventHandler(p.onChange, event);
34
+ invokeEventHandler(p.onNativeChange, event);
35
35
  if (event.defaultPrevented) return;
36
36
  if (isDisabled()) return;
37
- if (group && void 0 !== optionValue()) return void group.toggleValue(optionValue(), event.currentTarget.checked, event);
38
- if (!isControlled()) setInternalSelected(event.currentTarget.checked);
37
+ const checked = event.currentTarget.checked;
38
+ if (group && void 0 !== optionValue()) {
39
+ group.toggleValue(optionValue(), checked, event);
40
+ p.onChange?.(checked);
41
+ return;
42
+ }
43
+ if (!isControlled()) setInternalSelected(checked);
44
+ p.onChange?.(checked);
39
45
  };
40
46
  var _el$ = _tmpl$5(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild;
41
47
  spread(_el$, mergeProps(()=>({
@@ -168,7 +174,9 @@ const Checkbox = defineComponent({
168
174
  "issues",
169
175
  "isIndeterminate",
170
176
  "indeterminate",
171
- "variant"
177
+ "variant",
178
+ "onChange",
179
+ "onNativeChange"
172
180
  ]
173
181
  });
174
182
  const Checkbox_generated = Checkbox;
@@ -50,19 +50,35 @@
50
50
  transform: rotate(-180deg);
51
51
  }
52
52
 
53
+ /*
54
+ * A closed panel is out of the page, not merely flattened. Same fault and
55
+ * same fix as `.accordion__content`: `keepMounted` is the default, so a
56
+ * closed panel stays in the document carrying `aria-hidden="true"` while
57
+ * everything inside it kept `visibility: visible` and stayed in the tab
58
+ * order. Tab moved focus into a panel nobody can see, inside an
59
+ * `aria-hidden` subtree, which is the one thing `aria-hidden` must never
60
+ * contain.
61
+ */
53
62
  .collapsible__content {
54
63
  display: grid;
55
64
  grid-template-rows: 0fr;
56
65
  opacity: 0;
57
66
  overflow: hidden;
67
+ visibility: hidden;
58
68
  transition:
59
69
  grid-template-rows 200ms ease,
60
- opacity 200ms ease;
70
+ opacity 200ms ease,
71
+ visibility 0s linear 200ms;
61
72
  }
62
73
 
63
74
  .collapsible__content[data-expanded="true"] {
64
75
  grid-template-rows: 1fr;
65
76
  opacity: 1;
77
+ visibility: visible;
78
+ transition:
79
+ grid-template-rows 200ms ease,
80
+ opacity 200ms ease,
81
+ visibility 0s linear 0s;
66
82
  }
67
83
 
68
84
  .collapsible__body {
@@ -1,5 +1,6 @@
1
1
  import type { Component as __LayoutComponent } from "solid-js";
2
2
  import "./ColorWheelFlower.css";
3
+ import { type ColorValue } from "./ColorUtils";
3
4
  import { type ColorWheelFlowerMode } from "./ColorWheelFlower.palette";
4
5
  export interface ColorWheelFlowerProps {
5
6
  /** Stable base for the flower and each interactive petal. */
@@ -9,6 +10,13 @@ export interface ColorWheelFlowerProps {
9
10
  mode?: ColorWheelFlowerMode;
10
11
  /** Exactly 31 literal colors, ordered outer ring, middle ring, inner ring, center. */
11
12
  palette?: readonly string[];
13
+ /** Controlled selection. A hex, `rgb()` or `hsl()` string, or a parsed value. */
14
+ color?: ColorValue | string;
15
+ /** Initial selection when uncontrolled. */
16
+ defaultColor?: ColorValue | string;
17
+ disabled?: boolean;
18
+ /** The colour a petal was clicked to choose. */
19
+ onChange?: (color: ColorValue) => void;
12
20
  }
13
21
  declare const ColorWheelFlower: __LayoutComponent<ColorWheelFlowerProps>;
14
22
  export default ColorWheelFlower;
@@ -231,7 +231,20 @@ function buildColors(palette) {
231
231
  }
232
232
  const CENTER_INDEX = LAYOUT.findIndex((l)=>l.isCenter);
233
233
  const __solidLayoutColorWheelFlower = (_stable, p)=>{
234
- const context = useColorPickerContext();
234
+ const providedContext = useColorPickerContext();
235
+ const toColorValue = (value)=>void 0 === value ? null : "string" == typeof value ? parseColor(value) : value;
236
+ const WHITE = createColorFromHsl(0, 0, 100, 1);
237
+ const [standaloneColor, setStandaloneColor] = createSignal(toColorValue(p.defaultColor) ?? WHITE);
238
+ const context = providedContext ?? {
239
+ color: ()=>toColorValue(p.color) ?? standaloneColor(),
240
+ format: ()=>"hex",
241
+ disabled: ()=>Boolean(p.disabled),
242
+ onChange: (next)=>{
243
+ if (void 0 === p.color) setStandaloneColor(next);
244
+ p.onChange?.(next);
245
+ },
246
+ onFormatChange: ()=>{}
247
+ };
235
248
  const [selectedIndex, setSelectedIndex] = createSignal(null);
236
249
  const [pulseState, setPulseState] = createSignal(null);
237
250
  const [currentTheme, setCurrentTheme] = createSignal("u" > typeof document && "dark" === document.documentElement.getAttribute("data-theme") ? "dark" : "light");
@@ -7,5 +7,12 @@ export interface ColorPickerContextType {
7
7
  onChange: (color: ColorValue) => void;
8
8
  onFormatChange: (format: ColorFormat) => void;
9
9
  }
10
- export declare const ColorPickerContext: import("solid-js").Context<ColorPickerContextType | undefined>;
11
- export declare function useColorPickerContext(): ColorPickerContextType;
10
+ export declare const ColorPickerContext: import("solid-js").Context<ColorPickerContextType | null>;
11
+ /**
12
+ * The surrounding picker's state, or `null` when there is no picker.
13
+ *
14
+ * Returning `null` rather than throwing is deliberate: a consumer that can
15
+ * stand alone decides for itself what to do without a provider, and one that
16
+ * genuinely cannot say so in its own words.
17
+ */
18
+ export declare function useColorPickerContext(): ColorPickerContextType | null;
@@ -1,8 +1,6 @@
1
1
  import { createContext, useContext } from "solid-js";
2
- const ColorPickerContext = createContext(void 0);
2
+ const ColorPickerContext = createContext(null);
3
3
  function useColorPickerContext() {
4
- const context = useContext(ColorPickerContext);
5
- if (!context) throw new Error("useColorPickerContext must be used within a ColorPickerContext.Provider");
6
- return context;
4
+ return useContext(ColorPickerContext);
7
5
  }
8
6
  export { ColorPickerContext, useColorPickerContext };
@@ -0,0 +1,76 @@
1
+ @layer components {
2
+ .connection-settings {
3
+ display: flex;
4
+ width: 100%;
5
+ flex-direction: column;
6
+ gap: 1.5rem;
7
+ }
8
+
9
+ .connection-settings__header {
10
+ display: flex;
11
+ align-items: center;
12
+ justify-content: space-between;
13
+ gap: 1rem;
14
+ }
15
+
16
+ .connection-settings__title {
17
+ font-weight: 500;
18
+ }
19
+
20
+ .connection-settings__description {
21
+ font-size: 0.875rem;
22
+ opacity: 0.7;
23
+ }
24
+
25
+ /*
26
+ * The fields are absent from the tree while closed rather than hidden. A
27
+ * reveal that only sets `display: none` reads as present to anything driving
28
+ * the renderer, so a broken toggle still looks like it worked.
29
+ */
30
+ .connection-settings__fields {
31
+ display: flex;
32
+ flex-direction: column;
33
+ gap: 1rem;
34
+ }
35
+
36
+ .connection-settings__field {
37
+ display: flex;
38
+ flex-direction: column;
39
+ gap: 0.375rem;
40
+ }
41
+
42
+ .connection-settings__label {
43
+ font-size: 0.875rem;
44
+ font-weight: 500;
45
+ }
46
+
47
+ .connection-settings__input {
48
+ width: 100%;
49
+ }
50
+
51
+ .connection-settings__hint {
52
+ font-size: 0.875rem;
53
+ opacity: 0.7;
54
+ }
55
+
56
+ .connection-settings__current {
57
+ display: flex;
58
+ flex-direction: column;
59
+ gap: 0.25rem;
60
+ font-size: 0.875rem;
61
+ opacity: 0.6;
62
+ }
63
+
64
+ .connection-settings__actions {
65
+ display: flex;
66
+ flex-direction: column;
67
+ gap: 0.5rem;
68
+ }
69
+
70
+ /* `data-applying`, not a class: the flag is this component's own runtime
71
+ state, not a prop, so a recipe prop could never be driven by it. State
72
+ attributes are what the library documents for exactly this. */
73
+ .connection-settings[data-applying="true"] .connection-settings__actions {
74
+ opacity: 0.6;
75
+ }
76
+ }
@@ -0,0 +1,45 @@
1
+ import type { Component as __LayoutComponent } from "solid-js";
2
+ import "./ConnectionSettings.css";
3
+ import type { JSX } from "@solidjs/web";
4
+ import type { ConnectionSettingsStore } from "../../hooks/connection";
5
+ import type { UIBaseProps } from "../vocabulary";
6
+ /** One backend, as this panel presents it. `name` matches the store's endpoint. */
7
+ export type ConnectionSettingsEndpointLabel = {
8
+ name: string;
9
+ label: string;
10
+ /** Shown under the field. The place to say what the default is for. */
11
+ hint?: string;
12
+ placeholder?: string;
13
+ };
14
+ export type ConnectionSettingsLabels = {
15
+ /** The switch's own label. */
16
+ useCustom: string;
17
+ useCustomDescription?: string;
18
+ appPublicId?: string;
19
+ save: string;
20
+ reset: string;
21
+ /** Prefix for the read-only "this is where you are pointed" lines. */
22
+ current?: string;
23
+ };
24
+ export type ConnectionSettingsProps = Omit<JSX.FormHTMLAttributes<HTMLFormElement>, "onSubmit"> & UIBaseProps & {
25
+ /** From `createConnectionSettings`. The panel reads and writes it directly. */
26
+ store: ConnectionSettingsStore;
27
+ endpoints: readonly ConnectionSettingsEndpointLabel[];
28
+ labels: ConnectionSettingsLabels;
29
+ /** Omit to hide the app id field entirely. */
30
+ showAppPublicId?: boolean;
31
+ /**
32
+ * Rendered inside the revealed region, after the endpoint fields.
33
+ *
34
+ * Every site has one field the others do not: an app id, a second backend,
35
+ * a network selector. Putting them here keeps them inside the same reveal
36
+ * instead of forcing a second copy of the panel.
37
+ */
38
+ children?: JSX.Element;
39
+ /** Called after the store has applied. For a toast, or navigation. */
40
+ onSaved?: () => void;
41
+ /** Called when applying threw. The panel also shows the message itself. */
42
+ onSaveFailed?: (error: unknown) => void;
43
+ onResetDone?: () => void;
44
+ };
45
+ export declare const ConnectionSettingsLayout: __LayoutComponent<ConnectionSettingsProps>;