@dimaan/ui 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -76,6 +76,51 @@ interface AppShellProps extends Pick<DashboardLayoutProps, 'defaultCollapsed' |
76
76
  sidebarFooter?: ReactNode;
77
77
  children: ReactNode;
78
78
  }
79
+ /**
80
+ * Opinionated dashboard shell that combines `<DashboardLayout>` + `<Sidebar>` + `<Header>`
81
+ * with a flat `nav` array. Hosts `<DirectionProvider>` so any Radix-based component
82
+ * inside (Select, future Tooltip/Popover/etc.) auto-detects direction from `<html dir>`.
83
+ *
84
+ * For more complex layouts (custom sections, dividers, multi-row headers), compose
85
+ * the underlying primitives (`Sidebar` + `SidebarNav` + `DashboardHeader`) directly.
86
+ *
87
+ * @example Basic usage
88
+ * ```tsx
89
+ * <AppShell
90
+ * brand={{ logo: <Logo />, name: 'Acme' }}
91
+ * nav={[
92
+ * { key: 'home', label: 'Home', href: '/', icon: <Home /> },
93
+ * {
94
+ * key: 'settings',
95
+ * label: 'Settings',
96
+ * icon: <Settings />,
97
+ * items: [
98
+ * { key: 'profile', label: 'Profile', href: '/settings/profile' },
99
+ * { key: 'team', label: 'Team', href: '/settings/team' },
100
+ * ],
101
+ * },
102
+ * ]}
103
+ * title="Dashboard"
104
+ * searchPlaceholder="Search…"
105
+ * headerActions={<UserMenu />}
106
+ * sidebarFooter={<UserBadge />}
107
+ * >
108
+ * <Routes>...</Routes>
109
+ * </AppShell>
110
+ * ```
111
+ *
112
+ * @example With React Router Link integration via render prop
113
+ * ```tsx
114
+ * const nav = [{
115
+ * key: 'home',
116
+ * label: 'Home',
117
+ * icon: <Home />,
118
+ * render: ({ children, className, ...rest }) => (
119
+ * <Link to="/" className={className} {...rest}>{children}</Link>
120
+ * ),
121
+ * }];
122
+ * ```
123
+ */
79
124
  declare function AppShell({ brand, nav, title, searchPlaceholder, onSearch, headerActions, sidebarFooter, defaultCollapsed, collapsed, onCollapsedChange, children, }: AppShellProps): react_jsx_runtime.JSX.Element;
80
125
 
81
126
  interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {
@@ -111,6 +156,29 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
111
156
  */
112
157
  asChild?: boolean;
113
158
  }
159
+ /**
160
+ * Polymorphic button with 6 variants, 4 sizes, and a built-in loading state.
161
+ * Supports the `asChild` slot pattern for routing-library `<Link>` integration.
162
+ *
163
+ * @example Default usage
164
+ * ```tsx
165
+ * <Button onClick={handleSave}>Save</Button>
166
+ * ```
167
+ *
168
+ * @example Variant + size + loading
169
+ * ```tsx
170
+ * <Button variant="outline" size="sm" loading={isSubmitting}>
171
+ * Cancel
172
+ * </Button>
173
+ * ```
174
+ *
175
+ * @example asChild — wrap a router Link without a wrapper element
176
+ * ```tsx
177
+ * <Button asChild variant="ghost">
178
+ * <Link to="/settings">Open settings</Link>
179
+ * </Button>
180
+ * ```
181
+ */
114
182
  declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
115
183
 
116
184
  type CheckboxSize = 'sm' | 'md';
@@ -134,8 +202,16 @@ interface FieldRHFProps<TValues extends FieldValues = FieldValues, TName extends
134
202
  /** Path to the field within the form values. */
135
203
  name: TName;
136
204
  }
205
+ /**
206
+ * `vertical` (default) — label on top, control below, helper/error under.
207
+ * `horizontal` — label on start, control on end (same row); helper/error below.
208
+ *
209
+ * Use `horizontal` for boolean controls (Switch, Checkbox) where the universal
210
+ * pattern is "label · toggle" rather than "label / toggle below".
211
+ */
212
+ type FieldOrientation = 'vertical' | 'horizontal';
137
213
  interface FieldLayoutProps {
138
- /** Label rendered above the control. */
214
+ /** Label rendered with the control. Position depends on `orientation`. */
139
215
  label?: ReactNode;
140
216
  /** Helper text rendered under the control when there's no error. */
141
217
  description?: ReactNode;
@@ -145,6 +221,8 @@ interface FieldLayoutProps {
145
221
  disabled?: boolean;
146
222
  /** Stretch the wrapper to fill its parent. Defaults to `true`. */
147
223
  fullWidth?: boolean;
224
+ /** Layout direction. `vertical` (default) for inputs; `horizontal` for switches/checkboxes. */
225
+ orientation?: FieldOrientation;
148
226
  /** Class applied to the outer wrapper. */
149
227
  className?: string;
150
228
  /** The single control element to wrap. Receives id + aria + (in RHF mode) field props. */
@@ -253,6 +331,32 @@ interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'
253
331
  /** Class applied to the field container (`<label>` block). */
254
332
  containerClassName?: string;
255
333
  }
334
+ /**
335
+ * Text input with optional label, helper text, error message, and leading/trailing icons.
336
+ * Works standalone (uses `label`/`helperText`/`error` props) OR wrapped inside `<Field>`
337
+ * (id and aria-* are injected by Field via `cloneElement`).
338
+ *
339
+ * @example Standalone with label + helper
340
+ * ```tsx
341
+ * <Input label="Email" helperText="We'll never share it." type="email" />
342
+ * ```
343
+ *
344
+ * @example With icons
345
+ * ```tsx
346
+ * <Input
347
+ * label="Search"
348
+ * leadingIcon={<Search />}
349
+ * trailingIcon={<X onClick={clear} />}
350
+ * />
351
+ * ```
352
+ *
353
+ * @example Inside a Field (RHF + Zod)
354
+ * ```tsx
355
+ * <Field name="email" label="Email" required>
356
+ * <Input type="email" />
357
+ * </Field>
358
+ * ```
359
+ */
256
360
  declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
257
361
 
258
362
  interface LanguageOption<TCode extends string = string> {
@@ -268,6 +372,101 @@ interface LanguageSwitcherProps<TCode extends string = string> extends Omit<Fiel
268
372
  }
269
373
  declare function LanguageSwitcher<TCode extends string = string>({ languages, value, onChange, ariaLabel, className, ...props }: LanguageSwitcherProps<TCode>): react_jsx_runtime.JSX.Element;
270
374
 
375
+ type SelectVariant = 'default' | 'filled' | 'ghost';
376
+ type SelectSize = 'sm' | 'md' | 'lg';
377
+ declare const selectVariantClass: Record<SelectVariant, string>;
378
+ /**
379
+ * `pe-*` is wider than `ps-*` to leave room for the chevron icon. Logical
380
+ * properties keep RTL working free.
381
+ */
382
+ declare const selectSizeClass: Record<SelectSize, string>;
383
+ declare const selectBaseClass = "group/select relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus:ring-2 focus:ring-ring/40 focus:ring-offset-1 focus:ring-offset-background aria-[invalid=true]:border-destructive aria-[invalid=true]:focus:ring-destructive/40 disabled:pointer-events-none disabled:opacity-50 cursor-pointer data-[placeholder]:text-muted-foreground";
384
+
385
+ interface SelectOption {
386
+ value: string;
387
+ label: string;
388
+ disabled?: boolean;
389
+ }
390
+ interface SelectGroup {
391
+ label: string;
392
+ options: SelectOption[];
393
+ }
394
+ /**
395
+ * `options` accepts either a flat list of options OR a list of groups.
396
+ * Use `children` for full Radix composition (Select.Item, Select.Separator…).
397
+ */
398
+ type SelectOptions = SelectOption[] | SelectGroup[];
399
+ interface SelectProps {
400
+ variant?: SelectVariant;
401
+ /** Visual size. Named `selectSize` to mirror Input's `inputSize`. */
402
+ selectSize?: SelectSize;
403
+ /** Declarative options (flat or grouped). When `children` is provided it wins. */
404
+ options?: SelectOptions;
405
+ /** Placeholder shown when no value is selected. */
406
+ placeholder?: string;
407
+ /** Controlled value. */
408
+ value?: string;
409
+ /** Initial value for uncontrolled usage. */
410
+ defaultValue?: string;
411
+ /** Radix-style change handler — receives the new value directly. */
412
+ onValueChange?: (value: string) => void;
413
+ /**
414
+ * Synthetic-event handler for compatibility with `react-hook-form`'s
415
+ * `field.onChange` and other consumers that expect a `ChangeEvent`-shaped
416
+ * object. Both this and `onValueChange` fire on selection.
417
+ */
418
+ onChange?: (event: ChangeEvent<HTMLSelectElement>) => void;
419
+ /** Called when focus leaves the trigger. */
420
+ onBlur?: () => void;
421
+ /** Form name (for native form submission). */
422
+ name?: string;
423
+ /** Disables the trigger. */
424
+ disabled?: boolean;
425
+ /** Marks the underlying form input as required. */
426
+ required?: boolean;
427
+ /** Override id (otherwise auto-generated via useId). */
428
+ id?: string;
429
+ /** Class applied to the trigger button. */
430
+ className?: string;
431
+ 'aria-invalid'?: boolean | 'true' | 'false';
432
+ 'aria-describedby'?: string;
433
+ 'aria-label'?: string;
434
+ /** Radix children — used for advanced composition (Select.Group, etc.). */
435
+ children?: ReactNode;
436
+ }
437
+ /**
438
+ * Dropdown select built on `@radix-ui/react-select`. Renders only the trigger
439
+ * button + Radix popup — wrap it in `<Field label="…">` to add a label, helper
440
+ * text, error, and aria wiring.
441
+ *
442
+ * @example Inside a Field (RHF + Zod)
443
+ * ```tsx
444
+ * <Field name="country" label="Country" required>
445
+ * <Select options={COUNTRIES} placeholder="Pick one" />
446
+ * </Field>
447
+ * ```
448
+ *
449
+ * @example Bare in a filter bar (no label)
450
+ * ```tsx
451
+ * <Select
452
+ * value={status}
453
+ * onValueChange={setStatus}
454
+ * options={STATUS_OPTIONS}
455
+ * placeholder="Status"
456
+ * aria-label="Status filter"
457
+ * />
458
+ * ```
459
+ *
460
+ * @example Grouped options
461
+ * ```tsx
462
+ * <Select options={[
463
+ * { label: 'GCC', options: [{ value: 'sa', label: 'Saudi Arabia' }] },
464
+ * { label: 'Levant', options: [{ value: 'jo', label: 'Jordan' }] },
465
+ * ]} />
466
+ * ```
467
+ */
468
+ declare const Select: react.ForwardRefExoticComponent<SelectProps & react.RefAttributes<HTMLButtonElement>>;
469
+
271
470
  type SidebarProps = HTMLAttributes<HTMLElement>;
272
471
  declare function Sidebar({ className, children, ...props }: SidebarProps): react_jsx_runtime.JSX.Element;
273
472
 
@@ -320,6 +519,82 @@ interface SidebarNavItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
320
519
  }
321
520
  declare function SidebarNavItem({ icon, active, label, endSlot, className, children, render, ...props }: SidebarNavItemProps): react_jsx_runtime.JSX.Element;
322
521
 
522
+ type SwitchSize = 'sm' | 'md' | 'lg';
523
+ /**
524
+ * Each size is a tuple: track dimensions + thumb size + thumb travel distance.
525
+ * Track is `w` x `h`; thumb is `w/h size-X`; travel is the translation distance
526
+ * when checked (= track width − thumb size − padding).
527
+ */
528
+ declare const switchTrackClass: Record<SwitchSize, string>;
529
+ declare const switchThumbClass: Record<SwitchSize, string>;
530
+ declare const switchTrackBaseClass = "relative inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent bg-input transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary aria-[invalid=true]:ring-2 aria-[invalid=true]:ring-destructive/40";
531
+ declare const switchThumbBaseClass = "pointer-events-none block rounded-full bg-background shadow-sm ring-0 transition-transform";
532
+
533
+ interface SwitchProps {
534
+ /** Visual size. */
535
+ switchSize?: SwitchSize;
536
+ /** Controlled checked state (Radix-style). */
537
+ checked?: boolean;
538
+ /** Initial checked state for uncontrolled usage. */
539
+ defaultChecked?: boolean;
540
+ /** Radix-style change handler — receives the new boolean directly. */
541
+ onCheckedChange?: (checked: boolean) => void;
542
+ /**
543
+ * Form-library compatibility props. `value` mirrors what `<Field>` injects
544
+ * (RHF passes `field.value` as a boolean). `onChange` fires alongside
545
+ * `onCheckedChange` with a synthetic event so `field.onChange` works too.
546
+ */
547
+ value?: boolean | string | number;
548
+ onChange?: (event: ChangeEvent<HTMLButtonElement>) => void;
549
+ onBlur?: () => void;
550
+ /** Form name for native form submission. */
551
+ name?: string;
552
+ /** Disable interaction. */
553
+ disabled?: boolean;
554
+ /** Mark required for form validation. */
555
+ required?: boolean;
556
+ /** Override id (otherwise auto-generated via useId). */
557
+ id?: string;
558
+ /** Class on the track (the switch itself). */
559
+ className?: string;
560
+ 'aria-label'?: string;
561
+ 'aria-describedby'?: string;
562
+ 'aria-invalid'?: boolean | 'true' | 'false';
563
+ }
564
+ /**
565
+ * Boolean toggle built on `@radix-ui/react-switch`. Renders only the track +
566
+ * thumb — wrap it in `<Field orientation="horizontal" label="…">` to add a
567
+ * label, helper text, error, and aria wiring without duplicating that logic
568
+ * inside every form control.
569
+ *
570
+ * @example Inside a Field (RHF + Zod)
571
+ * ```tsx
572
+ * <Field name="darkMode" label="Dark mode" orientation="horizontal">
573
+ * <Switch />
574
+ * </Field>
575
+ * ```
576
+ *
577
+ * @example Bare in a settings list (custom layout)
578
+ * ```tsx
579
+ * <ul className="divide-y divide-border">
580
+ * <li className="flex items-center justify-between py-3">
581
+ * <span>Email digest</span>
582
+ * <Switch checked={digest} onCheckedChange={setDigest} aria-label="Email digest" />
583
+ * </li>
584
+ * </ul>
585
+ * ```
586
+ *
587
+ * @example Standalone controlled
588
+ * ```tsx
589
+ * <Switch
590
+ * checked={enabled}
591
+ * onCheckedChange={setEnabled}
592
+ * aria-label="Enable notifications"
593
+ * />
594
+ * ```
595
+ */
596
+ declare const Switch: react.ForwardRefExoticComponent<SwitchProps & react.RefAttributes<HTMLButtonElement>>;
597
+
323
598
  type TableSize = 'sm' | 'md' | 'lg';
324
599
  interface TableSizeClasses {
325
600
  /** Applied to <tr> when needed (currently empty — present for symmetry). */
@@ -457,6 +732,31 @@ interface TextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>
457
732
  /** Class applied to the field container (`<label>` block). */
458
733
  containerClassName?: string;
459
734
  }
735
+ /**
736
+ * Multi-line text input with the same label/helper/error/aria contract as `<Input>`.
737
+ * Works standalone OR wrapped inside `<Field>`.
738
+ *
739
+ * @example Standalone
740
+ * ```tsx
741
+ * <Textarea label="Bio" helperText="Up to 280 characters." rows={4} />
742
+ * ```
743
+ *
744
+ * @example With error + custom resize
745
+ * ```tsx
746
+ * <Textarea
747
+ * label="Notes"
748
+ * error={errors.notes?.message}
749
+ * resize="vertical"
750
+ * />
751
+ * ```
752
+ *
753
+ * @example Inside a Field (RHF + Zod)
754
+ * ```tsx
755
+ * <Field name="bio" label="Bio">
756
+ * <Textarea rows={4} />
757
+ * </Field>
758
+ * ```
759
+ */
460
760
  declare const Textarea: react.ForwardRefExoticComponent<TextareaProps & react.RefAttributes<HTMLTextAreaElement>>;
461
761
 
462
762
  type Direction = 'ltr' | 'rtl';
@@ -464,4 +764,4 @@ declare function useDirection(): Direction;
464
764
 
465
765
  declare function cn(...inputs: ClassValue[]): string;
466
766
 
467
- export { AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellProps, Avatar, type AvatarProps, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, type Direction, Field, type FieldProps, type FieldRHFProps, HeaderActions, type HeaderActionsProps, HeaderCollapseTrigger, type HeaderCollapseTriggerProps, HeaderMobileTrigger, type HeaderMobileTriggerProps, HeaderSearch, type HeaderSearchProps, HeaderTitle, type HeaderTitleProps, Input, type InputProps, type InputSize, type InputVariant, type LanguageOption, LanguageSwitcher, type LanguageSwitcherProps, type PaginationState, type RowSelectionState, Sidebar, SidebarFooter, type SidebarFooterProps, SidebarGroup, type SidebarGroupProps, SidebarHeader, type SidebarHeaderProps, SidebarNav, SidebarNavGroup, type SidebarNavGroupProps, SidebarNavItem, type SidebarNavItemProps, type SidebarNavItemRenderProps, type SidebarNavProps, type SidebarProps, type SortDirection, type SortState, type SortableValue, Table, type TableProps, type TableSize, type TableSizeClasses, Textarea, type TextareaProps, type TextareaResize, type TextareaSize, type TextareaVariant, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, inputBaseClass, inputSizeClass, inputVariantClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, textareaBaseClass, textareaResizeClass, textareaSizeClass, textareaVariantClass, useDashboardLayout, useDirection };
767
+ export { AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellProps, Avatar, type AvatarProps, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, type Direction, Field, type FieldOrientation, type FieldProps, type FieldRHFProps, HeaderActions, type HeaderActionsProps, HeaderCollapseTrigger, type HeaderCollapseTriggerProps, HeaderMobileTrigger, type HeaderMobileTriggerProps, HeaderSearch, type HeaderSearchProps, HeaderTitle, type HeaderTitleProps, Input, type InputProps, type InputSize, type InputVariant, type LanguageOption, LanguageSwitcher, type LanguageSwitcherProps, type PaginationState, type RowSelectionState, Select, type SelectOption, type SelectProps, type SelectSize, type SelectVariant, Sidebar, SidebarFooter, type SidebarFooterProps, SidebarGroup, type SidebarGroupProps, SidebarHeader, type SidebarHeaderProps, SidebarNav, SidebarNavGroup, type SidebarNavGroupProps, SidebarNavItem, type SidebarNavItemProps, type SidebarNavItemRenderProps, type SidebarNavProps, type SidebarProps, type SortDirection, type SortState, type SortableValue, Switch, type SwitchProps, type SwitchSize, Table, type TableProps, type TableSize, type TableSizeClasses, Textarea, type TextareaProps, type TextareaResize, type TextareaSize, type TextareaVariant, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, inputBaseClass, inputSizeClass, inputVariantClass, selectBaseClass, selectSizeClass, selectVariantClass, switchThumbBaseClass, switchThumbClass, switchTrackBaseClass, switchTrackClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, textareaBaseClass, textareaResizeClass, textareaSizeClass, textareaVariantClass, useDashboardLayout, useDirection };