@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
|
@@ -15,11 +15,14 @@ export declare const monthTestid: (root: string, month: Date) => string;
|
|
|
15
15
|
* `undefined` for a day borrowed from the neighbouring month, which is why the
|
|
16
16
|
* `outside` argument is not optional — the caller has to have answered it.
|
|
17
17
|
*
|
|
18
|
-
* Such a day is drawn in a grid it does not belong to,
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
18
|
+
* Such a day is drawn in a grid it does not belong to, purely as padding.
|
|
19
|
+
* Giving it an id would either collide with the id of the grid that owns it, or
|
|
20
|
+
* mean an id that does not say which grid it came from. Neither is worth it for
|
|
21
|
+
* a day that is decoration — a test that wants the 1st of April pins April.
|
|
22
|
+
*
|
|
23
|
+
* It is only drawn at all while the month that owns it has no grid on screen:
|
|
24
|
+
* see `isDrawnByAnotherMonth`. So the `outside` argument stays required, and
|
|
25
|
+
* stays the caller's to answer — the id is about which grid a day belongs to,
|
|
26
|
+
* which is a different question from whether the day is drawn.
|
|
24
27
|
*/
|
|
25
28
|
export declare const dayTestid: (monthId: string, day: Date, outside: boolean) => string | undefined;
|
|
@@ -6,6 +6,24 @@ export type WeekStart = 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
|
6
6
|
* the locale already carries the answer for every region ICU knows.
|
|
7
7
|
*/
|
|
8
8
|
export declare const weekStartsOnFor: (locale: string) => WeekStart;
|
|
9
|
+
/**
|
|
10
|
+
* How a weekday is abbreviated above its column.
|
|
11
|
+
*
|
|
12
|
+
* The design draws two letters — `Su Mo Tu` — and `Intl` has no two-letter
|
|
13
|
+
* weekday: `narrow` is one character, `short` is the locale's own abbreviation
|
|
14
|
+
* (`Sun`, `dom`, `Mo.`), `long` is the whole word. `short` is the nearest of
|
|
15
|
+
* the three and the only one that is still the locale's, so it is what both
|
|
16
|
+
* packages ask for. Trimming `short` to two characters would match the English
|
|
17
|
+
* mock and produce nonsense everywhere the abbreviation is not built that way,
|
|
18
|
+
* which is most places — and it would be this package inventing a format rather
|
|
19
|
+
* than reading one, which is the line the no-strings rule draws.
|
|
20
|
+
*
|
|
21
|
+
* Named here rather than written at each call site because reka takes it as a
|
|
22
|
+
* `weekdayFormat` prop and `react-day-picker` takes it as a formatter we write
|
|
23
|
+
* ourselves: two spellings of one decision, which is exactly the kind of thing
|
|
24
|
+
* that drifts.
|
|
25
|
+
*/
|
|
26
|
+
export declare const WEEKDAY_FORMAT = "short";
|
|
9
27
|
/**
|
|
10
28
|
* The locale the calendar formats in, and the week start that follows from it.
|
|
11
29
|
*
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ChatInputActionLabels, ChatInputState } from './index.ts';
|
|
3
|
+
export interface ChatInputProps extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'defaultValue' | 'rows' | 'children' | 'onSubmit'> {
|
|
4
|
+
/**
|
|
5
|
+
* What a screen reader announces for the three default action buttons.
|
|
6
|
+
* Required, and required for the same reason `IconButton`'s `aria-label` is:
|
|
7
|
+
* a glyph is the whole control, so an unlabelled one announces as "button"
|
|
8
|
+
* and nothing else — and no default the design system could ship would be in
|
|
9
|
+
* the reader's language. One object rather than three props so that naming
|
|
10
|
+
* the buttons costs one line, not three.
|
|
11
|
+
*/
|
|
12
|
+
actionLabels: ChatInputActionLabels;
|
|
13
|
+
/**
|
|
14
|
+
* How tall the surface may grow before it starts to scroll, counted in
|
|
15
|
+
* lines of text.
|
|
16
|
+
*/
|
|
17
|
+
maxRows?: number;
|
|
18
|
+
/** Controlled message. Pair with `onValueChange`; omit for uncontrolled. */
|
|
19
|
+
value?: string;
|
|
20
|
+
/** Starting message when uncontrolled. */
|
|
21
|
+
defaultValue?: string;
|
|
22
|
+
/** Called on every keystroke with the next message. */
|
|
23
|
+
onValueChange?: (value: string) => void;
|
|
24
|
+
/** Enter, or the send button. Never called for an empty or whitespace value. */
|
|
25
|
+
onSubmit?: (value: string) => void;
|
|
26
|
+
/** The default add-attachment button was pressed. */
|
|
27
|
+
onAttach?: () => void;
|
|
28
|
+
/** The default microphone button was pressed. */
|
|
29
|
+
onRecord?: () => void;
|
|
30
|
+
/** The text surface. Falls back to an auto-growing textarea. */
|
|
31
|
+
children?: ReactNode | ((state: ChatInputState) => ReactNode);
|
|
32
|
+
/** A full-width band above the text surface. Renders nothing when omitted. */
|
|
33
|
+
toolbar?: ReactNode | ((state: ChatInputState) => ReactNode);
|
|
34
|
+
/** Bottom-left corner. Falls back to the add-attachment button. */
|
|
35
|
+
actionsStart?: ReactNode | ((state: ChatInputState) => ReactNode);
|
|
36
|
+
/** Bottom-right corner. Falls back to the microphone and send buttons. */
|
|
37
|
+
actionsEnd?: ReactNode | ((state: ChatInputState) => ReactNode);
|
|
38
|
+
dataTestid: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The frame around a chat composer: the box, the growth, the keyboard
|
|
42
|
+
* contract and the two action corners. Deliberately *not* an editor.
|
|
43
|
+
* Mirrors `@sesame/orxata-core` ChatInput.
|
|
44
|
+
*
|
|
45
|
+
* The text surface is `children`, and what it renders by default is a plain
|
|
46
|
+
* auto-growing `<textarea>` — so `value` is a string, and a consumer who
|
|
47
|
+
* later needs mentions or rich paste drops their own editor in without the
|
|
48
|
+
* design system taking a dependency on one. The alternative — building on a
|
|
49
|
+
* rich-text library — would put ProseMirror in front of every consumer of the
|
|
50
|
+
* package, turn `value` into HTML, and leave two different integrations to
|
|
51
|
+
* keep in step across React and Vue, for a design that has no formatting
|
|
52
|
+
* controls in it.
|
|
53
|
+
*
|
|
54
|
+
* `children`, `toolbar`, `actionsStart` and `actionsEnd` each take a node or a
|
|
55
|
+
* render prop called with `{ empty, submit }`, because the frame is the only
|
|
56
|
+
* part that knows whether the field is empty. A caller who replaces the send
|
|
57
|
+
* button keeps the empty-state refusal for free instead of re-deriving it,
|
|
58
|
+
* which is the way the two can never disagree.
|
|
59
|
+
*
|
|
60
|
+
* `className` lands on the root, which is the box; everything else a native
|
|
61
|
+
* `<textarea>` takes — `placeholder`, `name`, `disabled`, `aria-label` — falls
|
|
62
|
+
* through to the surface. That is also how every human-readable string
|
|
63
|
+
* arrives: the design system ships none of its own. Replace `children` and the
|
|
64
|
+
* fallthrough has nowhere to go — a caller supplying their own surface labels
|
|
65
|
+
* their own surface. The `ref` is the root, for the same reason `className`
|
|
66
|
+
* is.
|
|
67
|
+
*/
|
|
68
|
+
export declare const ChatInput: import('react').ForwardRefExoticComponent<ChatInputProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export { ChatInput } from './ChatInput.tsx';
|
|
3
|
+
export type { ChatInputProps } from './ChatInput.tsx';
|
|
4
|
+
/**
|
|
5
|
+
* The accessible names for the three default action buttons.
|
|
6
|
+
*
|
|
7
|
+
* A separate type rather than an inline literal so the Vue original can hold
|
|
8
|
+
* the identical shape, and so a caller can keep their copy in one place.
|
|
9
|
+
*
|
|
10
|
+
* There is no `cva` here on purpose. `ChatInput` has no variants — the design
|
|
11
|
+
* draws one box — and an empty variant map would be a thing to keep in step
|
|
12
|
+
* across two packages in exchange for nothing.
|
|
13
|
+
*/
|
|
14
|
+
export interface ChatInputActionLabels {
|
|
15
|
+
/** The `+` button that starts an attachment. */
|
|
16
|
+
attach: string;
|
|
17
|
+
/** The microphone button. */
|
|
18
|
+
record: string;
|
|
19
|
+
/** The send button. */
|
|
20
|
+
send: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* What every slot is handed. The frame is the only part that knows whether
|
|
24
|
+
* the field is empty, so it passes that down rather than making each caller
|
|
25
|
+
* re-derive it.
|
|
26
|
+
*/
|
|
27
|
+
export interface ChatInputState {
|
|
28
|
+
/** The value is blank or nothing but whitespace. */
|
|
29
|
+
empty: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The whole composer is disabled. Handed over so a replaced action button
|
|
32
|
+
* goes down with the rest of it instead of staying live beside a field
|
|
33
|
+
* nobody can type in.
|
|
34
|
+
*/
|
|
35
|
+
disabled: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Submits, unless `empty` or `disabled`. The same refusal the Enter key and
|
|
38
|
+
* the send button follow.
|
|
39
|
+
*/
|
|
40
|
+
submit: () => void;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A slot: a node, or a render prop — the React translation of Vue's scoped
|
|
44
|
+
* slot.
|
|
45
|
+
*/
|
|
46
|
+
export type ChatInputSlot = ReactNode | ((state: ChatInputState) => ReactNode);
|
|
@@ -9,5 +9,10 @@ export interface ComboboxContentProps extends Omit<React.ComponentPropsWithoutRe
|
|
|
9
9
|
* `@radix-ui/react-popover` provides the portal + positioning; `cmdk`'s `Command`
|
|
10
10
|
* provides item filtering. A visually-hidden `CommandInput` receives the shared
|
|
11
11
|
* search string so typing in the anchored input filters the list.
|
|
12
|
+
*
|
|
13
|
+
* `asChild` puts the shared `Surface` where the popover content element would
|
|
14
|
+
* be, and the shared viewport where cmdk's list would be, so a combobox and a
|
|
15
|
+
* select are the same card with the same padding by construction rather than
|
|
16
|
+
* by two stylesheets agreeing.
|
|
12
17
|
*/
|
|
13
18
|
export declare const ComboboxContent: import('react').ForwardRefExoticComponent<ComboboxContentProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { CommandGroup } from 'cmdk';
|
|
2
2
|
export interface ComboboxGroupProps extends React.ComponentPropsWithoutRef<typeof CommandGroup> {
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The group heading. A node rather than a string: it is the caller's word
|
|
5
|
+
* for their own category, and taking it as text would decide for them that
|
|
6
|
+
* it can only ever be text.
|
|
7
|
+
*/
|
|
8
|
+
label?: React.ReactNode;
|
|
5
9
|
}
|
|
6
10
|
/** ComboboxGroup — a labelled set of items. */
|
|
7
11
|
export declare const ComboboxGroup: import('react').ForwardRefExoticComponent<ComboboxGroupProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -3,7 +3,12 @@ export interface ComboboxInputProps extends Omit<React.InputHTMLAttributes<HTMLI
|
|
|
3
3
|
placeholder?: string;
|
|
4
4
|
disabled?: boolean;
|
|
5
5
|
size?: InputSize;
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Overrides the text shown for the current selection. The default resolves
|
|
8
|
+
* the option's own label, so pass this only when the label is not the text:
|
|
9
|
+
* a name that comes from a server, or an option whose content is an avatar
|
|
10
|
+
* and two lines where none of them is the useful one.
|
|
11
|
+
*/
|
|
7
12
|
displayValue?: (value: unknown) => string;
|
|
8
13
|
/** Custom trigger content (defaults to a chevron icon). */
|
|
9
14
|
trigger?: React.ReactNode;
|
|
@@ -6,5 +6,9 @@ export interface ComboboxItemProps extends Omit<React.ComponentPropsWithoutRef<t
|
|
|
6
6
|
/**
|
|
7
7
|
* ComboboxItem — a selectable option, with its own check indicator.
|
|
8
8
|
* Selecting commits the value through the shared context (toggles for multiple).
|
|
9
|
+
*
|
|
10
|
+
* See `SelectItem` for why the row is shared and the primitive wrapping it is
|
|
11
|
+
* not. The indicator is always passed, even while unchecked, so the space it
|
|
12
|
+
* needs is reserved once rather than appearing the moment the row is picked.
|
|
9
13
|
*/
|
|
10
14
|
export declare const ComboboxItem: import('react').ForwardRefExoticComponent<ComboboxItemProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -21,6 +21,13 @@ export interface ComboboxContextValue {
|
|
|
21
21
|
/** Search string driving cmdk filtering. */
|
|
22
22
|
search: string;
|
|
23
23
|
setSearch: (search: string) => void;
|
|
24
|
+
/**
|
|
25
|
+
* The text each option renders, keyed by the value it selects, so the field
|
|
26
|
+
* can show `Barcelona` rather than `barcelona`. See `useComboboxLabels` for
|
|
27
|
+
* why it never forgets an entry.
|
|
28
|
+
*/
|
|
29
|
+
registerLabel: (value: string, label: string) => void;
|
|
30
|
+
labelFor: (value: string) => string | undefined;
|
|
24
31
|
}
|
|
25
32
|
export declare const ComboboxContext: import('react').Context<ComboboxContextValue | null>;
|
|
26
33
|
export declare function useComboboxContext(): ComboboxContextValue;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ComboboxLabels {
|
|
2
|
+
/** Record the text an option renders, keyed by the value it selects. */
|
|
3
|
+
register: (value: string, label: string) => void;
|
|
4
|
+
/** The recorded text for a value, or `undefined` if no option ever had it. */
|
|
5
|
+
labelFor: (value: string) => string | undefined;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* What lets the field show `Barcelona` where the caller wrote
|
|
9
|
+
* `<OxComboboxItem value="barcelona">Barcelona</OxComboboxItem>`. Port of
|
|
10
|
+
* `core/src/Forms/Inputs/Combobox/useComboboxLabels`, where Vue's
|
|
11
|
+
* `provide`/`inject` does what this hook plus `ComboboxContext` do here.
|
|
12
|
+
*
|
|
13
|
+
* **It never forgets.** That is the whole design decision, and it is not
|
|
14
|
+
* laziness: cmdk unmounts an option that does not match the search, so typing
|
|
15
|
+
* over a selection removes the very option the field is naming. A registry that
|
|
16
|
+
* dropped a label on unmount would blank the field mid-search, which is the
|
|
17
|
+
* common case, not the edge case. The cost is a label that outlives its option,
|
|
18
|
+
* which is the best answer available and strictly better than the raw value.
|
|
19
|
+
* Entries are per-root and die with it.
|
|
20
|
+
*/
|
|
21
|
+
export declare function useComboboxLabels(): ComboboxLabels;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CalendarDayState } from '../Calendar/CalendarDay.tsx';
|
|
2
|
+
import { CalendarConstraints } from '../Calendar/constraints.ts';
|
|
3
|
+
/**
|
|
4
|
+
* A field that shows the chosen day and opens a calendar to change it. Mirrors
|
|
5
|
+
* `@sesame/orxata-core` DatePicker.
|
|
6
|
+
*
|
|
7
|
+
* This is `OxCalendar` plus the three things a calendar deliberately refuses to
|
|
8
|
+
* own: a control to hang off, a popover to live in, and the opinionated header
|
|
9
|
+
* — the month and an arrow at each end — that an embedded calendar would have to
|
|
10
|
+
* strip. Nothing here reimplements any of them; `OxPopover`, `OxCalendar` and
|
|
11
|
+
* `OxDatePickerTrigger` do the work.
|
|
12
|
+
*
|
|
13
|
+
* Same date contract as the calendar: a `Date` at the boundary means the
|
|
14
|
+
* calendar day formed by its local year, month and day. The time is ignored on
|
|
15
|
+
* the way in and is local midnight on the way out.
|
|
16
|
+
*
|
|
17
|
+
* It ships no strings. The trigger shows the day formatted by `Intl` in the
|
|
18
|
+
* locale `LocaleProvider` publishes, and shows nothing at all until one is
|
|
19
|
+
* picked — a placeholder is words, so it is `children`'s to supply.
|
|
20
|
+
*/
|
|
21
|
+
export interface DatePickerProps extends Pick<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className'> {
|
|
22
|
+
/** The chosen day, or `undefined` for none. Controlled. */
|
|
23
|
+
value?: Date;
|
|
24
|
+
/** The initially chosen day, for the uncontrolled case. */
|
|
25
|
+
defaultValue?: Date;
|
|
26
|
+
onValueChange?: (value: Date | undefined) => void;
|
|
27
|
+
/** How many month grids the popover shows. */
|
|
28
|
+
months?: number;
|
|
29
|
+
/** What can be picked, and where navigation stops. Passed straight through. */
|
|
30
|
+
constraints?: CalendarConstraints;
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* What the trigger shows. Falls back to the day from `Intl`, and to nothing
|
|
34
|
+
* while none is chosen — pass one to put a placeholder there.
|
|
35
|
+
*/
|
|
36
|
+
children?: (state: {
|
|
37
|
+
value: Date | undefined;
|
|
38
|
+
}) => React.ReactNode;
|
|
39
|
+
/** The trailing glyph. Falls back to a calendar. */
|
|
40
|
+
icon?: React.ReactNode;
|
|
41
|
+
/** One day in the grid. Handed to `OxCalendar` untouched. */
|
|
42
|
+
day?: (props: {
|
|
43
|
+
date: Date;
|
|
44
|
+
state: CalendarDayState;
|
|
45
|
+
}) => React.ReactNode;
|
|
46
|
+
dataTestid: string;
|
|
47
|
+
}
|
|
48
|
+
export declare const DatePicker: {
|
|
49
|
+
({ className, value, defaultValue, onValueChange, months, constraints, disabled, children, icon, day, dataTestid, }: DatePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
50
|
+
displayName: string;
|
|
51
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { CalendarConstraints } from '../Calendar/constraints.ts';
|
|
2
|
+
import { CalendarNav } from '../Calendar/nav.ts';
|
|
3
|
+
export interface DatePickerHeaderProps {
|
|
4
|
+
/** Everything the calendar's `header` render prop hands over, passed in. */
|
|
5
|
+
nav: CalendarNav;
|
|
6
|
+
/**
|
|
7
|
+
* The same object the calendar was given. Published to `children` rather than
|
|
8
|
+
* read here: the year selector offers the years `from` and `to` allow, which
|
|
9
|
+
* `canGoPrev` and `canGoNext` cannot answer for.
|
|
10
|
+
*/
|
|
11
|
+
constraints?: CalendarConstraints;
|
|
12
|
+
/**
|
|
13
|
+
* What sits between the arrows. Falls back to the months on screen, named by
|
|
14
|
+
* `Intl`. Fill it with the two selectors to get the design's month-and-year
|
|
15
|
+
* variant, or with anything else that should be centred there.
|
|
16
|
+
*/
|
|
17
|
+
children?: React.ReactNode;
|
|
18
|
+
dataTestid: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The header `Calendar` deliberately does not draw: one arrow at each end, and
|
|
22
|
+
* whatever names the months between them. Mirrors `@sesame/orxata-core`
|
|
23
|
+
* DatePickerHeader.
|
|
24
|
+
*
|
|
25
|
+
* It exists as its own component because the two pickers share it and because
|
|
26
|
+
* an embedded `OxCalendar` can wear it too —
|
|
27
|
+
*
|
|
28
|
+
* ```tsx
|
|
29
|
+
* <OxCalendar
|
|
30
|
+
* header={nav => <OxDatePickerHeader nav={nav} dataTestid="calendar-header" />}
|
|
31
|
+
* />
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* **Two arrows, not four.** There used to be a year jump at each end as well,
|
|
35
|
+
* because stepping a month at a time is no way to reach a birth year. The
|
|
36
|
+
* design answers that with a pair of dropdowns instead, which is both a shorter
|
|
37
|
+
* journey and one that says where it is going — so the outer arrows are gone
|
|
38
|
+
* and `OxDatePickerMonthSelect` / `OxDatePickerYearSelect` go in `children`:
|
|
39
|
+
*
|
|
40
|
+
* ```tsx
|
|
41
|
+
* <OxDatePickerHeader nav={nav} constraints={constraints} dataTestid="head">
|
|
42
|
+
* <OxDatePickerMonthSelect dataTestid="head-month" />
|
|
43
|
+
* <OxDatePickerYearSelect dataTestid="head-year" />
|
|
44
|
+
* </OxDatePickerHeader>
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* `nav.goTo` survives the loss of the year arrows and is now what the selectors
|
|
48
|
+
* run on: stepping cannot express "the same month in 1974", and in React it
|
|
49
|
+
* cannot even accumulate — each `goToNext` is computed from the month of the
|
|
50
|
+
* render that produced it.
|
|
51
|
+
*
|
|
52
|
+
* **An arrow is absent, not disabled, when there is nothing that way.** The
|
|
53
|
+
* design has two independent show/hide axes for them and draws no disabled
|
|
54
|
+
* state, and `canGoPrev` / `canGoNext` already say exactly when a step is
|
|
55
|
+
* possible — so they drive presence rather than a second boolean the caller
|
|
56
|
+
* would have to keep in step with `constraints`.
|
|
57
|
+
*
|
|
58
|
+
* It ships no strings. The title is `Intl`'s, and each arrow announces the
|
|
59
|
+
* month it would move to, which is a date the locale formats rather than a
|
|
60
|
+
* phrase we would have to translate.
|
|
61
|
+
*/
|
|
62
|
+
export declare const DatePickerHeader: {
|
|
63
|
+
({ nav, constraints, children, dataTestid, }: DatePickerHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
64
|
+
displayName: string;
|
|
65
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface DatePickerMonthSelectProps {
|
|
2
|
+
dataTestid: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* The month half of the design's "Month and Year Selector" header. Goes in
|
|
6
|
+
* `OxDatePickerHeader`'s `children`, beside `OxDatePickerYearSelect`. Mirrors
|
|
7
|
+
* `@sesame/orxata-core` DatePickerMonthSelect.
|
|
8
|
+
*
|
|
9
|
+
* It reads the visible month and the bounds out of the header's context rather
|
|
10
|
+
* than taking them as props: they are the header's already, and a part that
|
|
11
|
+
* asked for them again would put `nav` on the public API of every piece of a
|
|
12
|
+
* header a caller assembles.
|
|
13
|
+
*
|
|
14
|
+
* Twelve options, named by `Intl` in the locale `LocaleProvider` publishes —
|
|
15
|
+
* this ships no month names of its own. A month the bounds put out of reach is
|
|
16
|
+
* offered and disabled rather than dropped, so the list is the same twelve rows
|
|
17
|
+
* in the same order whatever the constraints say.
|
|
18
|
+
*
|
|
19
|
+
* The trigger carries no `aria-label`, and that is the no-strings rule rather
|
|
20
|
+
* than an oversight: the only honest label would be the word "month" in the
|
|
21
|
+
* user's language, which this package does not have. What it announces is its
|
|
22
|
+
* role and its value, and its value is the month it is showing.
|
|
23
|
+
*/
|
|
24
|
+
export declare const DatePickerMonthSelect: {
|
|
25
|
+
({ dataTestid, }: DatePickerMonthSelectProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
displayName: string;
|
|
27
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface DatePickerTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
2
|
+
/**
|
|
3
|
+
* Nothing chosen yet. Dims the content and marks the button
|
|
4
|
+
* `data-placeholder`, the flag `OxSelectTrigger` already uses for the same
|
|
5
|
+
* state — so the styling is a boolean and not a second slot.
|
|
6
|
+
*/
|
|
7
|
+
empty?: boolean;
|
|
8
|
+
/** The trailing glyph. Falls back to a calendar. */
|
|
9
|
+
icon?: React.ReactNode;
|
|
10
|
+
dataTestid: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The closed control both pickers hang off: what is chosen on one side, a
|
|
14
|
+
* calendar glyph on the other. Mirrors `@sesame/orxata-core` DatePickerTrigger.
|
|
15
|
+
*
|
|
16
|
+
* It is one component and not two copies because the alternative is two
|
|
17
|
+
* stylesheets describing the same control. That is exactly how `OxSelect` and
|
|
18
|
+
* `OxCombobox` came to disagree about a radius, a border and a background, and
|
|
19
|
+
* the fix cost more than the component.
|
|
20
|
+
*
|
|
21
|
+
* It takes no size prop: height and radius come from the `--controller-*`
|
|
22
|
+
* variables every input in the package reads, so `inputSizeClass[size]` on any
|
|
23
|
+
* ancestor sizes it. Its declarations are `OxSelectTrigger`'s, so the two sit
|
|
24
|
+
* level in one form.
|
|
25
|
+
*
|
|
26
|
+
* It shows what it is given and formats nothing. A date is a date in a locale,
|
|
27
|
+
* and the picker above it is the one holding the locale.
|
|
28
|
+
*/
|
|
29
|
+
export declare const DatePickerTrigger: import('react').ForwardRefExoticComponent<DatePickerTriggerProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface DatePickerYearSelectProps {
|
|
2
|
+
dataTestid: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* The year half of the design's "Month and Year Selector" header. Goes in
|
|
6
|
+
* `OxDatePickerHeader`'s `children`, beside `OxDatePickerMonthSelect`. Mirrors
|
|
7
|
+
* `@sesame/orxata-core` DatePickerYearSelect.
|
|
8
|
+
*
|
|
9
|
+
* This is what replaced the header's year arrows. Stepping a year at a time is
|
|
10
|
+
* no way to reach a birth year, and it was the arrows' only justification; a
|
|
11
|
+
* list says where it is going and gets there in one move.
|
|
12
|
+
*
|
|
13
|
+
* **Which years it offers.** Exactly the ones `constraints` allows, when there
|
|
14
|
+
* are constraints — that is the only statement about reachable dates this
|
|
15
|
+
* package will believe. With none, there is no bound to read and any window is
|
|
16
|
+
* a guess, so it takes the documented default in `month.ts`: deep enough behind
|
|
17
|
+
* the visible year to hold a date of birth, shallow enough ahead to stay a
|
|
18
|
+
* list. A caller who wants another window passes `constraints`.
|
|
19
|
+
*
|
|
20
|
+
* No `aria-label`, for the reason `OxDatePickerMonthSelect` gives.
|
|
21
|
+
*/
|
|
22
|
+
export declare const DatePickerYearSelect: {
|
|
23
|
+
({ dataTestid, }: DatePickerYearSelectProps): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
displayName: string;
|
|
25
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { CalendarDayState } from '../Calendar/CalendarDay.tsx';
|
|
2
|
+
import { CalendarDateRange } from '../Calendar/CalendarRange.tsx';
|
|
3
|
+
import { CalendarConstraints } from '../Calendar/constraints.ts';
|
|
4
|
+
/**
|
|
5
|
+
* A field that shows the chosen span and opens a range calendar to change it.
|
|
6
|
+
* Mirrors `@sesame/orxata-core` DateRangePicker.
|
|
7
|
+
*
|
|
8
|
+
* A sibling of `OxDatePicker` with its own API, the same way `OxCalendarRange`
|
|
9
|
+
* is a sibling of `OxCalendar` — not a mode of it.
|
|
10
|
+
*
|
|
11
|
+
* Two months by default, because a span usually crosses one. The trigger shows
|
|
12
|
+
* the span collapsed the way the locale collapses one (`12–15 mar 2026`), from
|
|
13
|
+
* `Intl.DateTimeFormat.formatRange` where the runtime has it.
|
|
14
|
+
*
|
|
15
|
+
* There is an `aside` render prop beside the grids and nothing in it. Presets
|
|
16
|
+
* are the obvious thing to put there, and they are entirely the caller's: the
|
|
17
|
+
* design system ships no list, no exported constant of one, and no function
|
|
18
|
+
* that knows what "this week" means. It lays the column out and hands over
|
|
19
|
+
* `select`, which sets the span and closes the popover — whether the column
|
|
20
|
+
* holds shortcuts, a legend or a summary is not this component's business.
|
|
21
|
+
*/
|
|
22
|
+
export interface DateRangePickerProps extends Pick<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className'> {
|
|
23
|
+
/** The chosen span. Either end may be absent while one is being picked. */
|
|
24
|
+
value?: CalendarDateRange;
|
|
25
|
+
/** The initially chosen span, for the uncontrolled case. */
|
|
26
|
+
defaultValue?: CalendarDateRange;
|
|
27
|
+
onValueChange?: (value: CalendarDateRange) => void;
|
|
28
|
+
/** How many month grids the popover shows. */
|
|
29
|
+
months?: number;
|
|
30
|
+
/** What can be picked, and where navigation stops. Passed straight through. */
|
|
31
|
+
constraints?: CalendarConstraints;
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* What the trigger shows. Falls back to the span from `Intl`, and to nothing
|
|
35
|
+
* while neither end is chosen — pass one to put a placeholder there.
|
|
36
|
+
*/
|
|
37
|
+
children?: (state: {
|
|
38
|
+
value: CalendarDateRange | undefined;
|
|
39
|
+
}) => React.ReactNode;
|
|
40
|
+
/** The trailing glyph. Falls back to a calendar. */
|
|
41
|
+
icon?: React.ReactNode;
|
|
42
|
+
/**
|
|
43
|
+
* A column beside the grids. Receives `select`, which sets the span and
|
|
44
|
+
* closes the popover in one call — so whatever goes in here behaves like a
|
|
45
|
+
* second click. Not called until you pass one, and the column is not drawn at
|
|
46
|
+
* all until then.
|
|
47
|
+
*/
|
|
48
|
+
aside?: (state: {
|
|
49
|
+
select: (value: CalendarDateRange) => void;
|
|
50
|
+
}) => React.ReactNode;
|
|
51
|
+
/** One day in the grid. Handed to `OxCalendarRange` untouched. */
|
|
52
|
+
day?: (props: {
|
|
53
|
+
date: Date;
|
|
54
|
+
state: CalendarDayState;
|
|
55
|
+
}) => React.ReactNode;
|
|
56
|
+
dataTestid: string;
|
|
57
|
+
}
|
|
58
|
+
export declare const DateRangePicker: {
|
|
59
|
+
({ className, value, defaultValue, onValueChange, months, constraints, disabled, children, icon, aside, day, dataTestid, }: DateRangePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
60
|
+
displayName: string;
|
|
61
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a picker writes a date down.
|
|
3
|
+
*
|
|
4
|
+
* Everything here goes through `Intl` and the tag `LocaleProvider` publishes,
|
|
5
|
+
* so the design system ships no strings: the only characters it contributes are
|
|
6
|
+
* the separator a runtime too old for `formatRange` never gets from CLDR.
|
|
7
|
+
* Internal — none of it is exported from the package, because a caller who
|
|
8
|
+
* wants a different format fills the trigger slot with their own.
|
|
9
|
+
*/
|
|
10
|
+
/** One day, in the locale's medium form — `12 mar 2026`, `Mar 12, 2026`. */
|
|
11
|
+
export declare const formatDay: (locale: string, date: Date) => string;
|
|
12
|
+
/**
|
|
13
|
+
* A span, collapsed the way the locale collapses one: `12–15 mar 2026` rather
|
|
14
|
+
* than the two ends spelled out in full.
|
|
15
|
+
*
|
|
16
|
+
* A half-made span is the start alone. It is not an error state — it is the
|
|
17
|
+
* moment between the two clicks, and `CalendarDateRange` makes both ends
|
|
18
|
+
* optional precisely so it can be shown.
|
|
19
|
+
*/
|
|
20
|
+
export declare const formatDayRange: (locale: string, start: Date | undefined, end: Date | undefined) => string;
|
|
21
|
+
/**
|
|
22
|
+
* The month a header names, and what its navigation announces.
|
|
23
|
+
*
|
|
24
|
+
* Capitalisation is left to CSS: `Intl` lowercases the month in Spanish and
|
|
25
|
+
* capitalises it in English, and uppercasing it here would be the design system
|
|
26
|
+
* overruling the locale in the one place it has no business doing so.
|
|
27
|
+
*/
|
|
28
|
+
export declare const formatMonthYear: (locale: string, month: Date) => string;
|
|
29
|
+
/**
|
|
30
|
+
* The months on screen when there is more than one of them — `March – April
|
|
31
|
+
* 2026`, with the year said once where the locale says it once.
|
|
32
|
+
*/
|
|
33
|
+
export declare const formatMonthYearRange: (locale: string, first: Date, last: Date) => string;
|
|
34
|
+
/** The year alone, for the year selector's options and its current value. */
|
|
35
|
+
export declare const formatYear: (locale: string, month: Date) => string;
|
|
36
|
+
/**
|
|
37
|
+
* The month alone and abbreviated — `Jan`, `ene`, `1月` — which is what the
|
|
38
|
+
* month selector shows and what the design draws in it.
|
|
39
|
+
*
|
|
40
|
+
* `Intl` and not a table of our own, for the reason `Calendar` spells out: the
|
|
41
|
+
* names belong to the runtime's locale, not to a translation this package would
|
|
42
|
+
* have to carry.
|
|
43
|
+
*/
|
|
44
|
+
export declare const formatMonthShort: (locale: string, month: Date) => string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { DatePicker, type DatePickerProps } from './DatePicker.tsx';
|
|
2
|
+
export { DateRangePicker, type DateRangePickerProps, } from './DateRangePicker.tsx';
|
|
3
|
+
export { DatePickerTrigger, type DatePickerTriggerProps, } from './DatePickerTrigger.tsx';
|
|
4
|
+
export { DatePickerHeader, type DatePickerHeaderProps, } from './DatePickerHeader.tsx';
|
|
5
|
+
export { DatePickerMonthSelect, type DatePickerMonthSelectProps, } from './DatePickerMonthSelect.tsx';
|
|
6
|
+
export { DatePickerYearSelect, type DatePickerYearSelectProps, } from './DatePickerYearSelect.tsx';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Month arithmetic the header and its two selectors all need. Mirrors
|
|
3
|
+
* `@sesame/orxata-core` `DatePicker/month.ts`.
|
|
4
|
+
*
|
|
5
|
+
* Shared rather than repeated because the comparison has to be the same one
|
|
6
|
+
* `Calendar` makes: bounds are read by month, so a `from` set mid-month does
|
|
7
|
+
* not hide the month it sits in.
|
|
8
|
+
*/
|
|
9
|
+
/** Months since year zero, so two months compare as two numbers. */
|
|
10
|
+
export declare const monthIndex: (date: Date) => number;
|
|
11
|
+
/** The first day of the month `offsetInMonths` away from `date`. */
|
|
12
|
+
export declare const monthOf: (date: Date, offsetInMonths?: number) => Date;
|
|
13
|
+
/**
|
|
14
|
+
* How far the year selector reaches when nothing bounds it.
|
|
15
|
+
*
|
|
16
|
+
* A birth year is the case that makes a year selector worth having at all, so
|
|
17
|
+
* the window has to be deep enough to hold one; forward it only has to cover
|
|
18
|
+
* the scheduling a caller who set no bounds could plausibly want. Both are
|
|
19
|
+
* defaults a caller overrides by passing `constraints`, which is the only
|
|
20
|
+
* statement about reachable dates this package will believe.
|
|
21
|
+
*/
|
|
22
|
+
export declare const YEARS_BACK = 100;
|
|
23
|
+
export declare const YEARS_FORWARD = 10;
|
|
24
|
+
/** The inclusive year range the year selector offers. */
|
|
25
|
+
export declare const yearRange: (visible: Date, from?: Date, to?: Date) => {
|
|
26
|
+
first: number;
|
|
27
|
+
last: number;
|
|
28
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CalendarConstraints } from '../Calendar/constraints.ts';
|
|
2
|
+
import { CalendarNav } from '../Calendar/nav.ts';
|
|
3
|
+
/**
|
|
4
|
+
* What `DatePickerHeader` publishes to whatever is put inside it. Mirrors
|
|
5
|
+
* `@sesame/orxata-core` `useDatePickerHeader`.
|
|
6
|
+
*
|
|
7
|
+
* The two selectors need the visible month, a way to jump to another one, and
|
|
8
|
+
* the bounds that say which months exist — the same three things the header
|
|
9
|
+
* itself is given. Passing them down as props would be prop drilling through
|
|
10
|
+
* `children`, and would put `nav` on the public API of every part.
|
|
11
|
+
*/
|
|
12
|
+
export interface DatePickerHeaderContextValue {
|
|
13
|
+
nav: CalendarNav;
|
|
14
|
+
constraints?: CalendarConstraints;
|
|
15
|
+
}
|
|
16
|
+
export declare const DatePickerHeaderContext: import('react').Context<DatePickerHeaderContextValue | null>;
|
|
17
|
+
/**
|
|
18
|
+
* The message is spelled identically in `@sesame/orxata-core`. A part that
|
|
19
|
+
* escapes its header is the same mistake in both packages, and a developer who
|
|
20
|
+
* meets it twice should not have to recognise two wordings of it.
|
|
21
|
+
*/
|
|
22
|
+
export declare const DATE_PICKER_HEADER_MISSING = "OxDatePickerMonthSelect and OxDatePickerYearSelect must be rendered inside OxDatePickerHeader.";
|
|
23
|
+
export declare const useDatePickerHeader: () => DatePickerHeaderContextValue;
|
|
@@ -5,5 +5,12 @@ import { InputOtpProps } from './types.ts';
|
|
|
5
5
|
* Radix ships no PinInput, so the behaviour lives here — focus advance,
|
|
6
6
|
* backspace, arrow keys, paste spreading, per-slot labels — and reaches the
|
|
7
7
|
* slots through context. One `<input>` per slot.
|
|
8
|
+
*
|
|
9
|
+
* `role="group"` is here unconditionally, not just inside a field. A bare
|
|
10
|
+
* `<div>` cannot take a name from the author — so without the role the slots
|
|
11
|
+
* announce as anonymous text fields and the `aria-labelledby` below would be
|
|
12
|
+
* dropped on the floor. Outside an `<OxFieldGroup>` the group has no name,
|
|
13
|
+
* which is correct: the design system ships no strings, so there is nothing to
|
|
14
|
+
* call it.
|
|
8
15
|
*/
|
|
9
16
|
export declare const InputOtp: import('react').ForwardRefExoticComponent<InputOtpProps & import('react').RefAttributes<HTMLDivElement>>;
|