@dimaan/ui 0.0.21 → 0.0.23
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.cjs +712 -196
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +479 -245
- package/dist/index.d.ts +479 -245
- package/dist/index.js +694 -198
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
|
-
import { ComponentPropsWithoutRef, HTMLAttributes, ReactNode, ButtonHTMLAttributes, ReactElement, InputHTMLAttributes, ChangeEvent, FormEventHandler, FieldsetHTMLAttributes, Ref, TextareaHTMLAttributes } from 'react';
|
|
3
|
+
import { ComponentPropsWithoutRef, HTMLAttributes, ReactNode, ButtonHTMLAttributes, ReactElement, InputHTMLAttributes, ChangeEvent, ForwardRefExoticComponent, RefAttributes, FormEventHandler, FieldsetHTMLAttributes, Ref, TextareaHTMLAttributes } from 'react';
|
|
4
4
|
import * as RadixAlertDialog from '@radix-ui/react-alert-dialog';
|
|
5
5
|
import { LinkProps } from 'react-router-dom';
|
|
6
6
|
import { Locale } from 'react-day-picker';
|
|
@@ -594,107 +594,6 @@ interface DatePickerProps {
|
|
|
594
594
|
*/
|
|
595
595
|
declare const DatePicker: react.ForwardRefExoticComponent<DatePickerProps & react.RefAttributes<HTMLButtonElement>>;
|
|
596
596
|
|
|
597
|
-
type PageHeaderHeadingLevel = 'h1' | 'h2' | 'h3' | 'h4';
|
|
598
|
-
/** Props passed to the routing-library `render` slot of the back button. */
|
|
599
|
-
interface PageHeaderBackRenderProps {
|
|
600
|
-
to?: LinkProps['to'];
|
|
601
|
-
className?: string;
|
|
602
|
-
children: ReactNode;
|
|
603
|
-
onClick?: () => void;
|
|
604
|
-
}
|
|
605
|
-
interface PageHeaderBackProps {
|
|
606
|
-
/** Visible label next to the arrow. Defaults to `"Back"`. */
|
|
607
|
-
label?: ReactNode;
|
|
608
|
-
/** Target to — renders a React Router `<Link>`. */
|
|
609
|
-
to?: LinkProps['to'];
|
|
610
|
-
/** Click handler — renders a `<button>` (or wraps the `render` element). */
|
|
611
|
-
onClick?: () => void;
|
|
612
|
-
/** Routing-library render prop (e.g. wrap a different link component). Wins over `to`. */
|
|
613
|
-
render?: (props: PageHeaderBackRenderProps) => ReactElement;
|
|
614
|
-
}
|
|
615
|
-
interface PageHeaderProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
616
|
-
/** Page title (required). */
|
|
617
|
-
title: ReactNode;
|
|
618
|
-
/** Optional secondary text under the title. */
|
|
619
|
-
description?: ReactNode;
|
|
620
|
-
/** Slot above the title for breadcrumbs (e.g. `<Breadcrumbs items={…} />` or your own JSX). */
|
|
621
|
-
breadcrumbs?: ReactNode;
|
|
622
|
-
/** Optional back button rendered above the title row. */
|
|
623
|
-
back?: PageHeaderBackProps;
|
|
624
|
-
/** Slot on the trailing side of the title row — buttons, dropdowns, etc. */
|
|
625
|
-
actions?: ReactNode;
|
|
626
|
-
/** Heading level for the title element. Defaults to `'h1'`. */
|
|
627
|
-
as?: PageHeaderHeadingLevel;
|
|
628
|
-
/** Add a bottom border separator. Default: `false`. */
|
|
629
|
-
bordered?: boolean;
|
|
630
|
-
}
|
|
631
|
-
/**
|
|
632
|
-
* Top-of-page header — title, optional description, breadcrumbs, back button,
|
|
633
|
-
* and actions slot. The first thing a user sees on any list / detail / form
|
|
634
|
-
* page in a dashboard.
|
|
635
|
-
*
|
|
636
|
-
* Designed to drop directly into `<DashboardContent>` (or any padded page
|
|
637
|
-
* container). Has no outer padding of its own — the surrounding layout owns
|
|
638
|
-
* spacing.
|
|
639
|
-
*
|
|
640
|
-
* @example List page header with primary action
|
|
641
|
-
* ```tsx
|
|
642
|
-
* <PageHeader
|
|
643
|
-
* title="Users"
|
|
644
|
-
* description="Manage your team members and their roles."
|
|
645
|
-
* actions={<Button onClick={openCreate}>Add user</Button>}
|
|
646
|
-
* bordered
|
|
647
|
-
* />
|
|
648
|
-
* ```
|
|
649
|
-
*
|
|
650
|
-
* @example Detail page header with back button
|
|
651
|
-
* ```tsx
|
|
652
|
-
* <PageHeader
|
|
653
|
-
* title={user.name}
|
|
654
|
-
* description={user.email}
|
|
655
|
-
* back={{
|
|
656
|
-
* label: 'Users',
|
|
657
|
-
* to: '/users',
|
|
658
|
-
* }}
|
|
659
|
-
* actions={
|
|
660
|
-
* <>
|
|
661
|
-
* <Button variant="outline">Edit</Button>
|
|
662
|
-
* <Button variant="destructive">Delete</Button>
|
|
663
|
-
* </>
|
|
664
|
-
* }
|
|
665
|
-
* />
|
|
666
|
-
* ```
|
|
667
|
-
*
|
|
668
|
-
* @example With breadcrumbs slot
|
|
669
|
-
* ```tsx
|
|
670
|
-
* <PageHeader
|
|
671
|
-
* breadcrumbs={
|
|
672
|
-
* <nav aria-label="Breadcrumb">
|
|
673
|
-
* <ol className="flex items-center gap-1">
|
|
674
|
-
* <li><Link to="/">Home</Link></li>
|
|
675
|
-
* <li>/</li>
|
|
676
|
-
* <li>Users</li>
|
|
677
|
-
* </ol>
|
|
678
|
-
* </nav>
|
|
679
|
-
* }
|
|
680
|
-
* title="Users"
|
|
681
|
-
* />
|
|
682
|
-
* ```
|
|
683
|
-
*/
|
|
684
|
-
declare const PageHeader: react.ForwardRefExoticComponent<PageHeaderProps & react.RefAttributes<HTMLElement>>;
|
|
685
|
-
|
|
686
|
-
declare const pageHeaderBaseClass = "flex w-full flex-col gap-3";
|
|
687
|
-
/** Adds a bottom border separator below the header. */
|
|
688
|
-
declare const pageHeaderBorderedClass = "border-b border-border pb-4";
|
|
689
|
-
declare const pageHeaderTitleRowClass = "flex flex-wrap items-start justify-between gap-3 sm:gap-4";
|
|
690
|
-
declare const pageHeaderTitleBlockClass = "min-w-0 flex-1 space-y-1";
|
|
691
|
-
declare const pageHeaderTitleClass = "text-2xl font-semibold tracking-tight text-foreground";
|
|
692
|
-
declare const pageHeaderDescriptionClass = "text-sm text-muted-foreground";
|
|
693
|
-
declare const pageHeaderActionsClass = "flex shrink-0 flex-wrap items-center gap-2";
|
|
694
|
-
declare const pageHeaderBackClass = "inline-flex items-center gap-1.5 self-start text-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background rounded-md";
|
|
695
|
-
declare const pageHeaderBackIconClass = "size-4 shrink-0 rtl:rotate-180";
|
|
696
|
-
declare const pageHeaderBreadcrumbsClass = "text-xs text-muted-foreground";
|
|
697
|
-
|
|
698
597
|
interface DetailPageNotFoundState {
|
|
699
598
|
icon?: ReactNode;
|
|
700
599
|
title?: ReactNode;
|
|
@@ -703,6 +602,8 @@ interface DetailPageNotFoundState {
|
|
|
703
602
|
action?: ReactNode | null;
|
|
704
603
|
}
|
|
705
604
|
interface DetailPageLabels {
|
|
605
|
+
/** Back button label. Direction-aware default: `"Back"` / `"رجوع"`. */
|
|
606
|
+
back?: string;
|
|
706
607
|
notFoundTitle?: string;
|
|
707
608
|
notFoundDescription?: string;
|
|
708
609
|
}
|
|
@@ -711,8 +612,6 @@ interface DetailPageProps {
|
|
|
711
612
|
title: ReactNode;
|
|
712
613
|
/** Optional secondary text under the title (e.g. status pill, joined date). */
|
|
713
614
|
description?: ReactNode;
|
|
714
|
-
/** Optional back-button config — forwarded straight to `PageHeader.back`. */
|
|
715
|
-
back?: PageHeaderBackProps;
|
|
716
615
|
/** Header action slot — Edit / Archive / Delete buttons. */
|
|
717
616
|
actions?: ReactNode;
|
|
718
617
|
/** Page-header bottom border separator. Defaults to `true` for detail pages. */
|
|
@@ -753,6 +652,10 @@ interface DetailPageProps {
|
|
|
753
652
|
* Pairs with `<ListPage>` (read flow) and `<FormPage>` (write flow) as the
|
|
754
653
|
* third Phase-4 template. RHF-agnostic — no form integration.
|
|
755
654
|
*
|
|
655
|
+
* A back button is always rendered in the top-left of the header; clicking it
|
|
656
|
+
* calls `navigate(-1)`. The label is direction-aware (EN / AR) via
|
|
657
|
+
* `useDirection()` and can be overridden through `labels.back`.
|
|
658
|
+
*
|
|
756
659
|
* @example View user
|
|
757
660
|
* ```tsx
|
|
758
661
|
* const { data: user, isLoading } = useUser(id);
|
|
@@ -761,7 +664,6 @@ interface DetailPageProps {
|
|
|
761
664
|
* <DetailPage
|
|
762
665
|
* title={user ? `${user.name}` : 'Loading…'}
|
|
763
666
|
* description={user?.role}
|
|
764
|
-
* back={{ to: '/users' }}
|
|
765
667
|
* actions={
|
|
766
668
|
* <>
|
|
767
669
|
* <Button variant="outline" onClick={onArchive}>Archive</Button>
|
|
@@ -793,7 +695,7 @@ interface DetailPageProps {
|
|
|
793
695
|
* </DetailPage>
|
|
794
696
|
* ```
|
|
795
697
|
*/
|
|
796
|
-
declare function DetailPage({ title, description,
|
|
698
|
+
declare function DetailPage({ title, description, actions, bordered, isLoading, loadingRowCount, notFound, notFoundState, labels: labelsProp, children, className, bodyClassName, }: DetailPageProps): react_jsx_runtime.JSX.Element;
|
|
797
699
|
|
|
798
700
|
/** Outermost wrapper of `DetailPage` — vertical flex column with consistent spacing. */
|
|
799
701
|
declare const detailPageBaseClass = "flex w-full flex-col gap-6";
|
|
@@ -1127,6 +1029,117 @@ type FieldProps<TValues extends FieldValues = FieldValues, TName extends FieldPa
|
|
|
1127
1029
|
*/
|
|
1128
1030
|
declare function Field<TValues extends FieldValues = FieldValues, TName extends FieldPath<TValues> = FieldPath<TValues>>(props: FieldProps<TValues, TName>): ReactElement;
|
|
1129
1031
|
|
|
1032
|
+
type FileUploadErrorCode = 'file-too-large' | 'file-type-rejected';
|
|
1033
|
+
interface FileUploadError {
|
|
1034
|
+
code: FileUploadErrorCode;
|
|
1035
|
+
/** Direction-aware human-readable message. */
|
|
1036
|
+
message: string;
|
|
1037
|
+
/** The rejected file. */
|
|
1038
|
+
file: File;
|
|
1039
|
+
}
|
|
1040
|
+
interface FileUploadLabels {
|
|
1041
|
+
/** Empty-dropzone prompt. Direction-aware default. */
|
|
1042
|
+
prompt?: string;
|
|
1043
|
+
/** Hint line under the prompt. Defaults to `Max {maxSize} MB` (direction-aware). */
|
|
1044
|
+
hint?: string;
|
|
1045
|
+
/** aria-label prefix for the remove (×) button. Direction-aware default. */
|
|
1046
|
+
remove?: string;
|
|
1047
|
+
}
|
|
1048
|
+
interface FileUploadBaseProps {
|
|
1049
|
+
/** Native `accept` filter (e.g. `"image/*,.pdf"`). Also enforced on drop. */
|
|
1050
|
+
accept?: string;
|
|
1051
|
+
/** Max size per file, in MB. Defaults to `5`. */
|
|
1052
|
+
maxSize?: number;
|
|
1053
|
+
disabled?: boolean;
|
|
1054
|
+
/** Marks the underlying input required (for form validation). */
|
|
1055
|
+
required?: boolean;
|
|
1056
|
+
/** Native form name. */
|
|
1057
|
+
name?: string;
|
|
1058
|
+
/** Override id (otherwise auto-generated via useId). */
|
|
1059
|
+
id?: string;
|
|
1060
|
+
/** Fires when a file is rejected by `accept` / `maxSize`. */
|
|
1061
|
+
onError?: (error: FileUploadError) => void;
|
|
1062
|
+
/** Called when focus leaves the input. */
|
|
1063
|
+
onBlur?: () => void;
|
|
1064
|
+
/** Localized copy. */
|
|
1065
|
+
labels?: FileUploadLabels;
|
|
1066
|
+
/** Class on the outer wrapper. */
|
|
1067
|
+
className?: string;
|
|
1068
|
+
'aria-invalid'?: boolean | 'true' | 'false';
|
|
1069
|
+
'aria-describedby'?: string;
|
|
1070
|
+
'aria-label'?: string;
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Discriminated on `multiple`: the value is `File | null` for single mode and
|
|
1074
|
+
* `File[]` for multiple mode.
|
|
1075
|
+
*/
|
|
1076
|
+
type FileUploadProps = FileUploadBaseProps & ({
|
|
1077
|
+
multiple?: false;
|
|
1078
|
+
value?: File | null;
|
|
1079
|
+
defaultValue?: File | null;
|
|
1080
|
+
onValueChange?: (file: File | null) => void;
|
|
1081
|
+
onChange?: (file: File | null) => void;
|
|
1082
|
+
} | {
|
|
1083
|
+
multiple: true;
|
|
1084
|
+
value?: File[];
|
|
1085
|
+
defaultValue?: File[];
|
|
1086
|
+
onValueChange?: (files: File[]) => void;
|
|
1087
|
+
onChange?: (files: File[]) => void;
|
|
1088
|
+
});
|
|
1089
|
+
/**
|
|
1090
|
+
* Drag-and-drop file picker. **Bare control** (no inline label/error) — wrap in
|
|
1091
|
+
* `<Field label="…">` for label + helper + error wiring (ADR-007). Discriminated
|
|
1092
|
+
* on `multiple`: value is `File | null` (single) or `File[]` (multiple).
|
|
1093
|
+
*
|
|
1094
|
+
* Rejected files (by `accept` / `maxSize`) are not added and reported through
|
|
1095
|
+
* `onError` — surface them via `toast(...)` or the wrapping `<Field>` error.
|
|
1096
|
+
* Direction-aware copy (EN / AR) via `useDirection()`; override with `labels`.
|
|
1097
|
+
*
|
|
1098
|
+
* @example Single file inside a Field (RHF + Zod)
|
|
1099
|
+
* ```tsx
|
|
1100
|
+
* <Field name="cv" label="CV (PDF)" required>
|
|
1101
|
+
* <FileUpload accept=".pdf" maxSize={10} onError={(e) => toast.error(e.message)} />
|
|
1102
|
+
* </Field>
|
|
1103
|
+
* ```
|
|
1104
|
+
*
|
|
1105
|
+
* @example Multiple files, controlled
|
|
1106
|
+
* ```tsx
|
|
1107
|
+
* <FileUpload
|
|
1108
|
+
* multiple
|
|
1109
|
+
* accept="image/*"
|
|
1110
|
+
* value={images}
|
|
1111
|
+
* onValueChange={setImages}
|
|
1112
|
+
* aria-label="Gallery images"
|
|
1113
|
+
* />
|
|
1114
|
+
* ```
|
|
1115
|
+
*/
|
|
1116
|
+
declare const FileUpload: ForwardRefExoticComponent<FileUploadProps & RefAttributes<HTMLDivElement>>;
|
|
1117
|
+
|
|
1118
|
+
/**
|
|
1119
|
+
* FileUpload styling. The dropzone is a `<label>` whose state is driven by
|
|
1120
|
+
* `data-drag-active` / `data-invalid` / `data-disabled` and the focus ring of
|
|
1121
|
+
* the visually-hidden `peer` input. Re-exported from `src/index.ts` so consumers
|
|
1122
|
+
* can compose the same look onto custom elements.
|
|
1123
|
+
*/
|
|
1124
|
+
/** Outer wrapper — owns the drag handlers + stacks the dropzone and file rows. */
|
|
1125
|
+
declare const fileUploadBaseClass = "flex w-full min-w-0 flex-col gap-2";
|
|
1126
|
+
/** The clickable / drop target. */
|
|
1127
|
+
declare const fileUploadDropzoneClass: string;
|
|
1128
|
+
/** Upload glyph in the empty dropzone. */
|
|
1129
|
+
declare const fileUploadIconClass = "size-8 text-muted-foreground";
|
|
1130
|
+
/** Primary prompt line. */
|
|
1131
|
+
declare const fileUploadPromptClass = "text-sm text-foreground";
|
|
1132
|
+
/** Secondary hint line (size limit, etc.). */
|
|
1133
|
+
declare const fileUploadHintClass = "text-xs text-muted-foreground";
|
|
1134
|
+
/** A selected-file row (icon + name/size + remove). */
|
|
1135
|
+
declare const fileUploadFileRowClass = "flex items-center justify-between gap-2 rounded-md border border-border bg-card px-3 py-2";
|
|
1136
|
+
/** File name (truncates). */
|
|
1137
|
+
declare const fileUploadFileNameClass = "truncate text-sm font-medium text-foreground";
|
|
1138
|
+
/** File size sub-label. */
|
|
1139
|
+
declare const fileUploadFileSizeClass = "text-xs text-muted-foreground";
|
|
1140
|
+
/** The per-file "×" remove button. */
|
|
1141
|
+
declare const fileUploadRemoveClass = "inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50";
|
|
1142
|
+
|
|
1130
1143
|
interface FormPageLabels {
|
|
1131
1144
|
/** Back button label (top-left). Direction-aware default: `"Back"` / `"رجوع"`. */
|
|
1132
1145
|
back?: string;
|
|
@@ -1343,101 +1356,6 @@ interface LanguageSwitcherProps<TCode extends string = string> extends Omit<Fiel
|
|
|
1343
1356
|
}
|
|
1344
1357
|
declare function LanguageSwitcher<TCode extends string = string>({ languages, value, onChange, ariaLabel, className, ...props }: LanguageSwitcherProps<TCode>): react_jsx_runtime.JSX.Element;
|
|
1345
1358
|
|
|
1346
|
-
type SelectVariant = 'default' | 'filled' | 'ghost';
|
|
1347
|
-
type SelectSize = 'sm' | 'md' | 'lg';
|
|
1348
|
-
declare const selectVariantClass: Record<SelectVariant, string>;
|
|
1349
|
-
/**
|
|
1350
|
-
* `pe-*` is wider than `ps-*` to leave room for the chevron icon. Logical
|
|
1351
|
-
* properties keep RTL working free.
|
|
1352
|
-
*/
|
|
1353
|
-
declare const selectSizeClass: Record<SelectSize, string>;
|
|
1354
|
-
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";
|
|
1355
|
-
|
|
1356
|
-
interface SelectOption {
|
|
1357
|
-
value: string;
|
|
1358
|
-
label: string;
|
|
1359
|
-
disabled?: boolean;
|
|
1360
|
-
}
|
|
1361
|
-
interface SelectGroup {
|
|
1362
|
-
label: string;
|
|
1363
|
-
options: SelectOption[];
|
|
1364
|
-
}
|
|
1365
|
-
/**
|
|
1366
|
-
* `options` accepts either a flat list of options OR a list of groups.
|
|
1367
|
-
* Use `children` for full Radix composition (Select.Item, Select.Separator…).
|
|
1368
|
-
*/
|
|
1369
|
-
type SelectOptions = SelectOption[] | SelectGroup[];
|
|
1370
|
-
interface SelectProps {
|
|
1371
|
-
variant?: SelectVariant;
|
|
1372
|
-
/** Visual size. Named `selectSize` to mirror Input's `inputSize`. */
|
|
1373
|
-
selectSize?: SelectSize;
|
|
1374
|
-
/** Declarative options (flat or grouped). When `children` is provided it wins. */
|
|
1375
|
-
options?: SelectOptions;
|
|
1376
|
-
/** Placeholder shown when no value is selected. */
|
|
1377
|
-
placeholder?: string;
|
|
1378
|
-
/** Controlled value. */
|
|
1379
|
-
value?: string;
|
|
1380
|
-
/** Initial value for uncontrolled usage. */
|
|
1381
|
-
defaultValue?: string;
|
|
1382
|
-
/** Radix-style change handler — receives the new value directly. */
|
|
1383
|
-
onValueChange?: (value: string) => void;
|
|
1384
|
-
/**
|
|
1385
|
-
* Synthetic-event handler for compatibility with `react-hook-form`'s
|
|
1386
|
-
* `field.onChange` and other consumers that expect a `ChangeEvent`-shaped
|
|
1387
|
-
* object. Both this and `onValueChange` fire on selection.
|
|
1388
|
-
*/
|
|
1389
|
-
onChange?: (event: ChangeEvent<HTMLSelectElement>) => void;
|
|
1390
|
-
/** Called when focus leaves the trigger. */
|
|
1391
|
-
onBlur?: () => void;
|
|
1392
|
-
/** Form name (for native form submission). */
|
|
1393
|
-
name?: string;
|
|
1394
|
-
/** Disables the trigger. */
|
|
1395
|
-
disabled?: boolean;
|
|
1396
|
-
/** Marks the underlying form input as required. */
|
|
1397
|
-
required?: boolean;
|
|
1398
|
-
/** Override id (otherwise auto-generated via useId). */
|
|
1399
|
-
id?: string;
|
|
1400
|
-
/** Class applied to the trigger button. */
|
|
1401
|
-
className?: string;
|
|
1402
|
-
'aria-invalid'?: boolean | 'true' | 'false';
|
|
1403
|
-
'aria-describedby'?: string;
|
|
1404
|
-
'aria-label'?: string;
|
|
1405
|
-
/** Radix children — used for advanced composition (Select.Group, etc.). */
|
|
1406
|
-
children?: ReactNode;
|
|
1407
|
-
}
|
|
1408
|
-
/**
|
|
1409
|
-
* Dropdown select built on `@radix-ui/react-select`. Renders only the trigger
|
|
1410
|
-
* button + Radix popup — wrap it in `<Field label="…">` to add a label, helper
|
|
1411
|
-
* text, error, and aria wiring.
|
|
1412
|
-
*
|
|
1413
|
-
* @example Inside a Field (RHF + Zod)
|
|
1414
|
-
* ```tsx
|
|
1415
|
-
* <Field name="country" label="Country" required>
|
|
1416
|
-
* <Select options={COUNTRIES} placeholder="Pick one" />
|
|
1417
|
-
* </Field>
|
|
1418
|
-
* ```
|
|
1419
|
-
*
|
|
1420
|
-
* @example Bare in a filter bar (no label)
|
|
1421
|
-
* ```tsx
|
|
1422
|
-
* <Select
|
|
1423
|
-
* value={status}
|
|
1424
|
-
* onValueChange={setStatus}
|
|
1425
|
-
* options={STATUS_OPTIONS}
|
|
1426
|
-
* placeholder="Status"
|
|
1427
|
-
* aria-label="Status filter"
|
|
1428
|
-
* />
|
|
1429
|
-
* ```
|
|
1430
|
-
*
|
|
1431
|
-
* @example Grouped options
|
|
1432
|
-
* ```tsx
|
|
1433
|
-
* <Select options={[
|
|
1434
|
-
* { label: 'GCC', options: [{ value: 'sa', label: 'Saudi Arabia' }] },
|
|
1435
|
-
* { label: 'Levant', options: [{ value: 'jo', label: 'Jordan' }] },
|
|
1436
|
-
* ]} />
|
|
1437
|
-
* ```
|
|
1438
|
-
*/
|
|
1439
|
-
declare const Select: react.ForwardRefExoticComponent<SelectProps & react.RefAttributes<HTMLButtonElement>>;
|
|
1440
|
-
|
|
1441
1359
|
type TableSize = 'sm' | 'md' | 'lg';
|
|
1442
1360
|
interface TableSizeClasses {
|
|
1443
1361
|
/** Applied to <tr> when needed (currently empty — present for symmetry). */
|
|
@@ -1588,21 +1506,152 @@ interface TableProps<T> {
|
|
|
1588
1506
|
*/
|
|
1589
1507
|
declare function Table<T>(props: TableProps<T>): react_jsx_runtime.JSX.Element;
|
|
1590
1508
|
|
|
1509
|
+
type SelectVariant = 'default' | 'filled' | 'ghost';
|
|
1510
|
+
type SelectSize = 'sm' | 'md' | 'lg';
|
|
1511
|
+
declare const selectVariantClass: Record<SelectVariant, string>;
|
|
1591
1512
|
/**
|
|
1592
|
-
*
|
|
1593
|
-
*
|
|
1594
|
-
* renders the Select + reports changes.
|
|
1513
|
+
* `pe-*` is wider than `ps-*` to leave room for the chevron icon. Logical
|
|
1514
|
+
* properties keep RTL working free.
|
|
1595
1515
|
*/
|
|
1596
|
-
|
|
1597
|
-
|
|
1516
|
+
declare const selectSizeClass: Record<SelectSize, string>;
|
|
1517
|
+
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";
|
|
1518
|
+
|
|
1519
|
+
interface SelectOption {
|
|
1520
|
+
value: string;
|
|
1521
|
+
label: string;
|
|
1522
|
+
disabled?: boolean;
|
|
1523
|
+
}
|
|
1524
|
+
interface SelectGroup {
|
|
1525
|
+
label: string;
|
|
1526
|
+
options: SelectOption[];
|
|
1527
|
+
}
|
|
1528
|
+
/**
|
|
1529
|
+
* `options` accepts either a flat list of options OR a list of groups.
|
|
1530
|
+
* Use `children` for full Radix composition (Select.Item, Select.Separator…).
|
|
1531
|
+
*/
|
|
1532
|
+
type SelectOptions = SelectOption[] | SelectGroup[];
|
|
1533
|
+
interface SelectProps {
|
|
1534
|
+
variant?: SelectVariant;
|
|
1535
|
+
/** Visual size. Named `selectSize` to mirror Input's `inputSize`. */
|
|
1536
|
+
selectSize?: SelectSize;
|
|
1537
|
+
/** Declarative options (flat or grouped). When `children` is provided it wins. */
|
|
1538
|
+
options?: SelectOptions;
|
|
1539
|
+
/** Placeholder shown when no value is selected. */
|
|
1540
|
+
placeholder?: string;
|
|
1541
|
+
/** Controlled value. */
|
|
1542
|
+
value?: string;
|
|
1543
|
+
/** Initial value for uncontrolled usage. */
|
|
1544
|
+
defaultValue?: string;
|
|
1545
|
+
/** Radix-style change handler — receives the new value directly. */
|
|
1546
|
+
onValueChange?: (value: string) => void;
|
|
1547
|
+
/**
|
|
1548
|
+
* Synthetic-event handler for compatibility with `react-hook-form`'s
|
|
1549
|
+
* `field.onChange` and other consumers that expect a `ChangeEvent`-shaped
|
|
1550
|
+
* object. Both this and `onValueChange` fire on selection.
|
|
1551
|
+
*/
|
|
1552
|
+
onChange?: (event: ChangeEvent<HTMLSelectElement>) => void;
|
|
1553
|
+
/** Called when focus leaves the trigger. */
|
|
1554
|
+
onBlur?: () => void;
|
|
1555
|
+
/** Form name (for native form submission). */
|
|
1556
|
+
name?: string;
|
|
1557
|
+
/** Disables the trigger. */
|
|
1558
|
+
disabled?: boolean;
|
|
1559
|
+
/** Marks the underlying form input as required. */
|
|
1560
|
+
required?: boolean;
|
|
1561
|
+
/** Override id (otherwise auto-generated via useId). */
|
|
1562
|
+
id?: string;
|
|
1563
|
+
/** Class applied to the trigger button. */
|
|
1564
|
+
className?: string;
|
|
1565
|
+
'aria-invalid'?: boolean | 'true' | 'false';
|
|
1566
|
+
'aria-describedby'?: string;
|
|
1567
|
+
'aria-label'?: string;
|
|
1568
|
+
/** Radix children — used for advanced composition (Select.Group, etc.). */
|
|
1569
|
+
children?: ReactNode;
|
|
1570
|
+
}
|
|
1571
|
+
/**
|
|
1572
|
+
* Dropdown select built on `@radix-ui/react-select`. Renders only the trigger
|
|
1573
|
+
* button + Radix popup — wrap it in `<Field label="…">` to add a label, helper
|
|
1574
|
+
* text, error, and aria wiring.
|
|
1575
|
+
*
|
|
1576
|
+
* @example Inside a Field (RHF + Zod)
|
|
1577
|
+
* ```tsx
|
|
1578
|
+
* <Field name="country" label="Country" required>
|
|
1579
|
+
* <Select options={COUNTRIES} placeholder="Pick one" />
|
|
1580
|
+
* </Field>
|
|
1581
|
+
* ```
|
|
1582
|
+
*
|
|
1583
|
+
* @example Bare in a filter bar (no label)
|
|
1584
|
+
* ```tsx
|
|
1585
|
+
* <Select
|
|
1586
|
+
* value={status}
|
|
1587
|
+
* onValueChange={setStatus}
|
|
1588
|
+
* options={STATUS_OPTIONS}
|
|
1589
|
+
* placeholder="Status"
|
|
1590
|
+
* aria-label="Status filter"
|
|
1591
|
+
* />
|
|
1592
|
+
* ```
|
|
1593
|
+
*
|
|
1594
|
+
* @example Grouped options
|
|
1595
|
+
* ```tsx
|
|
1596
|
+
* <Select options={[
|
|
1597
|
+
* { label: 'GCC', options: [{ value: 'sa', label: 'Saudi Arabia' }] },
|
|
1598
|
+
* { label: 'Levant', options: [{ value: 'jo', label: 'Jordan' }] },
|
|
1599
|
+
* ]} />
|
|
1600
|
+
* ```
|
|
1601
|
+
*/
|
|
1602
|
+
declare const Select: react.ForwardRefExoticComponent<SelectProps & react.RefAttributes<HTMLButtonElement>>;
|
|
1603
|
+
|
|
1604
|
+
/** How many columns a filter spans in the responsive filter grid. */
|
|
1605
|
+
type ListPageFilterWidth = 'narrow' | 'default' | 'wide';
|
|
1606
|
+
interface ListPageFilterBase {
|
|
1607
|
+
/** Unique key — used in the `filterValues` record and as the aria-label fallback. */
|
|
1598
1608
|
key: string;
|
|
1599
|
-
/** Display label.
|
|
1609
|
+
/** Display label. Drives the control's accessible name; falls back to `key`. */
|
|
1600
1610
|
label?: ReactNode;
|
|
1601
|
-
/**
|
|
1611
|
+
/**
|
|
1612
|
+
* Column span in the responsive filter grid. `'wide'` spans two columns on
|
|
1613
|
+
* `sm+` (good for a search box); `'narrow'` / `'default'` span one. Controls
|
|
1614
|
+
* always fill their cell, so this only affects how many columns they take.
|
|
1615
|
+
*/
|
|
1616
|
+
width?: ListPageFilterWidth;
|
|
1617
|
+
}
|
|
1618
|
+
/** Dropdown filter — the first option's value is treated as "show all / no filter". */
|
|
1619
|
+
interface ListPageSelectFilter extends ListPageFilterBase {
|
|
1620
|
+
type: 'select';
|
|
1621
|
+
options: SelectOption[];
|
|
1622
|
+
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Free-text filter — rendered as a search input (with a leading search icon).
|
|
1625
|
+
* Use it for the page's global text query as well as per-field text filters.
|
|
1626
|
+
* Empty / whitespace-only string means "no filter".
|
|
1627
|
+
*/
|
|
1628
|
+
interface ListPageTextFilter extends ListPageFilterBase {
|
|
1629
|
+
type: 'text';
|
|
1630
|
+
placeholder?: string;
|
|
1631
|
+
}
|
|
1632
|
+
/** Date filter — rendered as a `DatePicker`. ISO `YYYY-MM-DD`; empty means "no filter". */
|
|
1633
|
+
interface ListPageDateFilter extends ListPageFilterBase {
|
|
1634
|
+
type: 'date';
|
|
1635
|
+
placeholder?: string;
|
|
1636
|
+
}
|
|
1637
|
+
/**
|
|
1638
|
+
* Multi-select filter — rendered as a `MultiSelect`. The value is the selected
|
|
1639
|
+
* option values joined by commas (e.g. `"admin,editor"`); empty = no filter.
|
|
1640
|
+
* Consumers `.split(',')` to build the server query.
|
|
1641
|
+
*/
|
|
1642
|
+
interface ListPageMultiSelectFilter extends ListPageFilterBase {
|
|
1643
|
+
type: 'multiselect';
|
|
1602
1644
|
options: SelectOption[];
|
|
1603
|
-
|
|
1604
|
-
width?: 'narrow' | 'default' | 'wide';
|
|
1645
|
+
placeholder?: string;
|
|
1605
1646
|
}
|
|
1647
|
+
/**
|
|
1648
|
+
* One filter definition for `<ListPage>`, discriminated by `type`. The consumer
|
|
1649
|
+
* declares the control kind explicitly (`select` / `text` / `date`); the server
|
|
1650
|
+
* still owns the actual filtering — every filter reads and writes a single
|
|
1651
|
+
* string in the `filterValues` record.
|
|
1652
|
+
*/
|
|
1653
|
+
type ListPageFilter = ListPageSelectFilter | ListPageTextFilter | ListPageDateFilter | ListPageMultiSelectFilter;
|
|
1654
|
+
|
|
1606
1655
|
interface ListPageEmptyState {
|
|
1607
1656
|
icon?: ReactNode;
|
|
1608
1657
|
title?: ReactNode;
|
|
@@ -1616,10 +1665,6 @@ interface ListPageEmptyState {
|
|
|
1616
1665
|
* `nextPage`) flow through to the inner Table without re-declaration.
|
|
1617
1666
|
*/
|
|
1618
1667
|
interface ListPageLabels extends TableLabels {
|
|
1619
|
-
/** Search input placeholder. */
|
|
1620
|
-
searchPlaceholder?: string;
|
|
1621
|
-
/** Search input aria-label. Falls back to the placeholder. */
|
|
1622
|
-
searchAriaLabel?: string;
|
|
1623
1668
|
/** "Reset filters" button label. */
|
|
1624
1669
|
reset?: string;
|
|
1625
1670
|
/** "No results matching filters" title. */
|
|
@@ -1650,21 +1695,15 @@ interface ListPageProps<T> {
|
|
|
1650
1695
|
isLoading?: boolean;
|
|
1651
1696
|
/** Number of skeleton rows rendered while loading. Defaults to the table page size. */
|
|
1652
1697
|
loadingRowCount?: number;
|
|
1653
|
-
/** Current search query — the consumer's state. */
|
|
1654
|
-
searchValue?: string;
|
|
1655
1698
|
/**
|
|
1656
|
-
*
|
|
1657
|
-
*
|
|
1658
|
-
|
|
1659
|
-
onSearchChange?: (value: string) => void;
|
|
1660
|
-
/**
|
|
1661
|
-
* Filter definitions. Renders one `<Select>` per entry. Pair with
|
|
1662
|
-
* `filterValues` + `onFilterChange` to drive them.
|
|
1699
|
+
* Typed filter definitions (`select` / `text` / `date`). Renders the matching
|
|
1700
|
+
* control per entry via `ListPageFilterBar`. A `text` filter doubles as the
|
|
1701
|
+
* page's search box. Pair with `filterValues` + `onFilterChange` to drive them.
|
|
1663
1702
|
*/
|
|
1664
1703
|
filters?: ListPageFilter[];
|
|
1665
|
-
/** Current filter selections, keyed by `filter.key
|
|
1704
|
+
/** Current filter selections, keyed by `filter.key` (date values are ISO `YYYY-MM-DD`). */
|
|
1666
1705
|
filterValues?: Record<string, string>;
|
|
1667
|
-
/** Fires when any filter
|
|
1706
|
+
/** Fires when any filter control changes. */
|
|
1668
1707
|
onFilterChange?: (key: string, value: string) => void;
|
|
1669
1708
|
enableRowSelection?: boolean;
|
|
1670
1709
|
bulkActions?: (selected: T[]) => ReactNode;
|
|
@@ -1690,29 +1729,29 @@ interface ListPageProps<T> {
|
|
|
1690
1729
|
className?: string;
|
|
1691
1730
|
}
|
|
1692
1731
|
/**
|
|
1693
|
-
* Declarative server-driven list-page template — composes `PageHeader +
|
|
1694
|
-
*
|
|
1732
|
+
* Declarative server-driven list-page template — composes `PageHeader + filter
|
|
1733
|
+
* bar + Table + EmptyState` into a single component.
|
|
1695
1734
|
*
|
|
1696
1735
|
* **All data-shaping is server-side.** ListPage does not filter / search /
|
|
1697
1736
|
* paginate `data` locally; it renders whatever the consumer's data layer
|
|
1698
|
-
* returned for the current `
|
|
1699
|
-
*
|
|
1700
|
-
*
|
|
1737
|
+
* returned for the current `filterValues` + `pagination` query. ListPage's job
|
|
1738
|
+
* is the UI: render the controls, report user input back through callbacks, and
|
|
1739
|
+
* pick the right empty state. Search is just a `text` filter — there is no
|
|
1740
|
+
* separate search prop.
|
|
1701
1741
|
*
|
|
1702
1742
|
* **Three rendering branches in the table area:**
|
|
1703
1743
|
* - `isLoading` → Table with skeleton rows.
|
|
1704
|
-
* - `data` empty AND
|
|
1705
|
-
* -
|
|
1744
|
+
* - `data` empty AND no filter active → `noDataState` (first-run).
|
|
1745
|
+
* - a filter active but `data` empty → `emptyState` (no results) with a Reset button.
|
|
1706
1746
|
*
|
|
1707
1747
|
* @example Server-driven list with TanStack Query
|
|
1708
1748
|
* ```tsx
|
|
1709
|
-
* const [
|
|
1710
|
-
* const [filters, setFilters] = useState({ status: 'all' });
|
|
1749
|
+
* const [filters, setFilters] = useState({ q: '', status: 'all', createdFrom: '' });
|
|
1711
1750
|
* const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
|
|
1712
1751
|
*
|
|
1713
1752
|
* const { data, isLoading } = useQuery({
|
|
1714
|
-
* queryKey: ['users',
|
|
1715
|
-
* queryFn: () => fetchUsers({
|
|
1753
|
+
* queryKey: ['users', filters, pagination],
|
|
1754
|
+
* queryFn: () => fetchUsers({ ...filters, ...pagination }),
|
|
1716
1755
|
* });
|
|
1717
1756
|
*
|
|
1718
1757
|
* return (
|
|
@@ -1724,14 +1763,10 @@ interface ListPageProps<T> {
|
|
|
1724
1763
|
* isLoading={isLoading}
|
|
1725
1764
|
* columns={USER_COLUMNS}
|
|
1726
1765
|
*
|
|
1727
|
-
* searchValue={search}
|
|
1728
|
-
* onSearchChange={(v) => {
|
|
1729
|
-
* setSearch(v);
|
|
1730
|
-
* setPagination((p) => ({ ...p, pageIndex: 0 }));
|
|
1731
|
-
* }}
|
|
1732
|
-
*
|
|
1733
1766
|
* filters={[
|
|
1734
|
-
* { key: '
|
|
1767
|
+
* { type: 'text', key: 'q', placeholder: 'Search…', width: 'wide' },
|
|
1768
|
+
* { type: 'select', key: 'status', label: 'Status', options: STATUS_OPTIONS },
|
|
1769
|
+
* { type: 'date', key: 'createdFrom', label: 'Created after' },
|
|
1735
1770
|
* ]}
|
|
1736
1771
|
* filterValues={filters}
|
|
1737
1772
|
* onFilterChange={(key, value) => {
|
|
@@ -1745,7 +1780,206 @@ interface ListPageProps<T> {
|
|
|
1745
1780
|
* );
|
|
1746
1781
|
* ```
|
|
1747
1782
|
*/
|
|
1748
|
-
declare function ListPage<T>({ title, description, bordered, actions, data, columns, getRowId, isLoading, loadingRowCount,
|
|
1783
|
+
declare function ListPage<T>({ title, description, bordered, actions, data, columns, getRowId, isLoading, loadingRowCount, filters, filterValues, onFilterChange, enableRowSelection, bulkActions, pagination, onPaginationChange, totalCount, pageSizeOptions, emptyState, noDataState, labels: labelsProp, className, }: ListPageProps<T>): react_jsx_runtime.JSX.Element;
|
|
1784
|
+
|
|
1785
|
+
interface MultiSelectLabels {
|
|
1786
|
+
/** Search input placeholder. Direction-aware default: `"Search…"` / `"بحث…"`. */
|
|
1787
|
+
search?: string;
|
|
1788
|
+
/** Empty-state text when the search matches nothing. Default: `"No results"` / `"لا نتائج"`. */
|
|
1789
|
+
empty?: string;
|
|
1790
|
+
}
|
|
1791
|
+
interface MultiSelectProps {
|
|
1792
|
+
variant?: SelectVariant;
|
|
1793
|
+
/** Visual size. Named `selectSize` to mirror `Select`. */
|
|
1794
|
+
selectSize?: SelectSize;
|
|
1795
|
+
/** Options to choose from. */
|
|
1796
|
+
options: SelectOption[];
|
|
1797
|
+
/** Placeholder shown when nothing is selected. */
|
|
1798
|
+
placeholder?: string;
|
|
1799
|
+
/** Controlled value (array of selected option values). */
|
|
1800
|
+
value?: string[];
|
|
1801
|
+
/** Initial value for uncontrolled usage. */
|
|
1802
|
+
defaultValue?: string[];
|
|
1803
|
+
/** Radix-style change handler — receives the new array directly. */
|
|
1804
|
+
onValueChange?: (value: string[]) => void;
|
|
1805
|
+
/** Compatibility handler (e.g. react-hook-form's `field.onChange`). Receives the array. */
|
|
1806
|
+
onChange?: (value: string[]) => void;
|
|
1807
|
+
/** Called when focus leaves the trigger. */
|
|
1808
|
+
onBlur?: () => void;
|
|
1809
|
+
/** Show the in-dropdown search input. Defaults to `true`. */
|
|
1810
|
+
searchable?: boolean;
|
|
1811
|
+
/** Collapse chips beyond this count into a `+N` badge. Default: show all (wrap). */
|
|
1812
|
+
maxTagCount?: number;
|
|
1813
|
+
/** Localized copy for search / empty-state. */
|
|
1814
|
+
labels?: MultiSelectLabels;
|
|
1815
|
+
/** Form name — renders a hidden input with the comma-joined value. */
|
|
1816
|
+
name?: string;
|
|
1817
|
+
/** Disables the trigger. */
|
|
1818
|
+
disabled?: boolean;
|
|
1819
|
+
/** Marks the field as required (for form validation). */
|
|
1820
|
+
required?: boolean;
|
|
1821
|
+
/** Override id (otherwise auto-generated via useId). */
|
|
1822
|
+
id?: string;
|
|
1823
|
+
/** Class applied to the trigger. */
|
|
1824
|
+
className?: string;
|
|
1825
|
+
/** Class applied to the popover content. */
|
|
1826
|
+
contentClassName?: string;
|
|
1827
|
+
'aria-invalid'?: boolean | 'true' | 'false';
|
|
1828
|
+
'aria-describedby'?: string;
|
|
1829
|
+
'aria-label'?: string;
|
|
1830
|
+
}
|
|
1831
|
+
/**
|
|
1832
|
+
* Multi-select control built on `@radix-ui/react-popover` (Radix Select is
|
|
1833
|
+
* single-select only). Selected values render as removable chips in the
|
|
1834
|
+
* trigger; the popup lists checkbox options with an optional search filter.
|
|
1835
|
+
* **RHF-friendly**: works inside `<Field>` — it coerces a non-array `value`
|
|
1836
|
+
* (e.g. `''`) to `[]` and emits the new array through `onChange`.
|
|
1837
|
+
*
|
|
1838
|
+
* @example Inside a Field (RHF + Zod)
|
|
1839
|
+
* ```tsx
|
|
1840
|
+
* <Field name="roles" label="Roles" required>
|
|
1841
|
+
* <MultiSelect options={ROLE_OPTIONS} placeholder="Pick roles" />
|
|
1842
|
+
* </Field>
|
|
1843
|
+
* ```
|
|
1844
|
+
*
|
|
1845
|
+
* @example Bare / controlled
|
|
1846
|
+
* ```tsx
|
|
1847
|
+
* <MultiSelect
|
|
1848
|
+
* options={ROLE_OPTIONS}
|
|
1849
|
+
* value={roles}
|
|
1850
|
+
* onValueChange={setRoles}
|
|
1851
|
+
* placeholder="Roles"
|
|
1852
|
+
* aria-label="Roles filter"
|
|
1853
|
+
* />
|
|
1854
|
+
* ```
|
|
1855
|
+
*/
|
|
1856
|
+
declare const MultiSelect: react.ForwardRefExoticComponent<MultiSelectProps & react.RefAttributes<HTMLDivElement>>;
|
|
1857
|
+
|
|
1858
|
+
/**
|
|
1859
|
+
* MultiSelect reuses the Select trigger look (`selectBaseClass` + variant) and
|
|
1860
|
+
* a Select-like popup. These constants cover only what's MultiSelect-specific:
|
|
1861
|
+
* the (auto-height) trigger, the chip row, the search row, and the option list.
|
|
1862
|
+
* Re-exported from `src/index.ts` so consumers can compose the same styling.
|
|
1863
|
+
*/
|
|
1864
|
+
/** Trigger height is `auto` (chips may wrap to multiple rows) unlike Select's fixed height. */
|
|
1865
|
+
declare const multiSelectTriggerSizeClass: Record<'sm' | 'md' | 'lg', string>;
|
|
1866
|
+
/** Wraps the chips / placeholder inside the trigger. */
|
|
1867
|
+
declare const multiSelectValueRowClass = "flex min-w-0 flex-1 flex-wrap items-center gap-1";
|
|
1868
|
+
/** A single selected-value chip (Badge-styled) with its remove button. */
|
|
1869
|
+
declare const multiSelectChipClass = "max-w-full gap-1 pe-1";
|
|
1870
|
+
/** The chip's "×" remove control. */
|
|
1871
|
+
declare const multiSelectChipRemoveClass = "inline-flex size-3.5 shrink-0 items-center justify-center rounded-sm hover:bg-foreground/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40";
|
|
1872
|
+
/** Popup content (the open dropdown panel) — width tracks the trigger. */
|
|
1873
|
+
declare const multiSelectContentClass = "z-50 w-(--radix-popover-trigger-width) overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95";
|
|
1874
|
+
/** Search row pinned to the top of the popup. */
|
|
1875
|
+
declare const multiSelectSearchRowClass = "border-b border-border p-1";
|
|
1876
|
+
/** Scrollable option list. */
|
|
1877
|
+
declare const multiSelectListClass = "max-h-60 overflow-y-auto overflow-x-hidden p-1";
|
|
1878
|
+
/** A single option row (Checkbox + label). */
|
|
1879
|
+
declare const multiSelectOptionClass = "flex w-full cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground has-[:focus-visible]:bg-accent has-[:disabled]:pointer-events-none has-[:disabled]:opacity-50";
|
|
1880
|
+
/** Empty-state row shown when the search matches nothing. */
|
|
1881
|
+
declare const multiSelectEmptyClass = "px-2 py-6 text-center text-sm text-muted-foreground";
|
|
1882
|
+
|
|
1883
|
+
type PageHeaderHeadingLevel = 'h1' | 'h2' | 'h3' | 'h4';
|
|
1884
|
+
/** Props passed to the routing-library `render` slot of the back button. */
|
|
1885
|
+
interface PageHeaderBackRenderProps {
|
|
1886
|
+
to?: LinkProps['to'];
|
|
1887
|
+
className?: string;
|
|
1888
|
+
children: ReactNode;
|
|
1889
|
+
onClick?: () => void;
|
|
1890
|
+
}
|
|
1891
|
+
interface PageHeaderBackProps {
|
|
1892
|
+
/** Visible label next to the arrow. Defaults to `"Back"`. */
|
|
1893
|
+
label?: ReactNode;
|
|
1894
|
+
/** Target to — renders a React Router `<Link>`. */
|
|
1895
|
+
to?: LinkProps['to'];
|
|
1896
|
+
/** Click handler — renders a `<button>` (or wraps the `render` element). */
|
|
1897
|
+
onClick?: () => void;
|
|
1898
|
+
/** Routing-library render prop (e.g. wrap a different link component). Wins over `to`. */
|
|
1899
|
+
render?: (props: PageHeaderBackRenderProps) => ReactElement;
|
|
1900
|
+
}
|
|
1901
|
+
interface PageHeaderProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
1902
|
+
/** Page title (required). */
|
|
1903
|
+
title: ReactNode;
|
|
1904
|
+
/** Optional secondary text under the title. */
|
|
1905
|
+
description?: ReactNode;
|
|
1906
|
+
/** Slot above the title for breadcrumbs (e.g. `<Breadcrumbs items={…} />` or your own JSX). */
|
|
1907
|
+
breadcrumbs?: ReactNode;
|
|
1908
|
+
/** Optional back button rendered above the title row. */
|
|
1909
|
+
back?: PageHeaderBackProps;
|
|
1910
|
+
/** Slot on the trailing side of the title row — buttons, dropdowns, etc. */
|
|
1911
|
+
actions?: ReactNode;
|
|
1912
|
+
/** Heading level for the title element. Defaults to `'h1'`. */
|
|
1913
|
+
as?: PageHeaderHeadingLevel;
|
|
1914
|
+
/** Add a bottom border separator. Default: `false`. */
|
|
1915
|
+
bordered?: boolean;
|
|
1916
|
+
}
|
|
1917
|
+
/**
|
|
1918
|
+
* Top-of-page header — title, optional description, breadcrumbs, back button,
|
|
1919
|
+
* and actions slot. The first thing a user sees on any list / detail / form
|
|
1920
|
+
* page in a dashboard.
|
|
1921
|
+
*
|
|
1922
|
+
* Designed to drop directly into `<DashboardContent>` (or any padded page
|
|
1923
|
+
* container). Has no outer padding of its own — the surrounding layout owns
|
|
1924
|
+
* spacing.
|
|
1925
|
+
*
|
|
1926
|
+
* @example List page header with primary action
|
|
1927
|
+
* ```tsx
|
|
1928
|
+
* <PageHeader
|
|
1929
|
+
* title="Users"
|
|
1930
|
+
* description="Manage your team members and their roles."
|
|
1931
|
+
* actions={<Button onClick={openCreate}>Add user</Button>}
|
|
1932
|
+
* bordered
|
|
1933
|
+
* />
|
|
1934
|
+
* ```
|
|
1935
|
+
*
|
|
1936
|
+
* @example Detail page header with back button
|
|
1937
|
+
* ```tsx
|
|
1938
|
+
* <PageHeader
|
|
1939
|
+
* title={user.name}
|
|
1940
|
+
* description={user.email}
|
|
1941
|
+
* back={{
|
|
1942
|
+
* label: 'Users',
|
|
1943
|
+
* to: '/users',
|
|
1944
|
+
* }}
|
|
1945
|
+
* actions={
|
|
1946
|
+
* <>
|
|
1947
|
+
* <Button variant="outline">Edit</Button>
|
|
1948
|
+
* <Button variant="destructive">Delete</Button>
|
|
1949
|
+
* </>
|
|
1950
|
+
* }
|
|
1951
|
+
* />
|
|
1952
|
+
* ```
|
|
1953
|
+
*
|
|
1954
|
+
* @example With breadcrumbs slot
|
|
1955
|
+
* ```tsx
|
|
1956
|
+
* <PageHeader
|
|
1957
|
+
* breadcrumbs={
|
|
1958
|
+
* <nav aria-label="Breadcrumb">
|
|
1959
|
+
* <ol className="flex items-center gap-1">
|
|
1960
|
+
* <li><Link to="/">Home</Link></li>
|
|
1961
|
+
* <li>/</li>
|
|
1962
|
+
* <li>Users</li>
|
|
1963
|
+
* </ol>
|
|
1964
|
+
* </nav>
|
|
1965
|
+
* }
|
|
1966
|
+
* title="Users"
|
|
1967
|
+
* />
|
|
1968
|
+
* ```
|
|
1969
|
+
*/
|
|
1970
|
+
declare const PageHeader: react.ForwardRefExoticComponent<PageHeaderProps & react.RefAttributes<HTMLElement>>;
|
|
1971
|
+
|
|
1972
|
+
declare const pageHeaderBaseClass = "flex w-full flex-col gap-3";
|
|
1973
|
+
/** Adds a bottom border separator below the header. */
|
|
1974
|
+
declare const pageHeaderBorderedClass = "border-b border-border pb-4";
|
|
1975
|
+
declare const pageHeaderTitleRowClass = "flex flex-wrap items-start justify-between gap-3 sm:gap-4";
|
|
1976
|
+
declare const pageHeaderTitleBlockClass = "min-w-0 flex-1 space-y-1";
|
|
1977
|
+
declare const pageHeaderTitleClass = "text-2xl font-semibold tracking-tight text-foreground";
|
|
1978
|
+
declare const pageHeaderDescriptionClass = "text-sm text-muted-foreground";
|
|
1979
|
+
declare const pageHeaderActionsClass = "flex shrink-0 flex-wrap items-center gap-2";
|
|
1980
|
+
declare const pageHeaderBackClass = "inline-flex items-center gap-1.5 self-start text-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background rounded-md";
|
|
1981
|
+
declare const pageHeaderBackIconClass = "size-4 shrink-0 rtl:rotate-180";
|
|
1982
|
+
declare const pageHeaderBreadcrumbsClass = "text-xs text-muted-foreground";
|
|
1749
1983
|
|
|
1750
1984
|
type RadioGroupSize = 'sm' | 'md' | 'lg';
|
|
1751
1985
|
/** Outer circle (radio button itself) — sized + bordered. */
|
|
@@ -2138,4 +2372,4 @@ declare function useDirection(): Direction;
|
|
|
2138
2372
|
|
|
2139
2373
|
declare function cn(...inputs: ClassValue[]): string;
|
|
2140
2374
|
|
|
2141
|
-
export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, type AlertDialogContentProps, AlertDialogDescription, type AlertDialogDescriptionProps, AlertDialogFooter, type AlertDialogFooterProps, AlertDialogHeader, type AlertDialogHeaderProps, AlertDialogOverlay, type AlertDialogOverlayProps, AlertDialogPortal, AlertDialogTitle, type AlertDialogTitleProps, AlertDialogTrigger, AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellProps, Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, type ConfirmDialogLabels, ConfirmDialogProvider, type ConfirmDialogProviderProps, type ConfirmOptions, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, DatePicker, type DatePickerProps, type DatePickerSize, type DatePickerVariant, DetailPage, type DetailPageLabels, type DetailPageNotFoundState, type DetailPageProps, Dialog, DialogClose, DialogContent, type DialogContentProps, DialogDescription, type DialogDescriptionProps, DialogFooter, type DialogFooterProps, DialogHeader, type DialogHeaderProps, DialogOverlay, type DialogOverlayProps, DialogPortal, DialogTitle, type DialogTitleProps, DialogTrigger, type Direction, DropdownMenu, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuItem, type DropdownMenuItemProps, type DropdownMenuItemVariant, DropdownMenuLabel, type DropdownMenuLabelProps, DropdownMenuPortal, DropdownMenuSeparator, type DropdownMenuSeparatorProps, DropdownMenuShortcut, type DropdownMenuShortcutProps, DropdownMenuTrigger, EmptyState, type EmptyStateProps, type EmptyStateSize, Field, type FieldOrientation, type FieldProps, type FieldRHFProps, FormPage, type FormPageLabels, type FormPageProps, 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, ListPage, type ListPageEmptyState, type ListPageFilter, type ListPageLabels, type ListPageProps, PageHeader, type PageHeaderBackProps, type PageHeaderBackRenderProps, type PageHeaderHeadingLevel, type PageHeaderProps, type PaginationState, RadioGroup, RadioGroupItem, type RadioGroupOption, type RadioGroupOrientation, type RadioGroupProps, type RadioGroupSize, 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, Switch, type SwitchProps, type SwitchSize, Table, type TableLabels, type TableProps, type TableSize, type TableSizeClasses, Textarea, type TextareaProps, type TextareaResize, type TextareaSize, type TextareaVariant, Toaster, type ToasterProps, Tooltip, type TooltipProps, TooltipProvider, type TooltipProviderProps, badgeBaseClass, badgeDotSizeClass, badgeSizeClass, badgeVariantClass, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, datePickerCalendarClass, datePickerCaptionClass, datePickerContentClass, datePickerDayBaseClass, datePickerDayWrapperClass, datePickerDisabledClass, datePickerMonthClass, datePickerMonthGridClass, datePickerMonthsClass, datePickerNavButtonClass, datePickerNavClass, datePickerOutsideClass, datePickerPlaceholderClass, datePickerSelectedClass, datePickerTodayClass, datePickerTriggerBaseClass, datePickerTriggerSizeClass, datePickerTriggerVariantClass, datePickerValueClass, datePickerWeekClass, datePickerWeekdayClass, datePickerWeekdaysClass, detailPageBaseClass, detailPageBodyClass, detailPageEmptyClass, detailPageSkeletonRowClass, dialogCloseButtonClass, dialogContentClass, dialogDescriptionClass, dialogFooterClass, dialogHeaderClass, dialogOverlayClass, dialogTitleClass, dropdownMenuContentClass, dropdownMenuItemBaseClass, dropdownMenuItemInsetClass, dropdownMenuItemVariantClass, dropdownMenuLabelClass, dropdownMenuSeparatorClass, dropdownMenuShortcutClass, emptyStateActionsSpacingClass, emptyStateBaseClass, emptyStateContainerSizeClass, emptyStateDescriptionSizeClass, emptyStateIconWrapperBaseClass, emptyStateIconWrapperSizeClass, emptyStateTitleSizeClass, formPageActionsBarClass, formPageBaseClass, formPageBodyClass, formPageSkeletonRowClass, inputBaseClass, inputSizeClass, inputVariantClass, pageHeaderActionsClass, pageHeaderBackClass, pageHeaderBackIconClass, pageHeaderBaseClass, pageHeaderBorderedClass, pageHeaderBreadcrumbsClass, pageHeaderDescriptionClass, pageHeaderTitleBlockClass, pageHeaderTitleClass, pageHeaderTitleRowClass, radioGroupBaseClass, radioGroupOrientationClass, radioIndicatorBaseClass, radioIndicatorDotClass, radioIndicatorSizeClass, radioItemBaseClass, radioItemSizeClass, radioLabelSizeClass, radioOptionRowClass, selectBaseClass, selectSizeClass, selectVariantClass, switchThumbBaseClass, switchThumbClass, switchTrackBaseClass, switchTrackClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, textareaBaseClass, textareaResizeClass, textareaSizeClass, textareaVariantClass, toastClassNames, tooltipArrowClass, tooltipContentClass, useConfirm, useDashboardLayout, useDirection };
|
|
2375
|
+
export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, type AlertDialogContentProps, AlertDialogDescription, type AlertDialogDescriptionProps, AlertDialogFooter, type AlertDialogFooterProps, AlertDialogHeader, type AlertDialogHeaderProps, AlertDialogOverlay, type AlertDialogOverlayProps, AlertDialogPortal, AlertDialogTitle, type AlertDialogTitleProps, AlertDialogTrigger, AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellProps, Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, type ConfirmDialogLabels, ConfirmDialogProvider, type ConfirmDialogProviderProps, type ConfirmOptions, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, DatePicker, type DatePickerProps, type DatePickerSize, type DatePickerVariant, DetailPage, type DetailPageLabels, type DetailPageNotFoundState, type DetailPageProps, Dialog, DialogClose, DialogContent, type DialogContentProps, DialogDescription, type DialogDescriptionProps, DialogFooter, type DialogFooterProps, DialogHeader, type DialogHeaderProps, DialogOverlay, type DialogOverlayProps, DialogPortal, DialogTitle, type DialogTitleProps, DialogTrigger, type Direction, DropdownMenu, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuItem, type DropdownMenuItemProps, type DropdownMenuItemVariant, DropdownMenuLabel, type DropdownMenuLabelProps, DropdownMenuPortal, DropdownMenuSeparator, type DropdownMenuSeparatorProps, DropdownMenuShortcut, type DropdownMenuShortcutProps, DropdownMenuTrigger, EmptyState, type EmptyStateProps, type EmptyStateSize, Field, type FieldOrientation, type FieldProps, type FieldRHFProps, FileUpload, type FileUploadError, type FileUploadErrorCode, type FileUploadLabels, type FileUploadProps, FormPage, type FormPageLabels, type FormPageProps, 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, ListPage, type ListPageDateFilter, type ListPageEmptyState, type ListPageFilter, type ListPageFilterWidth, type ListPageLabels, type ListPageMultiSelectFilter, type ListPageProps, type ListPageSelectFilter, type ListPageTextFilter, MultiSelect, type MultiSelectLabels, type MultiSelectProps, PageHeader, type PageHeaderBackProps, type PageHeaderBackRenderProps, type PageHeaderHeadingLevel, type PageHeaderProps, type PaginationState, RadioGroup, RadioGroupItem, type RadioGroupOption, type RadioGroupOrientation, type RadioGroupProps, type RadioGroupSize, 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, Switch, type SwitchProps, type SwitchSize, Table, type TableLabels, type TableProps, type TableSize, type TableSizeClasses, Textarea, type TextareaProps, type TextareaResize, type TextareaSize, type TextareaVariant, Toaster, type ToasterProps, Tooltip, type TooltipProps, TooltipProvider, type TooltipProviderProps, badgeBaseClass, badgeDotSizeClass, badgeSizeClass, badgeVariantClass, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, datePickerCalendarClass, datePickerCaptionClass, datePickerContentClass, datePickerDayBaseClass, datePickerDayWrapperClass, datePickerDisabledClass, datePickerMonthClass, datePickerMonthGridClass, datePickerMonthsClass, datePickerNavButtonClass, datePickerNavClass, datePickerOutsideClass, datePickerPlaceholderClass, datePickerSelectedClass, datePickerTodayClass, datePickerTriggerBaseClass, datePickerTriggerSizeClass, datePickerTriggerVariantClass, datePickerValueClass, datePickerWeekClass, datePickerWeekdayClass, datePickerWeekdaysClass, detailPageBaseClass, detailPageBodyClass, detailPageEmptyClass, detailPageSkeletonRowClass, dialogCloseButtonClass, dialogContentClass, dialogDescriptionClass, dialogFooterClass, dialogHeaderClass, dialogOverlayClass, dialogTitleClass, dropdownMenuContentClass, dropdownMenuItemBaseClass, dropdownMenuItemInsetClass, dropdownMenuItemVariantClass, dropdownMenuLabelClass, dropdownMenuSeparatorClass, dropdownMenuShortcutClass, emptyStateActionsSpacingClass, emptyStateBaseClass, emptyStateContainerSizeClass, emptyStateDescriptionSizeClass, emptyStateIconWrapperBaseClass, emptyStateIconWrapperSizeClass, emptyStateTitleSizeClass, fileUploadBaseClass, fileUploadDropzoneClass, fileUploadFileNameClass, fileUploadFileRowClass, fileUploadFileSizeClass, fileUploadHintClass, fileUploadIconClass, fileUploadPromptClass, fileUploadRemoveClass, formPageActionsBarClass, formPageBaseClass, formPageBodyClass, formPageSkeletonRowClass, inputBaseClass, inputSizeClass, inputVariantClass, multiSelectChipClass, multiSelectChipRemoveClass, multiSelectContentClass, multiSelectEmptyClass, multiSelectListClass, multiSelectOptionClass, multiSelectSearchRowClass, multiSelectTriggerSizeClass, multiSelectValueRowClass, pageHeaderActionsClass, pageHeaderBackClass, pageHeaderBackIconClass, pageHeaderBaseClass, pageHeaderBorderedClass, pageHeaderBreadcrumbsClass, pageHeaderDescriptionClass, pageHeaderTitleBlockClass, pageHeaderTitleClass, pageHeaderTitleRowClass, radioGroupBaseClass, radioGroupOrientationClass, radioIndicatorBaseClass, radioIndicatorDotClass, radioIndicatorSizeClass, radioItemBaseClass, radioItemSizeClass, radioLabelSizeClass, radioOptionRowClass, selectBaseClass, selectSizeClass, selectVariantClass, switchThumbBaseClass, switchThumbClass, switchTrackBaseClass, switchTrackClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, textareaBaseClass, textareaResizeClass, textareaSizeClass, textareaVariantClass, toastClassNames, tooltipArrowClass, tooltipContentClass, useConfirm, useDashboardLayout, useDirection };
|