@danxbot/ui 3.5.2 → 3.6.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/dist/index.js +20695 -20271
- package/dist/index.js.map +1 -1
- package/dist/types/components/ConnectionCard.d.ts +64 -0
- package/dist/types/components/Input.d.ts +1 -1
- package/dist/types/components/SecretField.d.ts +48 -0
- package/dist/types/components/SettingRow.d.ts +130 -0
- package/dist/types/components/Table.d.ts +16 -1
- package/dist/types/index.d.ts +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { type CardHeaderProps } from "./Card";
|
|
3
|
+
export type ConnectionHealth = "healthy" | "degraded" | "broken" | "unknown";
|
|
4
|
+
export interface ConnectionCardProps {
|
|
5
|
+
/**
|
|
6
|
+
* The service's brand mark. A consumer normally passes a real logo — an
|
|
7
|
+
* `<img>`, an inline SVG. Omit it and the card falls back to this library's
|
|
8
|
+
* own `Icon`, so a catalogue is never missing a media slot entirely just
|
|
9
|
+
* because one integration has no artwork yet.
|
|
10
|
+
*/
|
|
11
|
+
logo?: ReactNode;
|
|
12
|
+
/** The service's name. Plain text — it is composed into the action button's
|
|
13
|
+
* accessible name (see `actionLabel`), which a JSX tree cannot be. */
|
|
14
|
+
name: string;
|
|
15
|
+
/** What this connection is FOR, one line — "Email via Mailchimp
|
|
16
|
+
* Transactional", not "Mailchimp integration". */
|
|
17
|
+
description?: ReactNode;
|
|
18
|
+
/** The four-state health model. See the file header for why not a boolean. */
|
|
19
|
+
status: ConnectionHealth;
|
|
20
|
+
/** A failure reason, a partial-failure explanation, or a last-checked
|
|
21
|
+
* timestamp — whatever the status badge does not already say. Rendered
|
|
22
|
+
* only when supplied; omitting it drops the line rather than reserving
|
|
23
|
+
* empty space for it. */
|
|
24
|
+
detail?: ReactNode;
|
|
25
|
+
/**
|
|
26
|
+
* The primary action's visible label — typically "Connect" for `unknown`,
|
|
27
|
+
* "Manage" (or "Reconnect", "Fix") otherwise. Omitting it renders no action
|
|
28
|
+
* at all, for a read-only tile.
|
|
29
|
+
*
|
|
30
|
+
* The button's PROMINENCE follows `status`, not this label's wording: an
|
|
31
|
+
* `unknown` card gets the solid, high-contrast treatment because getting it
|
|
32
|
+
* connected is the one thing worth doing; every other state gets the
|
|
33
|
+
* quieter outline treatment, because the card's border and badge are
|
|
34
|
+
* already carrying the "look here" signal and a second loud button would
|
|
35
|
+
* just compete with them.
|
|
36
|
+
*/
|
|
37
|
+
actionLabel?: string;
|
|
38
|
+
onAction?: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* Present (and non-`undefined`) disables the action and explains why.
|
|
41
|
+
*
|
|
42
|
+
* This is `IconButton`'s `disabledReason` contract, carried over verbatim:
|
|
43
|
+
* `aria-disabled` rather than native `disabled`, so the control stays
|
|
44
|
+
* hoverable and focusable — a `disabled` button drops out of hit-testing
|
|
45
|
+
* entirely, and a control nobody can point at can never be asked why it
|
|
46
|
+
* won't fire. The reason is announced two ways at once, neither of them
|
|
47
|
+
* "only on hover": an always-present `sr-only` node wired through
|
|
48
|
+
* `aria-describedby` for a screen reader, and a visible `Tooltip` that opens
|
|
49
|
+
* on focus as well as on pointer hover, for a keyboard user who generates
|
|
50
|
+
* no hover event at all.
|
|
51
|
+
*/
|
|
52
|
+
actionDisabledReason?: string;
|
|
53
|
+
/**
|
|
54
|
+
* The heading level the name renders as. See `CardHeader.titleAs` — the
|
|
55
|
+
* reasoning is identical: a card's correct heading level is a property of
|
|
56
|
+
* where it sits in the page outline, not of the card, so only the caller
|
|
57
|
+
* of a whole catalogue grid knows it.
|
|
58
|
+
*
|
|
59
|
+
* @default "h3"
|
|
60
|
+
*/
|
|
61
|
+
titleAs?: CardHeaderProps["titleAs"];
|
|
62
|
+
className?: string;
|
|
63
|
+
}
|
|
64
|
+
export declare function ConnectionCard({ logo, name, description, status, detail, actionLabel, onAction, actionDisabledReason, titleAs, className, }: ConnectionCardProps): import("react").JSX.Element;
|
|
@@ -57,7 +57,7 @@ export interface InputProps extends Omit<BaseInput.Props, "className" | "render"
|
|
|
57
57
|
loading?: boolean;
|
|
58
58
|
ref?: Ref<HTMLInputElement>;
|
|
59
59
|
}
|
|
60
|
-
export declare function Input(
|
|
60
|
+
export declare function Input(allProps: InputProps): import("react").JSX.Element;
|
|
61
61
|
declare const textarea: import("tailwind-variants").TVReturnType<{
|
|
62
62
|
size: {
|
|
63
63
|
sm: "rounded-md px-3 py-2 text-xs";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Ref } from "react";
|
|
2
|
+
import { type FieldProps } from "./Field";
|
|
3
|
+
import { type InputProps } from "./Input";
|
|
4
|
+
export type SecretValue = {
|
|
5
|
+
kind: "unchanged";
|
|
6
|
+
} | {
|
|
7
|
+
kind: "set";
|
|
8
|
+
value: string;
|
|
9
|
+
} | {
|
|
10
|
+
kind: "cleared";
|
|
11
|
+
};
|
|
12
|
+
export interface SecretFieldProps extends Pick<FieldProps, "label" | "description" | "error" | "required" | "disabled" | "name" | "className">, Pick<InputProps, "size" | "placeholder"> {
|
|
13
|
+
/** The pending edit. See the module doc comment for why this is not a `string`. */
|
|
14
|
+
value: SecretValue;
|
|
15
|
+
onChange: (value: SecretValue) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Whether a secret is CURRENTLY stored server-side, independent of `value`
|
|
18
|
+
* — this is the fact the empty, masked field is standing in for. Drives the
|
|
19
|
+
* "a secret is stored" announcement, the hint row, and whether the clear
|
|
20
|
+
* action is offered at all (there is nothing to clear when nothing is set).
|
|
21
|
+
*/
|
|
22
|
+
configured: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* A partial, already-safe rendering of the stored value — e.g. `{ prefix:
|
|
25
|
+
* "sk-ab", suffix: "9f4c" }` for a key the consuming app's own API already
|
|
26
|
+
* truncates before it ever reaches the client. This is NOT the secret; it
|
|
27
|
+
* is a confirmation aid ("is this the key I think it is?") and is shown
|
|
28
|
+
* only while a stored value exists and has not been typed over or cleared.
|
|
29
|
+
*/
|
|
30
|
+
hint?: {
|
|
31
|
+
prefix: string;
|
|
32
|
+
suffix: string;
|
|
33
|
+
};
|
|
34
|
+
/** When the stored value was last written, for the same confirmation purpose as `hint`. */
|
|
35
|
+
updatedAt?: string | Date;
|
|
36
|
+
/** Who wrote it, if the caller's system tracks that. */
|
|
37
|
+
updatedBy?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Offers a show/hide toggle for text the operator just TYPED. Default true.
|
|
40
|
+
* Never offered for the stored value — see the module doc comment — and
|
|
41
|
+
* never rendered while there is no typed text to reveal.
|
|
42
|
+
*/
|
|
43
|
+
revealable?: boolean;
|
|
44
|
+
/** Label on the destructive confirm button. Default "Clear". */
|
|
45
|
+
clearConfirmLabel?: string;
|
|
46
|
+
ref?: Ref<HTMLInputElement>;
|
|
47
|
+
}
|
|
48
|
+
export declare function SecretField({ value, onChange, configured, hint, updatedAt, updatedBy, revealable, clearConfirmLabel, label, description, error, required, disabled, name, placeholder, size, className, ref, }: SecretFieldProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type CardHeaderProps } from "./Card";
|
|
3
|
+
/**
|
|
4
|
+
* What `SettingRow` hands to a `control` supplied as a render function —
|
|
5
|
+
* two ARIA id references to place on the control's own focusable element(s).
|
|
6
|
+
*
|
|
7
|
+
* WHY A RENDER PROP, NOT AN AUTOMATIC ASSOCIATION LIKE `Field`.
|
|
8
|
+
*
|
|
9
|
+
* `Field` (this library's other labelled wrapper) gets the label/description
|
|
10
|
+
* link for free, but only because every control it has ever wrapped is one of
|
|
11
|
+
* THIS library's own Base UI–backed primitives — `Checkbox`, `Switch`,
|
|
12
|
+
* `Input`, `Select`… — and those read Base UI's internal field context
|
|
13
|
+
* themselves to pick up `aria-describedby`. That mechanism is a private
|
|
14
|
+
* implementation detail of Base UI (there is no public hook a third-party
|
|
15
|
+
* control could subscribe to), so it silently does NOTHING for anything that
|
|
16
|
+
* is not one of those primitives.
|
|
17
|
+
*
|
|
18
|
+
* `SettingRow.control` is typed to accept literally anything a settings page
|
|
19
|
+
* might need in that slot — a bare `<input>`, a third-party widget, a
|
|
20
|
+
* composite the CONSUMER wrote that has never heard of this library, let
|
|
21
|
+
* alone Base UI's field internals. Wrapping arbitrary children in the same
|
|
22
|
+
* context-based `Field` would look correct and associate nothing, which is
|
|
23
|
+
* the worse failure: it fails silently, exactly the thing this component
|
|
24
|
+
* exists to prevent for settings prose.
|
|
25
|
+
*
|
|
26
|
+
* So the association is made an explicit VALUE instead of an implicit
|
|
27
|
+
* context read: `SettingRow` generates the ids, and a `control` passed as a
|
|
28
|
+
* function receives them and is responsible for spreading them onto the
|
|
29
|
+
* element that actually receives focus (the switch's button, the input
|
|
30
|
+
* itself, a slider's thumb — for a multi-thumb control, every thumb).
|
|
31
|
+
*
|
|
32
|
+
* `control` may also be passed as a plain `ReactNode` — the escape hatch for
|
|
33
|
+
* a control that already carries its own accessible name and description
|
|
34
|
+
* through some other channel (for example a `SwitchField`/`Field`-wrapped
|
|
35
|
+
* control, or a composite region where per-control labelling does not apply)
|
|
36
|
+
* — in which case NEITHER id is wired anywhere, and getting the control
|
|
37
|
+
* properly named and described is entirely the caller's responsibility.
|
|
38
|
+
*/
|
|
39
|
+
export interface SettingRowControlRenderProps {
|
|
40
|
+
/** Always present — `label` is required, so the row always has a name to give. */
|
|
41
|
+
"aria-labelledby": string;
|
|
42
|
+
/** `undefined` when this row has no `description` — nothing to describe with. */
|
|
43
|
+
"aria-describedby": string | undefined;
|
|
44
|
+
}
|
|
45
|
+
export interface SettingRowBaseProps {
|
|
46
|
+
/** The setting's name. Always rendered as visible text and always given an id. */
|
|
47
|
+
label: ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* What the setting actually DOES, in one line. Always visible — see the
|
|
50
|
+
* module doc comment for why this is not a tooltip. Rendered with a
|
|
51
|
+
* generated id and, when `control` is a render function, offered to it via
|
|
52
|
+
* `SettingRowControlRenderProps["aria-describedby"]`.
|
|
53
|
+
*/
|
|
54
|
+
description?: ReactNode;
|
|
55
|
+
/**
|
|
56
|
+
* The long-form "why this matters" — collapsed by default, revealed by a
|
|
57
|
+
* disclosure built on this library's `Collapsible`. Omit entirely when
|
|
58
|
+
* `description` alone says everything worth saying; not every setting earns
|
|
59
|
+
* a second paragraph.
|
|
60
|
+
*/
|
|
61
|
+
details?: ReactNode;
|
|
62
|
+
/** Accessible name + visible label of the `details` disclosure trigger. */
|
|
63
|
+
detailsLabel?: ReactNode;
|
|
64
|
+
/** Renders the `details` disclosure already open — for a setting a caller deep-links to. */
|
|
65
|
+
detailsDefaultOpen?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* The CONSEQUENCE of changing this setting, stated plainly — "takes effect
|
|
68
|
+
* on next dispatch", "requires a worker restart" — never the mechanism. See
|
|
69
|
+
* the module doc comment: this is what stops a setting from silently not
|
|
70
|
+
* applying yet.
|
|
71
|
+
*/
|
|
72
|
+
effect?: ReactNode;
|
|
73
|
+
/**
|
|
74
|
+
* Right-aligned indicator — a `Badge` showing the setting's current derived
|
|
75
|
+
* state, most often. Rendered beside the control, not inside it, so it
|
|
76
|
+
* survives a `readOnly` row where there is no control at all.
|
|
77
|
+
*/
|
|
78
|
+
status?: ReactNode;
|
|
79
|
+
className?: string;
|
|
80
|
+
}
|
|
81
|
+
export interface SettingRowEditableProps extends SettingRowBaseProps {
|
|
82
|
+
readOnly?: undefined;
|
|
83
|
+
/**
|
|
84
|
+
* The setting's control. Either a plain node, or a function receiving the
|
|
85
|
+
* ids to associate — see `SettingRowControlRenderProps`.
|
|
86
|
+
*/
|
|
87
|
+
control: ReactNode | ((renderProps: SettingRowControlRenderProps) => ReactNode);
|
|
88
|
+
}
|
|
89
|
+
export interface SettingRowReadOnlyProps extends SettingRowBaseProps {
|
|
90
|
+
/**
|
|
91
|
+
* Presents this row as READ-ONLY instead of rendering `control` at all —
|
|
92
|
+
* see the module doc comment for why this is a first-class state rather
|
|
93
|
+
* than a disabled control. `reason` is required; `value`, when given, is
|
|
94
|
+
* the setting's current value, shown as plain text beside it.
|
|
95
|
+
*/
|
|
96
|
+
readOnly: {
|
|
97
|
+
reason: ReactNode;
|
|
98
|
+
value?: ReactNode;
|
|
99
|
+
};
|
|
100
|
+
control?: undefined;
|
|
101
|
+
}
|
|
102
|
+
export type SettingRowProps = SettingRowEditableProps | SettingRowReadOnlyProps;
|
|
103
|
+
export declare function SettingRow(props: SettingRowProps): import("react").JSX.Element;
|
|
104
|
+
export interface SettingGroupProps {
|
|
105
|
+
/** The group's name — e.g. "Notifications", "Dispatch limits". */
|
|
106
|
+
title: ReactNode;
|
|
107
|
+
/** One line of context for the whole group. */
|
|
108
|
+
description?: ReactNode;
|
|
109
|
+
/** @default "h3" — see `CardHeader`'s own doc comment on why this is the caller's call. */
|
|
110
|
+
titleAs?: CardHeaderProps["titleAs"];
|
|
111
|
+
/** Where a Save button or a "last changed" line lives. Rendered as a `CardFooter`. */
|
|
112
|
+
footer?: ReactNode;
|
|
113
|
+
className?: string;
|
|
114
|
+
/** `SettingRow` elements, in display order. */
|
|
115
|
+
children: ReactNode;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* A titled card holding several `SettingRow`s.
|
|
119
|
+
*
|
|
120
|
+
* `SettingGroup` simply IS a `Card` — a fixed shape (`CardHeader` for the
|
|
121
|
+
* title/description, a divided list of rows, an optional `CardFooter`) built
|
|
122
|
+
* from parts this library already ships, rather than a new container
|
|
123
|
+
* component that happens to look like one. Nesting, theming, radius
|
|
124
|
+
* arithmetic and padding all come from `Card` for free, and any future fix to
|
|
125
|
+
* that component (the nested-radius correction, for one) reaches every
|
|
126
|
+
* settings page without this file changing at all. The rows themselves supply
|
|
127
|
+
* only the divider and the per-row padding — everything else about "a card
|
|
128
|
+
* with a header" was already solved.
|
|
129
|
+
*/
|
|
130
|
+
export declare function SettingGroup({ title, description, titleAs, footer, className, children, }: SettingGroupProps): import("react").JSX.Element;
|
|
@@ -24,6 +24,21 @@ export interface DataTableProps<TData> {
|
|
|
24
24
|
refreshing?: boolean;
|
|
25
25
|
/** Skeleton row count while `loading`. */
|
|
26
26
|
loadingRows?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Rows per page. **Omit for no pagination** — that is the default and it is
|
|
29
|
+
* what every existing consumer already gets, unchanged.
|
|
30
|
+
*
|
|
31
|
+
* WHY OPT-IN RATHER THAN A DEFAULT PAGE SIZE: paginating a table nobody
|
|
32
|
+
* asked to paginate hides rows. A short table that suddenly grows a footer
|
|
33
|
+
* and a "1 of 3" is a worse regression than a long table, because the rows
|
|
34
|
+
* that vanished were on screen yesterday. So the caller says when the list
|
|
35
|
+
* is long enough to warrant it.
|
|
36
|
+
*
|
|
37
|
+
* The `Pagination` control this renders has existed in this library since
|
|
38
|
+
* long before `DataTable` did, as a fully independent component that was
|
|
39
|
+
* never connected to anything. This is that connection.
|
|
40
|
+
*/
|
|
41
|
+
pageSize?: number;
|
|
27
42
|
emptyState?: ReactNode;
|
|
28
43
|
onRowClick?: (row: TData) => void;
|
|
29
44
|
/** Rendered above the table; receives the table instance for counts/filters. */
|
|
@@ -31,7 +46,7 @@ export interface DataTableProps<TData> {
|
|
|
31
46
|
className?: string;
|
|
32
47
|
getRowId?: (row: TData, index: number) => string;
|
|
33
48
|
}
|
|
34
|
-
export declare function DataTable<TData>({ data, columns, density, selectable, maxHeight, zebra, loading, refreshing, loadingRows, emptyState, onRowClick, toolbar, className, getRowId, }: DataTableProps<TData>): import("react").JSX.Element;
|
|
49
|
+
export declare function DataTable<TData>({ data, columns, density, selectable, maxHeight, zebra, loading, refreshing, loadingRows, pageSize, emptyState, onRowClick, toolbar, className, getRowId, }: DataTableProps<TData>): import("react").JSX.Element;
|
|
35
50
|
export declare function TableEmptyState({ icon, title, description, action, }: {
|
|
36
51
|
icon?: ReactNode;
|
|
37
52
|
title?: string;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -21,6 +21,9 @@ export { Skeleton, SkeletonText, LoadingOverlay, type SkeletonProps, type Skelet
|
|
|
21
21
|
export { ErrorBoundary } from "./components/ErrorBoundary";
|
|
22
22
|
export { Field, FieldSet, type FieldProps, type FieldSetProps } from "./components/Field";
|
|
23
23
|
export { Input, Textarea, type InputProps, type TextareaProps } from "./components/Input";
|
|
24
|
+
export { SecretField, type SecretFieldProps, type SecretValue } from "./components/SecretField";
|
|
25
|
+
export { SettingRow, SettingGroup, type SettingRowProps, type SettingGroupProps, type SettingRowControlRenderProps, } from "./components/SettingRow";
|
|
26
|
+
export { ConnectionCard, type ConnectionCardProps, type ConnectionHealth, } from "./components/ConnectionCard";
|
|
24
27
|
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";
|
|
25
28
|
export { Dialog, DialogClose, AlertDialog, type DialogProps, type AlertDialogProps, } from "./components/Dialog";
|
|
26
29
|
export { Popover, PopoverClose, Tooltip, TooltipProvider, type PopoverProps, type TooltipProps, } from "./components/Popover";
|