@overdoser/react-toolkit 0.0.16 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/AGENTS.md +53 -0
  2. package/CHANGELOG.md +226 -0
  3. package/README.md +102 -3
  4. package/components/Alert/Alert.d.ts +34 -0
  5. package/components/Alert/index.d.ts +2 -0
  6. package/components/Avatar/Avatar.d.ts +36 -0
  7. package/components/Avatar/index.d.ts +2 -0
  8. package/components/Badge/Badge.d.ts +25 -0
  9. package/components/Badge/index.d.ts +2 -0
  10. package/components/Breadcrumbs/Breadcrumbs.d.ts +44 -0
  11. package/components/Breadcrumbs/index.d.ts +2 -0
  12. package/components/Divider/Divider.d.ts +28 -0
  13. package/components/Divider/index.d.ts +2 -0
  14. package/components/Draggable/Draggable.d.ts +50 -0
  15. package/components/Draggable/index.d.ts +2 -0
  16. package/components/Drawer/Drawer.d.ts +65 -0
  17. package/components/Drawer/index.d.ts +2 -0
  18. package/components/Dropzone/Dropzone.d.ts +50 -0
  19. package/components/Dropzone/index.d.ts +2 -0
  20. package/components/Form/Form.d.ts +16 -1
  21. package/components/Form/FormField.d.ts +17 -2
  22. package/components/Form/formFieldDefaults.d.ts +9 -0
  23. package/components/Link/Link.d.ts +10 -0
  24. package/components/Pagination/Pagination.d.ts +48 -0
  25. package/components/Pagination/index.d.ts +4 -0
  26. package/components/Pagination/paginationRange.d.ts +8 -0
  27. package/components/Popover/Popover.d.ts +7 -0
  28. package/components/Skeleton/Skeleton.d.ts +28 -0
  29. package/components/Skeleton/index.d.ts +2 -0
  30. package/components/Spinner/Spinner.d.ts +29 -0
  31. package/components/Spinner/index.d.ts +2 -0
  32. package/components/Tabs/Tabs.d.ts +66 -0
  33. package/components/Tabs/index.d.ts +2 -0
  34. package/components/Timer/Timer.d.ts +103 -0
  35. package/components/Timer/index.d.ts +2 -0
  36. package/components/Toast/Toast.d.ts +82 -0
  37. package/components/Toast/index.d.ts +2 -0
  38. package/components/Toast/toastStore.d.ts +28 -0
  39. package/components/Tooltip/Tooltip.d.ts +38 -0
  40. package/components/Tooltip/index.d.ts +2 -0
  41. package/components/inputs/Checkbox/Checkbox.d.ts +11 -1
  42. package/components/inputs/Checkbox/CheckboxGroup.d.ts +83 -0
  43. package/components/inputs/Checkbox/index.d.ts +2 -0
  44. package/components/inputs/DatePicker/DatePicker.d.ts +58 -0
  45. package/components/inputs/DatePicker/dateUtils.d.ts +16 -0
  46. package/components/inputs/DatePicker/index.d.ts +2 -0
  47. package/components/inputs/NumberInput/NumberInput.d.ts +41 -0
  48. package/components/inputs/NumberInput/index.d.ts +2 -0
  49. package/components/inputs/Slider/Slider.d.ts +44 -0
  50. package/components/inputs/Slider/index.d.ts +2 -0
  51. package/index.css +1 -1
  52. package/index.d.ts +38 -2
  53. package/index.js +5047 -2698
  54. package/index.layered.css +5 -0
  55. package/llms.txt +331 -5
  56. package/manifest.json +2057 -289
  57. package/package.json +3 -2
@@ -0,0 +1,50 @@
1
+ import { forwardRef, ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ /** An `{ x, y }` translation offset, in pixels, from the element's natural position. */
3
+ export interface DraggablePosition {
4
+ x: number;
5
+ y: number;
6
+ }
7
+ export interface DraggableClasses {
8
+ root: string;
9
+ handle: string;
10
+ }
11
+ export interface DraggableProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onDrag' | 'onDragStart' | 'onDragEnd'> {
12
+ /** Container content. Include a `<Draggable.Handle>` to restrict the grab area; without one, the whole surface drags. */
13
+ children?: ReactNode;
14
+ /** Uncontrolled initial offset. @default { x: 0, y: 0 } */
15
+ defaultPosition?: DraggablePosition;
16
+ /** Controlled offset. When set, the component renders at this value and you must update it from `onDrag`. */
17
+ position?: DraggablePosition;
18
+ /** Restrict movement to one axis. @default 'both' */
19
+ axis?: 'both' | 'x' | 'y';
20
+ /** Where the element is allowed to move. `'viewport'` and `'parent'` clamp to those bounds; `'none'` is unconstrained. @default 'viewport' */
21
+ bounds?: 'viewport' | 'parent' | 'none';
22
+ /** Pixel step applied when moving via arrow keys with a focused handle. @default 10 */
23
+ keyboardStep?: number;
24
+ /** Disable dragging entirely. @default false */
25
+ disabled?: boolean;
26
+ /** Fired when a drag gesture begins, with the current offset. */
27
+ onDragStart?: (position: DraggablePosition) => void;
28
+ /** Fired on every move (pointer or keyboard) with the new offset. Required to update a controlled `position`. */
29
+ onDrag?: (position: DraggablePosition) => void;
30
+ /** Fired when a drag gesture ends, with the final offset. */
31
+ onDragEnd?: (position: DraggablePosition) => void;
32
+ /** Override class names on internal elements. */
33
+ classes?: Partial<DraggableClasses>;
34
+ }
35
+ type DraggableComponent = ReturnType<typeof forwardRef<HTMLDivElement, DraggableProps>> & {
36
+ Handle: typeof DraggableHandle;
37
+ };
38
+ export interface DraggableHandleProps extends ComponentPropsWithoutRef<'div'> {
39
+ children?: ReactNode;
40
+ }
41
+ /**
42
+ * Grab area for a `<Draggable>`. Place it inside the container; only this element
43
+ * initiates dragging, and it's keyboard-movable (arrow keys) when focused.
44
+ */
45
+ declare function DraggableHandle({ children, className, style, ...rest }: DraggableHandleProps): import("react/jsx-runtime").JSX.Element;
46
+ declare namespace DraggableHandle {
47
+ var displayName: string;
48
+ }
49
+ export declare const Draggable: DraggableComponent;
50
+ export {};
@@ -0,0 +1,2 @@
1
+ export { Draggable } from './Draggable';
2
+ export type { DraggableProps, DraggableClasses, DraggablePosition, DraggableHandleProps, } from './Draggable';
@@ -0,0 +1,65 @@
1
+ import { forwardRef, CSSProperties, FC, ReactNode } from 'react';
2
+ export interface DrawerClasses {
3
+ backdrop: string;
4
+ drawer: string;
5
+ header: string;
6
+ closeButton: string;
7
+ body: string;
8
+ footer: string;
9
+ }
10
+ export interface DrawerHeaderProps {
11
+ children: ReactNode;
12
+ className?: string;
13
+ style?: CSSProperties;
14
+ /** When provided, renders an "×" close button in the header. */
15
+ onClose?: () => void;
16
+ }
17
+ export interface DrawerBodyProps {
18
+ children: ReactNode;
19
+ className?: string;
20
+ style?: CSSProperties;
21
+ }
22
+ export interface DrawerFooterProps {
23
+ children: ReactNode;
24
+ className?: string;
25
+ style?: CSSProperties;
26
+ }
27
+ declare const Header: FC<DrawerHeaderProps>;
28
+ declare const Body: FC<DrawerBodyProps>;
29
+ declare const Footer: FC<DrawerFooterProps>;
30
+ export interface DrawerProps {
31
+ /** Whether the drawer is visible. */
32
+ open: boolean;
33
+ /** Called on backdrop click, Escape, or the `Drawer.Header` close button. */
34
+ onClose: () => void;
35
+ /** Edge the panel slides in from. @default 'right' */
36
+ side?: 'left' | 'right' | 'top' | 'bottom';
37
+ /** Panel size (width for left/right, height for top/bottom). @default 'md' */
38
+ size?: 'sm' | 'md' | 'lg' | 'full';
39
+ /**
40
+ * `'temporary'` overlays the page with a dimmed scrim and is modal (click the
41
+ * scrim or press Escape to close). `'persistent'` shows no scrim and leaves the
42
+ * page interactive — a fixed side panel. @default 'temporary'
43
+ */
44
+ variant?: 'temporary' | 'persistent';
45
+ /** Close when the backdrop is clicked (temporary only). @default true */
46
+ closeOnBackdrop?: boolean;
47
+ /** Close when Escape is pressed. @default true */
48
+ closeOnEscape?: boolean;
49
+ /** Override class names on internal elements. */
50
+ classes?: Partial<DrawerClasses>;
51
+ className?: string;
52
+ style?: CSSProperties;
53
+ /** Should be `<Drawer.Header>`, `<Drawer.Body>`, `<Drawer.Footer>`. */
54
+ children: ReactNode;
55
+ /** Accessible label. Use this OR `aria-labelledby`. If neither is set, `Drawer.Header` is auto-wired. */
56
+ 'aria-label'?: string;
57
+ 'aria-labelledby'?: string;
58
+ }
59
+ type DrawerComponent = ReturnType<typeof forwardRef<HTMLDivElement, DrawerProps>> & {
60
+ Header: typeof Header;
61
+ Body: typeof Body;
62
+ Footer: typeof Footer;
63
+ };
64
+ export declare const Drawer: DrawerComponent;
65
+ export {};
@@ -0,0 +1,2 @@
1
+ export { Drawer } from './Drawer';
2
+ export type { DrawerProps, DrawerClasses, DrawerHeaderProps, DrawerBodyProps, DrawerFooterProps, } from './Drawer';
@@ -0,0 +1,50 @@
1
+ import { ReactNode } from 'react';
2
+ export interface DropzoneRejection {
3
+ file: File;
4
+ reason: 'type' | 'size' | 'multiple';
5
+ }
6
+ export interface DropzoneClasses {
7
+ root: string;
8
+ input: string;
9
+ content: string;
10
+ icon: string;
11
+ label: string;
12
+ hint: string;
13
+ }
14
+ export interface DropzoneProps {
15
+ /** Called with the accepted files. */
16
+ onFiles?: (files: File[]) => void;
17
+ /** Called with rejected files and the reason, when validation fails. */
18
+ onReject?: (rejections: DropzoneRejection[]) => void;
19
+ /** Accepted types — a comma list of extensions and/or MIME patterns (e.g. `'.png,image/*'`). */
20
+ accept?: string;
21
+ /** Allow selecting multiple files. @default false */
22
+ multiple?: boolean;
23
+ /** Maximum size per file, in bytes. */
24
+ maxSize?: number;
25
+ /** Disable the dropzone. @default false */
26
+ disabled?: boolean;
27
+ /** Primary label text (ignored if `children` is provided). */
28
+ label?: ReactNode;
29
+ /** Secondary hint text (ignored if `children` is provided). */
30
+ hint?: ReactNode;
31
+ /** Custom content; receives the current drag state. Replaces the default UI. */
32
+ children?: ReactNode | ((state: {
33
+ isDragging: boolean;
34
+ }) => ReactNode);
35
+ /** Override class names on internal elements. */
36
+ classes?: Partial<DropzoneClasses>;
37
+ className?: string;
38
+ style?: React.CSSProperties;
39
+ /** Accessible label for the dropzone button. @default 'Upload files' */
40
+ 'aria-label'?: string;
41
+ }
42
+ /**
43
+ * File upload dropzone — drag-and-drop or click to browse. Validates `accept`
44
+ * and `maxSize`, emitting accepted files via `onFiles` and rejected ones via
45
+ * `onReject`. File-list/state management is left to the consumer.
46
+ *
47
+ * @example
48
+ * <Dropzone accept="image/*" maxSize={2_000_000} multiple onFiles={setFiles} />
49
+ */
50
+ export declare const Dropzone: import('react').ForwardRefExoticComponent<DropzoneProps & import('react').RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,2 @@
1
+ export { Dropzone } from './Dropzone';
2
+ export type { DropzoneProps, DropzoneClasses, DropzoneRejection } from './Dropzone';
@@ -1,4 +1,5 @@
1
1
  import { UseFormReturn, FieldValues, SubmitHandler } from 'react-hook-form';
2
+ import { FormFieldClasses } from './FormField';
2
3
  export interface FormProps<T extends FieldValues> {
3
4
  /** The result of `useForm()`. */
4
5
  form: UseFormReturn<T>;
@@ -6,6 +7,20 @@ export interface FormProps<T extends FieldValues> {
6
7
  onSubmit: SubmitHandler<T>;
7
8
  /** Top-of-form error messages. Rendered above children with `role="alert"`. */
8
9
  errors?: React.ReactNode[];
10
+ /**
11
+ * Default `reserveErrorSpace` applied to every `FormField` inside this form
12
+ * (each field can still override it via its own `reserveErrorSpace` prop).
13
+ * Same accepted values as `FormField`: `boolean | number | string`.
14
+ * @default true
15
+ */
16
+ reserveErrorSpace?: boolean | number | string;
17
+ /**
18
+ * Default `classes` applied to every `FormField` inside this form. These are
19
+ * *merged* with each field's own `classes` (both class names are applied), so
20
+ * a field can add to — not just replace — the form-wide defaults. Keys:
21
+ * `{ field, label, message, error, helperText }`.
22
+ */
23
+ fieldClasses?: Partial<FormFieldClasses>;
9
24
  className?: string;
10
25
  style?: React.CSSProperties;
11
26
  children: React.ReactNode;
@@ -23,4 +38,4 @@ export interface FormProps<T extends FieldValues> {
23
38
  * <Button type="submit">Save</Button>
24
39
  * </Form>
25
40
  */
26
- export declare function Form<T extends FieldValues>({ form, onSubmit, errors, className, style, children, }: FormProps<T>): import("react/jsx-runtime").JSX.Element;
41
+ export declare function Form<T extends FieldValues>({ form, onSubmit, errors, reserveErrorSpace, fieldClasses, className, style, children, }: FormProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -2,6 +2,7 @@ import { ReactElement, CSSProperties, ReactNode } from 'react';
2
2
  export interface FormFieldClasses {
3
3
  field: string;
4
4
  label: string;
5
+ message: string;
5
6
  error: string;
6
7
  helperText: string;
7
8
  }
@@ -10,12 +11,26 @@ export interface FormFieldProps {
10
11
  name: string;
11
12
  /** Field label rendered above the input. */
12
13
  label?: ReactNode;
13
- /** Helper text rendered below the input (replaced by error message when invalid). */
14
+ /** Helper/description text rendered below the input. Stays visible when invalid — the error message appears above it, between the input and this text. */
14
15
  helperText?: ReactNode;
15
16
  /** Renders a `*` indicator next to the label. Does NOT add validation rules — pass those in `rules`. */
16
17
  required?: boolean;
17
18
  /** react-hook-form `useController` rules (e.g., `{ required: 'msg', minLength: { value: 8, message: '…' } }`). */
18
19
  rules?: Record<string, unknown>;
20
+ /**
21
+ * Reserve vertical space (after the description) for the validation message so
22
+ * the field's outer height does not change when an error appears/disappears.
23
+ * - `true`: reserve one line via the `--crk-field-error-min-height` token.
24
+ * - `false`: no reservation — an error pushes content down (legacy behaviour).
25
+ * - `number`: reserved height in pixels.
26
+ * - `string`: any CSS length (e.g. `'2.5em'` to fit two lines).
27
+ *
28
+ * Multi-line messages are allowed to grow past the reserved height. When unset,
29
+ * inherits the `reserveErrorSpace` set on the enclosing `<Form>`, falling back
30
+ * to `true`.
31
+ * @default inherited from `<Form>`, else `true`
32
+ */
33
+ reserveErrorSpace?: boolean | number | string;
19
34
  /** Override class names on internal elements. */
20
35
  classes?: Partial<FormFieldClasses>;
21
36
  className?: string;
@@ -41,4 +56,4 @@ export interface FormFieldProps {
41
56
  * <Input type="email" />
42
57
  * </FormField>
43
58
  */
44
- export declare function FormField({ name, label, helperText, required, rules, classes, className, style, children, }: FormFieldProps): import("react/jsx-runtime").JSX.Element;
59
+ export declare function FormField({ name, label, helperText, required, rules, reserveErrorSpace, classes, className, style, children, }: FormFieldProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { FormFieldClasses } from './FormField';
2
+ /** Field-level defaults supplied by `<Form>` and inherited by every `<FormField>`. */
3
+ export interface FormFieldDefaults {
4
+ /** Default `reserveErrorSpace` for fields that don't set their own. */
5
+ reserveErrorSpace?: boolean | number | string;
6
+ /** Default `classes` merged into every field (each field's own `classes` are also applied). */
7
+ classes?: Partial<FormFieldClasses>;
8
+ }
9
+ export declare const FormFieldDefaultsContext: import('react').Context<FormFieldDefaults | null>;
@@ -9,10 +9,20 @@ export interface LinkProps extends ComponentPropsWithRef<'a'> {
9
9
  * @default false
10
10
  */
11
11
  external?: boolean;
12
+ /**
13
+ * Hide the inline "opens in a new tab" icon that is shown by default whenever
14
+ * the link opens in a new tab (`external` or `target="_blank"`). The
15
+ * screen-reader suffix is kept regardless. @default false
16
+ */
17
+ hideExternalIcon?: boolean;
12
18
  }
13
19
  /**
14
20
  * Styled `<a>` with variants and safe external-link defaults.
15
21
  *
22
+ * When the link opens in a new tab (via `external`, or a manual
23
+ * `target="_blank"`), a small inline ↗ icon is appended to the right so users
24
+ * know the link leaves the current tab. Pass `hideExternalIcon` to suppress it.
25
+ *
16
26
  * @example <Link href="https://example.com" external>Docs</Link>
17
27
  */
18
28
  export declare const Link: import('react').ForwardRefExoticComponent<Omit<LinkProps, "ref"> & import('react').RefAttributes<HTMLAnchorElement>>;
@@ -0,0 +1,48 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export interface PaginationClasses {
3
+ root: string;
4
+ list: string;
5
+ item: string;
6
+ active: string;
7
+ ellipsis: string;
8
+ control: string;
9
+ }
10
+ export interface PaginationProps extends Omit<ComponentPropsWithRef<'nav'>, 'onChange'> {
11
+ /** Total number of pages. Provide this, or `total` + `pageSize`. */
12
+ count?: number;
13
+ /** Total item count — used with `pageSize` to derive `count`. */
14
+ total?: number;
15
+ /** Items per page — used with `total` to derive `count`. @default 10 */
16
+ pageSize?: number;
17
+ /** Controlled current page (1-based). */
18
+ page?: number;
19
+ /** Uncontrolled initial page (1-based). @default 1 */
20
+ defaultPage?: number;
21
+ /** Called with the new page number. */
22
+ onChange?: (page: number) => void;
23
+ /** Pages always shown at the start and end. @default 1 */
24
+ boundaryCount?: number;
25
+ /** Pages shown on each side of the current page. @default 2 (→ up to 9 chips) */
26
+ siblingCount?: number;
27
+ /** Show the previous/next arrow controls. @default true */
28
+ showPrevNext?: boolean;
29
+ /** Show the jump-to-first/last controls. @default false */
30
+ showFirstLast?: boolean;
31
+ /** Control size. @default 'md' */
32
+ size?: 'sm' | 'md' | 'lg';
33
+ /** Disable all controls. @default false */
34
+ disabled?: boolean;
35
+ /** Accessible label for the nav landmark. @default 'Pagination' */
36
+ label?: string;
37
+ /** Override class names on internal elements. */
38
+ classes?: Partial<PaginationClasses>;
39
+ }
40
+ /**
41
+ * Page navigation with a windowed range and ellipses (e.g. `1 … 6 7 8 9 10 … 99`).
42
+ * With the default `siblingCount={2}` it shows at most 9 page chips.
43
+ *
44
+ * @example
45
+ * <Pagination count={99} page={page} onChange={setPage} />
46
+ * <Pagination total={480} pageSize={20} page={page} onChange={setPage} showFirstLast />
47
+ */
48
+ export declare const Pagination: import('react').ForwardRefExoticComponent<Omit<PaginationProps, "ref"> & import('react').RefAttributes<HTMLElement>>;
@@ -0,0 +1,4 @@
1
+ export { Pagination } from './Pagination';
2
+ export type { PaginationProps, PaginationClasses } from './Pagination';
3
+ export { paginationRange } from './paginationRange';
4
+ export type { PaginationItem } from './paginationRange';
@@ -0,0 +1,8 @@
1
+ export type PaginationItem = number | 'ellipsis';
2
+ /**
3
+ * Builds the windowed page list with ellipses — e.g. with `count=99`, `page=8`,
4
+ * `boundaryCount=1`, `siblingCount=2` → `[1, 'ellipsis', 6, 7, 8, 9, 10, 'ellipsis', 99]`.
5
+ * Mirrors MUI's `usePagination` range logic. The widest output is
6
+ * `boundaryCount*2 + siblingCount*2 + 3` items (two ellipses + current).
7
+ */
8
+ export declare function paginationRange(page: number, count: number, boundaryCount?: number, siblingCount?: number): PaginationItem[];
@@ -26,6 +26,13 @@ export interface PopoverProps {
26
26
  content: React.ReactNode;
27
27
  /** Side of the trigger to anchor the panel to. @default 'bottom' */
28
28
  position?: 'top' | 'bottom' | 'left' | 'right';
29
+ /**
30
+ * Keep the panel inside the viewport: flip to the opposite side when the
31
+ * requested one would overflow, and shift along the cross-axis so the panel
32
+ * stays fully visible near a screen edge. The requested `position` is honored
33
+ * whenever it fits. @default true
34
+ */
35
+ autoPosition?: boolean;
29
36
  /** Controlled open state. */
30
37
  open?: boolean;
31
38
  /** Called when the open state changes. */
@@ -0,0 +1,28 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export interface SkeletonClasses {
3
+ root: string;
4
+ line: string;
5
+ }
6
+ export interface SkeletonProps extends Omit<ComponentPropsWithRef<'div'>, 'children'> {
7
+ /** Shape of the placeholder. @default 'text' */
8
+ variant?: 'text' | 'circle' | 'rect';
9
+ /** Explicit width (number → px). Defaults to `100%`. */
10
+ width?: number | string;
11
+ /** Explicit height (number → px). Defaults per variant. */
12
+ height?: number | string;
13
+ /** Shimmer style. @default 'pulse' */
14
+ animation?: 'pulse' | 'wave' | 'none';
15
+ /** For `variant="text"`, render this many stacked lines (the last is shorter). @default 1 */
16
+ lines?: number;
17
+ /** Override class names on internal elements. */
18
+ classes?: Partial<SkeletonClasses>;
19
+ }
20
+ /**
21
+ * Loading placeholder that mimics content while it's fetching. Decorative
22
+ * (`aria-hidden`) — pair the surrounding region with its own loading status.
23
+ *
24
+ * @example
25
+ * <Skeleton variant="text" lines={3} />
26
+ * <Skeleton variant="circle" width={40} height={40} />
27
+ */
28
+ export declare const Skeleton: import('react').ForwardRefExoticComponent<Omit<SkeletonProps, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,2 @@
1
+ export { Skeleton } from './Skeleton';
2
+ export type { SkeletonProps, SkeletonClasses } from './Skeleton';
@@ -0,0 +1,29 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export interface SpinnerClasses {
3
+ root: string;
4
+ circle: string;
5
+ label: string;
6
+ }
7
+ export interface SpinnerProps extends ComponentPropsWithRef<'span'> {
8
+ /** Spinner size. @default 'md' */
9
+ size?: 'sm' | 'md' | 'lg';
10
+ /** Stroke color. Defaults to `currentColor`, so it inherits the surrounding text color. */
11
+ color?: string;
12
+ /**
13
+ * Accessible label announced to screen readers (visually hidden). Set to an
14
+ * empty string only when an adjacent visible element already labels the busy
15
+ * state. @default 'Loading'
16
+ */
17
+ label?: string;
18
+ /** Override class names on internal elements. */
19
+ classes?: Partial<SpinnerClasses>;
20
+ }
21
+ /**
22
+ * Indeterminate loading spinner. Inherits `currentColor` by default, so it works
23
+ * on any surface (including inside a `Button`).
24
+ *
25
+ * @example
26
+ * <Spinner size="lg" />
27
+ * <Button disabled><Spinner size="sm" label="" /> Saving…</Button>
28
+ */
29
+ export declare const Spinner: import('react').ForwardRefExoticComponent<Omit<SpinnerProps, "ref"> & import('react').RefAttributes<HTMLSpanElement>>;
@@ -0,0 +1,2 @@
1
+ export { Spinner } from './Spinner';
2
+ export type { SpinnerProps, SpinnerClasses } from './Spinner';
@@ -0,0 +1,66 @@
1
+ import { ComponentPropsWithRef, ReactNode } from 'react';
2
+ export type TabsOrientation = 'horizontal' | 'vertical';
3
+ export type TabsVariant = 'line' | 'solid' | 'pill';
4
+ export type TabsSize = 'sm' | 'md' | 'lg';
5
+ export interface TabsClasses {
6
+ root: string;
7
+ list: string;
8
+ tab: string;
9
+ panel: string;
10
+ }
11
+ export interface TabsProps extends Omit<ComponentPropsWithRef<'div'>, 'onChange'> {
12
+ /** Controlled active tab value. */
13
+ value?: string;
14
+ /** Uncontrolled initial active tab value. */
15
+ defaultValue?: string;
16
+ /** Called with the new value when the active tab changes. */
17
+ onValueChange?: (value: string) => void;
18
+ /** Layout direction. @default 'horizontal' */
19
+ orientation?: TabsOrientation;
20
+ /** Visual style of the tab list. @default 'line' */
21
+ variant?: TabsVariant;
22
+ /** Tab sizing. @default 'md' */
23
+ size?: TabsSize;
24
+ /** Override class names on internal elements. */
25
+ classes?: Partial<TabsClasses>;
26
+ }
27
+ export interface TabsListProps extends ComponentPropsWithRef<'div'> {
28
+ children?: ReactNode;
29
+ }
30
+ export interface TabsTabProps extends Omit<ComponentPropsWithRef<'button'>, 'value'> {
31
+ /** Identifier linking this tab to its panel. */
32
+ value: string;
33
+ /** Disable selection of this tab. @default false */
34
+ disabled?: boolean;
35
+ children?: ReactNode;
36
+ }
37
+ export interface TabsPanelProps extends ComponentPropsWithRef<'div'> {
38
+ /** Identifier linking this panel to its tab. */
39
+ value: string;
40
+ /**
41
+ * Keep the panel mounted (but hidden) when inactive. Useful to preserve
42
+ * scroll/input state across tab switches. @default false
43
+ */
44
+ keepMounted?: boolean;
45
+ children?: ReactNode;
46
+ }
47
+ /**
48
+ * Accessible tabs. Compose with `Tabs.List`, `Tabs.Tab`, and `Tabs.Panel`.
49
+ * Arrow keys (plus Home/End) move between tabs and activate them; activation is
50
+ * automatic on focus.
51
+ *
52
+ * @example
53
+ * <Tabs defaultValue="overview">
54
+ * <Tabs.List>
55
+ * <Tabs.Tab value="overview">Overview</Tabs.Tab>
56
+ * <Tabs.Tab value="activity">Activity</Tabs.Tab>
57
+ * </Tabs.List>
58
+ * <Tabs.Panel value="overview">…</Tabs.Panel>
59
+ * <Tabs.Panel value="activity">…</Tabs.Panel>
60
+ * </Tabs>
61
+ */
62
+ export declare const Tabs: import('react').ForwardRefExoticComponent<Omit<TabsProps, "ref"> & import('react').RefAttributes<HTMLDivElement>> & {
63
+ List: import('react').ForwardRefExoticComponent<Omit<TabsListProps, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
64
+ Tab: import('react').ForwardRefExoticComponent<Omit<TabsTabProps, "ref"> & import('react').RefAttributes<HTMLButtonElement>>;
65
+ Panel: import('react').ForwardRefExoticComponent<Omit<TabsPanelProps, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
66
+ };
@@ -0,0 +1,2 @@
1
+ export { Tabs } from './Tabs';
2
+ export type { TabsProps, TabsListProps, TabsTabProps, TabsPanelProps, TabsClasses, TabsOrientation, TabsVariant, TabsSize, } from './Tabs';
@@ -0,0 +1,103 @@
1
+ import { CSSProperties, ReactNode } from 'react';
2
+ export type TimerMode = 'countdown' | 'stopwatch';
3
+ export type TimerVariant = 'digital' | 'ring' | 'segments';
4
+ export type TimerLabelPlacement = 'top' | 'bottom' | 'left' | 'right';
5
+ export type TimerUnit = 'days' | 'hours' | 'minutes' | 'seconds';
6
+ /** One unit cell of the segmented display. */
7
+ export interface TimerSegment {
8
+ /** Which unit this segment represents. */
9
+ unit: TimerUnit;
10
+ /** Numeric value for the unit. */
11
+ value: number;
12
+ /** Display text (zero-padded except the leading unit). */
13
+ text: string;
14
+ /** Resolved unit label (e.g. `'h'`, `'hours'`). */
15
+ label: ReactNode;
16
+ }
17
+ export interface TimerHandle {
18
+ /** Start (or resume) ticking. */
19
+ start: () => void;
20
+ /** Pause, preserving elapsed time. */
21
+ pause: () => void;
22
+ /** Stop and reset to the initial value. */
23
+ reset: () => void;
24
+ /** Reset then start again. */
25
+ restart: () => void;
26
+ /** Current displayed time, in seconds. */
27
+ getTime: () => number;
28
+ /** Whether the timer is currently running. */
29
+ readonly isRunning: boolean;
30
+ }
31
+ export interface TimerClasses {
32
+ root: string;
33
+ display: string;
34
+ label: string;
35
+ ringTrack: string;
36
+ ringProgress: string;
37
+ segments: string;
38
+ segment: string;
39
+ segmentValue: string;
40
+ segmentLabel: string;
41
+ }
42
+ export interface TimerProps {
43
+ /** Count down to zero, or up from zero. @default 'countdown' */
44
+ mode?: TimerMode;
45
+ /** Countdown length / stopwatch cap, in seconds. Drives ring progress. */
46
+ duration?: number;
47
+ /** Absolute countdown target (`Date` or epoch ms). Overrides `duration`/pause; always counts down. */
48
+ to?: Date | number;
49
+ /** Controlled display time in seconds — makes the timer display-only (no internal clock). */
50
+ value?: number;
51
+ /** Start ticking on mount (uncontrolled). @default true */
52
+ autoStart?: boolean;
53
+ /** Controlled run state. When set, start/pause follow this prop. */
54
+ running?: boolean;
55
+ /** Tick interval in milliseconds. @default 1000 */
56
+ interval?: number;
57
+ /** Visual style: `'digital'` digits, `'ring'` progress circle, or `'segments'` (one boxed cell per unit). @default 'digital' */
58
+ variant?: TimerVariant;
59
+ /** Size of the digits / ring / segments. @default 'md' */
60
+ size?: 'sm' | 'md' | 'lg';
61
+ /** Format the time for display (digital/ring only). Receives whole seconds. */
62
+ format?: (seconds: number) => ReactNode;
63
+ /** Which segments to show (segments variant). Defaults to the smallest set that fits the duration. */
64
+ units?: TimerUnit[];
65
+ /** Default unit-label style for the segments variant. `'short'` → `d/h/m/s`, `'long'` → `days/hours/minutes/seconds` (fixed — no singular/plural switching). @default 'short' */
66
+ unitFormat?: 'long' | 'short';
67
+ /** Override unit labels — a node, or a function of the unit's value (for custom pluralization). */
68
+ unitLabels?: Partial<Record<TimerUnit, ReactNode | ((value: number) => ReactNode)>>;
69
+ /** Built-in segment style. `'boxed'` is a square with the number and the unit below. @default 'boxed' */
70
+ segmentVariant?: 'boxed' | 'plain';
71
+ /** Fully custom segment renderer (segments variant). Overrides `segmentVariant`. */
72
+ renderSegment?: (segment: TimerSegment, index: number) => ReactNode;
73
+ /** Content rendered between segments (e.g. `':'`). */
74
+ segmentSeparator?: ReactNode;
75
+ /** Content shown alongside the timer (e.g. a caption). */
76
+ label?: ReactNode;
77
+ /** Where `label` sits relative to the timer. @default 'bottom' */
78
+ labelPlacement?: TimerLabelPlacement;
79
+ /** Fired once when a countdown reaches zero. */
80
+ onComplete?: () => void;
81
+ /** Fired each tick with the current seconds. */
82
+ onTick?: (seconds: number) => void;
83
+ /** Override class names on internal elements. */
84
+ classes?: Partial<TimerClasses>;
85
+ className?: string;
86
+ style?: CSSProperties;
87
+ 'aria-label'?: string;
88
+ }
89
+ /**
90
+ * A flexible timer: countdown or stopwatch, shown as digits or a progress ring,
91
+ * with an optional attached label. Uncontrolled with `autoStart` + an imperative
92
+ * ref (`start`/`pause`/`reset`/`restart`), or display-only via `value`.
93
+ *
94
+ * @example
95
+ * // Countdown with a caption underneath
96
+ * <Timer mode="countdown" duration={90} label="Time left" onComplete={onDone} />
97
+ *
98
+ * @example
99
+ * // Ring stopwatch driven by a ref
100
+ * const t = useRef<TimerHandle>(null);
101
+ * <Timer ref={t} mode="stopwatch" duration={60} variant="ring" autoStart={false} />
102
+ */
103
+ export declare const Timer: import('react').ForwardRefExoticComponent<TimerProps & import('react').RefAttributes<TimerHandle>>;
@@ -0,0 +1,2 @@
1
+ export { Timer } from './Timer';
2
+ export type { TimerProps, TimerHandle, TimerClasses, TimerMode, TimerVariant, TimerLabelPlacement, TimerUnit, TimerSegment, } from './Timer';