@danxbot/ui 3.10.1 → 3.12.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.
@@ -20,6 +20,16 @@ export interface MenuProps {
20
20
  children: ReactNode;
21
21
  }
22
22
  export declare function Menu({ trigger, side, align, open, onOpenChange, className, children, }: MenuProps): import("react").JSX.Element;
23
+ /**
24
+ * Neutral, or destructive.
25
+ *
26
+ * The same two-value union `IconButtonTone` declares, and named to match it
27
+ * rather than to be exhaustive: a menu row is not a palette, and every tone
28
+ * beyond "this one deletes something" would be a colour choice rather than a
29
+ * property of the action. `Badge` has seven because a badge's whole job is to
30
+ * carry a state; a menu item's job is to be picked.
31
+ */
32
+ export type MenuItemTone = "neutral" | "danger";
23
33
  export interface MenuItemProps extends Omit<BaseMenu.Item.Props, "className"> {
24
34
  className?: string;
25
35
  /**
@@ -30,9 +40,24 @@ export interface MenuItemProps extends Omit<BaseMenu.Item.Props, "className"> {
30
40
  * a tick is not a state a pointer can see it is already on.
31
41
  */
32
42
  selected?: boolean;
43
+ /**
44
+ * `danger` marks the row destructive. Resting state is unchanged.
45
+ *
46
+ * Same sentence as `IconButton.tone`, and the same contract behind it — the
47
+ * row is quiet until approached, and "approached" here includes arrowing onto
48
+ * it, which a `hover:` rule cannot see. See `DANGER_ITEM` above for why that
49
+ * distinction is the reason this lives in the library rather than in each
50
+ * consumer's stylesheet.
51
+ *
52
+ * A DANGER ROW THAT IS ALSO `selected` DRAWS AS SELECTED. The two are merged
53
+ * in that order deliberately: "this is the one you are on" is the more urgent
54
+ * of the two things to say, and a destructive action is a poor candidate for
55
+ * being the current choice in the first place.
56
+ */
57
+ tone?: MenuItemTone;
33
58
  ref?: Ref<HTMLDivElement>;
34
59
  }
35
- export declare function MenuItem({ className, selected, children, ref, ...props }: MenuItemProps): import("react").JSX.Element;
60
+ export declare function MenuItem({ className, selected, tone, children, ref, ...props }: MenuItemProps): import("react").JSX.Element;
36
61
  export interface MenuRadioGroupProps extends Omit<BaseMenu.RadioGroup.Props, "className"> {
37
62
  className?: string;
38
63
  }
@@ -18,6 +18,19 @@ export interface PopoverProps {
18
18
  * documentation surface cannot dispatch a click.
19
19
  */
20
20
  defaultOpen?: boolean;
21
+ /**
22
+ * Told when the popup opens and when it closes. Uncontrolled still — this
23
+ * OBSERVES the state Base UI owns rather than taking it over, which is why
24
+ * there is no `open` prop beside it.
25
+ *
26
+ * `Collapsible`, `Dialog` and `Menu` all already carry this exact signature;
27
+ * the popover was the one overlay a consumer could not hear. The reason to
28
+ * hear it is almost never styling — it is WORK: a panel whose contents cost
29
+ * a request must not pay for that request while it is shut, and a page of a
30
+ * hundred closed popovers that each fetched on mount is a hundred requests
31
+ * for the one panel somebody eventually opens.
32
+ */
33
+ onOpenChange?: (open: boolean) => void;
21
34
  /**
22
35
  * Names the popup for assistive technology.
23
36
  *
@@ -30,7 +43,7 @@ export interface PopoverProps {
30
43
  "aria-labelledby"?: string;
31
44
  "aria-label"?: string;
32
45
  }
33
- export declare function Popover({ trigger, side, align, arrow, className, children, ref, defaultOpen, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabel, }: PopoverProps): import("react").JSX.Element;
46
+ export declare function Popover({ trigger, side, align, arrow, className, children, ref, defaultOpen, onOpenChange, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabel, }: PopoverProps): import("react").JSX.Element;
34
47
  /** Closes the nearest Popover. */
35
48
  export declare function PopoverClose({ children }: {
36
49
  children: ReactNode;
@@ -34,7 +34,7 @@ declare const record: import("tailwind-variants").TVReturnType<{
34
34
  identifier: string;
35
35
  title: string;
36
36
  subtitle: string;
37
- badges: string;
37
+ badges: string[];
38
38
  metrics: string;
39
39
  metricLabel: string;
40
40
  metricValue: string;
@@ -72,7 +72,7 @@ declare const record: import("tailwind-variants").TVReturnType<{
72
72
  identifier: string;
73
73
  title: string;
74
74
  subtitle: string;
75
- badges: string;
75
+ badges: string[];
76
76
  metrics: string;
77
77
  metricLabel: string;
78
78
  metricValue: string;
@@ -110,7 +110,7 @@ declare const record: import("tailwind-variants").TVReturnType<{
110
110
  identifier: string;
111
111
  title: string;
112
112
  subtitle: string;
113
- badges: string;
113
+ badges: string[];
114
114
  metrics: string;
115
115
  metricLabel: string;
116
116
  metricValue: string;
@@ -136,7 +136,7 @@ declare const recordCard: import("tailwind-variants").TVReturnType<{
136
136
  handle: string;
137
137
  eyebrow: string;
138
138
  title: string;
139
- badges: string;
139
+ badges: string[];
140
140
  media: string;
141
141
  meta: string;
142
142
  }, undefined, {
@@ -159,7 +159,7 @@ declare const recordCard: import("tailwind-variants").TVReturnType<{
159
159
  handle: string;
160
160
  eyebrow: string;
161
161
  title: string;
162
- badges: string;
162
+ badges: string[];
163
163
  media: string;
164
164
  meta: string;
165
165
  }, import("tailwind-variants").TVReturnTypeLike<{
@@ -182,7 +182,7 @@ declare const recordCard: import("tailwind-variants").TVReturnType<{
182
182
  handle: string;
183
183
  eyebrow: string;
184
184
  title: string;
185
- badges: string;
185
+ badges: string[];
186
186
  media: string;
187
187
  meta: string;
188
188
  }>>;
@@ -273,7 +273,14 @@ export interface RecordCardBadgesProps {
273
273
  }
274
274
  /** A wrapping row for a SMALL set of status/priority badges — `Badge` from
275
275
  * this same library, composed by the consumer. This component supplies only
276
- * the row layout; it has no opinion on how many badges is too many. */
276
+ * the row layout; it has no opinion on how many badges is too many.
277
+ *
278
+ * IT DOES HAVE AN OPINION ON HOW WIDE. The row can never exceed its card, and
279
+ * a single badge can never exceed the row — the containment is the row's job
280
+ * because the consumer's badge cannot do it from inside. `BADGE_ROW` above
281
+ * carries the measurements and the one limitation (it clips; it does not
282
+ * ellipsize). A caller's `className` still wins over everything here, including
283
+ * `shrink-0`, which is exactly the class that made the reported card leak. */
277
284
  export declare function RecordCardBadges({ className, children, ref }: RecordCardBadgesProps): import("react").JSX.Element;
278
285
  export interface RecordCardMediaProps extends VariantProps<typeof recordCard> {
279
286
  className?: string;
@@ -37,7 +37,19 @@ export interface StatusSelectProps<Value extends string = string> {
37
37
  value: Value;
38
38
  options: StatusOption<Value>[];
39
39
  onValueChange: (value: Value) => void;
40
- size?: "sm" | "md";
40
+ /**
41
+ * The same three steps `Badge` has, because the trigger IS a Badge.
42
+ *
43
+ * It stopped at `md` for no reason anybody could point at, and the cost was
44
+ * paid one surface at a time: a consumer that wanted the status at the weight
45
+ * of a page heading pinned the metrics by hand, beside a component that
46
+ * already knew how to draw them and would have kept them in step with the
47
+ * rest of the scale for free.
48
+ *
49
+ * The chevron travels with it — see the trigger below. Defaults to `sm`,
50
+ * unchanged: this is a step ADDED to the top of the scale, not a new default.
51
+ */
52
+ size?: "sm" | "md" | "lg";
41
53
  /** Accessible name for the trigger — there is no visible label otherwise. */
42
54
  "aria-label"?: string;
43
55
  disabled?: boolean;
@@ -1,4 +1,46 @@
1
1
  export interface ThemeMenuProps {
2
+ /**
3
+ * Restyles the POPUP, not the trigger — see `triggerClassName` below.
4
+ *
5
+ * Stated rather than left to be discovered, because the discovery is
6
+ * expensive and has already been made once. This is the only styling prop
7
+ * this component had, `Popover` forwards it to `Popover.Popup`, and a caller
8
+ * reaching for "the class that styles this component" reasonably expects it
9
+ * on the button they can see. It is kept where it is because a consumer sizes
10
+ * the panel with it; moving it would be a silent breaking change wearing a
11
+ * bug fix's clothes.
12
+ */
2
13
  className?: string;
14
+ /**
15
+ * Restyles the TRIGGER.
16
+ *
17
+ * Named after `Collapsible.triggerClassName`, which exists for exactly this
18
+ * situation one component over: a component that supplies its own trigger has
19
+ * two boxes a caller might mean, and only one of them can have `className`.
20
+ * Prefer `iconOnly` below when the goal is the icon-only shape — that is a
21
+ * MODE this component knows how to enter, and re-drawing it from classes
22
+ * means re-deriving `Button`'s square box by hand.
23
+ */
24
+ triggerClassName?: string;
25
+ /**
26
+ * Drop the "Appearance" label and render the trigger as a square icon button.
27
+ *
28
+ * Named after `Button.iconOnly`, which is the variant it forwards to — the
29
+ * width is pinned to the control height there, so the hit area stays square
30
+ * and can never fall below the tap minimum.
31
+ *
32
+ * WHY A MODE AND NOT A CLASS. The label is `hidden sm:inline`: present from
33
+ * 640px up, which is most screens the app runs on. So "make it icon-only"
34
+ * from the outside means a descendant selector plus an `!` to out-specify a
35
+ * responsive rule, next to a hand-copy of `Button`'s `px-0 aspect-square` —
36
+ * which is what the consuming app that reported this shipped, and which
37
+ * drifts the moment either of those changes here. The mode removes the label
38
+ * from the tree instead of fighting a media query for it.
39
+ *
40
+ * The accessible name is unaffected: `aria-label="Appearance settings"` is on
41
+ * the button in both modes, and it is what a screen reader announces either
42
+ * way — the visible text was never the name.
43
+ */
44
+ iconOnly?: boolean;
3
45
  }
4
- export declare function ThemeMenu({ className }: ThemeMenuProps): import("react").JSX.Element;
46
+ export declare function ThemeMenu({ className, triggerClassName, iconOnly }: ThemeMenuProps): import("react").JSX.Element;
@@ -59,6 +59,24 @@ export interface ProvenanceDisclosureProps {
59
59
  * edges and does not want a second one.
60
60
  */
61
61
  triggerContent?: ReactNode;
62
+ /**
63
+ * Called with `true` when the panel opens and `false` when it closes.
64
+ *
65
+ * The signature `Collapsible`, `Dialog`, `Menu` and `Popover` all use, for
66
+ * the reason a fourth spelling would be worse than a familiar one: a
67
+ * consumer already knows what `onOpenChange` does everywhere else here.
68
+ *
69
+ * Purely an observation. The popover stays uncontrolled, so this does not
70
+ * make the caller responsible for closing it, for returning focus, or for
71
+ * escape — pass the callback and nothing else about the component moves.
72
+ *
73
+ * The reason it exists is the fetch: a value's citations, its source pages,
74
+ * its audit trail are usually a request, and this is the only moment at
75
+ * which a consumer knows that request is now worth making. It does NOT fire
76
+ * on mount — see the note at the top of this file for why that is the load-
77
+ * bearing half of the guarantee, not a footnote to it.
78
+ */
79
+ onOpenChange?: (open: boolean) => void;
62
80
  className?: string;
63
81
  }
64
- export declare function ProvenanceDisclosure({ record, actions, emptyLabel, redactedLabel, triggerBadge, valueWrap, triggerContent, className, }: ProvenanceDisclosureProps): import("react").JSX.Element;
82
+ export declare function ProvenanceDisclosure({ record, actions, emptyLabel, redactedLabel, triggerBadge, valueWrap, triggerContent, onOpenChange, className, }: ProvenanceDisclosureProps): import("react").JSX.Element;
@@ -29,7 +29,7 @@ export { Checkbox, Switch, Radio, RadioGroup, CheckboxField, SwitchField, RadioF
29
29
  export { Dialog, DialogClose, AlertDialog, type DialogProps, type AlertDialogProps, } from "./components/Dialog";
30
30
  export { Popover, PopoverClose, Tooltip, TooltipProvider, type PopoverProps, type TooltipProps, } from "./components/Popover";
31
31
  export { Toaster, ToastProvider, useToast, type ToasterProps, type ToastProviderProps, type ToastOptions, type ToastTone, } from "./components/Toast";
32
- export { Menu, MenuItem, MenuGroup, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSub, type MenuProps, type MenuItemProps, type MenuGroupProps, type MenuRadioGroupProps, type MenuRadioItemProps, type MenuSubProps, } from "./components/Menu";
32
+ export { Menu, MenuItem, MenuGroup, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSub, type MenuProps, type MenuItemProps, type MenuItemTone, type MenuGroupProps, type MenuRadioGroupProps, type MenuRadioItemProps, type MenuSubProps, } from "./components/Menu";
33
33
  export { ThemeMenu, type ThemeMenuProps } from "./components/ThemeMenu";
34
34
  export { AppShell, type AppShellProps, type NavItem, type NavSection, } from "./components/AppShell";
35
35
  export { FileUpload, type FileUploadProps, type UploadFile } from "./components/FileUpload";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "3.10.1",
3
+ "version": "3.12.0",
4
4
  "type": "module",
5
5
  "description": "Danxbot — a domain-agnostic React design system with motion as a first-class primitive.",
6
6
  "license": "MIT",