@danxbot/ui 7.3.1 → 7.4.1

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.
@@ -19,6 +19,22 @@ declare const numberInput: import("tailwind-variants").TVReturnType<{
19
19
  stepper: string;
20
20
  };
21
21
  };
22
+ /**
23
+ * Centered is the field's own long-standing look — a value read the way a
24
+ * calculator or a stepper shows one, and unchanged for every existing
25
+ * caller (SG-907 adds this variant; it does not touch the default). A
26
+ * data-entry field reads the opposite way: left-aligned, like every other
27
+ * text box beside it, so a column of them lines up on their leading edge
28
+ * rather than swimming around a shared centre.
29
+ */
30
+ align: {
31
+ center: {
32
+ input: string;
33
+ };
34
+ start: {
35
+ input: string;
36
+ };
37
+ };
22
38
  }, {
23
39
  group: string[];
24
40
  input: string[];
@@ -42,6 +58,22 @@ declare const numberInput: import("tailwind-variants").TVReturnType<{
42
58
  stepper: string;
43
59
  };
44
60
  };
61
+ /**
62
+ * Centered is the field's own long-standing look — a value read the way a
63
+ * calculator or a stepper shows one, and unchanged for every existing
64
+ * caller (SG-907 adds this variant; it does not touch the default). A
65
+ * data-entry field reads the opposite way: left-aligned, like every other
66
+ * text box beside it, so a column of them lines up on their leading edge
67
+ * rather than swimming around a shared centre.
68
+ */
69
+ align: {
70
+ center: {
71
+ input: string;
72
+ };
73
+ start: {
74
+ input: string;
75
+ };
76
+ };
45
77
  }, {
46
78
  group: string[];
47
79
  input: string[];
@@ -65,13 +97,50 @@ declare const numberInput: import("tailwind-variants").TVReturnType<{
65
97
  stepper: string;
66
98
  };
67
99
  };
100
+ /**
101
+ * Centered is the field's own long-standing look — a value read the way a
102
+ * calculator or a stepper shows one, and unchanged for every existing
103
+ * caller (SG-907 adds this variant; it does not touch the default). A
104
+ * data-entry field reads the opposite way: left-aligned, like every other
105
+ * text box beside it, so a column of them lines up on their leading edge
106
+ * rather than swimming around a shared centre.
107
+ */
108
+ align: {
109
+ center: {
110
+ input: string;
111
+ };
112
+ start: {
113
+ input: string;
114
+ };
115
+ };
68
116
  }, {
69
117
  group: string[];
70
118
  input: string[];
71
119
  stepper: string[];
72
120
  scrub: string;
73
121
  }>>;
74
- export interface NumberInputProps extends Omit<NumberField.Root.Props, "className" | "render">, VariantProps<typeof numberInput> {
122
+ /**
123
+ * The five props below are declared here, EXPLICITLY, rather than left to flow through the
124
+ * `Omit<NumberField.Root.Props, ...>` this interface otherwise extends (SG-907).
125
+ *
126
+ * `NumberField.Root` renders a `<div>` — `aria-label`/`aria-labelledby`/`aria-describedby` are
127
+ * universal ARIA attributes TypeScript accepts on any element, so they type-checked and silently
128
+ * landed on that wrapping div, never reaching the `<input>` a screen reader (or
129
+ * `getByRole("textbox", { name })`) actually reads the accessible name from. `placeholder` was
130
+ * worse: `NumberFieldRootProps` never declared it at all, so a caller could not pass one through
131
+ * this component regardless of which element it would have reached. Both are fixed the same way
132
+ * — destructured out of the props this component accepts from its caller, forwarded to
133
+ * `NumberField.Input` below, which is exactly where `<input>`-shaped props belong.
134
+ *
135
+ * `name` stays out of this list on purpose. It is already declared on `NumberFieldRootProps`
136
+ * itself (not inherited from the generic div props the way the three ARIA attributes are), and
137
+ * Base UI's own `NumberField.Root` reads it to name a HIDDEN native `<input type="hidden">` it
138
+ * renders for real form submission — never the visible text `<input>`, which the library
139
+ * deliberately gives no `name` of its own so a form posts the field exactly once. Moving `name`
140
+ * onto the visible input here would give the form two same-named inputs instead of fixing
141
+ * anything.
142
+ */
143
+ export interface NumberInputProps extends Omit<NumberField.Root.Props, "className" | "render" | "aria-label" | "aria-labelledby" | "aria-describedby">, VariantProps<typeof numberInput> {
75
144
  className?: string;
76
145
  /** Hide the +/− buttons — for a field driven by typing or scrubbing alone. */
77
146
  hideSteppers?: boolean;
@@ -83,6 +152,26 @@ export interface NumberInputProps extends Omit<NumberField.Root.Props, "classNam
83
152
  */
84
153
  scrubLabel?: string;
85
154
  ref?: Ref<HTMLDivElement>;
155
+ /** The accessible name — reaches the `<input>` itself, never the wrapping group (SG-907). */
156
+ "aria-label"?: string;
157
+ /** @see `aria-label`'s own note above — same fix, same reason. */
158
+ "aria-labelledby"?: string;
159
+ /** @see `aria-label`'s own note above — same fix, same reason. */
160
+ "aria-describedby"?: string;
161
+ /** What an empty field says. Reaches the `<input>` — `NumberFieldRootProps` never had one. */
162
+ placeholder?: string;
163
+ /**
164
+ * Whether a decimal separator may be typed or pasted at all.
165
+ *
166
+ * Base UI's own `NumberField` keeps the decimal key typeable even under an integer-only
167
+ * `format` (its own source: "must stay typeable regardless of whether the format renders a
168
+ * fraction") and instead ROUNDS a typed fraction away on blur — `3.7` silently becomes `4`,
169
+ * which is a value the reviewer never typed. `allowDecimal={false}` refuses the keystroke (and
170
+ * a pasted fraction) outright, so nothing the reviewer entered is ever changed behind their
171
+ * back. Defaults to `false` exactly when `format?.maximumFractionDigits === 0` — an
172
+ * integer-only format refuses a decimal point unless a caller explicitly asks otherwise.
173
+ */
174
+ allowDecimal?: boolean;
86
175
  }
87
- export declare function NumberInput({ size, className, hideSteppers, scrubLabel, ref, ...props }: NumberInputProps): import("react").JSX.Element;
176
+ export declare function NumberInput({ size, align, className, hideSteppers, scrubLabel, ref, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, placeholder, allowDecimal, onKeyDown, onPaste, ...props }: NumberInputProps): import("react").JSX.Element;
88
177
  export {};
@@ -0,0 +1,69 @@
1
+ import { type VariantProps } from "tailwind-variants";
2
+ declare const track: import("tailwind-variants").TVReturnType<{
3
+ size: {
4
+ sm: "h-(--tri-h) w-(--tri-w) [--tri-h:calc(1.25rem*var(--ui-scale))] [--tri-w:calc(3.125rem*var(--ui-scale))]";
5
+ md: "h-(--tri-h) w-(--tri-w) [--tri-h:calc(1.5rem*var(--ui-scale))] [--tri-w:calc(3.75rem*var(--ui-scale))]";
6
+ lg: "h-(--tri-h) w-(--tri-w) [--tri-h:calc(1.75rem*var(--ui-scale))] [--tri-w:calc(4.375rem*var(--ui-scale))]";
7
+ };
8
+ state: {
9
+ no: "border-border bg-switch-track-off";
10
+ unset: "border-dashed border-border-strong bg-transparent";
11
+ yes: "border-accent bg-accent";
12
+ };
13
+ disabled: {
14
+ true: "cursor-not-allowed opacity-45";
15
+ false: "";
16
+ };
17
+ }, undefined, string[], {
18
+ size: {
19
+ sm: "h-(--tri-h) w-(--tri-w) [--tri-h:calc(1.25rem*var(--ui-scale))] [--tri-w:calc(3.125rem*var(--ui-scale))]";
20
+ md: "h-(--tri-h) w-(--tri-w) [--tri-h:calc(1.5rem*var(--ui-scale))] [--tri-w:calc(3.75rem*var(--ui-scale))]";
21
+ lg: "h-(--tri-h) w-(--tri-w) [--tri-h:calc(1.75rem*var(--ui-scale))] [--tri-w:calc(4.375rem*var(--ui-scale))]";
22
+ };
23
+ state: {
24
+ no: "border-border bg-switch-track-off";
25
+ unset: "border-dashed border-border-strong bg-transparent";
26
+ yes: "border-accent bg-accent";
27
+ };
28
+ disabled: {
29
+ true: "cursor-not-allowed opacity-45";
30
+ false: "";
31
+ };
32
+ }, undefined, import("tailwind-variants").TVReturnTypeLike<{
33
+ size: {
34
+ sm: "h-(--tri-h) w-(--tri-w) [--tri-h:calc(1.25rem*var(--ui-scale))] [--tri-w:calc(3.125rem*var(--ui-scale))]";
35
+ md: "h-(--tri-h) w-(--tri-w) [--tri-h:calc(1.5rem*var(--ui-scale))] [--tri-w:calc(3.75rem*var(--ui-scale))]";
36
+ lg: "h-(--tri-h) w-(--tri-w) [--tri-h:calc(1.75rem*var(--ui-scale))] [--tri-w:calc(4.375rem*var(--ui-scale))]";
37
+ };
38
+ state: {
39
+ no: "border-border bg-switch-track-off";
40
+ unset: "border-dashed border-border-strong bg-transparent";
41
+ yes: "border-accent bg-accent";
42
+ };
43
+ disabled: {
44
+ true: "cursor-not-allowed opacity-45";
45
+ false: "";
46
+ };
47
+ }, undefined>>;
48
+ export type TriStateSwitchSize = NonNullable<VariantProps<typeof track>["size"]>;
49
+ export interface TriStateSwitchProps {
50
+ /** `true` Yes, `false` No, `null` not answered. */
51
+ value: boolean | null;
52
+ onValueChange: (value: boolean | null) => void;
53
+ /** The question being answered — the group's accessible name. Required. */
54
+ "aria-label": string;
55
+ /** The words for each stop, read aloud and shown in the caption. */
56
+ labels?: {
57
+ yes?: string;
58
+ no?: string;
59
+ unset?: string;
60
+ };
61
+ /** Shows the current state's word beside the track. @default true */
62
+ showCaption?: boolean;
63
+ disabled?: boolean;
64
+ /** @default "md" */
65
+ size?: TriStateSwitchSize;
66
+ className?: string;
67
+ }
68
+ export declare function TriStateSwitch({ value, onValueChange, "aria-label": ariaLabel, labels, showCaption, disabled, size, className, }: TriStateSwitchProps): import("react").JSX.Element;
69
+ export {};
@@ -27,6 +27,7 @@ export { SettingRow, SettingGroup, type SettingRowProps, type SettingGroupProps,
27
27
  export { DescriptionList, DescriptionListItem, type DescriptionListProps, type DescriptionListItemProps, type DescriptionListEntry, } from "./components/DescriptionList";
28
28
  export { ConnectionCard, type ConnectionCardProps, type ConnectionHealth, } from "./components/ConnectionCard";
29
29
  export { Checkbox, Switch, Radio, RadioGroup, CheckboxField, SwitchField, RadioField, RadioCard, type CheckboxProps, type SwitchProps, type RadioProps, type RadioGroupProps, type CheckboxFieldProps, type SwitchFieldProps, type RadioFieldProps, type RadioCardProps, } from "./components/Choice";
30
+ export { TriStateSwitch, type TriStateSwitchProps, type TriStateSwitchSize, } from "./components/TriStateSwitch";
30
31
  export { Dialog, DialogClose, AlertDialog, type DialogProps, type AlertDialogProps, } from "./components/Dialog";
31
32
  export { Popover, PopoverClose, Tooltip, TooltipProvider, type PopoverProps, type TooltipProps, } from "./components/Popover";
32
33
  export { Toaster, ToastProvider, useToast, type ToasterProps, type ToastProviderProps, type ToastOptions, type ToastTone, } from "./components/Toast";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "7.3.1",
3
+ "version": "7.4.1",
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",