@uniflowed/ui 0.2.0 → 0.3.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/range-calendar.js CHANGED
@@ -7,11 +7,11 @@ import { useControlled } from "./internal/controlled-state.js";
7
7
  import type { Rest } from "./internal/merge-props.js";
8
8
  import type { DateRange } from "./internal/date-range.js";
9
9
  import { validateRange, unavailableInRange } from "./internal/date-range.js";
10
- import { CalendarRoot, CalendarMonth } from "./calendar.js";
10
+ import { Root as CalendarRoot, Month as CalendarMonth } from "./calendar.js";
11
11
  import { visuallyHiddenStyle } from "./internal/visually-hidden-style.js";
12
12
  export type { DateRange } from "./internal/date-range.js";
13
13
 
14
- export component RangeCalendarRoot(
14
+ component RangeCalendarRoot(
15
15
  children?: React.Node = <CalendarMonth />,
16
16
  value?: DateRange | null,
17
17
  defaultValue?: DateRange | null = null,
@@ -77,3 +77,21 @@ export component RangeCalendarRoot(
77
77
  </div>
78
78
  );
79
79
  }
80
+
81
+ /**
82
+ * The parts, under the names the `RangeCalendar` namespace gives them.
83
+ *
84
+ * `index.js` re-exports this module whole — `export * as RangeCalendar from "./range-calendar.js"` —
85
+ * so a caller writes `<RangeCalendar.Root>`, and the namespace is the prefix. Each
86
+ * part is still *declared* as `RangeCalendarRoot`, so React DevTools, a component
87
+ * stack and an error name the part a reader can find rather than one of forty
88
+ * `Root`s.
89
+ */
90
+ export { RangeCalendarRoot as Root };
91
+
92
+ /**
93
+ * The parts `RangeCalendar` shares with `Calendar`, re-exported so the `RangeCalendar`
94
+ * namespace is complete on its own: `<RangeCalendar.Month>` is `Calendar`'s part,
95
+ * not a copy of it.
96
+ */
97
+ export { Month, Day, Previous, Next } from "./calendar.js";
package/resizable.js CHANGED
@@ -165,7 +165,7 @@ hook useResizable(part: string): ResizableState {
165
165
  * `Enter` collapses the pane entirely; a group whose primary pane should never
166
166
  * disappear gives it a floor.
167
167
  */
168
- export component ResizablePanelGroup(
168
+ component ResizablePanelGroup(
169
169
  children: React.Node,
170
170
  value?: number,
171
171
  defaultValue?: number = 50,
@@ -225,7 +225,7 @@ export component ResizablePanelGroup(
225
225
  * caller renders a pane conditionally, and a handle pointing at the wrong pane
226
226
  * is a handle that announces someone else's size.
227
227
  */
228
- export component ResizablePanel(children: React.Node, primary?: boolean = false, ...rest: Rest) {
228
+ component ResizablePanel(children: React.Node, primary?: boolean = false, ...rest: Rest) {
229
229
  const group = useResizable("Resizable.Panel");
230
230
  const passed = withoutComposed(rest, ["style"]);
231
231
  const register = group.registerPrimary;
@@ -260,7 +260,7 @@ export component ResizablePanel(children: React.Node, primary?: boolean = false,
260
260
  * name is announced as "separator", which tells a reader there is a control
261
261
  * here and nothing about what it does.
262
262
  */
263
- export component ResizableHandle(label?: string = "Resize", ...rest: Rest) {
263
+ component ResizableHandle(label?: string = "Resize", ...rest: Rest) {
264
264
  const group = useResizable("Resizable.Handle");
265
265
  const passed = withoutComposed(rest, [
266
266
  "onKeyDown",
@@ -451,3 +451,14 @@ function stepFor(
451
451
  _ => null,
452
452
  };
453
453
  }
454
+
455
+ /**
456
+ * The parts, under the names the `Resizable` namespace gives them.
457
+ *
458
+ * `index.js` re-exports this module whole — `export * as Resizable from "./resizable.js"` —
459
+ * so a caller writes `<Resizable.PanelGroup>`, and the namespace is the prefix. Each
460
+ * part is still *declared* as `ResizablePanelGroup`, so React DevTools, a component
461
+ * stack and an error name the part a reader can find rather than one of forty
462
+ * `PanelGroup`s.
463
+ */
464
+ export { ResizablePanelGroup as PanelGroup, ResizablePanel as Panel, ResizableHandle as Handle };
package/scroll-area.js CHANGED
@@ -103,7 +103,7 @@ hook useScrollArea(part: string): ScrollAreaState {
103
103
  * lands them in it, and a scroll area that has to be scrolled to be read and is
104
104
  * announced as "region" has told them nothing.
105
105
  */
106
- export component ScrollAreaRoot(children: React.Node, label: string, ...rest: Rest) {
106
+ component ScrollAreaRoot(children: React.Node, label: string, ...rest: Rest) {
107
107
  const base = useId();
108
108
  const viewportRef = useRef<HTMLElement | null>(null);
109
109
  const rememberedRef = useRef<Offset>({ x: 0, y: 0 });
@@ -143,7 +143,7 @@ export component ScrollAreaRoot(children: React.Node, label: string, ...rest: Re
143
143
  * scrolls a native overflow container scrolls this one because it is one, and
144
144
  * the component's contribution is the tab stop that lets those keys arrive.
145
145
  */
146
- export component ScrollAreaViewport(children: React.Node, ...rest: Rest) {
146
+ component ScrollAreaViewport(children: React.Node, ...rest: Rest) {
147
147
  const area = useScrollArea("ScrollArea.Viewport");
148
148
  const { rememberedRef, report, viewportRef } = area;
149
149
  const passed = withoutComposed(rest, ["ref"]);
@@ -207,7 +207,7 @@ export component ScrollAreaViewport(children: React.Node, ...rest: Rest) {
207
207
  * measure nothing. `aria-hidden`, because the region it belongs to is already
208
208
  * the thing a reader operates.
209
209
  */
210
- export component ScrollAreaScrollbar(
210
+ component ScrollAreaScrollbar(
211
211
  children?: React.Node,
212
212
  orientation?: Orientation = "vertical",
213
213
  ...rest: Rest
@@ -281,3 +281,14 @@ function fraction(part: number, whole: number): number {
281
281
  }
282
282
  return Math.min(1, Math.max(0, part / whole));
283
283
  }
284
+
285
+ /**
286
+ * The parts, under the names the `ScrollArea` namespace gives them.
287
+ *
288
+ * `index.js` re-exports this module whole — `export * as ScrollArea from "./scroll-area.js"` —
289
+ * so a caller writes `<ScrollArea.Root>`, and the namespace is the prefix. Each
290
+ * part is still *declared* as `ScrollAreaRoot`, so React DevTools, a component
291
+ * stack and an error name the part a reader can find rather than one of forty
292
+ * `Root`s.
293
+ */
294
+ export { ScrollAreaRoot as Root, ScrollAreaViewport as Viewport, ScrollAreaScrollbar as Scrollbar };
package/select.js CHANGED
@@ -252,7 +252,7 @@ const SelectGroupContext: React.Context<SelectGroupState | null> = createContext
252
252
  * `onValueChange`, which is exactly the pair of props below. Neither package
253
253
  * imports the other and neither needs to.
254
254
  */
255
- export component SelectRoot(
255
+ component SelectRoot(
256
256
  children: React.Node,
257
257
  value?: string | null,
258
258
  defaultValue?: string | null = null,
@@ -365,7 +365,7 @@ export component SelectRoot(
365
365
  * shadcn's single `SelectLabel`, which is the group's, has no name for the
366
366
  * field's.
367
367
  */
368
- export component SelectLabel(children: React.Node, ...rest: Rest) {
368
+ component SelectLabel(children: React.Node, ...rest: Rest) {
369
369
  const select = useSelect("Select.Label");
370
370
  const register = select.registerFieldLabel;
371
371
  useEffect(() => {
@@ -392,7 +392,7 @@ export component SelectLabel(children: React.Node, ...rest: Rest) {
392
392
  * forms, and a `<button>` inside a `<form>` submits it by default. A select
393
393
  * that posted the form every time it was opened would be a memorable bug.
394
394
  */
395
- export component SelectTrigger(children: React.Node, ...rest: Rest) {
395
+ component SelectTrigger(children: React.Node, ...rest: Rest) {
396
396
  const select = useSelect("Select.Trigger");
397
397
  const passed = withoutComposed(rest, ["onClick", "onKeyDown", "ref"]);
398
398
 
@@ -550,7 +550,6 @@ export component SelectTrigger(children: React.Node, ...rest: Rest) {
550
550
  event.preventDefault();
551
551
  // The options are not in the document yet, so the keystroke travels
552
552
  // to the commit that renders them.
553
- // uf-lint-disable-next-line react-compiler/immutability
554
553
  select.pendingLandingRef.current = { kind: "typed", key: event.key };
555
554
  select.setOpen(true);
556
555
  return;
@@ -603,7 +602,7 @@ export component SelectTrigger(children: React.Node, ...rest: Rest) {
603
602
  *
604
603
  * Case 3 is a real edge and the way out of it is case 1.
605
604
  */
606
- export component SelectValue(children?: React.Node, placeholder?: React.Node, ...rest: Rest) {
605
+ component SelectValue(children?: React.Node, placeholder?: React.Node, ...rest: Rest) {
607
606
  const select = useSelect("Select.Value");
608
607
  const chosen = select.value;
609
608
 
@@ -626,7 +625,7 @@ export component SelectValue(children?: React.Node, placeholder?: React.Node, ..
626
625
  * The effect below keeps the one invariant this pattern rests on:
627
626
  * `aria-activedescendant` never names an option that is not in the document.
628
627
  */
629
- export component SelectList(
628
+ component SelectList(
630
629
  children: renders* (SelectOption | SelectGroup | SelectSeparator),
631
630
  align?: Align = "start",
632
631
  alignOffset?: number = 0,
@@ -666,8 +665,6 @@ export component SelectList(
666
665
  // render — a change to `children` that no dependency list can describe. Every
667
666
  // write is guarded by a comparison, so it settles after one extra pass rather
668
667
  // than looping.
669
- // This effect measures caller-rendered options after commit.
670
- // uf-lint-disable-next-line react-compiler/immutability
671
668
  useEffect(() => {
672
669
  const list = listRef.current;
673
670
  if (list == null) {
@@ -677,7 +674,6 @@ export component SelectList(
677
674
 
678
675
  const wanted = pendingLandingRef.current;
679
676
  if (wanted != null) {
680
- // uf-lint-disable-next-line react-compiler/immutability
681
677
  pendingLandingRef.current = null;
682
678
  // An `if` rather than a `match` on `wanted.kind`, because matching on a
683
679
  // property does not refine the object that property came from: inside
@@ -751,7 +747,7 @@ export component SelectList(
751
747
  * finds the option in the document rather than in a registry that could
752
748
  * disagree with the page — the reason `internal/roving-focus.js` gives.
753
749
  */
754
- export component SelectOption(
750
+ component SelectOption(
755
751
  value: string,
756
752
  children: React.Node,
757
753
  label?: string,
@@ -840,7 +836,7 @@ export component SelectOption(
840
836
  * fix is to hand the options to the group directly; a wrapper had no effect on
841
837
  * what this renders, because the group's element is the one below.
842
838
  */
843
- export component SelectGroup(children: renders* (SelectOption | SelectGroupLabel), ...rest: Rest) {
839
+ component SelectGroup(children: renders* (SelectOption | SelectGroupLabel), ...rest: Rest) {
844
840
  const base = useId();
845
841
  const [labelled, setLabelled] = useState(false);
846
842
 
@@ -862,7 +858,7 @@ export component SelectGroup(children: renders* (SelectOption | SelectGroupLabel
862
858
  * ordinary content a reader would hear the heading once as the group's name and
863
859
  * again as a stray line of text among the options.
864
860
  */
865
- export component SelectGroupLabel(children: React.Node, ...rest: Rest) {
861
+ component SelectGroupLabel(children: React.Node, ...rest: Rest) {
866
862
  const group = useContext(SelectGroupContext);
867
863
  const register = group?.registerLabel;
868
864
 
@@ -891,7 +887,7 @@ export component SelectGroupLabel(children: React.Node, ...rest: Rest) {
891
887
  * the software rather than the specification. The rule between two groups is
892
888
  * decoration, so it says so and stays out of the tree.
893
889
  */
894
- export component SelectSeparator(...rest: Rest) {
890
+ component SelectSeparator(...rest: Rest) {
895
891
  return <div {...rest} aria-hidden="true" />;
896
892
  }
897
893
 
@@ -899,3 +895,24 @@ export component SelectSeparator(...rest: Rest) {
899
895
  function textOf(element: HTMLElement | null): string {
900
896
  return (element?.textContent ?? "").replace(/\s+/g, " ").trim();
901
897
  }
898
+
899
+ /**
900
+ * The parts, under the names the `Select` namespace gives them.
901
+ *
902
+ * `index.js` re-exports this module whole — `export * as Select from "./select.js"` —
903
+ * so a caller writes `<Select.Root>`, and the namespace is the prefix. Each
904
+ * part is still *declared* as `SelectRoot`, so React DevTools, a component
905
+ * stack and an error name the part a reader can find rather than one of forty
906
+ * `Root`s.
907
+ */
908
+ export {
909
+ SelectRoot as Root,
910
+ SelectLabel as Label,
911
+ SelectTrigger as Trigger,
912
+ SelectValue as Value,
913
+ SelectList as List,
914
+ SelectOption as Option,
915
+ SelectGroup as Group,
916
+ SelectGroupLabel as GroupLabel,
917
+ SelectSeparator as Separator,
918
+ };
package/sheet.js CHANGED
@@ -46,15 +46,15 @@ import { createContext, useContext, useMemo } from "@uniflowed/react";
46
46
  import type { RenderProp, Rest } from "./internal/merge-props.js";
47
47
  import { forwarded } from "./internal/merge-props.js";
48
48
  import {
49
- DialogBody,
50
- DialogClose,
51
- DialogDescription,
52
- DialogFooter,
53
- DialogHeader,
54
- DialogOverlay,
55
- DialogRoot,
56
- DialogTitle,
57
- DialogTrigger,
49
+ Body as DialogBody,
50
+ Close as DialogClose,
51
+ Description as DialogDescription,
52
+ Footer as DialogFooter,
53
+ Header as DialogHeader,
54
+ Overlay as DialogOverlay,
55
+ Root as DialogRoot,
56
+ Title as DialogTitle,
57
+ Trigger as DialogTrigger,
58
58
  } from "./dialog.js";
59
59
 
60
60
  /**
@@ -91,7 +91,7 @@ hook useSheet(part: string): SheetState {
91
91
  }
92
92
 
93
93
  /** The sheet, open or closed. Uncontrolled unless `open` is given. */
94
- export component SheetRoot(
94
+ component SheetRoot(
95
95
  children: React.Node,
96
96
  defaultOpen?: boolean = false,
97
97
  onOpenChange?: (open: boolean) => void,
@@ -110,7 +110,7 @@ export component SheetRoot(
110
110
  }
111
111
 
112
112
  /** What opens it, and what focus comes back to when it closes. */
113
- export component SheetTrigger(children: React.Node, render?: RenderProp, ...rest: Rest) {
113
+ component SheetTrigger(children: React.Node, render?: RenderProp, ...rest: Rest) {
114
114
  return (
115
115
  <DialogTrigger {...forwarded(rest)} render={render}>
116
116
  {children}
@@ -122,7 +122,7 @@ export component SheetTrigger(children: React.Node, render?: RenderProp, ...rest
122
122
  * The backdrop, which knows the edge so a stylesheet does not have to be told
123
123
  * twice.
124
124
  */
125
- export component SheetOverlay(render?: RenderProp, ...rest: Rest) {
125
+ component SheetOverlay(render?: RenderProp, ...rest: Rest) {
126
126
  const sheet = useSheet("Sheet.Overlay");
127
127
  return <DialogOverlay {...forwarded(rest)} data-side={sheet.side} render={render} />;
128
128
  }
@@ -133,7 +133,7 @@ export component SheetOverlay(render?: RenderProp, ...rest: Rest) {
133
133
  * Every modal promise `dialog.js` makes is made here, unchanged. This part adds
134
134
  * `data-side` and nothing else, which is the honest size of the difference.
135
135
  */
136
- export component SheetBody(children: React.Node, render?: RenderProp, ...rest: Rest) {
136
+ component SheetBody(children: React.Node, render?: RenderProp, ...rest: Rest) {
137
137
  const sheet = useSheet("Sheet.Body");
138
138
 
139
139
  return (
@@ -144,7 +144,7 @@ export component SheetBody(children: React.Node, render?: RenderProp, ...rest: R
144
144
  }
145
145
 
146
146
  /** The top of the sheet. See `Dialog.Header` for why it is not a `<header>`. */
147
- export component SheetHeader(children: React.Node, render?: RenderProp, ...rest: Rest) {
147
+ component SheetHeader(children: React.Node, render?: RenderProp, ...rest: Rest) {
148
148
  return (
149
149
  <DialogHeader {...forwarded(rest)} render={render}>
150
150
  {children}
@@ -153,7 +153,7 @@ export component SheetHeader(children: React.Node, render?: RenderProp, ...rest:
153
153
  }
154
154
 
155
155
  /** The bottom of the sheet, where the actions go. */
156
- export component SheetFooter(children: React.Node, render?: RenderProp, ...rest: Rest) {
156
+ component SheetFooter(children: React.Node, render?: RenderProp, ...rest: Rest) {
157
157
  return (
158
158
  <DialogFooter {...forwarded(rest)} render={render}>
159
159
  {children}
@@ -162,7 +162,7 @@ export component SheetFooter(children: React.Node, render?: RenderProp, ...rest:
162
162
  }
163
163
 
164
164
  /** The sheet's accessible name. A modal without one is announced as "dialog". */
165
- export component SheetTitle(children: React.Node, render?: RenderProp, ...rest: Rest) {
165
+ component SheetTitle(children: React.Node, render?: RenderProp, ...rest: Rest) {
166
166
  return (
167
167
  <DialogTitle {...forwarded(rest)} render={render}>
168
168
  {children}
@@ -171,7 +171,7 @@ export component SheetTitle(children: React.Node, render?: RenderProp, ...rest:
171
171
  }
172
172
 
173
173
  /** What the sheet is for, announced after its name. */
174
- export component SheetDescription(children: React.Node, render?: RenderProp, ...rest: Rest) {
174
+ component SheetDescription(children: React.Node, render?: RenderProp, ...rest: Rest) {
175
175
  return (
176
176
  <DialogDescription {...forwarded(rest)} render={render}>
177
177
  {children}
@@ -180,10 +180,31 @@ export component SheetDescription(children: React.Node, render?: RenderProp, ...
180
180
  }
181
181
 
182
182
  /** A button that closes the sheet. */
183
- export component SheetClose(children: React.Node, render?: RenderProp, ...rest: Rest) {
183
+ component SheetClose(children: React.Node, render?: RenderProp, ...rest: Rest) {
184
184
  return (
185
185
  <DialogClose {...forwarded(rest)} render={render}>
186
186
  {children}
187
187
  </DialogClose>
188
188
  );
189
189
  }
190
+
191
+ /**
192
+ * The parts, under the names the `Sheet` namespace gives them.
193
+ *
194
+ * `index.js` re-exports this module whole — `export * as Sheet from "./sheet.js"` —
195
+ * so a caller writes `<Sheet.Root>`, and the namespace is the prefix. Each
196
+ * part is still *declared* as `SheetRoot`, so React DevTools, a component
197
+ * stack and an error name the part a reader can find rather than one of forty
198
+ * `Root`s.
199
+ */
200
+ export {
201
+ SheetRoot as Root,
202
+ SheetTrigger as Trigger,
203
+ SheetOverlay as Overlay,
204
+ SheetBody as Body,
205
+ SheetHeader as Header,
206
+ SheetFooter as Footer,
207
+ SheetTitle as Title,
208
+ SheetDescription as Description,
209
+ SheetClose as Close,
210
+ };
package/sidebar.js CHANGED
@@ -57,8 +57,13 @@ import { useMediaQuery } from "@uniflowed/hooks/browser";
57
57
 
58
58
  import type { RenderProp, Rest } from "./internal/merge-props.js";
59
59
  import { composeHandlers, forwarded, withProps, withoutComposed } from "./internal/merge-props.js";
60
- import { SheetBody, SheetOverlay, SheetRoot, SheetTrigger } from "./sheet.js";
61
- import { TooltipBody, TooltipRoot, TooltipTrigger } from "./tooltip.js";
60
+ import {
61
+ Body as SheetBody,
62
+ Overlay as SheetOverlay,
63
+ Root as SheetRoot,
64
+ Trigger as SheetTrigger,
65
+ } from "./sheet.js";
66
+ import { Body as TooltipBody, Root as TooltipRoot, Trigger as TooltipTrigger } from "./tooltip.js";
62
67
  import { useControlled } from "./internal/controlled-state.js";
63
68
 
64
69
  /**
@@ -115,7 +120,7 @@ hook useSidebar(part: string): SidebarState {
115
120
  * is the sheet's trigger and focus goes back to it — which is the half of the
116
121
  * transition a wrapper around only the navigation could not do.
117
122
  */
118
- export component SidebarRoot(
123
+ component SidebarRoot(
119
124
  children: React.Node,
120
125
  defaultOpen?: boolean = true,
121
126
  narrowQuery?: string = NARROW,
@@ -167,7 +172,7 @@ export component SidebarRoot(
167
172
  * id nothing has tells a reader there is somewhere to go and has nowhere to
168
173
  * send them.
169
174
  */
170
- export component SidebarTrigger(children: React.Node, ...rest: Rest) {
175
+ component SidebarTrigger(children: React.Node, ...rest: Rest) {
171
176
  const sidebar = useSidebar("Sidebar.Trigger");
172
177
  const passed = withoutComposed(rest, ["onClick"]);
173
178
  const named = sidebar.present ? `${sidebar.base}-nav` : undefined;
@@ -208,12 +213,7 @@ export component SidebarTrigger(children: React.Node, ...rest: Rest) {
208
213
  * announced as "navigation" — and a page with two of those has told the reader
209
214
  * there are two and which is which is a guess.
210
215
  */
211
- export component SidebarBody(
212
- children: React.Node,
213
- label: string,
214
- sheetProps?: Rest,
215
- ...rest: Rest
216
- ) {
216
+ component SidebarBody(children: React.Node, label: string, sheetProps?: Rest, ...rest: Rest) {
217
217
  const sidebar = useSidebar("Sidebar.Body");
218
218
  const nav = (
219
219
  <nav
@@ -243,12 +243,12 @@ export component SidebarBody(
243
243
  }
244
244
 
245
245
  /** The top of the sidebar, as a place to put styles. See `Dialog.Header`. */
246
- export component SidebarHeader(children: React.Node, ...rest: Rest) {
246
+ component SidebarHeader(children: React.Node, ...rest: Rest) {
247
247
  return <div {...rest}>{children}</div>;
248
248
  }
249
249
 
250
250
  /** The bottom of the sidebar. See `Sidebar.Header`. */
251
- export component SidebarFooter(children: React.Node, ...rest: Rest) {
251
+ component SidebarFooter(children: React.Node, ...rest: Rest) {
252
252
  return <div {...rest}>{children}</div>;
253
253
  }
254
254
 
@@ -267,7 +267,7 @@ export component SidebarFooter(children: React.Node, ...rest: Rest) {
267
267
  * `navigation-menu.js`, which is the same argument at the scale of a whole
268
268
  * menu.
269
269
  */
270
- export component SidebarItem(
270
+ component SidebarItem(
271
271
  children: React.Node,
272
272
  label: string,
273
273
  render?: RenderProp,
@@ -275,11 +275,8 @@ export component SidebarItem(
275
275
  ...rest: Rest
276
276
  ) {
277
277
  const sidebar = useSidebar("Sidebar.Item");
278
- // This removes the caller's ref from rest props; it does not read a ref value.
279
- // uf-lint-disable-next-line react-compiler/refs
280
278
  const passed = withoutComposed(rest, ["ref"]);
281
279
  // The forwarded ref is passed through to whichever entry wrapper renders.
282
- // uf-lint-disable-next-line react-compiler/refs
283
280
  const forwardedRef = rest.ref;
284
281
  const mine: Rest = {
285
282
  "aria-label": sidebar.collapsed ? label : undefined,
@@ -318,3 +315,21 @@ export component SidebarItem(
318
315
  </TooltipRoot>
319
316
  );
320
317
  }
318
+
319
+ /**
320
+ * The parts, under the names the `Sidebar` namespace gives them.
321
+ *
322
+ * `index.js` re-exports this module whole — `export * as Sidebar from "./sidebar.js"` —
323
+ * so a caller writes `<Sidebar.Root>`, and the namespace is the prefix. Each
324
+ * part is still *declared* as `SidebarRoot`, so React DevTools, a component
325
+ * stack and an error name the part a reader can find rather than one of forty
326
+ * `Root`s.
327
+ */
328
+ export {
329
+ SidebarRoot as Root,
330
+ SidebarTrigger as Trigger,
331
+ SidebarHeader as Header,
332
+ SidebarBody as Body,
333
+ SidebarFooter as Footer,
334
+ SidebarItem as Item,
335
+ };
package/skeleton.js CHANGED
@@ -92,7 +92,7 @@ import { withProps } from "./internal/merge-props.js";
92
92
  * beside it, mounted by this component, because that timing is the accessibility
93
93
  * contract rather than markup the caller can safely recreate by sight.
94
94
  */
95
- export component SkeletonRoot(
95
+ component SkeletonRoot(
96
96
  children: React.Node,
97
97
  busy?: boolean = true,
98
98
  label?: string = "Loading…",
@@ -114,7 +114,6 @@ export component SkeletonRoot(
114
114
  return;
115
115
  }
116
116
  // The live-region text changes after commit so assistive tech can announce it.
117
- // uf-lint-disable-next-line react-compiler/set-state-in-effect
118
117
  setMessage(waited.current ? doneLabel : "");
119
118
  }, [busy, doneLabel, label]);
120
119
 
@@ -154,10 +153,21 @@ export component SkeletonRoot(
154
153
  * `render` changes the placeholder element, not the fact that it is hidden
155
154
  * from the accessibility tree.
156
155
  */
157
- export component SkeletonBox(children?: React.Node, render?: RenderProp, ...rest: Rest) {
156
+ component SkeletonBox(children?: React.Node, render?: RenderProp, ...rest: Rest) {
158
157
  const props = withProps(rest, { "aria-hidden": "true", children });
159
158
  if (render != null) {
160
159
  return render(props);
161
160
  }
162
161
  return <div {...props} />;
163
162
  }
163
+
164
+ /**
165
+ * The parts, under the names the `Skeleton` namespace gives them.
166
+ *
167
+ * `index.js` re-exports this module whole — `export * as Skeleton from "./skeleton.js"` —
168
+ * so a caller writes `<Skeleton.Root>`, and the namespace is the prefix. Each
169
+ * part is still *declared* as `SkeletonRoot`, so React DevTools, a component
170
+ * stack and an error name the part a reader can find rather than one of forty
171
+ * `Root`s.
172
+ */
173
+ export { SkeletonRoot as Root, SkeletonBox as Box };
package/slider.js CHANGED
@@ -121,7 +121,7 @@ hook useSlider(part: string): SliderState {
121
121
  * with two thumbs, and a `number | [number, number]` prop would make every
122
122
  * caller narrow a union to read their own value back.
123
123
  */
124
- export component SliderRoot(
124
+ component SliderRoot(
125
125
  children: React.Node,
126
126
  value?: $ReadOnlyArray<number>,
127
127
  defaultValue?: $ReadOnlyArray<number> = [0],
@@ -209,7 +209,7 @@ export component SliderRoot(
209
209
  * wanders off the track — which every drag does — keeps arriving here instead
210
210
  * of being lost to whatever it wandered over.
211
211
  */
212
- export component SliderTrack(children: React.Node, render?: RenderProp, ...rest: Rest) {
212
+ component SliderTrack(children: React.Node, render?: RenderProp, ...rest: Rest) {
213
213
  const slider = useSlider("Slider.Track");
214
214
  const passed = withoutComposed(rest, ["onPointerDown", "onPointerMove", "onPointerUp", "ref"]);
215
215
  const dragging = useRef<number | null>(null);
@@ -291,7 +291,7 @@ export component SliderTrack(children: React.Node, render?: RenderProp, ...rest:
291
291
  * is told the value by the thumb and telling them again here would be telling
292
292
  * them twice.
293
293
  */
294
- export component SliderRange(render?: RenderProp, ...rest: Rest) {
294
+ component SliderRange(render?: RenderProp, ...rest: Rest) {
295
295
  const slider = useSlider("Slider.Range");
296
296
  const passed = withoutComposed(rest, ["style"]);
297
297
  const ends = [...slider.values].sort((first, second) => first - second);
@@ -323,7 +323,7 @@ export component SliderRange(render?: RenderProp, ...rest: Rest) {
323
323
  * "Maximum" told apart is the whole difference between a control a reader can
324
324
  * operate and two identical "slider"s.
325
325
  */
326
- export component SliderThumb(index?: number = 0, render?: RenderProp, ...rest: Rest) {
326
+ component SliderThumb(index?: number = 0, render?: RenderProp, ...rest: Rest) {
327
327
  const slider = useSlider("Slider.Thumb");
328
328
  const passed = withoutComposed(rest, ["onKeyDown", "style"]);
329
329
  const value = slider.values[index] ?? slider.min;
@@ -409,3 +409,14 @@ function boundsOf(
409
409
  const above = index < values.length - 1 ? values[index + 1] : undefined;
410
410
  return [below ?? min, above ?? max];
411
411
  }
412
+
413
+ /**
414
+ * The parts, under the names the `Slider` namespace gives them.
415
+ *
416
+ * `index.js` re-exports this module whole — `export * as Slider from "./slider.js"` —
417
+ * so a caller writes `<Slider.Root>`, and the namespace is the prefix. Each
418
+ * part is still *declared* as `SliderRoot`, so React DevTools, a component
419
+ * stack and an error name the part a reader can find rather than one of forty
420
+ * `Root`s.
421
+ */
422
+ export { SliderRoot as Root, SliderTrack as Track, SliderRange as Range, SliderThumb as Thumb };