@pravalabs/ui 0.0.0-stage → 1.0.0-rc.1

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 (160) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +142 -2
  3. package/dist/Accordion-CVRdRha1.js +107 -0
  4. package/dist/Alert-Bxv6CGPj.js +54 -0
  5. package/dist/Avatar-DUw9xBQ-.js +49 -0
  6. package/dist/Badge-cupXlWce.js +37 -0
  7. package/dist/Button-vjrnnaM_.js +65 -0
  8. package/dist/Card-BJNdpGjM.js +44 -0
  9. package/dist/Checkbox-BQtcnwwC.js +60 -0
  10. package/dist/Container-DO8bd1tv.js +19 -0
  11. package/dist/Dialog-D3-sT_1Z.js +147 -0
  12. package/dist/Drawer-BRzJmvQx.js +21 -0
  13. package/dist/DropdownMenu-CFa2vgXi.js +137 -0
  14. package/dist/FormField-CoC946w9.js +61 -0
  15. package/dist/Grid-vTrChm2w.js +31 -0
  16. package/dist/Input-B97l8Dj0.js +82 -0
  17. package/dist/Label-DYOFzyEM.js +25 -0
  18. package/dist/Popover-C9Vgtm3q.js +81 -0
  19. package/dist/PravaProvider-0znpKV4G.js +59 -0
  20. package/dist/Progress-_Hz8dxM4.js +51 -0
  21. package/dist/RadioGroup-CvdV80Pg.js +90 -0
  22. package/dist/Select-_urp2aA_.js +451 -0
  23. package/dist/Separator-MnFbL0eH.js +23 -0
  24. package/dist/Skeleton-CyjiU8o1.js +25 -0
  25. package/dist/Spinner-Da7h4BDn.js +77 -0
  26. package/dist/Stack-DNtmh6BN.js +30 -0
  27. package/dist/Switch-Cp-wriw6.js +50 -0
  28. package/dist/Tabs-C0SRJSv1.js +158 -0
  29. package/dist/Textarea-D0fNA7sQ.js +69 -0
  30. package/dist/Toast-7qJXHzEb.js +110 -0
  31. package/dist/Tooltip-CyW8YfU9.js +57 -0
  32. package/dist/accordion.js +8 -0
  33. package/dist/alert.js +7 -0
  34. package/dist/avatar.js +7 -0
  35. package/dist/badge.js +7 -0
  36. package/dist/button.js +7 -0
  37. package/dist/card.js +10 -0
  38. package/dist/checkbox.js +8 -0
  39. package/dist/components/accordion/Accordion.d.ts +42 -0
  40. package/dist/components/accordion/index.d.ts +2 -0
  41. package/dist/components/alert/Alert.d.ts +35 -0
  42. package/dist/components/alert/index.d.ts +2 -0
  43. package/dist/components/avatar/Avatar.d.ts +16 -0
  44. package/dist/components/avatar/index.d.ts +2 -0
  45. package/dist/components/badge/Badge.d.ts +22 -0
  46. package/dist/components/badge/index.d.ts +2 -0
  47. package/dist/components/button/Button.d.ts +50 -0
  48. package/dist/components/button/index.d.ts +2 -0
  49. package/dist/components/card/Card.d.ts +49 -0
  50. package/dist/components/card/index.d.ts +2 -0
  51. package/dist/components/checkbox/Checkbox.d.ts +23 -0
  52. package/dist/components/checkbox/index.d.ts +2 -0
  53. package/dist/components/container/Container.d.ts +22 -0
  54. package/dist/components/container/index.d.ts +2 -0
  55. package/dist/components/dialog/Dialog.d.ts +89 -0
  56. package/dist/components/dialog/index.d.ts +2 -0
  57. package/dist/components/drawer/Drawer.d.ts +46 -0
  58. package/dist/components/drawer/index.d.ts +2 -0
  59. package/dist/components/dropdown-menu/DropdownMenu.d.ts +59 -0
  60. package/dist/components/dropdown-menu/index.d.ts +2 -0
  61. package/dist/components/field/field.d.ts +87 -0
  62. package/dist/components/form-field/FormField.d.ts +41 -0
  63. package/dist/components/form-field/index.d.ts +2 -0
  64. package/dist/components/grid/Grid.d.ts +36 -0
  65. package/dist/components/grid/index.d.ts +2 -0
  66. package/dist/components/input/Input.d.ts +35 -0
  67. package/dist/components/input/index.d.ts +2 -0
  68. package/dist/components/label/Label.d.ts +15 -0
  69. package/dist/components/label/index.d.ts +2 -0
  70. package/dist/components/popover/Popover.d.ts +35 -0
  71. package/dist/components/popover/index.d.ts +2 -0
  72. package/dist/components/progress/Progress.d.ts +15 -0
  73. package/dist/components/progress/index.d.ts +2 -0
  74. package/dist/components/provider/PravaProvider.d.ts +69 -0
  75. package/dist/components/provider/index.d.ts +2 -0
  76. package/dist/components/radio-group/RadioGroup.d.ts +58 -0
  77. package/dist/components/radio-group/index.d.ts +2 -0
  78. package/dist/components/select/Select.d.ts +76 -0
  79. package/dist/components/select/index.d.ts +2 -0
  80. package/dist/components/separator/Separator.d.ts +9 -0
  81. package/dist/components/separator/index.d.ts +2 -0
  82. package/dist/components/skeleton/Skeleton.d.ts +7 -0
  83. package/dist/components/skeleton/index.d.ts +2 -0
  84. package/dist/components/spinner/Spinner.d.ts +15 -0
  85. package/dist/components/spinner/index.d.ts +2 -0
  86. package/dist/components/stack/Stack.d.ts +38 -0
  87. package/dist/components/stack/index.d.ts +2 -0
  88. package/dist/components/switch/Switch.d.ts +19 -0
  89. package/dist/components/switch/index.d.ts +2 -0
  90. package/dist/components/tabs/Tabs.d.ts +69 -0
  91. package/dist/components/tabs/index.d.ts +2 -0
  92. package/dist/components/textarea/Textarea.d.ts +26 -0
  93. package/dist/components/textarea/index.d.ts +2 -0
  94. package/dist/components/toast/Toast.d.ts +55 -0
  95. package/dist/components/toast/index.d.ts +2 -0
  96. package/dist/components/tooltip/Tooltip.d.ts +22 -0
  97. package/dist/components/tooltip/index.d.ts +2 -0
  98. package/dist/container.js +7 -0
  99. package/dist/dialog.js +8 -0
  100. package/dist/drawer.js +8 -0
  101. package/dist/dropdown-menu.js +8 -0
  102. package/dist/field-U1YinldE.js +152 -0
  103. package/dist/form-field.js +8 -0
  104. package/dist/grid.js +7 -0
  105. package/dist/index.d.ts +59 -0
  106. package/dist/index.js +29 -0
  107. package/dist/input.js +8 -0
  108. package/dist/internal/overlay.d.ts +39 -0
  109. package/dist/internal/useControllable.d.ts +2 -0
  110. package/dist/label.js +8 -0
  111. package/dist/overlay-9zlvgpUZ.js +121 -0
  112. package/dist/popover.js +8 -0
  113. package/dist/progress.js +7 -0
  114. package/dist/provider.js +7 -0
  115. package/dist/radio-group.js +8 -0
  116. package/dist/select.js +8 -0
  117. package/dist/separator.js +7 -0
  118. package/dist/skeleton.js +7 -0
  119. package/dist/spinner.js +7 -0
  120. package/dist/stack.js +7 -0
  121. package/dist/styles/components/accordion.css +1 -0
  122. package/dist/styles/components/alert.css +1 -0
  123. package/dist/styles/components/avatar.css +1 -0
  124. package/dist/styles/components/badge.css +1 -0
  125. package/dist/styles/components/button.css +1 -0
  126. package/dist/styles/components/card.css +1 -0
  127. package/dist/styles/components/checkbox.css +1 -0
  128. package/dist/styles/components/container.css +1 -0
  129. package/dist/styles/components/dialog.css +1 -0
  130. package/dist/styles/components/drawer.css +1 -0
  131. package/dist/styles/components/dropdown-menu.css +1 -0
  132. package/dist/styles/components/field.css +1 -0
  133. package/dist/styles/components/floating.css +1 -0
  134. package/dist/styles/components/form-field.css +1 -0
  135. package/dist/styles/components/grid.css +1 -0
  136. package/dist/styles/components/input.css +1 -0
  137. package/dist/styles/components/label.css +1 -0
  138. package/dist/styles/components/popover.css +1 -0
  139. package/dist/styles/components/progress.css +1 -0
  140. package/dist/styles/components/provider.css +1 -0
  141. package/dist/styles/components/radio-group.css +1 -0
  142. package/dist/styles/components/select.css +1 -0
  143. package/dist/styles/components/separator.css +1 -0
  144. package/dist/styles/components/skeleton.css +1 -0
  145. package/dist/styles/components/spinner.css +1 -0
  146. package/dist/styles/components/stack.css +1 -0
  147. package/dist/styles/components/switch.css +1 -0
  148. package/dist/styles/components/tabs.css +1 -0
  149. package/dist/styles/components/textarea.css +1 -0
  150. package/dist/styles/components/toast.css +1 -0
  151. package/dist/styles/components/tooltip.css +1 -0
  152. package/dist/styles.css +1 -0
  153. package/dist/switch.js +8 -0
  154. package/dist/tabs.js +10 -0
  155. package/dist/textarea.js +8 -0
  156. package/dist/toast.js +9 -0
  157. package/dist/tokens.css +192 -0
  158. package/dist/tooltip.js +8 -0
  159. package/dist/useControllable-C2Te1pSd.js +14 -0
  160. package/package.json +223 -4
@@ -0,0 +1,35 @@
1
+ import { InputHTMLAttributes, ReactNode } from 'react';
2
+ import { FieldProps } from '../field/field';
3
+ export type InputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "size"> & FieldProps & {
4
+ /** Selects the input's compact, default, or spacious dimensions; numbers preserve the native HTML size attribute. */
5
+ size?: "sm" | "md" | "lg" | number;
6
+ /** Optional visible label that floats above the value when focused or filled. */
7
+ label?: ReactNode;
8
+ /** Decorative content positioned at the input's inline start. */
9
+ startIcon?: ReactNode;
10
+ /** Decorative content positioned at the input's inline end. */
11
+ endIcon?: ReactNode;
12
+ /** Explains why a disabled input is unavailable; shown in place of `description` while disabled. */
13
+ disabledReason?: string;
14
+ };
15
+ /**
16
+ * A native, single-line input with an optional floating label, help text, and error message.
17
+ * Connect react-hook-form with `field={register("name")}` and pass `errors.name?.message` to `error`.
18
+ * @example
19
+ * ```tsx
20
+ * import { Input } from '@pravalabs/ui/input';
21
+ * <Input label="Email" type="email" required description="We never share it." />
22
+ * ```
23
+ */
24
+ export declare const Input: import('react').ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "size"> & FieldProps & {
25
+ /** Selects the input's compact, default, or spacious dimensions; numbers preserve the native HTML size attribute. */
26
+ size?: "sm" | "md" | "lg" | number;
27
+ /** Optional visible label that floats above the value when focused or filled. */
28
+ label?: ReactNode;
29
+ /** Decorative content positioned at the input's inline start. */
30
+ startIcon?: ReactNode;
31
+ /** Decorative content positioned at the input's inline end. */
32
+ endIcon?: ReactNode;
33
+ /** Explains why a disabled input is unavailable; shown in place of `description` while disabled. */
34
+ disabledReason?: string;
35
+ } & import('react').RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,2 @@
1
+ export { Input } from './Input';
2
+ export type { InputProps } from './Input';
@@ -0,0 +1,15 @@
1
+ import { LabelHTMLAttributes, ReactNode } from 'react';
2
+ export type LabelProps = LabelHTMLAttributes<HTMLLabelElement> & {
3
+ /** Marks the associated form control as required and presents a readable cue. */
4
+ required?: boolean;
5
+ children: ReactNode;
6
+ };
7
+ /**
8
+ * Names a form control using native label association and readable required text.
9
+ * @example
10
+ * ```tsx
11
+ * import { Label } from '@pravalabs/ui/label';
12
+ * <Label htmlFor="email" required>Email address</Label>
13
+ * ```
14
+ */
15
+ export declare function Label({ required, className, children, ...props }: LabelProps): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Label } from './Label';
2
+ export type { LabelProps } from './Label';
@@ -0,0 +1,35 @@
1
+ import { HTMLAttributes, ReactElement, ReactNode } from 'react';
2
+ import { FloatingAlign, FloatingPlacement } from '../../internal/overlay';
3
+ export type PopoverProps = Omit<HTMLAttributes<HTMLDivElement>, "title"> & {
4
+ /** Focusable element that toggles the popover, such as a Button. */
5
+ trigger: ReactElement;
6
+ /** Heading that names the popover. Without one, pass `aria-label`. */
7
+ title?: ReactNode;
8
+ /** Preferred side. It flips when there's no room; `start` and `end` follow the text direction. */
9
+ placement?: FloatingPlacement;
10
+ /** Alignment against the trigger along that side. */
11
+ align?: FloatingAlign;
12
+ /** Open state when controlled. */
13
+ open?: boolean;
14
+ /** Initial open state when uncontrolled. */
15
+ defaultOpen?: boolean;
16
+ /** Called with the next state when it asks to open or close. */
17
+ onOpenChange?: (open: boolean) => void;
18
+ /** Extra class for the title slot; `className` goes on the floating surface. */
19
+ classNames?: {
20
+ title?: string;
21
+ };
22
+ };
23
+ /**
24
+ * Floating content anchored to a trigger. Focus moves in on open and back to the trigger on Escape.
25
+ * A press outside or tabbing away closes it. It doesn't trap focus; use Dialog for that.
26
+ * @example
27
+ * ```tsx
28
+ * import { Popover } from '@pravalabs/ui/popover';
29
+ *
30
+ * <Popover trigger={<Button>Share</Button>} title="Share this project">
31
+ * <Input label="Link" readOnly value={url} />
32
+ * </Popover>
33
+ * ```
34
+ */
35
+ export declare function Popover({ trigger, title, placement, align, open: openProp, defaultOpen, onOpenChange, classNames, className, children, id: idProp, ...props }: PopoverProps): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Popover } from './Popover';
2
+ export type { PopoverProps } from './Popover';
@@ -0,0 +1,15 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export type ProgressProps = Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
3
+ /** Current value; omit for an indeterminate task. */
4
+ value?: number;
5
+ /** Start of the progress range. */
6
+ min?: number;
7
+ /** End of the progress range; must be greater than `min`. */
8
+ max?: number;
9
+ /** Accessible name describing the task being measured. */
10
+ label: string;
11
+ /** Shows the label and the percentage (formatted for the provider locale) above the bar. */
12
+ showValue?: boolean;
13
+ };
14
+ /** Communicates determinate or indeterminate task progress with accessible progressbar semantics. */
15
+ export declare function Progress({ value, min, max, label, showValue, className, style, ...props }: ProgressProps): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Progress } from './Progress';
2
+ export type { ProgressProps } from './Progress';
@@ -0,0 +1,69 @@
1
+ import { ReactNode } from 'react';
2
+ /** Library-owned text. Override any entry through `PravaProvider` `messages`. */
3
+ export type BuiltInMessages = {
4
+ /** Announced after a required field label. */
5
+ required: string;
6
+ /** Announced while a component is busy. */
7
+ loading: string;
8
+ /** Close buttons on Dialog and Drawer. */
9
+ close: string;
10
+ /** Dismiss buttons on Alert and Toast. */
11
+ dismiss: string;
12
+ /** Accessible name of the Toast region. */
13
+ notifications: string;
14
+ /** Select search box label and placeholder. */
15
+ search: string;
16
+ /** Select list when nothing matches the search. */
17
+ noResults: string;
18
+ /** Select chip remove button; `{label}` is the option's text. */
19
+ removeOption: string;
20
+ /** Select multi-value summary for screen readers; `{count}` is locale-formatted. */
21
+ selectedCount: string;
22
+ /**
23
+ * Validation messages shown when a native constraint fails, named after `ValidityState`.
24
+ * `{minLength}`, `{maxLength}`, `{min}`, and `{max}` are replaced with locale-formatted values.
25
+ */
26
+ valueMissing: string;
27
+ /** `valueMissing` for checkboxes, radio groups, and selects. */
28
+ valueMissingChoice: string;
29
+ typeMismatchEmail: string;
30
+ typeMismatchUrl: string;
31
+ badInput: string;
32
+ patternMismatch: string;
33
+ tooShort: string;
34
+ tooLong: string;
35
+ rangeUnderflow: string;
36
+ rangeOverflow: string;
37
+ stepMismatch: string;
38
+ };
39
+ type PravaConfig = {
40
+ direction: "ltr" | "rtl";
41
+ locale: string;
42
+ messages: BuiltInMessages;
43
+ };
44
+ /** Reads the nearest provider configuration, or the documented defaults outside one. */
45
+ export declare const usePravaConfig: () => PravaConfig;
46
+ export type PravaProviderProps = {
47
+ /** Text direction for this subtree. Does not change the document's direction. */
48
+ direction?: "ltr" | "rtl";
49
+ /** Active locale for built-in messages and formatting; also sets `lang` on the subtree. */
50
+ locale?: string;
51
+ /** Overrides for library-owned labels and announcements. */
52
+ messages?: Partial<BuiltInMessages>;
53
+ /** Color theme for this subtree. `system` follows the user's OS preference. Omit to inherit. */
54
+ theme?: "light" | "dark" | "system";
55
+ children: ReactNode;
56
+ };
57
+ /**
58
+ * Scopes direction, locale, messages, and theme to its subtree without adding layout.
59
+ * @example
60
+ * ```tsx
61
+ * import { PravaProvider } from '@pravalabs/ui/provider';
62
+ *
63
+ * <PravaProvider direction="rtl" locale="ar" theme="system" messages={{ required: 'مطلوب' }}>
64
+ * <App />
65
+ * </PravaProvider>
66
+ * ```
67
+ */
68
+ export declare function PravaProvider({ direction, locale, messages, theme, children, }: PravaProviderProps): import("react").JSX.Element;
69
+ export {};
@@ -0,0 +1,2 @@
1
+ export { PravaProvider } from './PravaProvider';
2
+ export type { BuiltInMessages, PravaProviderProps } from './PravaProvider';
@@ -0,0 +1,58 @@
1
+ import { ChangeEventHandler, CSSProperties, FocusEventHandler, ReactNode } from 'react';
2
+ import { FieldProps } from '../field/field';
3
+ export type RadioOption = {
4
+ value: string;
5
+ label: ReactNode;
6
+ disabled?: boolean;
7
+ };
8
+ export type RadioGroupProps = FieldProps & {
9
+ /** Group label, rendered as the fieldset legend. */
10
+ label: ReactNode;
11
+ options: RadioOption[];
12
+ /** Shared input name; generated when omitted. */
13
+ name?: string;
14
+ value?: string;
15
+ defaultValue?: string;
16
+ /** Native change event from the selected radio (react-hook-form's `register` uses this). */
17
+ onChange?: ChangeEventHandler<HTMLInputElement>;
18
+ onBlur?: FocusEventHandler<HTMLInputElement>;
19
+ /** Called with the newly selected option value. */
20
+ onValueChange?: (value: string) => void;
21
+ required?: boolean;
22
+ disabled?: boolean;
23
+ /** Stacks options (default) or lays them out in a wrapping row. */
24
+ orientation?: "vertical" | "horizontal";
25
+ id?: string;
26
+ className?: string;
27
+ style?: CSSProperties;
28
+ };
29
+ /**
30
+ * One choice from a set, built from native radios so arrow keys move and select as browsers expect.
31
+ * Connect it with `field={register("plan")}` or Controller's `field={field}`.
32
+ * @example
33
+ * ```tsx
34
+ * import { RadioGroup } from '@pravalabs/ui/radio-group';
35
+ * <RadioGroup label="Plan" options={[{ value: 'free', label: 'Free' }, { value: 'pro', label: 'Pro' }]} field={register('plan')} />
36
+ * ```
37
+ */
38
+ export declare const RadioGroup: import('react').ForwardRefExoticComponent<FieldProps & {
39
+ /** Group label, rendered as the fieldset legend. */
40
+ label: ReactNode;
41
+ options: RadioOption[];
42
+ /** Shared input name; generated when omitted. */
43
+ name?: string;
44
+ value?: string;
45
+ defaultValue?: string;
46
+ /** Native change event from the selected radio (react-hook-form's `register` uses this). */
47
+ onChange?: ChangeEventHandler<HTMLInputElement>;
48
+ onBlur?: FocusEventHandler<HTMLInputElement>;
49
+ /** Called with the newly selected option value. */
50
+ onValueChange?: (value: string) => void;
51
+ required?: boolean;
52
+ disabled?: boolean;
53
+ /** Stacks options (default) or lays them out in a wrapping row. */
54
+ orientation?: "vertical" | "horizontal";
55
+ id?: string;
56
+ className?: string;
57
+ style?: CSSProperties;
58
+ } & import('react').RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,2 @@
1
+ export { RadioGroup } from './RadioGroup';
2
+ export type { RadioGroupProps, RadioOption } from './RadioGroup';
@@ -0,0 +1,76 @@
1
+ import { ButtonHTMLAttributes, ChangeEventHandler, FocusEventHandler, FormEventHandler, ReactElement, ReactNode, RefAttributes } from 'react';
2
+ import { FieldBinding, FieldProps } from '../field/field';
3
+ export type SelectOption = {
4
+ /** Stable value the form submits. Keep it the same in every language. */
5
+ value: string;
6
+ /** What people see; pass translated text or a node such as `<Trans>`. */
7
+ label: ReactNode;
8
+ /** Text for search and type-ahead when `label` is not a plain string. */
9
+ searchText?: string;
10
+ icon?: ReactNode;
11
+ description?: ReactNode;
12
+ disabled?: boolean;
13
+ };
14
+ export type SelectOptionGroup<T extends SelectOption = SelectOption> = {
15
+ /** Group heading; pass translated text or a node. */
16
+ label: ReactNode;
17
+ options: readonly T[];
18
+ };
19
+ type SelectBase<T extends SelectOption> = Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children" | "defaultValue" | "form" | "name" | "onBlur" | "onChange" | "onInvalid" | "type" | "value"> & Omit<FieldProps<HTMLSelectElement>, "field"> & {
20
+ /** Options and `{ label, options }` groups. Extra fields on an option are kept and typed. */
21
+ options: readonly (T | SelectOptionGroup<T>)[];
22
+ /** Visible label above the control. */
23
+ label?: ReactNode;
24
+ /** Shown until a choice is made. */
25
+ placeholder?: ReactNode;
26
+ size?: "sm" | "md" | "lg";
27
+ /**
28
+ * Where the list opens. `auto` picks from the space available. Another side is kept while it
29
+ * leaves about three rows of room (or fits, beside the field); otherwise `auto` takes over.
30
+ */
31
+ placement?: "auto" | "top" | "bottom" | "start" | "end";
32
+ name?: string;
33
+ form?: string;
34
+ required?: boolean;
35
+ /** Adds a search box that filters the options by label or `searchText`. */
36
+ searchable?: boolean;
37
+ /** Replaces the label and description of each row; use it to draw your extra fields. */
38
+ renderOption?: (option: T, state: {
39
+ selected: boolean;
40
+ }) => ReactNode;
41
+ /** Connects react-hook-form: `field={register("role")}` or Controller's `field={field}`. */
42
+ field?: FieldBinding<HTMLSelectElement>;
43
+ /** Change event from the form control underneath; react-hook-form uses this. */
44
+ onChange?: ChangeEventHandler<HTMLSelectElement>;
45
+ onBlur?: FocusEventHandler<HTMLSelectElement>;
46
+ onInvalid?: FormEventHandler<HTMLSelectElement>;
47
+ };
48
+ export type SelectProps<T extends SelectOption = SelectOption> = SelectBase<T> & ({
49
+ multiple?: false;
50
+ value?: string;
51
+ defaultValue?: string;
52
+ onValueChange?: (value: string, option: T) => void;
53
+ } | {
54
+ /** Choose several options; they show as removable chips and the value is an array. */
55
+ multiple: true;
56
+ value?: readonly string[];
57
+ defaultValue?: readonly string[];
58
+ onValueChange?: (values: string[], options: T[]) => void;
59
+ });
60
+ /**
61
+ * A custom dropdown with an options API, icons, groups, multi-select, and search, backed by a hidden
62
+ * native select so forms, native validation, and react-hook-form keep working.
63
+ * @example
64
+ * ```tsx
65
+ * import { Select } from '@pravalabs/ui/select';
66
+ * <Select
67
+ * label={t('role')}
68
+ * placeholder={t('chooseRole')}
69
+ * field={register('role')}
70
+ * error={errors.role?.message}
71
+ * options={[{ value: 'admin', label: <Trans id="admin">Admin</Trans>, searchText: t('admin'), icon: <Shield /> }]}
72
+ * />
73
+ * ```
74
+ */
75
+ export declare const Select: <T extends SelectOption = SelectOption>(props: SelectProps<T> & RefAttributes<HTMLSelectElement>) => ReactElement | null;
76
+ export {};
@@ -0,0 +1,2 @@
1
+ export { Select } from './Select';
2
+ export type { SelectOption, SelectOptionGroup, SelectProps } from './Select';
@@ -0,0 +1,9 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export type SeparatorProps = HTMLAttributes<HTMLDivElement> & {
3
+ /** The direction the separator follows in its layout. */
4
+ orientation?: "horizontal" | "vertical";
5
+ /** Expose a semantic separator to assistive technology when it marks a meaningful boundary. */
6
+ decorative?: boolean;
7
+ };
8
+ /** Separates adjacent content with a quiet, theme-aware rule. */
9
+ export declare function Separator({ orientation, decorative, className, ...props }: SeparatorProps): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Separator } from './Separator';
2
+ export type { SeparatorProps } from './Separator';
@@ -0,0 +1,7 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export type SkeletonProps = HTMLAttributes<HTMLSpanElement> & {
3
+ /** Shape of the reserved content space. Set dimensions with `style` when the content size is known. */
4
+ shape?: "text" | "rect" | "circle";
5
+ };
6
+ /** Reserves layout space while content is loading; decorative motion stops for reduced-motion users. */
7
+ export declare function Skeleton({ shape, className, style, ...props }: SkeletonProps): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Skeleton } from './Skeleton';
2
+ export type { SkeletonProps } from './Skeleton';
@@ -0,0 +1,15 @@
1
+ import { CSSProperties, HTMLAttributes } from 'react';
2
+ export type SpinnerProps = HTMLAttributes<HTMLSpanElement> & {
3
+ /** Optional status text for assistive technology. */
4
+ label?: string;
5
+ /** Indicator diameter. */
6
+ size?: "sm" | "md" | "lg";
7
+ /** Loading indicator style. */
8
+ variant?: "spinner" | "dots" | "bars" | "pulse" | "bounce";
9
+ /** Semantic color; follows the active light or dark tokens. */
10
+ tone?: "primary" | "neutral" | "success" | "warning" | "danger" | "info";
11
+ /** CSS color value, including a CSS custom property. Defaults to the primary token. */
12
+ color?: CSSProperties["color"];
13
+ };
14
+ /** Shows an ongoing process. Pass a label when the loading status needs to be announced. */
15
+ export declare function Spinner({ label, size, variant, tone, color, className, style, ...props }: SpinnerProps): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Spinner } from './Spinner';
2
+ export type { SpinnerProps } from './Spinner';
@@ -0,0 +1,38 @@
1
+ import { ElementType, HTMLAttributes } from 'react';
2
+ export type StackProps = HTMLAttributes<HTMLElement> & {
3
+ /** Flow direction; `horizontal` follows the text direction. */
4
+ orientation?: "vertical" | "horizontal";
5
+ /** Space between children, in steps of 4px. */
6
+ gap?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12;
7
+ /** Cross-axis alignment. Defaults to `stretch` when vertical and `center` when horizontal. */
8
+ align?: "start" | "center" | "end" | "stretch" | "baseline";
9
+ /** Main-axis distribution. */
10
+ justify?: "start" | "center" | "end" | "between";
11
+ /** Lets children wrap onto new lines when they run out of room. */
12
+ wrap?: boolean;
13
+ /** Element to render, such as `ul` or `nav`. */
14
+ as?: ElementType;
15
+ };
16
+ /**
17
+ * Arranges children in a row or column with a consistent gap, without wrapping each child.
18
+ * @example
19
+ * ```tsx
20
+ * import { Stack } from '@pravalabs/ui/stack';
21
+ *
22
+ * <Stack orientation="horizontal" gap={2} wrap><Button>Save</Button><Button>Cancel</Button></Stack>
23
+ * ```
24
+ */
25
+ export declare const Stack: import('react').ForwardRefExoticComponent<HTMLAttributes<HTMLElement> & {
26
+ /** Flow direction; `horizontal` follows the text direction. */
27
+ orientation?: "vertical" | "horizontal";
28
+ /** Space between children, in steps of 4px. */
29
+ gap?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12;
30
+ /** Cross-axis alignment. Defaults to `stretch` when vertical and `center` when horizontal. */
31
+ align?: "start" | "center" | "end" | "stretch" | "baseline";
32
+ /** Main-axis distribution. */
33
+ justify?: "start" | "center" | "end" | "between";
34
+ /** Lets children wrap onto new lines when they run out of room. */
35
+ wrap?: boolean;
36
+ /** Element to render, such as `ul` or `nav`. */
37
+ as?: ElementType;
38
+ } & import('react').RefAttributes<HTMLElement>>;
@@ -0,0 +1,2 @@
1
+ export { Stack } from './Stack';
2
+ export type { StackProps } from './Stack';
@@ -0,0 +1,19 @@
1
+ import { InputHTMLAttributes, ReactNode } from 'react';
2
+ import { FieldProps } from '../field/field';
3
+ export type SwitchProps = Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & FieldProps & {
4
+ /** Visible label; clicking it toggles the switch. */
5
+ label?: ReactNode;
6
+ };
7
+ /**
8
+ * An on/off setting that applies immediately: a native checkbox with `role="switch"`, so Space toggles it.
9
+ * Use Checkbox for choices that are submitted later.
10
+ * @example
11
+ * ```tsx
12
+ * import { Switch } from '@pravalabs/ui/switch';
13
+ * <Switch label="Dark mode" checked={dark} onChange={(e) => setDark(e.target.checked)} />
14
+ * ```
15
+ */
16
+ export declare const Switch: import('react').ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & FieldProps & {
17
+ /** Visible label; clicking it toggles the switch. */
18
+ label?: ReactNode;
19
+ } & import('react').RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,2 @@
1
+ export { Switch } from './Switch';
2
+ export type { SwitchProps } from './Switch';
@@ -0,0 +1,69 @@
1
+ import { ButtonHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
2
+ export type TabsProps = Omit<HTMLAttributes<HTMLDivElement>, "defaultValue"> & {
3
+ /** Called with the tab's `value` when it's chosen. */
4
+ onValueChange?: (value: string) => void;
5
+ /** `automatic` selects as focus moves. Use `manual` (Enter or Space) when panels are slow to show. */
6
+ activation?: "automatic" | "manual";
7
+ /** Layout of the tab list, which also picks the arrow keys: left/right or up/down. */
8
+ orientation?: "horizontal" | "vertical";
9
+ } & ({
10
+ /** Selected tab when controlled. */
11
+ value: string;
12
+ defaultValue?: undefined;
13
+ } | {
14
+ value?: undefined;
15
+ /** Initially selected tab when uncontrolled. */
16
+ defaultValue: string;
17
+ });
18
+ /**
19
+ * Switches between related panels. Inactive panels stay mounted and hidden, so they keep their state.
20
+ * @example
21
+ * ```tsx
22
+ * import { Tab, TabList, TabPanel, Tabs } from '@pravalabs/ui/tabs';
23
+ *
24
+ * <Tabs defaultValue="general">
25
+ * <TabList aria-label="Settings">
26
+ * <Tab value="general">General</Tab>
27
+ * <Tab value="billing">Billing</Tab>
28
+ * </TabList>
29
+ * <TabPanel value="general">General settings</TabPanel>
30
+ * <TabPanel value="billing">Billing settings</TabPanel>
31
+ * </Tabs>
32
+ * ```
33
+ */
34
+ export declare function Tabs({ value: valueProp, defaultValue, onValueChange, activation, orientation, className, ...props }: TabsProps): import("react").JSX.Element;
35
+ export type TabListProps = HTMLAttributes<HTMLDivElement>;
36
+ /**
37
+ * Holds the Tabs. Name it with `aria-label` or `aria-labelledby`. It scrolls when tabs don't fit.
38
+ * @example
39
+ * ```tsx
40
+ * <TabList aria-label="Settings"><Tab value="general">General</Tab></TabList>
41
+ * ```
42
+ */
43
+ export declare function TabList({ className, children, onKeyDown, ...props }: TabListProps): import("react").JSX.Element;
44
+ export type TabProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, "value" | "type"> & {
45
+ /** Matches the TabPanel it opens. Keep it stable across languages. */
46
+ value: string;
47
+ /** Decorative icon before the label. */
48
+ icon?: ReactNode;
49
+ };
50
+ /**
51
+ * One tab. Only the selected tab is in the page's tab order; arrow keys reach the rest.
52
+ * @example
53
+ * ```tsx
54
+ * <Tab value="billing">Billing</Tab>
55
+ * ```
56
+ */
57
+ export declare function Tab({ value, icon, className, children, onClick, ...props }: TabProps): import("react").JSX.Element;
58
+ export type TabPanelProps = Omit<HTMLAttributes<HTMLDivElement>, "value"> & {
59
+ /** Matches the Tab that opens it. */
60
+ value: string;
61
+ };
62
+ /**
63
+ * Content for one tab. It's focusable so keyboard users can reach and scroll it.
64
+ * @example
65
+ * ```tsx
66
+ * <TabPanel value="billing">Billing settings</TabPanel>
67
+ * ```
68
+ */
69
+ export declare function TabPanel({ value, className, ...props }: TabPanelProps): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Tab, TabList, TabPanel, Tabs } from './Tabs';
2
+ export type { TabListProps, TabPanelProps, TabProps, TabsProps } from './Tabs';
@@ -0,0 +1,26 @@
1
+ import { TextareaHTMLAttributes } from 'react';
2
+ import { FieldProps } from '../field/field';
3
+ export type TextareaProps = TextareaHTMLAttributes<HTMLTextAreaElement> & FieldProps<HTMLTextAreaElement> & {
4
+ /** Starting height in lines; the box never gets shorter than this. Defaults to 3. */
5
+ rows?: number;
6
+ /** Height limit in lines; past it the text scrolls. Set equal to `rows` for a fixed height. Defaults to 12. */
7
+ maxRows?: number;
8
+ /** Opt-in native drag handle. Off by default. */
9
+ resize?: "none" | "vertical" | "horizontal" | "both";
10
+ };
11
+ /**
12
+ * A multiline input that grows with its content between `rows` and `maxRows`, with help text and error message.
13
+ * @example
14
+ * ```tsx
15
+ * import { Textarea } from '@pravalabs/ui/textarea';
16
+ * <Textarea aria-label="Message" rows={2} maxRows={6} field={register('message')} />
17
+ * ```
18
+ */
19
+ export declare const Textarea: import('react').ForwardRefExoticComponent<TextareaHTMLAttributes<HTMLTextAreaElement> & FieldProps<HTMLTextAreaElement> & {
20
+ /** Starting height in lines; the box never gets shorter than this. Defaults to 3. */
21
+ rows?: number;
22
+ /** Height limit in lines; past it the text scrolls. Set equal to `rows` for a fixed height. Defaults to 12. */
23
+ maxRows?: number;
24
+ /** Opt-in native drag handle. Off by default. */
25
+ resize?: "none" | "vertical" | "horizontal" | "both";
26
+ } & import('react').RefAttributes<HTMLTextAreaElement>>;
@@ -0,0 +1,2 @@
1
+ export { Textarea } from './Textarea';
2
+ export type { TextareaProps } from './Textarea';
@@ -0,0 +1,55 @@
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
+ import { AlertProps } from '../alert';
3
+ export type ToastOptions = {
4
+ /** Reuse an id to update a toast in place, such as "Saving" to "Saved". */
5
+ id?: string;
6
+ /** Short summary in bold. */
7
+ title?: ReactNode;
8
+ /** Supporting text. */
9
+ description?: ReactNode;
10
+ /** Semantic color. `danger` announces at once and stays until dismissed. */
11
+ tone?: AlertProps["tone"];
12
+ /** Control for this toast, such as an Undo Button. */
13
+ action?: ReactNode;
14
+ /**
15
+ * Milliseconds on screen, paused while hovered, focused, or in a hidden tab. Defaults to 5000,
16
+ * 10000 with an `action`, and `Infinity` (stays until dismissed) for `danger`.
17
+ */
18
+ duration?: number;
19
+ };
20
+ /**
21
+ * Shows a toast through the page's `<Toaster />` and returns its id.
22
+ * @example
23
+ * ```tsx
24
+ * import { toast } from '@pravalabs/ui/toast';
25
+ *
26
+ * toast({ title: 'Invitation sent', tone: 'success' });
27
+ * ```
28
+ */
29
+ export declare function toast(options: ToastOptions): string;
30
+ /**
31
+ * Dismisses one toast, or every toast when called with no id.
32
+ * @example
33
+ * ```tsx
34
+ * import { dismissToast } from '@pravalabs/ui/toast';
35
+ *
36
+ * dismissToast(id);
37
+ * ```
38
+ */
39
+ export declare function dismissToast(id?: string): void;
40
+ export type ToasterProps = HTMLAttributes<HTMLDivElement> & {
41
+ /** Screen corner or edge. `start` and `end` follow the text direction. */
42
+ placement?: "top-start" | "top-center" | "top-end" | "bottom-start" | "bottom-center" | "bottom-end";
43
+ };
44
+ /**
45
+ * Renders the toasts started with `toast()`. Place one near your app's root, inside `PravaProvider`.
46
+ * shortcut: a modal Dialog makes everything outside it inert, so toasts show above it but can't
47
+ * be pressed or announced until it closes. Upgrade by rendering a Toaster inside that Dialog.
48
+ * @example
49
+ * ```tsx
50
+ * import { Toaster } from '@pravalabs/ui/toast';
51
+ *
52
+ * <Toaster placement="bottom-end" />
53
+ * ```
54
+ */
55
+ export declare function Toaster({ placement, className, ...props }: ToasterProps): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { dismissToast, toast, Toaster } from './Toast';
2
+ export type { ToasterProps, ToastOptions } from './Toast';
@@ -0,0 +1,22 @@
1
+ import { HTMLAttributes, ReactElement, ReactNode } from 'react';
2
+ import { FloatingPlacement } from '../../internal/overlay';
3
+ export type TooltipProps = Omit<HTMLAttributes<HTMLDivElement>, "content" | "children"> & {
4
+ /** Short plain text. Don't put links, buttons, or anything essential here. */
5
+ content: ReactNode;
6
+ /** The focusable element it describes. */
7
+ children: ReactElement;
8
+ /** Milliseconds to wait on hover before showing. Keyboard focus shows it at once. */
9
+ delay?: number;
10
+ /** Preferred side. It flips when there's no room; `start` and `end` follow the text direction. */
11
+ placement?: FloatingPlacement;
12
+ };
13
+ /**
14
+ * Short supplementary text shown on hover, keyboard focus, or tap, and hidden on Escape.
15
+ * @example
16
+ * ```tsx
17
+ * import { Tooltip } from '@pravalabs/ui/tooltip';
18
+ *
19
+ * <Tooltip content="Visible to your whole team"><Button>Publish</Button></Tooltip>
20
+ * ```
21
+ */
22
+ export declare function Tooltip({ content, children, delay, placement, className, id: idProp, ...props }: TooltipProps): import("react").JSX.Element;