@sesamehr/react-design-system 1.6.1 → 2.0.0-beta.10
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/README.md +34 -0
- package/dist/Button/ActionItem/ActionItem.d.ts +40 -0
- package/dist/Button/ActionItem/index.d.ts +1 -0
- package/dist/Button/IconButton/IconButton.d.ts +32 -0
- package/dist/Button/IconButton/index.d.ts +27 -0
- package/dist/Data/Table/Table.d.ts +1 -1
- package/dist/Data/Table/TableBody/TableBody.d.ts +3 -0
- package/dist/Data/Table/TableHead/TableHead.d.ts +25 -1
- package/dist/Data/Table/TableScrollbar/TableScrollbar.d.ts +21 -0
- package/dist/Data/Table/TableSelectCell/TableSelectCell.d.ts +8 -0
- package/dist/Data/Table/TableVirtualized/TableVirtualized.d.ts +45 -0
- package/dist/Data/Table/TableVirtualized/index.d.ts +2 -0
- package/dist/Data/Table/hooks/index.d.ts +3 -0
- package/dist/Data/Table/hooks/useDragToScroll/useDragToScroll.d.ts +12 -2
- package/dist/Data/Table/hooks/useTableVirtual/context.d.ts +16 -0
- package/dist/Data/Table/hooks/useTableVirtual/index.d.ts +3 -0
- package/dist/Data/Table/hooks/useTableVirtual/useTableVirtual.d.ts +36 -0
- package/dist/Data/Table/hooks/useTableVirtual/useTableVirtual.types.d.ts +74 -0
- package/dist/Data/Table/index.d.ts +2 -2
- package/dist/Display/Avatar/AvatarSkeleton/AvatarSkeleton.d.ts +30 -0
- package/dist/Display/Avatar/index.d.ts +2 -0
- package/dist/Display/AvatarDetails/AvatarDetails.d.ts +68 -0
- package/dist/Display/AvatarDetails/index.d.ts +1 -0
- package/dist/Display/Badge/Badge.d.ts +3 -2
- package/dist/Display/Badge/index.d.ts +10 -1
- package/dist/Display/ChatBubble/ChatBubble.d.ts +28 -0
- package/dist/Display/ChatBubble/ChatBubbleStatus/ChatBubbleStatus.d.ts +8 -0
- package/dist/Display/ChatBubble/ChatBubbleStatus/index.d.ts +10 -0
- package/dist/Display/ChatBubble/index.d.ts +44 -0
- package/dist/Display/Chip/Chip.d.ts +21 -5
- package/dist/Display/Chip/index.d.ts +19 -10
- 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/Loader/Loader.d.ts +16 -0
- package/dist/Feedback/Loader/index.d.ts +2 -0
- package/dist/Feedback/Popover/PopoverContent.d.ts +0 -1
- package/dist/Feedback/Progress/Progress.d.ts +3 -0
- package/dist/Feedback/Progress/index.d.ts +17 -0
- package/dist/Feedback/Skeleton/Skeleton.d.ts +20 -0
- package/dist/Feedback/Skeleton/index.d.ts +2 -0
- package/dist/Feedback/Tooltip/TooltipContent.d.ts +0 -1
- package/dist/Forms/Field/Counter/Counter.d.ts +9 -0
- package/dist/Forms/Field/Counter/index.d.ts +13 -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 +55 -0
- package/dist/Forms/Inputs/Calendar/CalendarDay.d.ts +37 -0
- package/dist/Forms/Inputs/Calendar/CalendarRange.d.ts +56 -0
- package/dist/Forms/Inputs/Calendar/constraints.d.ts +19 -0
- package/dist/Forms/Inputs/Calendar/date.d.ts +28 -0
- package/dist/Forms/Inputs/Calendar/index.d.ts +21 -0
- package/dist/Forms/Inputs/Calendar/nav.d.ts +34 -0
- package/dist/Forms/Inputs/Calendar/testids.d.ts +28 -0
- package/dist/Forms/Inputs/Calendar/useCalendarLocale.d.ts +40 -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/ComboboxCancel.d.ts +14 -0
- package/dist/Forms/Inputs/Combobox/ComboboxChipsInput.d.ts +4 -0
- package/dist/Forms/Inputs/Combobox/ComboboxContent.d.ts +0 -6
- 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/ComboboxItemEdit.d.ts +124 -0
- package/dist/Forms/Inputs/Combobox/context.d.ts +15 -1
- package/dist/Forms/Inputs/Combobox/index.d.ts +2 -0
- package/dist/Forms/Inputs/Combobox/useChipOverflow.d.ts +30 -0
- package/dist/Forms/Inputs/Combobox/useComboboxEditing.d.ts +40 -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/SearchBar.d.ts +35 -0
- package/dist/Forms/Inputs/SearchBar/index.d.ts +22 -0
- package/dist/Forms/Inputs/SearchBar/useSearchDelay.d.ts +24 -0
- 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 +11 -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 +0 -4
- 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 +6 -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/lib/cssModules.d.ts +13 -0
- package/dist/main.d.ts +18 -7
- package/dist/preflight.css +391 -0
- package/dist/react-design-system.css +1 -1
- package/dist/react-design-system.js +17345 -10589
- package/dist/react-design-system.umd.cjs +164 -117
- package/package.json +4 -2
- package/src/assets/styles/theme-v2.css +6 -6
- package/src/assets/styles/theme-v3.css +13 -5
- package/dist/Data/Table/TableAvatar/TableAvatar.d.ts +0 -14
- package/dist/Display/Tag/Tag.d.ts +0 -19
- package/dist/Display/Tag/index.d.ts +0 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ComboboxEditing } from './useComboboxEditing.ts';
|
|
1
2
|
/**
|
|
2
3
|
* Shared Combobox state.
|
|
3
4
|
*
|
|
@@ -6,7 +7,7 @@
|
|
|
6
7
|
* every part needs — the value, `multiple`, `disabled` and the search term — so
|
|
7
8
|
* a part can be used on its own without threading props through the tree.
|
|
8
9
|
*/
|
|
9
|
-
export interface ComboboxContextValue {
|
|
10
|
+
export interface ComboboxContextValue extends ComboboxEditing {
|
|
10
11
|
/** Current selection. `string` for single-select, `string[]` for multiple. */
|
|
11
12
|
value: string | string[] | undefined;
|
|
12
13
|
/** Commit a selection (toggles for `multiple`). */
|
|
@@ -21,6 +22,19 @@ export interface ComboboxContextValue {
|
|
|
21
22
|
/** Search string driving cmdk filtering. */
|
|
22
23
|
search: string;
|
|
23
24
|
setSearch: (search: string) => void;
|
|
25
|
+
/**
|
|
26
|
+
* The text each option renders, keyed by the value it selects, so the field
|
|
27
|
+
* can show `Barcelona` rather than `barcelona`. See `useComboboxLabels` for
|
|
28
|
+
* why it never forgets an entry.
|
|
29
|
+
*/
|
|
30
|
+
registerLabel: (value: string, label: string) => void;
|
|
31
|
+
labelFor: (value: string) => string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* The field itself, so a row that took focus for an in-place edit can hand it
|
|
34
|
+
* back when the edit ends. reka carries the same element on its own combobox
|
|
35
|
+
* context, which is where the Vue half gets it.
|
|
36
|
+
*/
|
|
37
|
+
inputRef: React.RefObject<HTMLInputElement | null>;
|
|
24
38
|
}
|
|
25
39
|
export declare const ComboboxContext: import('react').Context<ComboboxContextValue | null>;
|
|
26
40
|
export declare function useComboboxContext(): ComboboxContextValue;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export { Combobox, type ComboboxProps } from './Combobox.tsx';
|
|
2
|
+
export { ComboboxCancel, type ComboboxCancelProps } from './ComboboxCancel.tsx';
|
|
2
3
|
export { ComboboxInput, type ComboboxInputProps } from './ComboboxInput.tsx';
|
|
3
4
|
export { ComboboxChipsInput, type ComboboxChipsInputProps, } from './ComboboxChipsInput.tsx';
|
|
4
5
|
export { ComboboxContent, type ComboboxContentProps, } from './ComboboxContent.tsx';
|
|
5
6
|
export { ComboboxItem, type ComboboxItemProps } from './ComboboxItem.tsx';
|
|
7
|
+
export { ComboboxItemEdit, type ComboboxItemEditProps, } from './ComboboxItemEdit.tsx';
|
|
6
8
|
export { ComboboxEmpty, type ComboboxEmptyProps } from './ComboboxEmpty.tsx';
|
|
7
9
|
export { ComboboxGroup, type ComboboxGroupProps } from './ComboboxGroup.tsx';
|
|
8
10
|
export { ComboboxSeparator, type ComboboxSeparatorProps, } from './ComboboxSeparator.tsx';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
export interface ChipOverflowTargets {
|
|
3
|
+
/**
|
|
4
|
+
* The single-line row holding the chips, the `+N` counter and the query
|
|
5
|
+
* field. Its width is the whole budget, which only holds because the row is
|
|
6
|
+
* laid out `flex: 1 1 0` with `min-width: 0` — its width is then whatever its
|
|
7
|
+
* siblings leave behind and owes nothing to its own content. Measuring an
|
|
8
|
+
* element whose size depends on how many chips we decided to show is exactly
|
|
9
|
+
* what turns this into an infinite loop.
|
|
10
|
+
*/
|
|
11
|
+
row: RefObject<HTMLElement | null>;
|
|
12
|
+
/** Offscreen stand-in for the `+N` counter, rendered at its widest. */
|
|
13
|
+
sizer: RefObject<HTMLElement | null>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Decides how many chips of a multi-select field fit on one line.
|
|
17
|
+
*
|
|
18
|
+
* The chips past the edge are not removed from the DOM — the component keeps
|
|
19
|
+
* them rendered and takes them out of flow — so every chip reports its natural
|
|
20
|
+
* width on every pass, whether or not it is currently shown. That is the whole
|
|
21
|
+
* trick: nothing measured here changes as a result of what is decided here, so
|
|
22
|
+
* a measurement can never provoke the measurement that follows it.
|
|
23
|
+
*
|
|
24
|
+
* With no layout at all — a test environment, the tick before styles land —
|
|
25
|
+
* every width reads zero, `0 <= 0` holds, and the answer is "all of them".
|
|
26
|
+
* Showing the full selection is the right way to be wrong: it is what the field
|
|
27
|
+
* did before, and it fails towards markup that shows too much rather than a
|
|
28
|
+
* field that hides its own contents.
|
|
29
|
+
*/
|
|
30
|
+
export declare function useChipOverflow({ row, sizer }: ChipOverflowTargets, total: number): number;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface ComboboxEditing {
|
|
2
|
+
/** The row entering its editing state announces how to back out of it. */
|
|
3
|
+
openEdit: (cancel: () => void) => void;
|
|
4
|
+
/** The row leaving its editing state withdraws that offer. */
|
|
5
|
+
closeEdit: (cancel: () => void) => void;
|
|
6
|
+
/**
|
|
7
|
+
* Back out of the open edit, if there is one. Returns whether there was —
|
|
8
|
+
* the caller uses that to decide whether the keystroke has been spent.
|
|
9
|
+
*/
|
|
10
|
+
cancelOpenEdit: () => boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Which row, if any, is currently being edited in place. Port of
|
|
14
|
+
* `core/src/Forms/Inputs/Combobox/useComboboxEditing`, where Vue's
|
|
15
|
+
* `provide`/`inject` does what this hook plus `ComboboxContext` do here.
|
|
16
|
+
*
|
|
17
|
+
* It exists for one keystroke. `Escape` inside the edit has to cancel the edit
|
|
18
|
+
* and leave the list open, and the only thing that can stop the list closing is
|
|
19
|
+
* the content's `onEscapeKeyDown`: Radix's dismissable layer listens on
|
|
20
|
+
* `document` with `capture: true`, so the editing field never sees the key
|
|
21
|
+
* first and cannot swallow it however hard it tries. The layer offers exactly
|
|
22
|
+
* one way out — `preventDefault()` on the event it hands up. So the content is
|
|
23
|
+
* where `Escape` has to be answered, the state is in the row, and this is the
|
|
24
|
+
* wire between them.
|
|
25
|
+
*
|
|
26
|
+
* The Vue half reaches the same arrangement from the opposite constraint: reka
|
|
27
|
+
* listens on `window` in the bubble phase, so there the field *would* see the
|
|
28
|
+
* key first, and handling it in both places would close the edit before the
|
|
29
|
+
* content was asked whether to prevent the dismissal — closing the list, which
|
|
30
|
+
* is the one thing this must not do. One mechanism, in the content, on both
|
|
31
|
+
* sides.
|
|
32
|
+
*
|
|
33
|
+
* A ref rather than state: nothing renders differently for knowing which row is
|
|
34
|
+
* open, and the only reader is an event handler, which wants the current value
|
|
35
|
+
* and not the one captured when it was last rendered.
|
|
36
|
+
*
|
|
37
|
+
* One edit at a time, and opening a second cancels the first: two rows in edit
|
|
38
|
+
* mode have two answers to `Escape` and no way to say which one the user meant.
|
|
39
|
+
*/
|
|
40
|
+
export declare function useComboboxEditing(): ComboboxEditing;
|
|
@@ -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>>;
|
|
@@ -15,6 +15,14 @@ export interface InputPasswordProps extends Omit<React.HTMLAttributes<HTMLDivEle
|
|
|
15
15
|
* InputPassword root — mirrors `@sesame/orxata-core` InputPassword.
|
|
16
16
|
* Provides the value and clear-text state to `InputPasswordInput` and
|
|
17
17
|
* `InputPasswordToggle` through context.
|
|
18
|
-
*
|
|
18
|
+
*
|
|
19
|
+
* Both `field` and `visible` work controlled or uncontrolled, and which one
|
|
20
|
+
* you get depends on **whether the change handler is there, not whether the
|
|
21
|
+
* value is**. The Vue original is a pair of `defineModel`s, and a
|
|
22
|
+
* `defineModel` given a value but no listener keeps driving itself. Gate on
|
|
23
|
+
* the value alone and `visible={false}` — a perfectly ordinary way to say
|
|
24
|
+
* "start hidden" — turns the reveal toggle into a dead button: `toggle()`
|
|
25
|
+
* computes the next state, declines to store it because the prop is present,
|
|
26
|
+
* and calls a handler nobody passed.
|
|
19
27
|
*/
|
|
20
28
|
export declare const InputPassword: import('react').ForwardRefExoticComponent<InputPasswordProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -12,5 +12,14 @@ export interface InputTextProps extends Omit<React.InputHTMLAttributes<HTMLInput
|
|
|
12
12
|
* `field` + `onFieldChange` are the controlled pair; native `value`/`onChange`
|
|
13
13
|
* still pass through via `...props` for anyone who prefers them. `type`
|
|
14
14
|
* defaults to `'text'`, and a `type` passed by the caller wins.
|
|
15
|
+
*
|
|
16
|
+
* **`field` alone does not mean "controlled" — `field` *with* `onFieldChange`
|
|
17
|
+
* does.** The Vue original is a `defineModel`, and a `defineModel` only hands
|
|
18
|
+
* control to the parent when the parent actually listens; given a value and no
|
|
19
|
+
* listener it seeds its own state and goes on working. Port `field` as
|
|
20
|
+
* unconditionally controlled and that same usage becomes an input pinned to
|
|
21
|
+
* its initial value with nothing able to change it — one that silently will
|
|
22
|
+
* not accept a keystroke. Which is exactly what `<OxInputText field="" />`
|
|
23
|
+
* did, in the story and in any app that wrote it.
|
|
15
24
|
*/
|
|
16
25
|
export declare const InputText: import('react').ForwardRefExoticComponent<InputTextProps & import('react').RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { SearchBarVariants } from './index.ts';
|
|
2
|
+
export interface SearchBarProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'value' | 'defaultValue'> {
|
|
3
|
+
variant?: SearchBarVariants['variant'];
|
|
4
|
+
size?: SearchBarVariants['size'];
|
|
5
|
+
/**
|
|
6
|
+
* Milliseconds of no typing before `onSearch` fires. `0` fires on every
|
|
7
|
+
* keystroke.
|
|
8
|
+
*/
|
|
9
|
+
delay?: number;
|
|
10
|
+
/** Controlled term. Pair with `onValueChange`; omit for uncontrolled. */
|
|
11
|
+
value?: string;
|
|
12
|
+
/** Starting term when uncontrolled. */
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
/** Called on every keystroke with the next term, without waiting. */
|
|
15
|
+
onValueChange?: (value: string) => void;
|
|
16
|
+
/** Called once typing has been quiet for `delay` ms — and at once on Enter or clear. */
|
|
17
|
+
onSearch?: (term: string) => void;
|
|
18
|
+
dataTestid: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A search field: magnifier, term, and a clear button once there is something
|
|
22
|
+
* to clear. Mirrors `@sesame/orxata-core` SearchBar.
|
|
23
|
+
*
|
|
24
|
+
* Written on a native `<input type="search">` rather than on a primitive
|
|
25
|
+
* because there is no primitive to start from — Radix has no search component,
|
|
26
|
+
* and shadcn's own `Input` is a bare element too. Nothing here needs what a
|
|
27
|
+
* primitive would bring: no portal, no focus trap, no escape handling. The one
|
|
28
|
+
* browser affordance it *does* bring — WebKit's built-in cancel button — is
|
|
29
|
+
* turned off in the stylesheet, since we draw our own.
|
|
30
|
+
*
|
|
31
|
+
* `className` lands on the root, which is the box; everything else a native
|
|
32
|
+
* `<input>` takes — `placeholder`, `name`, `disabled`, `aria-label` — falls
|
|
33
|
+
* through to the control. The `ref` is the root for the same reason.
|
|
34
|
+
*/
|
|
35
|
+
export declare const SearchBar: import('react').ForwardRefExoticComponent<SearchBarProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { VariantProps } from 'class-variance-authority';
|
|
2
|
+
export { SearchBar } from './SearchBar.tsx';
|
|
3
|
+
export type { SearchBarProps } from './SearchBar.tsx';
|
|
4
|
+
export { useSearchDelay } from './useSearchDelay.ts';
|
|
5
|
+
export type { UseSearchDelayReturn } from './useSearchDelay.ts';
|
|
6
|
+
/**
|
|
7
|
+
* Class names, not utilities — see `Button/index.ts` for why the package
|
|
8
|
+
* cannot publish `.h-10` and `.rounded-lg` of its own. `SearchBar.module.css`
|
|
9
|
+
* gives each of these names its declarations, and `moduleClasses` does the
|
|
10
|
+
* lookup.
|
|
11
|
+
*
|
|
12
|
+
* Only two axes here. Figma models a third, `State`, with `Default | Focus |
|
|
13
|
+
* Filled`, and none of it belongs in a prop: focus is `:focus-within` and
|
|
14
|
+
* filled is "the input has a value". Both are things the component can see for
|
|
15
|
+
* itself, and a `state` prop would be asking the caller to keep telling it
|
|
16
|
+
* something it already knows — wrong the moment the two disagree.
|
|
17
|
+
*/
|
|
18
|
+
export declare const searchBarVariants: (props?: ({
|
|
19
|
+
variant?: "default" | "ghost" | null | undefined;
|
|
20
|
+
size?: "sm" | "md" | null | undefined;
|
|
21
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
22
|
+
export type SearchBarVariants = VariantProps<typeof searchBarVariants>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The quiet period between typing and searching — mirrors
|
|
3
|
+
* `@sesame/orxata-core` `useSearchDelay`.
|
|
4
|
+
*
|
|
5
|
+
* A search field that emits on every keystroke turns "Marie" into five
|
|
6
|
+
* requests, four of which are already stale by the time they land. Waiting for
|
|
7
|
+
* typing to stop collapses them into one.
|
|
8
|
+
*
|
|
9
|
+
* Two ways in, because the two are not the same event. `schedule` is typing:
|
|
10
|
+
* every keystroke restarts the clock, so only the pause at the end fires.
|
|
11
|
+
* `immediately` is an explicit request — the clear button, Enter — where the
|
|
12
|
+
* user has said what they want and there is nothing left to wait for; it also
|
|
13
|
+
* drops whatever `schedule` had pending, which would otherwise fire a moment
|
|
14
|
+
* later with a term the user has already moved on from.
|
|
15
|
+
*/
|
|
16
|
+
export interface UseSearchDelayReturn {
|
|
17
|
+
/** Restart the quiet period; emit when it elapses. */
|
|
18
|
+
schedule: (term: string) => void;
|
|
19
|
+
/** Emit now, dropping anything pending. */
|
|
20
|
+
immediately: (term: string) => void;
|
|
21
|
+
/** Drop anything pending without emitting. */
|
|
22
|
+
cancel: () => void;
|
|
23
|
+
}
|
|
24
|
+
export declare const useSearchDelay: (delay: number, emit: (term: string) => void) => UseSearchDelayReturn;
|