@sesamehr/react-design-system 2.0.0-beta.6 → 2.0.0-beta.8
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/Data/Table/hooks/useTableVirtual/useTableVirtual.types.d.ts +4 -3
- package/dist/Display/Avatar/AvatarSkeleton/AvatarSkeleton.d.ts +30 -0
- package/dist/Display/Avatar/index.d.ts +2 -0
- package/dist/Display/ChatBubble/ChatBubble.d.ts +20 -3
- package/dist/Display/ChatBubble/ChatBubbleStatus/ChatBubbleStatus.d.ts +2 -2
- package/dist/Display/ChatBubble/index.d.ts +31 -0
- 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 +11 -5
- package/dist/react-design-system.css +1 -1
- package/dist/react-design-system.js +10617 -9478
- 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 {
|
|
@@ -26,9 +26,10 @@ export interface UseTableVirtualOptions {
|
|
|
26
26
|
* This is what turns a scroll position into a row index, so it is worth
|
|
27
27
|
* getting right: the error is paid on every row crossed, which is nothing at
|
|
28
28
|
* one click of the wheel and hundreds of rows after a flick. The default,
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
29
|
+
* 52px, is `--table-row-height` on `.oxTableRoot` — the minimum a row's cells
|
|
30
|
+
* give it with plain text in them. (Not `TableRow`'s own CSS: `height` on a
|
|
31
|
+
* `<tr>` is ignored by the table layout algorithm.) Rows with an avatar or two
|
|
32
|
+
* lines of text are taller, and those tables should say so here.
|
|
32
33
|
*
|
|
33
34
|
* It is deliberately a number you give rather than one measured from the
|
|
34
35
|
* page. Measuring as you scroll means the total height changes as you scroll,
|
|
@@ -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,10 +1,27 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { ChatBubbleVariants } from './index.ts';
|
|
2
|
+
import { ChatBubbleDelivery, ChatBubbleVariants } from './index.ts';
|
|
3
3
|
export interface ChatBubbleProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
4
|
/** Who said it: the reader, or someone else */
|
|
5
5
|
author?: ChatBubbleVariants['author'];
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* When the message went and whether it arrived, drawn as the footer line.
|
|
8
|
+
*
|
|
9
|
+
* Each key stands alone, so `{ time }`, `{ status }`, both or neither all
|
|
10
|
+
* work and an omitted key renders nothing — there is no flag to set and no
|
|
11
|
+
* line to assemble. Anything this cannot express (a delivery error, an
|
|
12
|
+
* "edited" marker, an avatar) goes in `footer` instead, which replaces this
|
|
13
|
+
* line wholesale when both are given.
|
|
14
|
+
*/
|
|
15
|
+
delivery?: ChatBubbleDelivery;
|
|
16
|
+
/**
|
|
17
|
+
* The line under the message, drawn by hand. Ports the Vue `#footer` slot,
|
|
18
|
+
* and wins over `delivery` when both are supplied.
|
|
19
|
+
*
|
|
20
|
+
* Spelled `ReactNode` inline rather than behind an alias because
|
|
21
|
+
* `orxata/max-props` discounts a slot by reading the type *text*, and an alias
|
|
22
|
+
* hides it.
|
|
23
|
+
*/
|
|
24
|
+
footer?: ReactNode;
|
|
8
25
|
dataTestid: string;
|
|
9
26
|
}
|
|
10
27
|
/** ChatBubble — mirrors `@sesame/orxata-core` ChatBubble. */
|
|
@@ -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>>;
|
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
import { VariantProps } from 'class-variance-authority';
|
|
2
|
+
import { ChatBubbleStatusVariants } from './ChatBubbleStatus/index.ts';
|
|
2
3
|
export { ChatBubble, type ChatBubbleProps } from './ChatBubble.tsx';
|
|
4
|
+
/**
|
|
5
|
+
* When the message went and whether it arrived — the bubble's footer, as data
|
|
6
|
+
* rather than as markup.
|
|
7
|
+
*
|
|
8
|
+
* One object rather than a prop each, for the same reason `ChatInput` takes one
|
|
9
|
+
* `actionLabels`: the parts belong together, they are all optional, and spending
|
|
10
|
+
* a prop per part would put a two-field component against the five-prop cap for
|
|
11
|
+
* no gain. Every key is independent — a time with no receipt, a receipt with no
|
|
12
|
+
* time, both, or neither — and an omitted key renders nothing at all, so the
|
|
13
|
+
* four combinations need no flags to select between them.
|
|
14
|
+
*
|
|
15
|
+
* Nothing here is prose the design system invents. `time` is a string the caller
|
|
16
|
+
* has already formatted, because formatting a date needs a locale, a timezone
|
|
17
|
+
* and a house style, and this package ships no strings and knows none of those.
|
|
18
|
+
* `status` is not text at all — it is an enum the bubble draws as an icon.
|
|
19
|
+
*/
|
|
20
|
+
export interface ChatBubbleDelivery {
|
|
21
|
+
/**
|
|
22
|
+
* The timestamp, already formatted — `'13 mar'`, `'09:41'`, whatever the
|
|
23
|
+
* product shows. Omit it for a bubble that carries only a receipt.
|
|
24
|
+
*/
|
|
25
|
+
time?: string;
|
|
26
|
+
/**
|
|
27
|
+
* How far along the message is, drawn as a receipt.
|
|
28
|
+
*
|
|
29
|
+
* Only your own messages have one: there is no receipt for what somebody else
|
|
30
|
+
* said, so a bubble with `author: 'other'` normally omits this.
|
|
31
|
+
*/
|
|
32
|
+
status?: NonNullable<ChatBubbleStatusVariants['status']>;
|
|
33
|
+
}
|
|
3
34
|
/**
|
|
4
35
|
* Who said it, which is the only thing that varies.
|
|
5
36
|
*
|
|
@@ -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
|