@apliteni/apliteni-ui 0.120.1 → 0.122.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apliteni/apliteni-ui",
3
- "version": "0.120.1",
3
+ "version": "0.122.0",
4
4
  "workspaces": [
5
5
  "react"
6
6
  ],
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { InputHTMLAttributes, ReactNode, ButtonHTMLAttributes, RefAttributes, ReactElement, AnchorHTMLAttributes, HTMLAttributes, RefObject, MouseEvent, ElementType, ComponentPropsWithoutRef, SelectHTMLAttributes, TextareaHTMLAttributes, SVGAttributes } from 'react';
2
+ import { FieldsetHTMLAttributes, ReactNode, InputHTMLAttributes, ButtonHTMLAttributes, RefAttributes, ReactElement, AnchorHTMLAttributes, HTMLAttributes, RefObject, MouseEvent, ElementType, ComponentPropsWithoutRef, SelectHTMLAttributes, TextareaHTMLAttributes, SVGAttributes } from 'react';
3
3
  import { ACCENTS } from '@apliteni/apliteni-ui';
4
4
 
5
5
  declare function Icon({ name }: {
@@ -8,12 +8,22 @@ declare function Icon({ name }: {
8
8
 
9
9
  type CheckboxProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'children'> & {
10
10
  label: ReactNode;
11
+ /** Shown under the label words and described to assistive technology. */
12
+ hint?: ReactNode;
11
13
  type?: 'checkbox' | 'radio';
12
14
  };
13
15
  declare const Checkbox: react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "children"> & {
14
16
  label: ReactNode;
17
+ /** Shown under the label words and described to assistive technology. */
18
+ hint?: ReactNode;
15
19
  type?: "checkbox" | "radio";
16
20
  } & react.RefAttributes<HTMLInputElement>>;
21
+ type CheckListProps = Omit<FieldsetHTMLAttributes<HTMLFieldSetElement>, 'children'> & {
22
+ legend: ReactNode;
23
+ children: ReactNode;
24
+ };
25
+ /** A group of `Checkbox` children under a legend. */
26
+ declare function CheckList({ legend, children, className, ...props }: CheckListProps): react.JSX.Element;
17
27
 
18
28
  type SwitchProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'children'> & {
19
29
  label: string;
@@ -1060,4 +1070,4 @@ declare const AccentPicker: react.ForwardRefExoticComponent<Omit<HTMLAttributes<
1060
1070
  declare const PAGE_SIZES: readonly number[];
1061
1071
  declare const DEFAULT_PAGE_SIZE: number;
1062
1072
 
1063
- export { type Accent, AccentPicker, type AccentPickerProps, type AddFilter, AppShell, type AppShellProps, type AppShellSection, BackLink, type BackLinkOwnProps, type BackLinkProps, Badge, BusyRegion, type BusyRegionProps, Button, type ButtonLinkProps, type ButtonProps, Callout, type CalloutProps, type CalloutVariant, Card, Chart, type ChartBridgeStep, type ChartBridgeTones, type ChartPeriod, type ChartProps, type ChartSeries, type ChartTone, Checkbox, type CheckboxProps, type Column, type CommandGroup, type CommandItem, CommandPalette, type CommandPaletteProps, Confirm, type ConfirmProps, DEFAULT_PAGE_SIZE, DataTable, type DataTableProps, DatePicker, type DatePickerMode, type DatePickerPreset, type DatePickerProps, type DatePickerRange, DeltaValue, type DeltaValueProps, Denied, type DeniedProps, Drawer, type DrawerProps, DrawerSection, type DrawerSectionProps, Dropdown, type DropdownBadge, type DropdownEntry, type DropdownItem, type DropdownProps, type DropdownRowProps, type DropdownSearch, type DropdownSection, type DropdownSeparator, EmptyState, type EmptyStateProps, type EmptyStateVariant, Field, type FieldControlProps, type FieldProps, FileDrop, type FileDropFile, type FileDropProps, type FileDropStatus, FileField, type FileFieldProps, type Filter, FilterBar, type FilterBarProps, Icon, KeyValueList, type KeyValueListProps, type KeyValueRow, Modal, type ModalProps, type NativeButtonProps, NumericValue, type NumericValueProps, PAGE_SIZES, Pagination, type PaginationProps, Pill, type PillProps, RowIdentity, type RowIdentityProps, SearchField, type SearchFieldProps, type SegmentOption, Segmented, type SegmentedProps, SelectField, type SelectFieldProps, SidebarNav, type SidebarNavBadge, type SidebarNavItem, type SidebarNavLeaf, type SidebarNavProps, type SidebarNavSection, Skeleton, type SkeletonProps, SkeletonTable, type SkeletonTableProps, Snippet, type SnippetProps, StatBand, type StatBandProps, type StatDelta, type StatFigure, type StatTone, type StatVariant, StatusDot, type StatusDotProps, Success, SuccessCheck, type SuccessCheckProps, type SuccessCountdown, SuccessPanel, type SuccessPanelProps, type SuccessProps, Switch, type SwitchProps, THEME_INIT_SCRIPT, type TabItem, type TableSort, Tabs, type TabsProps, TextArea, type TextAreaProps, TextField, type TextFieldProps, ThemeToggle, type ThemeToggleProps, Timeline, type TimelineEvent, type TimelineEventKind, type TimelineProps, Toast, type ToastNotice, type ToastProps, Tooltip, type TooltipProps, sortTableRows, useToast };
1073
+ export { type Accent, AccentPicker, type AccentPickerProps, type AddFilter, AppShell, type AppShellProps, type AppShellSection, BackLink, type BackLinkOwnProps, type BackLinkProps, Badge, BusyRegion, type BusyRegionProps, Button, type ButtonLinkProps, type ButtonProps, Callout, type CalloutProps, type CalloutVariant, Card, Chart, type ChartBridgeStep, type ChartBridgeTones, type ChartPeriod, type ChartProps, type ChartSeries, type ChartTone, CheckList, type CheckListProps, Checkbox, type CheckboxProps, type Column, type CommandGroup, type CommandItem, CommandPalette, type CommandPaletteProps, Confirm, type ConfirmProps, DEFAULT_PAGE_SIZE, DataTable, type DataTableProps, DatePicker, type DatePickerMode, type DatePickerPreset, type DatePickerProps, type DatePickerRange, DeltaValue, type DeltaValueProps, Denied, type DeniedProps, Drawer, type DrawerProps, DrawerSection, type DrawerSectionProps, Dropdown, type DropdownBadge, type DropdownEntry, type DropdownItem, type DropdownProps, type DropdownRowProps, type DropdownSearch, type DropdownSection, type DropdownSeparator, EmptyState, type EmptyStateProps, type EmptyStateVariant, Field, type FieldControlProps, type FieldProps, FileDrop, type FileDropFile, type FileDropProps, type FileDropStatus, FileField, type FileFieldProps, type Filter, FilterBar, type FilterBarProps, Icon, KeyValueList, type KeyValueListProps, type KeyValueRow, Modal, type ModalProps, type NativeButtonProps, NumericValue, type NumericValueProps, PAGE_SIZES, Pagination, type PaginationProps, Pill, type PillProps, RowIdentity, type RowIdentityProps, SearchField, type SearchFieldProps, type SegmentOption, Segmented, type SegmentedProps, SelectField, type SelectFieldProps, SidebarNav, type SidebarNavBadge, type SidebarNavItem, type SidebarNavLeaf, type SidebarNavProps, type SidebarNavSection, Skeleton, type SkeletonProps, SkeletonTable, type SkeletonTableProps, Snippet, type SnippetProps, StatBand, type StatBandProps, type StatDelta, type StatFigure, type StatTone, type StatVariant, StatusDot, type StatusDotProps, Success, SuccessCheck, type SuccessCheckProps, type SuccessCountdown, SuccessPanel, type SuccessPanelProps, type SuccessProps, Switch, type SwitchProps, THEME_INIT_SCRIPT, type TabItem, type TableSort, Tabs, type TabsProps, TextArea, type TextAreaProps, TextField, type TextFieldProps, ThemeToggle, type ThemeToggleProps, Timeline, type TimelineEvent, type TimelineEventKind, type TimelineProps, Toast, type ToastNotice, type ToastProps, Tooltip, type TooltipProps, sortTableRows, useToast };
@@ -15,18 +15,33 @@ function Icon({ name }) {
15
15
  }
16
16
 
17
17
  // src/Checkbox.tsx
18
- import { forwardRef } from "react";
18
+ import { forwardRef, useId } from "react";
19
19
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
20
20
  var Checkbox = forwardRef(function Checkbox2({
21
21
  label,
22
+ hint,
22
23
  type = "checkbox",
24
+ "aria-describedby": describedBy,
23
25
  ...props
24
26
  }, ref) {
25
- return /* @__PURE__ */ jsxs("label", { className: "ui-check", children: [
26
- /* @__PURE__ */ jsx2("input", { ...props, ref, type }),
27
+ const hintId = useId();
28
+ const described = [describedBy, hint ? hintId : void 0].filter(Boolean).join(" ") || void 0;
29
+ const check = /* @__PURE__ */ jsxs("label", { className: "ui-check", children: [
30
+ /* @__PURE__ */ jsx2("input", { ...props, ref, type, "aria-describedby": described }),
27
31
  /* @__PURE__ */ jsx2("span", { children: label })
28
32
  ] });
33
+ if (!hint) return check;
34
+ return /* @__PURE__ */ jsxs("div", { className: "ui-check-item", children: [
35
+ check,
36
+ /* @__PURE__ */ jsx2("div", { id: hintId, className: "ui-check__hint", children: hint })
37
+ ] });
29
38
  });
39
+ function CheckList({ legend, children, className = "", ...props }) {
40
+ return /* @__PURE__ */ jsxs("fieldset", { ...props, className: `ui-check-list ${className}`.trim(), children: [
41
+ /* @__PURE__ */ jsx2("legend", { className: "ui-field__label", children: legend }),
42
+ children
43
+ ] });
44
+ }
30
45
 
31
46
  // src/Switch.tsx
32
47
  import { forwardRef as forwardRef2 } from "react";
@@ -269,7 +284,7 @@ function Callout({ variant, icon: icon6 = calloutIcons[variant ?? "neutral"], ch
269
284
  }
270
285
 
271
286
  // src/primitives/StatBand.tsx
272
- import { useId as useId2 } from "react";
287
+ import { useId as useId3 } from "react";
273
288
 
274
289
  // src/tip.ts
275
290
  var TIP_GAP = 8;
@@ -311,7 +326,7 @@ function placeTip(host, mark, tip, bound, placement = "top") {
311
326
  }
312
327
 
313
328
  // src/Tooltip.tsx
314
- import { useEffect, useId, useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState } from "react";
329
+ import { useEffect, useId as useId2, useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState } from "react";
315
330
  import { Fragment, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
316
331
  var DOC_EVENTS = ["pointerdown", "pointercancel", "click", "keydown", "touchend"];
317
332
  var CAPTURED = /* @__PURE__ */ new Set(["pointerdown", "pointercancel"]);
@@ -345,7 +360,7 @@ var Text = ({ label = "", value = "", detail: detail2 = "" }) => /* @__PURE__ */
345
360
  /* @__PURE__ */ jsx10("span", { className: "ui-tip__detail", hidden: !detail2, children: detail2 })
346
361
  ] });
347
362
  function Tooltip({ text: text2, label = text2, value, detail: detail2, placement = "top", children }) {
348
- const id = useId();
363
+ const id = useId2();
349
364
  const host = useRef2(null);
350
365
  const trigger = useRef2(null);
351
366
  const tip = useRef2(null);
@@ -526,7 +541,7 @@ function ContextRow({ caption, delta, basisId }) {
526
541
  ] });
527
542
  }
528
543
  function StatBand({ stats, variant = "tiles", basis, basisId: sharedBasisId, label, id }) {
529
- const auto = useId2();
544
+ const auto = useId3();
530
545
  const v = ["band", "tiles", "open"].includes(variant) ? variant : "tiles";
531
546
  const basisId = basis ? `${id || auto}-basis` : sharedBasisId;
532
547
  const root = ["ui-stats", `ui-stats--${v}`, v === "band" && "ui-card"].filter(Boolean).join(" ");
@@ -549,7 +564,7 @@ function StatBand({ stats, variant = "tiles", basis, basisId: sharedBasisId, lab
549
564
  import { useRef as useRef5 } from "react";
550
565
 
551
566
  // src/Modal.tsx
552
- import { useId as useId3, useRef as useRef4 } from "react";
567
+ import { useId as useId4, useRef as useRef4 } from "react";
553
568
  import { createPortal } from "react-dom";
554
569
 
555
570
  // src/dialog.ts
@@ -755,7 +770,7 @@ function useDialog(active, { root, panel, body, initialFocus }, onClose) {
755
770
  // src/Modal.tsx
756
771
  import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
757
772
  function Modal({ open, title, onClose, footer, children, initialFocusRef, role = "dialog" }) {
758
- const id = useId3();
773
+ const id = useId4();
759
774
  const titleId = `${id}-title`;
760
775
  const bodyId = `${id}-body`;
761
776
  const root = useRef4(null);
@@ -821,7 +836,7 @@ function Confirm({
821
836
  }
822
837
 
823
838
  // src/Drawer.tsx
824
- import { useId as useId4, useRef as useRef6 } from "react";
839
+ import { useId as useId5, useRef as useRef6 } from "react";
825
840
  import { createPortal as createPortal2 } from "react-dom";
826
841
  import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
827
842
  function Drawer({
@@ -837,7 +852,7 @@ function Drawer({
837
852
  const root = useRef6(null);
838
853
  const panel = useRef6(null);
839
854
  const body = useRef6(null);
840
- const titleId = useId4();
855
+ const titleId = useId5();
841
856
  const { mounted, shown } = usePresence(open, root, panel);
842
857
  const scope = useDialog(shown, { root, panel, body }, onClose);
843
858
  if (!mounted) return null;
@@ -870,7 +885,7 @@ function Drawer({
870
885
  }
871
886
 
872
887
  // src/CommandPalette.tsx
873
- import { useCallback, useEffect as useEffect3, useId as useId5, useMemo, useRef as useRef7, useState as useState3 } from "react";
888
+ import { useCallback, useEffect as useEffect3, useId as useId6, useMemo, useRef as useRef7, useState as useState3 } from "react";
874
889
  import { createPortal as createPortal3 } from "react-dom";
875
890
  import { rankGroups, icon as icon2 } from "@apliteni/apliteni-ui";
876
891
  import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
@@ -890,7 +905,7 @@ function CommandPalette({
890
905
  rank = true,
891
906
  onQueryChange
892
907
  }) {
893
- const uid = useId5().replace(/:/g, "");
908
+ const uid = useId6().replace(/:/g, "");
894
909
  const root = useRef7(null);
895
910
  const panel = useRef7(null);
896
911
  const search = useRef7(null);
@@ -1067,7 +1082,7 @@ import { useCallback as useCallback2, useEffect as useEffect5, useMemo as useMem
1067
1082
  import { DEFAULT_PAGE_SIZE as DEFAULT_PAGE_SIZE2 } from "@apliteni/apliteni-ui";
1068
1083
 
1069
1084
  // src/Pagination.tsx
1070
- import { useEffect as useEffect4, useId as useId6, useRef as useRef8, useState as useState4 } from "react";
1085
+ import { useEffect as useEffect4, useId as useId7, useRef as useRef8, useState as useState4 } from "react";
1071
1086
  import { DEFAULT_PAGE_SIZE } from "@apliteni/apliteni-ui";
1072
1087
  import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
1073
1088
  var GHOST_SM = "ui-btn ui-btn--ghost ui-btn--sm";
@@ -1111,7 +1126,7 @@ function Pagination({
1111
1126
  onPageChange,
1112
1127
  onPageSizeChange
1113
1128
  }) {
1114
- const auto = useId6();
1129
+ const auto = useId7();
1115
1130
  const [draft, setDraft] = useState4("");
1116
1131
  const [drafting, setDrafting] = useState4(false);
1117
1132
  const nav = useRef8(null);
@@ -2058,7 +2073,7 @@ import {
2058
2073
  Fragment as Fragment5,
2059
2074
  useCallback as useCallback4,
2060
2075
  useEffect as useEffect7,
2061
- useId as useId7,
2076
+ useId as useId8,
2062
2077
  useRef as useRef11,
2063
2078
  useState as useState7
2064
2079
  } from "react";
@@ -2142,7 +2157,7 @@ function Dropdown({
2142
2157
  const field = useRef11(null);
2143
2158
  const landOn = useRef11(null);
2144
2159
  const at = useRef11("");
2145
- const auto = useId7().replace(/:/g, "");
2160
+ const auto = useId8().replace(/:/g, "");
2146
2161
  const uid = id ?? auto;
2147
2162
  const setOpen = useCallback4((next) => {
2148
2163
  if (openProp === void 0) setSelfOpen(next);
@@ -2936,11 +2951,11 @@ function Snippet({ label = "shell", code = "", children, copy = true, reveal = f
2936
2951
  }
2937
2952
 
2938
2953
  // src/Tabs.tsx
2939
- import { useEffect as useEffect9, useId as useId8, useRef as useRef14 } from "react";
2954
+ import { useEffect as useEffect9, useId as useId9, useRef as useRef14 } from "react";
2940
2955
  import { playEntrance } from "@apliteni/apliteni-ui/motion";
2941
2956
  import { Fragment as Fragment9, jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
2942
2957
  function Tabs({ items, value, onChange, label }) {
2943
- const id = useId8();
2958
+ const id = useId9();
2944
2959
  const previous = useRef14(value);
2945
2960
  const activePanel = useRef14(null);
2946
2961
  const buttons = useRef14([]);
@@ -3063,7 +3078,7 @@ function Timeline({ events, className, ...rest }) {
3063
3078
  }
3064
3079
 
3065
3080
  // src/Field.tsx
3066
- import { forwardRef as forwardRef6, useEffect as useEffect11, useId as useId9, useRef as useRef16, useState as useState10 } from "react";
3081
+ import { forwardRef as forwardRef6, useEffect as useEffect11, useId as useId10, useRef as useRef16, useState as useState10 } from "react";
3067
3082
  import { esc, icon as icon4 } from "@apliteni/apliteni-ui";
3068
3083
  import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
3069
3084
  function messages(id, hint, error) {
@@ -3092,12 +3107,12 @@ function wiring(id, hint, error) {
3092
3107
  return { id, "aria-describedby": messages(id, hint, error), "aria-invalid": error ? true : void 0 };
3093
3108
  }
3094
3109
  function Field({ id: suppliedId, label, hint, error, required, children }) {
3095
- const generatedId = useId9();
3110
+ const generatedId = useId10();
3096
3111
  const id = suppliedId ?? generatedId;
3097
3112
  return /* @__PURE__ */ jsx29(Frame, { ...{ id, label, hint, error, required }, children: children({ ...wiring(id, hint, error), required }) });
3098
3113
  }
3099
3114
  var TextField = forwardRef6(function TextField2({ label, hint, error, required, type = "text", unit, icon: glyph, className = "", ...props }, ref) {
3100
- const id = useId9();
3115
+ const id = useId10();
3101
3116
  const hasUnit = type === "number" && !!unit;
3102
3117
  const describedBy = [messages(id, hint, error), hasUnit ? `${id}-unit` : ""].filter(Boolean).join(" ") || void 0;
3103
3118
  const control = /* @__PURE__ */ jsx29(
@@ -3124,7 +3139,7 @@ var TextField = forwardRef6(function TextField2({ label, hint, error, required,
3124
3139
  ] }) : control });
3125
3140
  });
3126
3141
  function TextArea({ label, hint, error, required, className = "", ...props }) {
3127
- const id = useId9();
3142
+ const id = useId10();
3128
3143
  return /* @__PURE__ */ jsx29(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsx29(
3129
3144
  "textarea",
3130
3145
  {
@@ -3137,7 +3152,7 @@ function TextArea({ label, hint, error, required, className = "", ...props }) {
3137
3152
  ) });
3138
3153
  }
3139
3154
  function SelectField({ label, hint, error, required, className = "", children, ...props }) {
3140
- const id = useId9();
3155
+ const id = useId10();
3141
3156
  return /* @__PURE__ */ jsx29(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsx29(
3142
3157
  "select",
3143
3158
  {
@@ -3150,7 +3165,7 @@ function SelectField({ label, hint, error, required, className = "", children, .
3150
3165
  ) });
3151
3166
  }
3152
3167
  function FileField({ label, hint, error, required, disabled, onFileChange, className = "", ...props }) {
3153
- const id = useId9();
3168
+ const id = useId10();
3154
3169
  const input = useRef16(null);
3155
3170
  const [file, setFile] = useState10(null);
3156
3171
  const [dragging, setDragging] = useState10(false);
@@ -3517,16 +3532,16 @@ function Toast({ children }) {
3517
3532
  }
3518
3533
 
3519
3534
  // src/AppShell.tsx
3520
- import { useEffect as useEffect14, useId as useId11, useState as useState14 } from "react";
3535
+ import { useEffect as useEffect14, useId as useId12, useState as useState14 } from "react";
3521
3536
  import { paletteHotkey, prism, railCollapsed } from "@apliteni/apliteni-ui";
3522
3537
 
3523
3538
  // src/SidebarNav.tsx
3524
- import { forwardRef as forwardRef8, useEffect as useEffect13, useId as useId10, useState as useState13 } from "react";
3539
+ import { forwardRef as forwardRef8, useEffect as useEffect13, useId as useId11, useState as useState13 } from "react";
3525
3540
  import { ENTRANCE_FALLBACK_MS } from "@apliteni/apliteni-ui/motion";
3526
3541
  import { Fragment as Fragment11, jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
3527
3542
  var badgeText = (badge) => typeof badge === "object" ? badge.text : badge;
3528
3543
  function Row({ item, active, activeIs, collapsed, renderLink, sub }) {
3529
- const uid = useId10();
3544
+ const uid = useId11();
3530
3545
  const group = !sub && !!item.items?.length;
3531
3546
  const childActive = group && item.items.some((child) => child.id === active);
3532
3547
  const [expanded, setExpanded] = useState13();
@@ -3583,7 +3598,7 @@ function Row({ item, active, activeIs, collapsed, renderLink, sub }) {
3583
3598
  return /* @__PURE__ */ jsx33("li", { children: renderLink ? renderLink(item, props) : /* @__PURE__ */ jsx33("a", { ...props }) });
3584
3599
  }
3585
3600
  function Section({ section, ...props }) {
3586
- const uid = useId10();
3601
+ const uid = useId11();
3587
3602
  return /* @__PURE__ */ jsxs28("div", { className: "ui-nav__section", children: [
3588
3603
  section.label && /* @__PURE__ */ jsx33("div", { className: "ui-nav__cap", id: uid, "aria-hidden": props.collapsed || void 0, children: section.label }),
3589
3604
  /* @__PURE__ */ jsx33("ul", { className: "ui-nav__list", "aria-labelledby": section.label ? uid : void 0, children: section.items.map((item) => /* @__PURE__ */ jsx33(Row, { item, ...props }, item.id)) })
@@ -3712,7 +3727,7 @@ function AppShell({
3712
3727
  palette,
3713
3728
  renderLink
3714
3729
  }) {
3715
- const uid = useId11();
3730
+ const uid = useId12();
3716
3731
  const [collapsed, setCollapsed] = useState14(defaultCollapsed);
3717
3732
  const [search, setSearch] = useState14(false);
3718
3733
  const [more, setMore] = useState14(false);
@@ -4011,7 +4026,7 @@ var Success = forwardRef9(function Success2({
4011
4026
  import {
4012
4027
  useCallback as useCallback6,
4013
4028
  useEffect as useEffect16,
4014
- useId as useId12,
4029
+ useId as useId13,
4015
4030
  useLayoutEffect as useLayoutEffect5,
4016
4031
  useMemo as useMemo4,
4017
4032
  useRef as useRef20,
@@ -4179,7 +4194,7 @@ function Chart(props) {
4179
4194
  const spark = variant === "spark";
4180
4195
  const plotHeight = height ?? HEIGHT[variant];
4181
4196
  const showTable = table ?? !spark;
4182
- const uid = useId12().replace(/[^\w-]/g, "");
4197
+ const uid = useId13().replace(/[^\w-]/g, "");
4183
4198
  const frameEl = useRef20(null);
4184
4199
  const scroller = useRef20(null);
4185
4200
  const plot = useRef20(null);
@@ -4741,6 +4756,7 @@ export {
4741
4756
  Callout,
4742
4757
  Card,
4743
4758
  Chart,
4759
+ CheckList,
4744
4760
  Checkbox,
4745
4761
  CommandPalette,
4746
4762
  Confirm,
@@ -211,6 +211,32 @@
211
211
  holds go quiet with the box beside them. */
212
212
  .ui-check:has(input:disabled) { /* muted-ink: state — unavailable control */ color: var(--disabled-ink); cursor: not-allowed; }
213
213
 
214
+ /* A hint under a box. It sits outside the label, so the label's name stays the label
215
+ words and the hint is read as a description (aria-describedby), and it takes the
216
+ field hint's type and ink. The left edge is the label words': the 19px box and the
217
+ 11px gap, a sum that lies between two grid steps for that reason alone. */
218
+ .ui-check-item { display: flex; flex-direction: column; align-items: flex-start; }
219
+ .ui-check__hint {
220
+ color: var(--text);
221
+ font-size: var(--text-sm);
222
+ line-height: 1.5;
223
+ margin-top: var(--space-1);
224
+ margin-left: 30px;
225
+ }
226
+ .ui-check-item:has(input:disabled) .ui-check__hint { /* muted-ink: state — unavailable control */ color: var(--disabled-ink); }
227
+
228
+ /* A group of boxes under a legend, the legend in the field label's type. */
229
+ .ui-check-list {
230
+ display: flex;
231
+ flex-direction: column;
232
+ align-items: flex-start;
233
+ gap: var(--space-4);
234
+ min-width: 0;
235
+ margin: 0;
236
+ padding: 0;
237
+ border: 0;
238
+ }
239
+
214
240
  /* Toggle switch */
215
241
  .ui-switch {
216
242
  --sw-w: 44px;
@@ -231,49 +231,45 @@
231
231
  the same neutral chip fill rather than the card surface — which, inside a panel that
232
232
  is itself lighter than a card, was darker than the ground it sat on. #453 */
233
233
  .vbadge.arch { /* muted-ink: state — archived version */ color: var(--muted); background: var(--chip-neutral-fill); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ }
234
- /* The phone step — the same one the rail folds at: docs/foundations.md#breakpoints.
235
- The switcher keeps its glyph and drops its label.
236
- The menu hangs the other way here. Anchored by its left edge it opened
237
- rightwards off a band that is as wide as the page, and a CLOSED menu is still
238
- laid out, so it scrolled the page sideways with nothing visible to explain it.
239
- `.amenu` beside it has always been anchored right. On a 320px viewport the
240
- page's scroll width was 527px and is 397px; the band's own controls still want
241
- more room than that page has, which is #558.
242
- why: guidelines/layout-and-density.md#use-the-three-breakpoints
243
- held by: stories/overlay-css.test.js */
234
+ /* The version label drops at the shell breakpoint.
235
+ Anchor the menu to its right edge so a closed panel cannot widen the page. */
244
236
  @media (max-width: 720px) {
245
237
  .vsw__btn .lbl { display: none; }
246
238
  .vsw__menu { left: auto; right: 0; }
247
239
  }
248
240
 
249
- /* One column, and the band is at its tightest. The row is already full at 390,
250
- and at the gap above this one the account avatar stood from 365 to 397 and was
251
- cut at the screen edge — the one control on this screen that opens the account
252
- area. Packed to --space-2 and a flat 14px trailing gutter the band needs 367.53
253
- of the 362px it has there, a 5.53px shortfall, because layout.css now pins the
254
- theme switch to a full 34px square so it keeps the tap floor it was given.
255
- The wordmark, the Deck/Text switch and the version label are each already at
256
- the width their own text needs, and the switch must not shrink again, so the
257
- account block's trailing gutter is what gives — but a FLAT 14px gutter has no
258
- fallback below the width it was sized for: at 375 it has already given every
259
- one of its 14px and the row is still 6.53px short, so the avatar was cut and
260
- the page gained 7px of horizontal scroll (#486 review round 2), worse again
261
- at 320.
262
- Both carry a share now, continuously, rather than the gutter alone holding a
263
- fixed budget: the gutter still narrows first, from 14px at 390 down to 0 by
264
- 381.53px of available row width, and once it is spent the inter-control gap
265
- takes the rest, from --space-2 down to its own floor of --space-1. 381.53px is
266
- this row's own fixed width minus its gutter's full 14px — not a general
267
- formula, a number that belongs to this composition's own wordmark, switch and
268
- version label. The avatar is whole and the page carries no horizontal scroll
269
- down to 375px. 320 still falls 41.53px short with both all the way down,
270
- which stays #558; it is 5px better than main's own 46.53px there, not solved.
271
- why: docs/foundations.md#breakpoints */
241
+ /* Keep the identity controls above the view controls on a phone.
242
+ The toolbar pattern uses the same inset for both rows. */
272
243
  @media (max-width: 560px) {
244
+ .topbar { height: auto; min-height: 52px; }
273
245
  .topbar__in {
274
- gap: clamp(var(--space-1), calc(var(--space-2) - (381.53px - 100vw) / 5), var(--space-2));
275
- padding-right: clamp(0px, calc(100vw - 381.53px), 14px);
246
+ display: grid;
247
+ grid-template-columns: max-content minmax(0, 1fr) auto auto;
248
+ grid-auto-rows: minmax(44px, auto);
249
+ gap: var(--space-2) 0;
250
+ /* 4px above and 3px below, because the band's 1px border is the fourth: one row is
251
+ then 52px, as on a wide screen, and the shell offset below stays true. */
252
+ padding: var(--space-1) var(--space-3) 3px;
276
253
  }
254
+ .topbar__in > .brand { grid-area: 1 / 1 / 2 / 3; justify-self: start; }
255
+ .topbar__in > .toggle { grid-area: 1 / 3; justify-self: end; }
256
+ /* The 8px beside the account is its own margin, so a hidden account leaves no gap and
257
+ the theme switch ends on the inset. */
258
+ .topbar__in > .acct { grid-area: 1 / 4; justify-self: end; margin-left: var(--space-2); }
259
+ .topbar__in > .spacer { display: none; }
260
+ .topbar__in > .dtsw { grid-area: 2 / 1; justify-self: start; }
261
+ /* The first column is as wide as Deck/Text and no wider, because the brand spans past it.
262
+ The version switch takes the flexible column and the two auto columns beside it, so its
263
+ width never widens the columns that pin the theme switch and the account to the row's
264
+ end inset. A long label gives way to an ellipsis, and 8px always stays between the
265
+ two controls. */
266
+ .topbar__in > .vsw { grid-area: 2 / 2 / 3 / -1; justify-self: end; min-width: 0; max-width: calc(100% - var(--space-2)); margin-left: var(--space-2); }
267
+ .vsw__btn { max-width: 100%; }
268
+ .vsw__btn .cur { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
269
+ .vsw__btn .car { flex: none; }
270
+ /* Two 44px rows, an 8px gap, the 4px and 3px insets and the bottom border. */
271
+ .ui-app-page:has(.topbar .dtsw.on),
272
+ .ui-app-page:has(.topbar .vsw) { --ui-app-top: 104px; }
277
273
  }
278
274
 
279
275
  /* Account — avatar + dropdown. Gated: hidden until the app confirms a session