@sesamehr/react-design-system 2.0.0-beta.6 → 2.0.0-beta.7
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/Button/ActionItem/ActionItem.d.ts +40 -0
- package/dist/Button/ActionItem/index.d.ts +1 -0
- package/dist/Data/Table/TableScrollbar/TableScrollbar.d.ts +5 -3
- package/dist/Display/Avatar/AvatarSkeleton/AvatarSkeleton.d.ts +30 -0
- package/dist/Display/Avatar/index.d.ts +2 -0
- package/dist/Display/ChatBubble/ChatBubbleStatus/ChatBubbleStatus.d.ts +2 -2
- package/dist/Display/FileCard/FileCard.d.ts +66 -0
- package/dist/Display/FileCard/index.d.ts +1 -0
- package/dist/Display/FilePreviewCard/FilePreviewCard.d.ts +49 -0
- package/dist/Display/FilePreviewCard/index.d.ts +1 -0
- package/dist/Feedback/Alert/AlertIcon.d.ts +1 -1
- package/dist/Feedback/Dialog/DialogBody.d.ts +18 -0
- package/dist/Feedback/Dialog/index.d.ts +1 -0
- package/dist/Feedback/Popover/PopoverContent.d.ts +7 -1
- package/dist/Feedback/Progress/index.d.ts +1 -1
- package/dist/Feedback/Skeleton/Skeleton.d.ts +20 -0
- package/dist/Feedback/Skeleton/index.d.ts +2 -0
- package/dist/Forms/Field/FieldGroup/FieldGroup.d.ts +16 -1
- package/dist/Forms/Field/FieldLabel/FieldLabel.d.ts +16 -0
- package/dist/Forms/Field/FieldMessage/FieldMessage.d.ts +22 -2
- package/dist/Forms/Field/index.d.ts +1 -0
- package/dist/Forms/Field/useFieldGroup.d.ts +108 -0
- package/dist/Forms/Inputs/Calendar/Calendar.d.ts +2 -7
- package/dist/Forms/Inputs/Calendar/CalendarRange.d.ts +2 -7
- package/dist/Forms/Inputs/Calendar/date.d.ts +28 -0
- package/dist/Forms/Inputs/Calendar/index.d.ts +1 -0
- package/dist/Forms/Inputs/Calendar/nav.d.ts +34 -0
- package/dist/Forms/Inputs/Calendar/testids.d.ts +9 -6
- package/dist/Forms/Inputs/Calendar/useCalendarLocale.d.ts +18 -0
- package/dist/Forms/Inputs/ChatInput/ChatInput.d.ts +68 -0
- package/dist/Forms/Inputs/ChatInput/index.d.ts +46 -0
- package/dist/Forms/Inputs/Combobox/ComboboxContent.d.ts +5 -0
- package/dist/Forms/Inputs/Combobox/ComboboxGroup.d.ts +6 -2
- package/dist/Forms/Inputs/Combobox/ComboboxInput.d.ts +6 -1
- package/dist/Forms/Inputs/Combobox/ComboboxItem.d.ts +4 -0
- package/dist/Forms/Inputs/Combobox/context.d.ts +7 -0
- package/dist/Forms/Inputs/Combobox/useComboboxLabels.d.ts +21 -0
- package/dist/Forms/Inputs/DatePicker/DatePicker.d.ts +51 -0
- package/dist/Forms/Inputs/DatePicker/DatePickerHeader.d.ts +65 -0
- package/dist/Forms/Inputs/DatePicker/DatePickerMonthSelect.d.ts +27 -0
- package/dist/Forms/Inputs/DatePicker/DatePickerTrigger.d.ts +29 -0
- package/dist/Forms/Inputs/DatePicker/DatePickerYearSelect.d.ts +25 -0
- package/dist/Forms/Inputs/DatePicker/DateRangePicker.d.ts +61 -0
- package/dist/Forms/Inputs/DatePicker/format.d.ts +44 -0
- package/dist/Forms/Inputs/DatePicker/index.d.ts +6 -0
- package/dist/Forms/Inputs/DatePicker/month.d.ts +28 -0
- package/dist/Forms/Inputs/DatePicker/useDatePickerHeader.d.ts +23 -0
- package/dist/Forms/Inputs/InputOtp/InputOtp.d.ts +7 -0
- package/dist/Forms/Inputs/InputPassword/InputPassword.d.ts +9 -1
- package/dist/Forms/Inputs/InputText/InputText.d.ts +9 -0
- package/dist/Forms/Inputs/SearchBar/useSearchDelay.d.ts +1 -1
- package/dist/Forms/Inputs/SearchPanel/SearchPanel.d.ts +71 -0
- package/dist/Forms/Inputs/SearchPanel/SearchPanelEmpty.d.ts +16 -0
- package/dist/Forms/Inputs/SearchPanel/SearchPanelGroup.d.ts +14 -0
- package/dist/Forms/Inputs/SearchPanel/SearchPanelInput.d.ts +31 -0
- package/dist/Forms/Inputs/SearchPanel/SearchPanelItem.d.ts +20 -0
- package/dist/Forms/Inputs/SearchPanel/SearchPanelList.d.ts +42 -0
- package/dist/Forms/Inputs/SearchPanel/context.d.ts +11 -0
- package/dist/Forms/Inputs/SearchPanel/index.d.ts +6 -0
- package/dist/Forms/Inputs/Select/SelectContent.d.ts +6 -0
- package/dist/Forms/Inputs/Select/SelectGroup.d.ts +6 -2
- package/dist/Forms/Inputs/Select/SelectItem.d.ts +6 -0
- package/dist/Forms/Inputs/Textarea/Textarea.d.ts +69 -0
- package/dist/Forms/Inputs/Textarea/index.d.ts +21 -0
- package/dist/Forms/Inputs/Toggle/RadioButton/RadioGroup.d.ts +5 -0
- package/dist/Forms/Inputs/Toggle/ToggleLabel/ToggleLabel.d.ts +10 -1
- package/dist/Forms/Inputs/index.d.ts +4 -0
- package/dist/Layout/Scrollbar/Scrollbar.d.ts +46 -0
- package/dist/Layout/Scrollbar/index.d.ts +2 -0
- package/dist/Layout/Scrollbar/useScrollbar.d.ts +52 -0
- package/dist/hooks/index.d.ts +12 -0
- package/dist/hooks/useAutoGrow.d.ts +22 -0
- package/dist/internal/Listbox/ListboxEmpty.d.ts +3 -0
- package/dist/internal/Listbox/ListboxItem.d.ts +23 -0
- package/dist/internal/Listbox/ListboxLabel.d.ts +9 -0
- package/dist/internal/Listbox/ListboxSeparator.d.ts +3 -0
- package/dist/internal/Listbox/ListboxViewport.d.ts +9 -0
- package/dist/internal/Surface/Surface.d.ts +35 -0
- package/dist/internal/index.d.ts +13 -0
- package/dist/main.d.ts +10 -4
- package/dist/react-design-system.css +1 -1
- package/dist/react-design-system.js +10563 -9466
- package/dist/react-design-system.umd.cjs +156 -132
- package/package.json +1 -2
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface ActionItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {
|
|
2
|
+
/**
|
|
3
|
+
* The chevron at the end. On by default: the row is drawn with one, and a
|
|
4
|
+
* row without it is the exception.
|
|
5
|
+
*
|
|
6
|
+
* A boolean is configuration, which the architecture rules push back on, and
|
|
7
|
+
* it earns the exception the same way `OxPopoverContent`'s `showArrow` does.
|
|
8
|
+
* The alternative is a slot prop with no default, which would make every call
|
|
9
|
+
* site write the chevron out — the common case paying for the rare one, and
|
|
10
|
+
* two call sites free to reach for a different glyph.
|
|
11
|
+
*/
|
|
12
|
+
showChevron?: boolean;
|
|
13
|
+
dataTestid: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* ActionItem — mirrors `@sesame/orxata-core` ActionItem.
|
|
17
|
+
*
|
|
18
|
+
* A full-width row that runs an action when pressed: a label that takes the
|
|
19
|
+
* width, and a chevron at the end saying there is something on the other side
|
|
20
|
+
* of the press.
|
|
21
|
+
*
|
|
22
|
+
* Not a `Button` variant, and not for the reason `IconButton` is not one —
|
|
23
|
+
* that one wears `.ox-button` for its colours and only redraws the box. This
|
|
24
|
+
* shares nothing with `Button`: the box is a block that fills its parent and
|
|
25
|
+
* grows with a label that wraps, where every `Button` is an inline-flex of a
|
|
26
|
+
* fixed height with `whitespace-nowrap`, and the fill is `brand-50` behind
|
|
27
|
+
* `brand-500` text, which is none of `Button`'s seven colours.
|
|
28
|
+
*
|
|
29
|
+
* **No `asChild`, and that is not an omission.** Both primitives' pass-through
|
|
30
|
+
* root is built for a component whose entire content is the caller's slot —
|
|
31
|
+
* `Button` and `Chip` are exactly that. This one owns the chevron, and that
|
|
32
|
+
* breaks both: Radix's `Slot` throws ("Expected a single React element child
|
|
33
|
+
* or `Slottable`"), and while `Slottable` answers that here, reka's `Slot` on
|
|
34
|
+
* the Vue side has no equivalent — it merges onto the first child of the
|
|
35
|
+
* component's own slot and leaves the chevron as a sibling of the caller's
|
|
36
|
+
* element. The two sides could not have been made to agree, and a prop that
|
|
37
|
+
* works on one and silently mis-renders on the other is worse than no prop.
|
|
38
|
+
* A row that navigates is an `onClick` and a `router.push`.
|
|
39
|
+
*/
|
|
40
|
+
export declare const ActionItem: import('react').ForwardRefExoticComponent<ActionItemProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ActionItem, type ActionItemProps } from './ActionItem.tsx';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Where a virtualised table's overlay scrollbar goes.
|
|
3
3
|
*
|
|
4
4
|
* Every other table in the system hides its bar: they scroll sideways, the
|
|
5
5
|
* shadows at the edges say there is more, and a bar would be chrome. A list of
|
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
* the scrollport, and the scrollport has to contain the header, so it always
|
|
11
11
|
* cuts across the column names. This one starts below them.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* The bar itself is `Scrollbar`, which knows nothing about any of that. What is
|
|
14
|
+
* left here is the arithmetic that is only true of a table, handed over as the
|
|
15
|
+
* custom properties it reads: the header's height, and the offset between the
|
|
16
|
+
* scrollport and whichever ancestor the bar is actually positioned in.
|
|
15
17
|
*/
|
|
16
18
|
export declare function TableScrollbar(): import("react/jsx-runtime").JSX.Element | null;
|
|
17
19
|
export declare namespace TableScrollbar {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AvatarSize } from '../index.ts';
|
|
2
|
+
export interface AvatarSkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
/** Matches the avatar's size scale — the placeholder is the same box */
|
|
4
|
+
size?: AvatarSize;
|
|
5
|
+
/** Which avatar it stands in for. Only the radius differs. */
|
|
6
|
+
shape?: 'rounded' | 'square';
|
|
7
|
+
dataTestid: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* An avatar-shaped placeholder, for while the avatar is still loading.
|
|
11
|
+
*
|
|
12
|
+
* It renders `OxSkeleton` and wears the *avatar's own* size class, which is why
|
|
13
|
+
* this is a component and not a documented pair of utilities. `size-12` is what
|
|
14
|
+
* `md` happens to be today; a caller who wrote that by hand would be holding a
|
|
15
|
+
* copy of our scale, and it would go quietly wrong the day the scale moved.
|
|
16
|
+
* Here the placeholder and the real avatar read the same rule in
|
|
17
|
+
* `../avatarSizes.css`, so they cannot drift.
|
|
18
|
+
*
|
|
19
|
+
* **One component, not two.** `AvatarRounded` and `AvatarSquare` are separate
|
|
20
|
+
* because they differ in substance — a ring, an image, a status bullet, an
|
|
21
|
+
* action and a label, and two different corner geometries. Strip all of that
|
|
22
|
+
* out and the only thing left that differs is the radius, so a second component
|
|
23
|
+
* would be a copy of this one with one class changed. That is the
|
|
24
|
+
* wrapper-with-no-behaviour that `.claude/rules/component-architecture.md` §11
|
|
25
|
+
* rejects.
|
|
26
|
+
*
|
|
27
|
+
* The pulse and the reduced-motion behaviour are not reimplemented here: they
|
|
28
|
+
* come from `Skeleton`, which is the only place they are declared.
|
|
29
|
+
*/
|
|
30
|
+
export declare const AvatarSkeleton: import('react').ForwardRefExoticComponent<AvatarSkeletonProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { VariantProps } from 'class-variance-authority';
|
|
2
2
|
export { AvatarRounded } from './AvatarRounded/AvatarRounded.tsx';
|
|
3
3
|
export type { AvatarRoundedProps } from './AvatarRounded/AvatarRounded.tsx';
|
|
4
|
+
export { AvatarSkeleton } from './AvatarSkeleton/AvatarSkeleton.tsx';
|
|
5
|
+
export type { AvatarSkeletonProps } from './AvatarSkeleton/AvatarSkeleton.tsx';
|
|
4
6
|
export { AvatarSquare } from './AvatarSquare/AvatarSquare.tsx';
|
|
5
7
|
export type { AvatarSquareProps } from './AvatarSquare/AvatarSquare.tsx';
|
|
6
8
|
export { useAvatarBullet } from './hooks/useAvatarBullet.ts';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ChatBubbleStatusVariants } from './index.ts';
|
|
2
|
-
export interface ChatBubbleStatusProps extends React.
|
|
2
|
+
export interface ChatBubbleStatusProps extends React.HTMLAttributes<HTMLElement> {
|
|
3
3
|
/** How far along the message is */
|
|
4
4
|
status?: NonNullable<ChatBubbleStatusVariants['status']>;
|
|
5
5
|
dataTestid: string;
|
|
6
6
|
}
|
|
7
7
|
/** ChatBubbleStatus — mirrors `@sesame/orxata-core` ChatBubbleStatus. */
|
|
8
|
-
export declare const ChatBubbleStatus: import('react').ForwardRefExoticComponent<ChatBubbleStatusProps & import('react').RefAttributes<
|
|
8
|
+
export declare const ChatBubbleStatus: import('react').ForwardRefExoticComponent<ChatBubbleStatusProps & import('react').RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One attached file as a row. Mirrors `@sesame/orxata-core` FileCard.
|
|
3
|
+
*
|
|
4
|
+
* Built on `Card` rather than redrawing the shell. The radius, the border and
|
|
5
|
+
* the white surface are already a component, and the only reason this file has
|
|
6
|
+
* a stylesheet at all is the row inside it. `flat` is the card the design
|
|
7
|
+
* draws: border, no lift — `Card`'s `flat` keeps the outline and drops only the
|
|
8
|
+
* shadow and the glass.
|
|
9
|
+
*
|
|
10
|
+
* ### Why `name` and `meta` are props and the other two are nodes
|
|
11
|
+
*
|
|
12
|
+
* Sameness is the product for the text, exactly as in `AvatarDetails`: every
|
|
13
|
+
* file row we ship is two lines at the same sizes and weights, and a node is
|
|
14
|
+
* where that guarantee goes to die — the first caller to put a link, a badge or
|
|
15
|
+
* a third line in it ends the point of having the component. `meta` is
|
|
16
|
+
* deliberately not called `size`: what the second line says is the
|
|
17
|
+
* application's business ("1,56 MB", "PDF · yesterday", "Uploaded by Ana"), and
|
|
18
|
+
* naming it after one of those would be a lie the day someone passes another.
|
|
19
|
+
*
|
|
20
|
+
* The glyph and the action are the opposite case. Mapping an extension to an
|
|
21
|
+
* icon is application knowledge — there are hundreds of extensions and we know
|
|
22
|
+
* none of them — so `icon` takes a node and falls back to a generic file glyph,
|
|
23
|
+
* which is the one honest thing a design system can draw. And `action` takes a
|
|
24
|
+
* node because *which* action is not ours either: download, delete, share,
|
|
25
|
+
* retry, or nothing at all. It also settles the accessible name, which we
|
|
26
|
+
* cannot supply since the design system ships no strings — whatever the caller
|
|
27
|
+
* puts there brings its own, and `IconButton` refuses to render without one.
|
|
28
|
+
*
|
|
29
|
+
* ### What it deliberately does not do
|
|
30
|
+
*
|
|
31
|
+
* **It has no width.** The design pins 300px with `min-width`, `max-width` and
|
|
32
|
+
* `width`, and that figure belongs to the screen it was drawn on, not to the
|
|
33
|
+
* component: a card that hardcodes its own width cannot sit in a grid, a
|
|
34
|
+
* sidebar or a flexible column, and the parent owns external layout. It fills
|
|
35
|
+
* what it is given. The 72px height stays, because that one is internal — a
|
|
36
|
+
* list of these has to have rows of equal height, and long names truncate
|
|
37
|
+
* rather than growing the row.
|
|
38
|
+
*
|
|
39
|
+
* **The root is not a button.** It already contains an interactive control, and
|
|
40
|
+
* a button inside a button is invalid HTML; making the root activate would also
|
|
41
|
+
* mean inventing a focus and keyboard contract the design has nothing to say
|
|
42
|
+
* about. A caller who wants the whole row to do something wraps it, or puts a
|
|
43
|
+
* link in `action`.
|
|
44
|
+
*/
|
|
45
|
+
export interface FileCardProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'title'> {
|
|
46
|
+
/** The file's name. Truncates rather than wrapping — the row is a fixed height. */
|
|
47
|
+
name: string;
|
|
48
|
+
/**
|
|
49
|
+
* The second line: whatever the app knows about the file. Size in the
|
|
50
|
+
* design, but a type, a date or an author read just as well. Omit it and the
|
|
51
|
+
* row is one line.
|
|
52
|
+
*/
|
|
53
|
+
meta?: string;
|
|
54
|
+
/**
|
|
55
|
+
* The glyph in the ring. Defaults to a generic file — mapping an extension to
|
|
56
|
+
* an icon is the application's knowledge, not ours.
|
|
57
|
+
*/
|
|
58
|
+
icon?: React.ReactNode;
|
|
59
|
+
/**
|
|
60
|
+
* The one thing you can do to this file. Nothing by default; whatever you put
|
|
61
|
+
* here brings its own accessible name.
|
|
62
|
+
*/
|
|
63
|
+
action?: React.ReactNode;
|
|
64
|
+
dataTestid: string;
|
|
65
|
+
}
|
|
66
|
+
export declare const FileCard: import('react').ForwardRefExoticComponent<FileCardProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FileCard, type FileCardProps } from './FileCard.tsx';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A file you can see: a square thumbnail with one line under it. Mirrors
|
|
3
|
+
* `@sesame/orxata-core` FilePreviewCard.
|
|
4
|
+
*
|
|
5
|
+
* The sibling of `FileCard`, and deliberately not a variant of it. They differ
|
|
6
|
+
* in axis, in padding, in how they take their width and in what they contain —
|
|
7
|
+
* and, decisively, this one has neither a title nor an action. A `variant` prop
|
|
8
|
+
* would have to flip the layout *and* switch off the title *and* switch off the
|
|
9
|
+
* action, which is three configuration props spent hiding the fact that these
|
|
10
|
+
* are two components. What they genuinely share is the shell, and both get it
|
|
11
|
+
* the same way: from `Card`.
|
|
12
|
+
*
|
|
13
|
+
* ### The image
|
|
14
|
+
*
|
|
15
|
+
* `src` and `alt` rather than a node, because there is nothing to compose — it
|
|
16
|
+
* is one `<img>`, and taking a node would only invite a second one. `alt` is
|
|
17
|
+
* required and has no default for the usual reason: the design system ships no
|
|
18
|
+
* strings, and only the caller knows what the picture is of. Pass `""` if it is
|
|
19
|
+
* genuinely decorative; that is a decision, and it should have to be made.
|
|
20
|
+
*
|
|
21
|
+
* Two failure modes, both handled without a state machine. **Not loaded yet**
|
|
22
|
+
* is a tinted square, so the card holds its shape and reads as a pending
|
|
23
|
+
* thumbnail instead of a white hole. **Failed to load** swaps the `<img>` for a
|
|
24
|
+
* generic picture glyph carrying the same `alt` through `role="img"` — the
|
|
25
|
+
* browser's broken-image icon is neither styleable nor meaningful, and dropping
|
|
26
|
+
* the `<img>` is the only way to be rid of it. A new `src` clears the flag, so
|
|
27
|
+
* one bad URL does not poison the ones after it.
|
|
28
|
+
*
|
|
29
|
+
* ### Size
|
|
30
|
+
*
|
|
31
|
+
* The thumbnail is 150px square from the design, exposed as
|
|
32
|
+
* `--ox-file-preview-card-size` rather than a prop — a dimension is a style
|
|
33
|
+
* concern and CSS variables are how this system inherits those. The card itself
|
|
34
|
+
* has no width at all: it hugs the thumbnail, which is why the design needed no
|
|
35
|
+
* width on it either.
|
|
36
|
+
*/
|
|
37
|
+
export interface FilePreviewCardProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
38
|
+
/** The image to show. */
|
|
39
|
+
src: string;
|
|
40
|
+
/** What the image is of. Required — pass `""` only if it is decorative. */
|
|
41
|
+
alt: string;
|
|
42
|
+
/**
|
|
43
|
+
* The single line under the thumbnail: "JPG - 937 KB" in the design, but the
|
|
44
|
+
* app decides what is worth saying.
|
|
45
|
+
*/
|
|
46
|
+
meta: string;
|
|
47
|
+
dataTestid: string;
|
|
48
|
+
}
|
|
49
|
+
export declare const FilePreviewCard: import('react').ForwardRefExoticComponent<FilePreviewCardProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FilePreviewCard, type FilePreviewCardProps, } from './FilePreviewCard.tsx';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export interface AlertIconProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
2
2
|
dataTestid: string;
|
|
3
3
|
}
|
|
4
|
-
/** AlertIcon — renders the variant's default
|
|
4
|
+
/** AlertIcon — renders the variant's default icon, or `children` if provided. */
|
|
5
5
|
export declare const AlertIcon: import('react').ForwardRefExoticComponent<AlertIconProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface DialogBodyProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
2
|
+
dataTestid: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* DialogBody — mirrors `@sesame/orxata-core` DialogBody. The scrolling region
|
|
6
|
+
* of a dialog.
|
|
7
|
+
*
|
|
8
|
+
* Everything else in the panel — header, footer, steppers, alerts — stays put;
|
|
9
|
+
* only this scrolls once the panel reaches its `max-height`. It carries no
|
|
10
|
+
* styling of its own: the declarations that make it the flexible, scrolling
|
|
11
|
+
* item live on `DialogContent` next to the `max-height` they depend on, since
|
|
12
|
+
* a body is only a scroll region because the panel is capped and splitting
|
|
13
|
+
* that pair across two files is how one of them gets changed alone.
|
|
14
|
+
*
|
|
15
|
+
* `data-slot` rather than position, so it can sit anywhere among the panel's
|
|
16
|
+
* children.
|
|
17
|
+
*/
|
|
18
|
+
export declare const DialogBody: import('react').ForwardRefExoticComponent<DialogBodyProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { Dialog, type DialogProps } from './Dialog.tsx';
|
|
2
2
|
export { DialogContent, type DialogContentProps } from './DialogContent.tsx';
|
|
3
|
+
export { DialogBody, type DialogBodyProps } from './DialogBody.tsx';
|
|
3
4
|
export { DialogTitle, type DialogTitleProps } from './DialogTitle.tsx';
|
|
4
5
|
export { DialogDescription, type DialogDescriptionProps, } from './DialogDescription.tsx';
|
|
5
6
|
export { DialogOverlay, type DialogOverlayProps } from './DialogOverlay.tsx';
|
|
@@ -3,5 +3,11 @@ export interface PopoverContentProps extends React.ComponentPropsWithoutRef<type
|
|
|
3
3
|
showArrow?: boolean;
|
|
4
4
|
dataTestid: string;
|
|
5
5
|
}
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* PopoverContent — portalled Radix popover content with optional arrow.
|
|
8
|
+
*
|
|
9
|
+
* `asChild` draws it on the shared `Surface`, which is what keeps a popover
|
|
10
|
+
* and a select open on the same screen from having different corners. Only the
|
|
11
|
+
* padding is a popover's own.
|
|
12
|
+
*/
|
|
7
13
|
export declare const PopoverContent: import('react').ForwardRefExoticComponent<PopoverContentProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -14,6 +14,6 @@ export type { ProgressProps } from './Progress.tsx';
|
|
|
14
14
|
* The variant is the caller's to say.
|
|
15
15
|
*/
|
|
16
16
|
export declare const progressVariants: (props?: ({
|
|
17
|
-
variant?: "success" | "
|
|
17
|
+
variant?: "success" | "error" | "warning" | "brand" | null | undefined;
|
|
18
18
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
19
19
|
export type ProgressVariants = VariantProps<typeof progressVariants>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
2
|
+
dataTestid: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* A block that pulses while the content it stands in for is still loading.
|
|
6
|
+
*
|
|
7
|
+
* It configures nothing. One surface, and the caller gives it its shape with
|
|
8
|
+
* ordinary classes — `h-4 w-48` is a line of text, `size-10 rounded-full` is an
|
|
9
|
+
* avatar, `h-32 w-full` is a block. A `shape` or `variant` prop would be three
|
|
10
|
+
* names for three combinations of width, height and radius that CSS already
|
|
11
|
+
* says better, and it would run out the moment somebody needed a fourth.
|
|
12
|
+
*
|
|
13
|
+
* `OxLoader` and `OxProgress` are the other two, and the three are not
|
|
14
|
+
* interchangeable — see the MDX for which is which.
|
|
15
|
+
*
|
|
16
|
+
* `aria-hidden` sits before the spread so a caller who genuinely needs one of
|
|
17
|
+
* these in the accessibility tree can override it. The region carrying
|
|
18
|
+
* `aria-busy` is the right level, and that is the caller's.
|
|
19
|
+
*/
|
|
20
|
+
export declare const Skeleton: import('react').ForwardRefExoticComponent<SkeletonProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -1,4 +1,19 @@
|
|
|
1
|
+
import { FieldVariant } from '../useFieldGroup.ts';
|
|
1
2
|
export interface FieldGroupProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
2
|
-
variant?:
|
|
3
|
+
variant?: FieldVariant;
|
|
3
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* A label, a control and a message, ordered and wired to each other.
|
|
7
|
+
*
|
|
8
|
+
* Two mechanisms, and they are not redundant. The custom properties in the
|
|
9
|
+
* stylesheet paint whatever is inside — including a consumer's own control,
|
|
10
|
+
* which never imported anything from here — with no prop drilling. The context
|
|
11
|
+
* in `useFieldGroup.ts` carries what a custom property cannot: the `id` the
|
|
12
|
+
* label points `htmlFor` at, the `aria-describedby` that reaches the message,
|
|
13
|
+
* and the `aria-invalid` that says the control is wrong.
|
|
14
|
+
*
|
|
15
|
+
* Ordering is done with direct-child selectors, so the label, the control and
|
|
16
|
+
* the message have to be direct children of this element. Anything a consumer
|
|
17
|
+
* wants to wrap around the field goes outside the group, not inside it.
|
|
18
|
+
*/
|
|
4
19
|
export declare const FieldGroup: import('react').ForwardRefExoticComponent<FieldGroupProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -1,2 +1,18 @@
|
|
|
1
1
|
export type FieldLabelProps = React.LabelHTMLAttributes<HTMLLabelElement>;
|
|
2
|
+
/**
|
|
3
|
+
* The field's label.
|
|
4
|
+
*
|
|
5
|
+
* `htmlFor` comes from the surrounding `<OxFieldGroup>` and points at whichever
|
|
6
|
+
* control claimed the field's id — without it this is a bare `<label>` that
|
|
7
|
+
* neither wraps a control nor names one, so clicking it focuses nothing and a
|
|
8
|
+
* screen reader reaching the control announces no name. It is left off
|
|
9
|
+
* entirely when no control has claimed the id, since a `htmlFor` pointing at
|
|
10
|
+
* nothing is not an improvement on no `htmlFor`.
|
|
11
|
+
*
|
|
12
|
+
* `id` is always there so a composite control — one with several focusable
|
|
13
|
+
* children, where `htmlFor` has no single target — can name itself with
|
|
14
|
+
* `aria-labelledby`.
|
|
15
|
+
*
|
|
16
|
+
* A `htmlFor` written by the caller comes in `...props` and wins, as it should.
|
|
17
|
+
*/
|
|
2
18
|
export declare const FieldLabel: import('react').ForwardRefExoticComponent<FieldLabelProps & import('react').RefAttributes<HTMLLabelElement>>;
|
|
@@ -1,5 +1,25 @@
|
|
|
1
|
+
import { FieldVariant } from '../useFieldGroup.ts';
|
|
1
2
|
export interface FieldMessageProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Overrides the group's variant. Leave it out inside an `<OxFieldGroup>` and
|
|
5
|
+
* the group's own variant comes through the context, so `error` is written
|
|
6
|
+
* once instead of on both.
|
|
7
|
+
*/
|
|
8
|
+
variant?: FieldVariant;
|
|
4
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* The field's feedback line.
|
|
12
|
+
*
|
|
13
|
+
* `id` comes from the surrounding `<OxFieldGroup>` so the control can point
|
|
14
|
+
* `aria-describedby` at it. Without one, the error was announced when it
|
|
15
|
+
* appeared and never again: tab back to a field that is already wrong and
|
|
16
|
+
* nothing described it.
|
|
17
|
+
*
|
|
18
|
+
* `role="alert"` and nothing else. The pair it used to carry — `role="alert"`
|
|
19
|
+
* with `aria-live="polite"` — contradicted itself, since `alert` already
|
|
20
|
+
* implies `assertive`. `alert` is the half worth keeping: it is what makes a
|
|
21
|
+
* message that appears after a submit interrupt, and the case it does not
|
|
22
|
+
* cover, a field that is *already* wrong when you reach it, is now covered by
|
|
23
|
+
* `aria-describedby` instead.
|
|
24
|
+
*/
|
|
5
25
|
export declare const FieldMessage: import('react').ForwardRefExoticComponent<FieldMessageProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { FieldGroup, type FieldGroupProps } from './FieldGroup/FieldGroup.tsx';
|
|
2
2
|
export { FieldLabel, type FieldLabelProps } from './FieldLabel/FieldLabel.tsx';
|
|
3
3
|
export { FieldMessage, type FieldMessageProps, } from './FieldMessage/FieldMessage.tsx';
|
|
4
|
+
export { useFieldControl, useFieldControlGroup, type FieldControlAttrs, type FieldControlGroupAttrs, type FieldVariant, } from './useFieldGroup.ts';
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a `<OxFieldGroup>` hands to the label, the control and the message
|
|
3
|
+
* inside it.
|
|
4
|
+
*
|
|
5
|
+
* `FieldGroup` already paints its children through custom properties
|
|
6
|
+
* (`--message-text-color`, `--controller-border-color`), and that stays: it is
|
|
7
|
+
* what lets a consumer's own control inherit the error colour with no prop
|
|
8
|
+
* drilling. A custom property cannot carry an `id` or an `aria-invalid`,
|
|
9
|
+
* though, so the accessible half needs a real context beside it.
|
|
10
|
+
*
|
|
11
|
+
* Every piece is optional. A control used on its own — no `FieldGroup`
|
|
12
|
+
* anywhere above it — gets an empty attribute bag and renders exactly as it
|
|
13
|
+
* did before, which is why `useFieldGroup` returns `undefined` instead of
|
|
14
|
+
* throwing the way `useInputPassword` does. There, a subcomponent outside its
|
|
15
|
+
* root is meaningless; here, a bare `<OxInputText>` is a perfectly good input.
|
|
16
|
+
*
|
|
17
|
+
* Nothing emits an IDREF that points at nothing. `aria-describedby` waits for
|
|
18
|
+
* a message to mount, `aria-labelledby` for a label, and `<label htmlFor>` for
|
|
19
|
+
* a control to claim the id — a reference to an element that is not there is
|
|
20
|
+
* worse than no reference, because some readers then announce nothing at all
|
|
21
|
+
* rather than falling back.
|
|
22
|
+
*/
|
|
23
|
+
export type FieldVariant = 'default' | 'error' | 'success' | 'warning';
|
|
24
|
+
/** The parts of the group that announce themselves so an IDREF never dangles. */
|
|
25
|
+
type FieldPart = 'label' | 'message';
|
|
26
|
+
export interface FieldGroupContextValue {
|
|
27
|
+
/**
|
|
28
|
+
* Id on the `<label>`. A composite control — one with several focusable
|
|
29
|
+
* children, where `htmlFor` has no single target — names itself by pointing
|
|
30
|
+
* `aria-labelledby` here.
|
|
31
|
+
*/
|
|
32
|
+
labelId: string;
|
|
33
|
+
/** Id on the message, and what a control points `aria-describedby` at. */
|
|
34
|
+
messageId: string;
|
|
35
|
+
/** What `<label htmlFor>` points at, once a control has claimed it. */
|
|
36
|
+
controlId: string | undefined;
|
|
37
|
+
variant: FieldVariant;
|
|
38
|
+
hasLabel: boolean;
|
|
39
|
+
hasMessage: boolean;
|
|
40
|
+
/** Announce a part as mounted. Returns the call that takes it back. */
|
|
41
|
+
register: (_part: FieldPart) => () => void;
|
|
42
|
+
/**
|
|
43
|
+
* Offer an id as the one the label names. The first control to ask gets it;
|
|
44
|
+
* a second is refused, because one label names one thing.
|
|
45
|
+
*/
|
|
46
|
+
claimControl: (_id: string) => () => void;
|
|
47
|
+
}
|
|
48
|
+
export interface FieldControlAttrs {
|
|
49
|
+
id?: string;
|
|
50
|
+
'aria-invalid'?: true;
|
|
51
|
+
'aria-describedby'?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface FieldControlGroupAttrs {
|
|
54
|
+
'aria-labelledby'?: string;
|
|
55
|
+
'aria-invalid'?: true;
|
|
56
|
+
'aria-describedby'?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface FieldLabelAttrs {
|
|
59
|
+
id?: string;
|
|
60
|
+
htmlFor?: string;
|
|
61
|
+
}
|
|
62
|
+
export declare const FieldGroupContext: import('react').Context<FieldGroupContextValue | null>;
|
|
63
|
+
/**
|
|
64
|
+
* The surrounding field, or `undefined` when there is none.
|
|
65
|
+
*
|
|
66
|
+
* Deliberately not a throwing `useXxx`: the context is optional, so its
|
|
67
|
+
* absence is not an error.
|
|
68
|
+
*/
|
|
69
|
+
export declare function useFieldGroup(): FieldGroupContextValue | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Wiring for a control the `<label>` can point `htmlFor` at — anything
|
|
72
|
+
* labelable: `input`, `textarea`, `select`, and the `button`s Radix renders
|
|
73
|
+
* for a checkbox, a switch or a select trigger.
|
|
74
|
+
*
|
|
75
|
+
* Spread it *before* `{...props}` so the caller's attributes win over it, and
|
|
76
|
+
* hand it the caller's own `id`: that is what makes an explicit `id` survive,
|
|
77
|
+
* with the label following it there rather than staying on the generated one.
|
|
78
|
+
* Vue's half reads the id out of `useAttrs()` instead — React has no such
|
|
79
|
+
* channel, so the prop has to be passed in.
|
|
80
|
+
*/
|
|
81
|
+
export declare function useFieldControl(id?: string): FieldControlAttrs;
|
|
82
|
+
/**
|
|
83
|
+
* Wiring for a composite — `OxRadioGroup`, `OxInputOtp` — where "put the id on
|
|
84
|
+
* the control" has no single answer because there are several focusable
|
|
85
|
+
* elements and one id cannot be on all of them.
|
|
86
|
+
*
|
|
87
|
+
* It names itself with `aria-labelledby` instead, so the element it goes on
|
|
88
|
+
* needs a role that takes a name from the author: Radix gives its radio group
|
|
89
|
+
* `role="radiogroup"`, and anything else has to say `role="group"` itself. On
|
|
90
|
+
* a plain `<div>` the name is dropped on the floor.
|
|
91
|
+
*/
|
|
92
|
+
export declare function useFieldControlGroup(): FieldControlGroupAttrs;
|
|
93
|
+
/** Wiring for a `<label>` inside the group: its own id, and what it names. */
|
|
94
|
+
export declare function useFieldLabel(): FieldLabelAttrs;
|
|
95
|
+
/**
|
|
96
|
+
* Wiring for the message: the id a control describes itself with, and the
|
|
97
|
+
* group's variant so it does not have to be written on both.
|
|
98
|
+
*/
|
|
99
|
+
export declare function useFieldMessage(): {
|
|
100
|
+
id?: string;
|
|
101
|
+
variant?: FieldVariant;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* The state a `<OxFieldGroup>` owns. Split out of the component so the ids and
|
|
105
|
+
* the bookkeeping live next to the hooks that read them.
|
|
106
|
+
*/
|
|
107
|
+
export declare function useProvideFieldGroup(variant: FieldVariant): FieldGroupContextValue;
|
|
108
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CalendarDayState } from './CalendarDay.tsx';
|
|
2
2
|
import { CalendarConstraints } from './constraints.ts';
|
|
3
|
+
import { CalendarNav } from './nav.ts';
|
|
3
4
|
/** One day. Falls back to `OxCalendarDay`. */
|
|
4
5
|
type DayRenderer = (props: {
|
|
5
6
|
date: Date;
|
|
@@ -34,13 +35,7 @@ export interface CalendarProps extends Pick<React.HTMLAttributes<HTMLDivElement>
|
|
|
34
35
|
* Empty by default. Receives the visible month and the navigation state,
|
|
35
36
|
* because without those nobody could build a header at all.
|
|
36
37
|
*/
|
|
37
|
-
header?: (
|
|
38
|
-
month: Date;
|
|
39
|
-
goToPrev: () => void;
|
|
40
|
-
goToNext: () => void;
|
|
41
|
-
canGoPrev: boolean;
|
|
42
|
-
canGoNext: boolean;
|
|
43
|
-
}) => React.ReactNode;
|
|
38
|
+
header?: (nav: CalendarNav) => React.ReactNode;
|
|
44
39
|
/**
|
|
45
40
|
* One month's name, above its grid. Falls back to the month and year from
|
|
46
41
|
* `Intl`, and only renders when `months` is more than one — a lone month is
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CalendarDayState } from './CalendarDay.tsx';
|
|
2
2
|
import { CalendarConstraints } from './constraints.ts';
|
|
3
|
+
import { CalendarNav } from './nav.ts';
|
|
3
4
|
/** One day. Falls back to `OxCalendarDay`. */
|
|
4
5
|
type DayRenderer = (props: {
|
|
5
6
|
date: Date;
|
|
@@ -35,13 +36,7 @@ export interface CalendarRangeProps extends Pick<React.HTMLAttributes<HTMLDivEle
|
|
|
35
36
|
* Empty by default. Receives the visible month and the navigation state,
|
|
36
37
|
* because without those nobody could build a header at all.
|
|
37
38
|
*/
|
|
38
|
-
header?: (
|
|
39
|
-
month: Date;
|
|
40
|
-
goToPrev: () => void;
|
|
41
|
-
goToNext: () => void;
|
|
42
|
-
canGoPrev: boolean;
|
|
43
|
-
canGoNext: boolean;
|
|
44
|
-
}) => React.ReactNode;
|
|
39
|
+
header?: (nav: CalendarNav) => React.ReactNode;
|
|
45
40
|
/**
|
|
46
41
|
* One month's name, above its grid. Falls back to the month and year from
|
|
47
42
|
* `Intl`, and only renders at all when there is more than one grid — a lone
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirrors `@sesame/orxata-core`'s `date.ts`. Internal — none of this is
|
|
3
|
+
* exported from the package.
|
|
4
|
+
*
|
|
5
|
+
* The Vue half also converts between the `Date` a caller speaks and the
|
|
6
|
+
* `CalendarDate` reka needs; `react-day-picker` speaks `Date` throughout, so
|
|
7
|
+
* only the part both sides need lives here.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Whether `day` only appears in `month`'s grid as padding, while the month it
|
|
11
|
+
* actually belongs to has a grid of its own on screen.
|
|
12
|
+
*
|
|
13
|
+
* Every grid pads its first and last weeks with days of the neighbouring
|
|
14
|
+
* months, so with `months: 2` the 4th of April is drawn twice: once in April's
|
|
15
|
+
* grid, which owns it, and once in the tail of March's. Both copies read the
|
|
16
|
+
* same selection, so a range ending on the 4th was painted as ending in two
|
|
17
|
+
* places at once.
|
|
18
|
+
*
|
|
19
|
+
* The rule is contextual, not per-grid — "a day another visible grid owns" —
|
|
20
|
+
* which is why the visible months have to be passed in rather than inferred
|
|
21
|
+
* from `month` alone. March's *leading* days from February stay drawn when
|
|
22
|
+
* February is not on screen, and disappear when it is.
|
|
23
|
+
*
|
|
24
|
+
* With a single grid nothing else is visible to own the day, so this is always
|
|
25
|
+
* `false` and every outside day is drawn exactly as before. That is the whole
|
|
26
|
+
* reason the behaviour needs no prop: it follows from how many months are up.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isDrawnByAnotherMonth(day: Date, month: Date, visible: readonly Date[]): boolean;
|
|
@@ -3,6 +3,7 @@ export { Calendar, type CalendarProps } from './Calendar.tsx';
|
|
|
3
3
|
export { CalendarRange, type CalendarRangeProps, type CalendarDateRange, } from './CalendarRange.tsx';
|
|
4
4
|
export { CalendarDay, type CalendarDayProps, type CalendarDayState, } from './CalendarDay.tsx';
|
|
5
5
|
export type { CalendarConstraints } from './constraints.ts';
|
|
6
|
+
export type { CalendarNav } from './nav.ts';
|
|
6
7
|
/**
|
|
7
8
|
* Only the range position varies here. The other five states — selected,
|
|
8
9
|
* today, disabled, focused, outside — are `data-*` attributes rather than
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a calendar hands to whoever draws its header.
|
|
3
|
+
*
|
|
4
|
+
* `Calendar` and `CalendarRange` render no header of their own, so this is the
|
|
5
|
+
* whole of what a header can be built from — a type rather than an inline
|
|
6
|
+
* literal because `DatePickerHeader` takes it as one prop, and a header that
|
|
7
|
+
* cannot name its own argument is one every caller has to retype.
|
|
8
|
+
*/
|
|
9
|
+
export interface CalendarNav {
|
|
10
|
+
/** The first month on screen. */
|
|
11
|
+
month: Date;
|
|
12
|
+
/**
|
|
13
|
+
* How many month grids are on screen, which is what a step moves by. A header
|
|
14
|
+
* that names only `month` names one of several and is wrong about the rest.
|
|
15
|
+
*/
|
|
16
|
+
months: number;
|
|
17
|
+
/** Page one screenful back, or forward. A screenful is `months` months. */
|
|
18
|
+
goToPrev: () => void;
|
|
19
|
+
goToNext: () => void;
|
|
20
|
+
canGoPrev: boolean;
|
|
21
|
+
canGoNext: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Jump to the month a `Date` falls in, however far away it is.
|
|
24
|
+
*
|
|
25
|
+
* Stepping cannot express "the same month next year" — twelve calls to
|
|
26
|
+
* `goToNext` only land there when `months` divides twelve, and in React they
|
|
27
|
+
* do not compound at all, since each one is computed from the month of the
|
|
28
|
+
* render that produced them. Anything that moves by more than a page needs
|
|
29
|
+
* this: `OxDatePickerMonthSelect` and `OxDatePickerYearSelect`, and any month
|
|
30
|
+
* or year list a caller builds instead. It outlived the header's year arrows,
|
|
31
|
+
* which were the first thing to need it.
|
|
32
|
+
*/
|
|
33
|
+
goTo: (month: Date) => void;
|
|
34
|
+
}
|