@dimaan/ui 0.0.10 → 0.0.11

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.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { DirectionProvider } from '@radix-ui/react-direction';
2
- import { createContext, forwardRef, Children, isValidElement, cloneElement, useRef, useImperativeHandle, useLayoutEffect, useId, useCallback, useState, useEffect, useContext, useMemo } from 'react';
2
+ import { createContext, forwardRef, Children, isValidElement, cloneElement, useRef, useImperativeHandle, useLayoutEffect, useId, createElement, useCallback, useState, useEffect, useContext, useMemo } from 'react';
3
3
  import { clsx } from 'clsx';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
6
- import { Loader2, Check, Minus, ChevronDown, ChevronUp, ChevronLeft, Menu, ChevronsUpDown, ChevronRight } from 'lucide-react';
6
+ import { Loader2, Check, Minus, ChevronDown, ChevronUp, ArrowLeft, ChevronLeft, Menu, ChevronsUpDown, Search, RefreshCw, ChevronRight } from 'lucide-react';
7
+ import * as RadixDropdown from '@radix-ui/react-dropdown-menu';
7
8
  import { useFormContext, Controller } from 'react-hook-form';
8
- import * as RadixRadioGroup from '@radix-ui/react-radio-group';
9
9
  import * as RadixSelect from '@radix-ui/react-select';
10
+ import * as RadixRadioGroup from '@radix-ui/react-radio-group';
10
11
  import * as RadixSwitch from '@radix-ui/react-switch';
11
12
 
12
13
  // src/components/app-shell/AppShell.tsx
@@ -700,6 +701,47 @@ function Avatar({ src, alt = "", fallback, size = "md", className, ...props }) {
700
701
  }
701
702
  );
702
703
  }
704
+
705
+ // src/components/badge/badgeVariants.ts
706
+ var badgeVariantClass = {
707
+ default: "bg-muted text-foreground border-transparent",
708
+ primary: "bg-primary text-primary-foreground border-transparent",
709
+ success: "bg-success text-success-foreground border-transparent",
710
+ warning: "bg-warning text-warning-foreground border-transparent",
711
+ destructive: "bg-destructive text-destructive-foreground border-transparent",
712
+ outline: "border-border bg-transparent text-foreground"
713
+ };
714
+ var badgeSizeClass = {
715
+ sm: "h-5 gap-1 px-2 text-[11px]",
716
+ md: "h-6 gap-1.5 px-2.5 text-xs"
717
+ };
718
+ var badgeDotSizeClass = {
719
+ sm: "size-1.5",
720
+ md: "size-2"
721
+ };
722
+ var badgeBaseClass = "inline-flex shrink-0 items-center rounded-full border font-medium leading-none whitespace-nowrap select-none transition-colors";
723
+ var Badge = forwardRef(function Badge2({ variant = "default", size = "md", dot = false, className, children, ...props }, ref) {
724
+ return /* @__PURE__ */ jsxs(
725
+ "span",
726
+ {
727
+ ref,
728
+ "data-slot": "badge",
729
+ "data-variant": variant,
730
+ className: cn(badgeBaseClass, badgeVariantClass[variant], badgeSizeClass[size], className),
731
+ ...props,
732
+ children: [
733
+ dot ? /* @__PURE__ */ jsx(
734
+ "span",
735
+ {
736
+ "aria-hidden": "true",
737
+ className: cn("inline-block rounded-full bg-current opacity-80", badgeDotSizeClass[size])
738
+ }
739
+ ) : null,
740
+ children
741
+ ]
742
+ }
743
+ );
744
+ });
703
745
  var sizeClass2 = {
704
746
  sm: "h-3.5 w-3.5",
705
747
  md: "h-4 w-4"
@@ -768,6 +810,166 @@ var Checkbox = forwardRef(function Checkbox2({
768
810
  )
769
811
  ] });
770
812
  });
813
+
814
+ // src/components/dropdown-menu/dropdownMenuVariants.ts
815
+ var dropdownMenuContentClass = "z-50 min-w-32 overflow-hidden rounded-md border border-border bg-popover p-1 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";
816
+ var dropdownMenuItemBaseClass = "relative flex w-full cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0";
817
+ var dropdownMenuItemVariantClass = {
818
+ default: "text-foreground data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground",
819
+ destructive: "text-destructive data-[highlighted]:bg-destructive data-[highlighted]:text-destructive-foreground"
820
+ };
821
+ var dropdownMenuItemInsetClass = "ps-8";
822
+ var dropdownMenuSeparatorClass = "-mx-1 my-1 h-px bg-border";
823
+ var dropdownMenuLabelClass = "px-2 py-1.5 text-xs font-semibold text-muted-foreground select-none";
824
+ var dropdownMenuShortcutClass = "ms-auto text-xs tracking-widest text-muted-foreground";
825
+ var DropdownMenu = RadixDropdown.Root;
826
+ var DropdownMenuTrigger = RadixDropdown.Trigger;
827
+ var DropdownMenuGroup = RadixDropdown.Group;
828
+ var DropdownMenuPortal = RadixDropdown.Portal;
829
+ var DropdownMenuContent = forwardRef(function DropdownMenuContent2({ className, sideOffset = 4, ...props }, ref) {
830
+ return /* @__PURE__ */ jsx(RadixDropdown.Portal, { children: /* @__PURE__ */ jsx(
831
+ RadixDropdown.Content,
832
+ {
833
+ ref,
834
+ sideOffset,
835
+ "data-slot": "dropdown-menu-content",
836
+ className: cn(dropdownMenuContentClass, className),
837
+ ...props
838
+ }
839
+ ) });
840
+ });
841
+ var DropdownMenuItem = forwardRef(function DropdownMenuItem2({ className, variant = "default", inset = false, ...props }, ref) {
842
+ return /* @__PURE__ */ jsx(
843
+ RadixDropdown.Item,
844
+ {
845
+ ref,
846
+ "data-slot": "dropdown-menu-item",
847
+ "data-variant": variant,
848
+ className: cn(
849
+ dropdownMenuItemBaseClass,
850
+ dropdownMenuItemVariantClass[variant],
851
+ inset && dropdownMenuItemInsetClass,
852
+ className
853
+ ),
854
+ ...props
855
+ }
856
+ );
857
+ });
858
+ var DropdownMenuSeparator = forwardRef(function DropdownMenuSeparator2({ className, ...props }, ref) {
859
+ return /* @__PURE__ */ jsx(
860
+ RadixDropdown.Separator,
861
+ {
862
+ ref,
863
+ "data-slot": "dropdown-menu-separator",
864
+ className: cn(dropdownMenuSeparatorClass, className),
865
+ ...props
866
+ }
867
+ );
868
+ });
869
+ var DropdownMenuLabel = forwardRef(function DropdownMenuLabel2({ className, inset = false, ...props }, ref) {
870
+ return /* @__PURE__ */ jsx(
871
+ RadixDropdown.Label,
872
+ {
873
+ ref,
874
+ "data-slot": "dropdown-menu-label",
875
+ className: cn(dropdownMenuLabelClass, inset && dropdownMenuItemInsetClass, className),
876
+ ...props
877
+ }
878
+ );
879
+ });
880
+ var DropdownMenuShortcut = forwardRef(
881
+ function DropdownMenuShortcut2({ className, ...props }, ref) {
882
+ return /* @__PURE__ */ jsx(
883
+ "span",
884
+ {
885
+ ref,
886
+ "data-slot": "dropdown-menu-shortcut",
887
+ className: cn(dropdownMenuShortcutClass, className),
888
+ ...props
889
+ }
890
+ );
891
+ }
892
+ );
893
+
894
+ // src/components/empty-state/emptyStateVariants.ts
895
+ var emptyStateContainerSizeClass = {
896
+ sm: "py-8 gap-2",
897
+ md: "py-14 gap-3",
898
+ lg: "py-20 gap-4"
899
+ };
900
+ var emptyStateIconWrapperSizeClass = {
901
+ sm: "size-10 [&_svg]:size-5",
902
+ md: "size-14 [&_svg]:size-7",
903
+ lg: "size-16 [&_svg]:size-8"
904
+ };
905
+ var emptyStateTitleSizeClass = {
906
+ sm: "text-sm",
907
+ md: "text-base",
908
+ lg: "text-lg"
909
+ };
910
+ var emptyStateDescriptionSizeClass = {
911
+ sm: "text-xs",
912
+ md: "text-sm",
913
+ lg: "text-sm"
914
+ };
915
+ var emptyStateActionsSpacingClass = {
916
+ sm: "mt-2",
917
+ md: "mt-4",
918
+ lg: "mt-6"
919
+ };
920
+ var emptyStateBaseClass = "flex flex-col items-center justify-center text-center px-4";
921
+ var emptyStateIconWrapperBaseClass = "inline-flex items-center justify-center rounded-full bg-muted text-muted-foreground";
922
+ var EmptyState = forwardRef(function EmptyState2({ icon, title, description, action, size = "md", className, ...props }, ref) {
923
+ return /* @__PURE__ */ jsxs(
924
+ "div",
925
+ {
926
+ ref,
927
+ role: "status",
928
+ "aria-live": "polite",
929
+ "data-slot": "empty-state",
930
+ className: cn(emptyStateBaseClass, emptyStateContainerSizeClass[size], className),
931
+ ...props,
932
+ children: [
933
+ icon ? /* @__PURE__ */ jsx(
934
+ "span",
935
+ {
936
+ "aria-hidden": "true",
937
+ "data-slot": "empty-state-icon",
938
+ className: cn(emptyStateIconWrapperBaseClass, emptyStateIconWrapperSizeClass[size]),
939
+ children: icon
940
+ }
941
+ ) : null,
942
+ /* @__PURE__ */ jsx(
943
+ "p",
944
+ {
945
+ "data-slot": "empty-state-title",
946
+ className: cn("font-semibold text-foreground", emptyStateTitleSizeClass[size]),
947
+ children: title
948
+ }
949
+ ),
950
+ description ? /* @__PURE__ */ jsx(
951
+ "p",
952
+ {
953
+ "data-slot": "empty-state-description",
954
+ className: cn("max-w-sm text-muted-foreground", emptyStateDescriptionSizeClass[size]),
955
+ children: description
956
+ }
957
+ ) : null,
958
+ action ? /* @__PURE__ */ jsx(
959
+ "div",
960
+ {
961
+ "data-slot": "empty-state-actions",
962
+ className: cn(
963
+ "flex flex-wrap items-center justify-center gap-2",
964
+ emptyStateActionsSpacingClass[size]
965
+ ),
966
+ children: action
967
+ }
968
+ ) : null
969
+ ]
970
+ }
971
+ );
972
+ });
771
973
  function Field(props) {
772
974
  const formContext = useFormContext();
773
975
  if (props.name !== void 0) {
@@ -1012,130 +1214,71 @@ function LanguageSwitcher({
1012
1214
  );
1013
1215
  }
1014
1216
 
1015
- // src/components/radio-group/radioGroupVariants.ts
1016
- var radioItemSizeClass = {
1017
- sm: "size-4",
1018
- md: "size-5",
1019
- lg: "size-6"
1020
- };
1021
- var radioIndicatorSizeClass = {
1022
- sm: "size-1.5",
1023
- md: "size-2",
1024
- lg: "size-2.5"
1025
- };
1026
- var radioLabelSizeClass = {
1027
- sm: "text-xs",
1028
- md: "text-sm",
1029
- lg: "text-base"
1030
- };
1031
- var radioItemBaseClass = "aspect-square shrink-0 rounded-full border border-input bg-background text-primary outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background hover:border-ring disabled:cursor-not-allowed disabled:opacity-50 aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:ring-destructive/40 data-[state=checked]:border-primary";
1032
- var radioIndicatorBaseClass = "flex h-full w-full items-center justify-center";
1033
- var radioIndicatorDotClass = "rounded-full bg-primary";
1034
- var radioOptionRowClass = "flex cursor-pointer items-start gap-2 has-[button:disabled]:cursor-not-allowed";
1035
- var radioGroupBaseClass = "flex gap-3";
1036
- var radioGroupOrientationClass = {
1037
- vertical: "flex-col",
1038
- horizontal: "flex-row flex-wrap"
1039
- };
1040
- var RadioGroup = forwardRef(function RadioGroup2({
1041
- radioSize = "md",
1042
- orientation = "vertical",
1043
- value,
1044
- defaultValue,
1045
- onValueChange,
1046
- onChange,
1047
- onBlur,
1048
- name,
1049
- disabled,
1050
- required,
1051
- id,
1052
- options,
1217
+ // src/components/page-header/pageHeaderVariants.ts
1218
+ var pageHeaderBaseClass = "flex w-full flex-col gap-3";
1219
+ var pageHeaderBorderedClass = "border-b border-border pb-4";
1220
+ var pageHeaderTitleRowClass = "flex flex-wrap items-start justify-between gap-3 sm:gap-4";
1221
+ var pageHeaderTitleBlockClass = "min-w-0 flex-1 space-y-1";
1222
+ var pageHeaderTitleClass = "text-2xl font-semibold tracking-tight text-foreground";
1223
+ var pageHeaderDescriptionClass = "text-sm text-muted-foreground";
1224
+ var pageHeaderActionsClass = "flex shrink-0 flex-wrap items-center gap-2";
1225
+ var 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";
1226
+ var pageHeaderBackIconClass = "size-4 shrink-0 rtl:rotate-180";
1227
+ var pageHeaderBreadcrumbsClass = "text-xs text-muted-foreground";
1228
+ var PageHeader = forwardRef(function PageHeader2({
1229
+ title,
1230
+ description,
1231
+ breadcrumbs,
1232
+ back,
1233
+ actions,
1234
+ as = "h1",
1235
+ bordered = false,
1053
1236
  className,
1054
- "aria-label": ariaLabel,
1055
- "aria-labelledby": ariaLabelledBy,
1056
- "aria-describedby": ariaDescribedBy,
1057
- "aria-invalid": ariaInvalid,
1058
- children
1237
+ ...props
1059
1238
  }, ref) {
1060
- const generatedId = useId();
1061
- const groupId = id ?? generatedId;
1062
- const handleValueChange = useCallback(
1063
- (next) => {
1064
- onValueChange?.(next);
1065
- if (onChange) {
1066
- const synthetic = {
1067
- target: { value: next, name },
1068
- currentTarget: { value: next, name },
1069
- type: "change"
1070
- };
1071
- onChange(synthetic);
1072
- }
1073
- },
1074
- [onValueChange, onChange, name]
1075
- );
1076
- return /* @__PURE__ */ jsx(
1077
- RadixRadioGroup.Root,
1239
+ return /* @__PURE__ */ jsxs(
1240
+ "header",
1078
1241
  {
1079
1242
  ref,
1080
- id: groupId,
1081
- value,
1082
- defaultValue,
1083
- onValueChange: handleValueChange,
1084
- onBlur,
1085
- disabled,
1086
- required,
1087
- name,
1088
- orientation,
1089
- "aria-label": ariaLabel,
1090
- "aria-labelledby": ariaLabelledBy,
1091
- "aria-describedby": ariaDescribedBy,
1092
- "aria-invalid": ariaInvalid,
1093
- "data-slot": "radio-group",
1094
- className: cn(radioGroupBaseClass, radioGroupOrientationClass[orientation], className),
1095
- children: children ?? options?.map((opt) => /* @__PURE__ */ jsx(
1096
- RadioGroupOptionRow,
1097
- {
1098
- option: opt,
1099
- radioSize,
1100
- groupId
1101
- },
1102
- opt.value
1103
- ))
1243
+ "data-slot": "page-header",
1244
+ className: cn(pageHeaderBaseClass, bordered && pageHeaderBorderedClass, className),
1245
+ ...props,
1246
+ children: [
1247
+ breadcrumbs ? /* @__PURE__ */ jsx("div", { "data-slot": "page-header-breadcrumbs", className: pageHeaderBreadcrumbsClass, children: breadcrumbs }) : null,
1248
+ back ? /* @__PURE__ */ jsx(PageHeaderBack, { ...back }) : null,
1249
+ /* @__PURE__ */ jsxs("div", { "data-slot": "page-header-row", className: pageHeaderTitleRowClass, children: [
1250
+ /* @__PURE__ */ jsxs("div", { className: pageHeaderTitleBlockClass, children: [
1251
+ createElement(
1252
+ as,
1253
+ { "data-slot": "page-header-title", className: pageHeaderTitleClass },
1254
+ title
1255
+ ),
1256
+ description ? /* @__PURE__ */ jsx("p", { "data-slot": "page-header-description", className: pageHeaderDescriptionClass, children: description }) : null
1257
+ ] }),
1258
+ actions ? /* @__PURE__ */ jsx("div", { "data-slot": "page-header-actions", className: pageHeaderActionsClass, children: actions }) : null
1259
+ ] })
1260
+ ]
1104
1261
  }
1105
1262
  );
1106
1263
  });
1107
- function RadioGroupOptionRow({ option, radioSize, groupId }) {
1108
- const itemId = `${groupId}-${option.value}`;
1109
- return /* @__PURE__ */ jsxs("label", { htmlFor: itemId, className: radioOptionRowClass, children: [
1110
- /* @__PURE__ */ jsx(
1111
- RadixRadioGroup.Item,
1112
- {
1113
- id: itemId,
1114
- value: option.value,
1115
- disabled: option.disabled,
1116
- "data-slot": "radio-item",
1117
- className: cn(radioItemBaseClass, radioItemSizeClass[radioSize], "mt-0.5"),
1118
- children: /* @__PURE__ */ jsx(RadixRadioGroup.Indicator, { className: radioIndicatorBaseClass, children: /* @__PURE__ */ jsx("span", { className: cn(radioIndicatorDotClass, radioIndicatorSizeClass[radioSize]) }) })
1119
- }
1120
- ),
1121
- /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 leading-tight", children: [
1122
- /* @__PURE__ */ jsx("span", { className: cn("block font-medium text-foreground", radioLabelSizeClass[radioSize]), children: option.label }),
1123
- option.description ? /* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: option.description }) : null
1124
- ] })
1264
+ function PageHeaderBack({ label = "Back", href, onClick, render }) {
1265
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
1266
+ /* @__PURE__ */ jsx(ArrowLeft, { className: pageHeaderBackIconClass, "aria-hidden": "true" }),
1267
+ /* @__PURE__ */ jsx("span", { children: label })
1125
1268
  ] });
1269
+ if (render) {
1270
+ return render({
1271
+ href,
1272
+ onClick,
1273
+ className: pageHeaderBackClass,
1274
+ children: inner
1275
+ });
1276
+ }
1277
+ if (href) {
1278
+ return /* @__PURE__ */ jsx("a", { href, onClick, className: pageHeaderBackClass, children: inner });
1279
+ }
1280
+ return /* @__PURE__ */ jsx("button", { type: "button", onClick, className: pageHeaderBackClass, children: inner });
1126
1281
  }
1127
- var RadioGroupItem = forwardRef(function RadioGroupItem2({ className, radioSize = "md", ...props }, ref) {
1128
- return /* @__PURE__ */ jsx(
1129
- RadixRadioGroup.Item,
1130
- {
1131
- ref,
1132
- "data-slot": "radio-item",
1133
- className: cn(radioItemBaseClass, radioItemSizeClass[radioSize], className),
1134
- ...props,
1135
- children: /* @__PURE__ */ jsx(RadixRadioGroup.Indicator, { className: radioIndicatorBaseClass, children: /* @__PURE__ */ jsx("span", { className: cn(radioIndicatorDotClass, radioIndicatorSizeClass[radioSize]) }) })
1136
- }
1137
- );
1138
- });
1139
1282
 
1140
1283
  // src/components/select/selectVariants.ts
1141
1284
  var selectVariantClass = {
@@ -1262,81 +1405,6 @@ var SelectItem = forwardRef(function SelectItem2({ className, children, ...props
1262
1405
  /* @__PURE__ */ jsx(RadixSelect.ItemText, { children })
1263
1406
  ] });
1264
1407
  });
1265
-
1266
- // src/components/switch/switchVariants.ts
1267
- var switchTrackClass = {
1268
- sm: "h-4 w-7",
1269
- md: "h-5 w-9",
1270
- lg: "h-6 w-11"
1271
- };
1272
- var switchThumbClass = {
1273
- sm: "size-3 data-[state=checked]:translate-x-3 data-[state=checked]:rtl:-translate-x-3",
1274
- md: "size-4 data-[state=checked]:translate-x-4 data-[state=checked]:rtl:-translate-x-4",
1275
- lg: "size-5 data-[state=checked]:translate-x-5 data-[state=checked]:rtl:-translate-x-5"
1276
- };
1277
- var 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";
1278
- var switchThumbBaseClass = "pointer-events-none block rounded-full bg-background shadow-sm ring-0 transition-transform";
1279
- var Switch = forwardRef(function Switch2({
1280
- switchSize = "md",
1281
- checked,
1282
- defaultChecked,
1283
- onCheckedChange,
1284
- value,
1285
- onChange,
1286
- onBlur,
1287
- name,
1288
- disabled,
1289
- required,
1290
- id,
1291
- className,
1292
- "aria-label": ariaLabel,
1293
- "aria-describedby": ariaDescribedBy,
1294
- "aria-invalid": ariaInvalid
1295
- }, ref) {
1296
- const generatedId = useId();
1297
- const switchId = id ?? generatedId;
1298
- const resolvedChecked = checked ?? (value === void 0 ? void 0 : Boolean(value));
1299
- const handleCheckedChange = useCallback(
1300
- (next) => {
1301
- onCheckedChange?.(next);
1302
- if (onChange) {
1303
- const synthetic = {
1304
- target: { checked: next, value: next, name },
1305
- currentTarget: { checked: next, value: next, name },
1306
- type: "change"
1307
- };
1308
- onChange(synthetic);
1309
- }
1310
- },
1311
- [onCheckedChange, onChange, name]
1312
- );
1313
- return /* @__PURE__ */ jsx(
1314
- RadixSwitch.Root,
1315
- {
1316
- ref,
1317
- id: switchId,
1318
- checked: resolvedChecked,
1319
- defaultChecked,
1320
- onCheckedChange: handleCheckedChange,
1321
- onBlur,
1322
- disabled,
1323
- required,
1324
- name,
1325
- "aria-label": ariaLabel,
1326
- "aria-invalid": ariaInvalid,
1327
- "aria-describedby": ariaDescribedBy,
1328
- "data-slot": "switch-track",
1329
- className: cn(switchTrackBaseClass, switchTrackClass[switchSize], className),
1330
- children: /* @__PURE__ */ jsx(
1331
- RadixSwitch.Thumb,
1332
- {
1333
- "data-slot": "switch-thumb",
1334
- className: cn(switchThumbBaseClass, switchThumbClass[switchSize])
1335
- }
1336
- )
1337
- }
1338
- );
1339
- });
1340
1408
  function Pagination({
1341
1409
  pageIndex,
1342
1410
  pageSize,
@@ -1824,6 +1892,333 @@ function SortIndicator({ active, direction }) {
1824
1892
  if (!active) return /* @__PURE__ */ jsx(ChevronsUpDown, { "aria-hidden": "true", className });
1825
1893
  return direction === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { "aria-hidden": "true", className }) : /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true", className });
1826
1894
  }
1895
+ var DEFAULT_LABELS = {
1896
+ searchPlaceholder: "Search\u2026",
1897
+ searchAriaLabel: "Search",
1898
+ reset: "Reset filters",
1899
+ emptyTitle: "No results",
1900
+ emptyDescription: "Try clearing the search or adjusting the filters."
1901
+ };
1902
+ var FILTER_WIDTH_CLASS = {
1903
+ narrow: "w-32",
1904
+ default: "w-44",
1905
+ wide: "w-56"
1906
+ };
1907
+ function ListPage({
1908
+ title,
1909
+ description,
1910
+ bordered = true,
1911
+ actions,
1912
+ data,
1913
+ columns,
1914
+ getRowId,
1915
+ searchKeys,
1916
+ filters,
1917
+ enableRowSelection,
1918
+ bulkActions,
1919
+ emptyState,
1920
+ labels: labelsProp,
1921
+ className
1922
+ }) {
1923
+ const labels = { ...DEFAULT_LABELS, ...labelsProp };
1924
+ const initialFilterValues = useMemo(() => {
1925
+ const init = {};
1926
+ for (const f of filters ?? []) {
1927
+ init[f.key] = f.defaultValue ?? f.options[0]?.value ?? "";
1928
+ }
1929
+ return init;
1930
+ }, [filters]);
1931
+ const [search, setSearch] = useState("");
1932
+ const [filterValues, setFilterValues] = useState(initialFilterValues);
1933
+ const setFilter = (key, value) => {
1934
+ setFilterValues((prev) => ({ ...prev, [key]: value }));
1935
+ };
1936
+ const reset = () => {
1937
+ setSearch("");
1938
+ setFilterValues(initialFilterValues);
1939
+ };
1940
+ const hasActiveFilters = useMemo(() => {
1941
+ if (search.trim() !== "") return true;
1942
+ for (const f of filters ?? []) {
1943
+ const current = filterValues[f.key];
1944
+ const def = f.defaultValue ?? f.options[0]?.value ?? "";
1945
+ if (current !== def) return true;
1946
+ }
1947
+ return false;
1948
+ }, [search, filters, filterValues]);
1949
+ const filtered = useMemo(() => {
1950
+ return data.filter((row) => {
1951
+ if (search.trim() && searchKeys && searchKeys.length > 0) {
1952
+ const q = search.trim().toLowerCase();
1953
+ const matches = searchKeys.some((key) => {
1954
+ const val = row[key];
1955
+ return val != null && String(val).toLowerCase().includes(q);
1956
+ });
1957
+ if (!matches) return false;
1958
+ }
1959
+ for (const f of filters ?? []) {
1960
+ const value = filterValues[f.key];
1961
+ const def = f.defaultValue ?? f.options[0]?.value ?? "";
1962
+ if (value !== void 0 && value !== def) {
1963
+ if (f.accessor(row) !== value) return false;
1964
+ }
1965
+ }
1966
+ return true;
1967
+ });
1968
+ }, [data, search, searchKeys, filters, filterValues]);
1969
+ const showFilterBar = Boolean(searchKeys?.length) || Boolean(filters?.length);
1970
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "list-page", className: cn("space-y-6", className), children: [
1971
+ /* @__PURE__ */ jsx(PageHeader, { title, description, bordered, actions }),
1972
+ showFilterBar ? /* @__PURE__ */ jsxs("div", { "data-slot": "list-page-filter-bar", className: "flex flex-wrap items-center gap-3", children: [
1973
+ searchKeys?.length ? /* @__PURE__ */ jsx(
1974
+ Input,
1975
+ {
1976
+ type: "search",
1977
+ placeholder: labels.searchPlaceholder,
1978
+ "aria-label": labels.searchAriaLabel || labels.searchPlaceholder,
1979
+ value: search,
1980
+ onChange: (e) => setSearch(e.target.value),
1981
+ leadingIcon: /* @__PURE__ */ jsx(Search, {}),
1982
+ wrapperClassName: "sm:max-w-xs"
1983
+ }
1984
+ ) : null,
1985
+ filters?.map((f) => /* @__PURE__ */ jsx(
1986
+ Select,
1987
+ {
1988
+ "aria-label": f.ariaLabel,
1989
+ value: filterValues[f.key],
1990
+ onValueChange: (v) => setFilter(f.key, v),
1991
+ options: f.options,
1992
+ className: FILTER_WIDTH_CLASS[f.width ?? "default"]
1993
+ },
1994
+ f.key
1995
+ )),
1996
+ hasActiveFilters ? /* @__PURE__ */ jsxs(Button, { variant: "ghost", onClick: reset, children: [
1997
+ /* @__PURE__ */ jsx(RefreshCw, {}),
1998
+ labels.reset
1999
+ ] }) : null
2000
+ ] }) : null,
2001
+ filtered.length > 0 ? /* @__PURE__ */ jsx(
2002
+ Table,
2003
+ {
2004
+ "aria-label": typeof title === "string" ? title : void 0,
2005
+ data: filtered,
2006
+ columns,
2007
+ getRowId,
2008
+ enableRowSelection,
2009
+ bulkActions
2010
+ }
2011
+ ) : /* @__PURE__ */ jsx("div", { "data-slot": "list-page-empty", className: "rounded-md border border-border", children: /* @__PURE__ */ jsx(
2012
+ EmptyState,
2013
+ {
2014
+ icon: emptyState?.icon,
2015
+ title: emptyState?.title ?? labels.emptyTitle,
2016
+ description: emptyState?.description ?? labels.emptyDescription,
2017
+ action: emptyState?.action !== void 0 ? emptyState.action : hasActiveFilters ? /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: reset, children: labels.reset }) : null
2018
+ }
2019
+ ) })
2020
+ ] });
2021
+ }
2022
+
2023
+ // src/components/radio-group/radioGroupVariants.ts
2024
+ var radioItemSizeClass = {
2025
+ sm: "size-4",
2026
+ md: "size-5",
2027
+ lg: "size-6"
2028
+ };
2029
+ var radioIndicatorSizeClass = {
2030
+ sm: "size-1.5",
2031
+ md: "size-2",
2032
+ lg: "size-2.5"
2033
+ };
2034
+ var radioLabelSizeClass = {
2035
+ sm: "text-xs",
2036
+ md: "text-sm",
2037
+ lg: "text-base"
2038
+ };
2039
+ var radioItemBaseClass = "aspect-square shrink-0 rounded-full border border-input bg-background text-primary outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background hover:border-ring disabled:cursor-not-allowed disabled:opacity-50 aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:ring-destructive/40 data-[state=checked]:border-primary";
2040
+ var radioIndicatorBaseClass = "flex h-full w-full items-center justify-center";
2041
+ var radioIndicatorDotClass = "rounded-full bg-primary";
2042
+ var radioOptionRowClass = "flex cursor-pointer items-start gap-2 has-[button:disabled]:cursor-not-allowed";
2043
+ var radioGroupBaseClass = "flex gap-3";
2044
+ var radioGroupOrientationClass = {
2045
+ vertical: "flex-col",
2046
+ horizontal: "flex-row flex-wrap"
2047
+ };
2048
+ var RadioGroup = forwardRef(function RadioGroup2({
2049
+ radioSize = "md",
2050
+ orientation = "vertical",
2051
+ value,
2052
+ defaultValue,
2053
+ onValueChange,
2054
+ onChange,
2055
+ onBlur,
2056
+ name,
2057
+ disabled,
2058
+ required,
2059
+ id,
2060
+ options,
2061
+ className,
2062
+ "aria-label": ariaLabel,
2063
+ "aria-labelledby": ariaLabelledBy,
2064
+ "aria-describedby": ariaDescribedBy,
2065
+ "aria-invalid": ariaInvalid,
2066
+ children
2067
+ }, ref) {
2068
+ const generatedId = useId();
2069
+ const groupId = id ?? generatedId;
2070
+ const handleValueChange = useCallback(
2071
+ (next) => {
2072
+ onValueChange?.(next);
2073
+ if (onChange) {
2074
+ const synthetic = {
2075
+ target: { value: next, name },
2076
+ currentTarget: { value: next, name },
2077
+ type: "change"
2078
+ };
2079
+ onChange(synthetic);
2080
+ }
2081
+ },
2082
+ [onValueChange, onChange, name]
2083
+ );
2084
+ return /* @__PURE__ */ jsx(
2085
+ RadixRadioGroup.Root,
2086
+ {
2087
+ ref,
2088
+ id: groupId,
2089
+ value,
2090
+ defaultValue,
2091
+ onValueChange: handleValueChange,
2092
+ onBlur,
2093
+ disabled,
2094
+ required,
2095
+ name,
2096
+ orientation,
2097
+ "aria-label": ariaLabel,
2098
+ "aria-labelledby": ariaLabelledBy,
2099
+ "aria-describedby": ariaDescribedBy,
2100
+ "aria-invalid": ariaInvalid,
2101
+ "data-slot": "radio-group",
2102
+ className: cn(radioGroupBaseClass, radioGroupOrientationClass[orientation], className),
2103
+ children: children ?? options?.map((opt) => /* @__PURE__ */ jsx(
2104
+ RadioGroupOptionRow,
2105
+ {
2106
+ option: opt,
2107
+ radioSize,
2108
+ groupId
2109
+ },
2110
+ opt.value
2111
+ ))
2112
+ }
2113
+ );
2114
+ });
2115
+ function RadioGroupOptionRow({ option, radioSize, groupId }) {
2116
+ const itemId = `${groupId}-${option.value}`;
2117
+ return /* @__PURE__ */ jsxs("label", { htmlFor: itemId, className: radioOptionRowClass, children: [
2118
+ /* @__PURE__ */ jsx(
2119
+ RadixRadioGroup.Item,
2120
+ {
2121
+ id: itemId,
2122
+ value: option.value,
2123
+ disabled: option.disabled,
2124
+ "data-slot": "radio-item",
2125
+ className: cn(radioItemBaseClass, radioItemSizeClass[radioSize], "mt-0.5"),
2126
+ children: /* @__PURE__ */ jsx(RadixRadioGroup.Indicator, { className: radioIndicatorBaseClass, children: /* @__PURE__ */ jsx("span", { className: cn(radioIndicatorDotClass, radioIndicatorSizeClass[radioSize]) }) })
2127
+ }
2128
+ ),
2129
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 leading-tight", children: [
2130
+ /* @__PURE__ */ jsx("span", { className: cn("block font-medium text-foreground", radioLabelSizeClass[radioSize]), children: option.label }),
2131
+ option.description ? /* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: option.description }) : null
2132
+ ] })
2133
+ ] });
2134
+ }
2135
+ var RadioGroupItem = forwardRef(function RadioGroupItem2({ className, radioSize = "md", ...props }, ref) {
2136
+ return /* @__PURE__ */ jsx(
2137
+ RadixRadioGroup.Item,
2138
+ {
2139
+ ref,
2140
+ "data-slot": "radio-item",
2141
+ className: cn(radioItemBaseClass, radioItemSizeClass[radioSize], className),
2142
+ ...props,
2143
+ children: /* @__PURE__ */ jsx(RadixRadioGroup.Indicator, { className: radioIndicatorBaseClass, children: /* @__PURE__ */ jsx("span", { className: cn(radioIndicatorDotClass, radioIndicatorSizeClass[radioSize]) }) })
2144
+ }
2145
+ );
2146
+ });
2147
+
2148
+ // src/components/switch/switchVariants.ts
2149
+ var switchTrackClass = {
2150
+ sm: "h-4 w-7",
2151
+ md: "h-5 w-9",
2152
+ lg: "h-6 w-11"
2153
+ };
2154
+ var switchThumbClass = {
2155
+ sm: "size-3 data-[state=checked]:translate-x-3 data-[state=checked]:rtl:-translate-x-3",
2156
+ md: "size-4 data-[state=checked]:translate-x-4 data-[state=checked]:rtl:-translate-x-4",
2157
+ lg: "size-5 data-[state=checked]:translate-x-5 data-[state=checked]:rtl:-translate-x-5"
2158
+ };
2159
+ var 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";
2160
+ var switchThumbBaseClass = "pointer-events-none block rounded-full bg-background shadow-sm ring-0 transition-transform";
2161
+ var Switch = forwardRef(function Switch2({
2162
+ switchSize = "md",
2163
+ checked,
2164
+ defaultChecked,
2165
+ onCheckedChange,
2166
+ value,
2167
+ onChange,
2168
+ onBlur,
2169
+ name,
2170
+ disabled,
2171
+ required,
2172
+ id,
2173
+ className,
2174
+ "aria-label": ariaLabel,
2175
+ "aria-describedby": ariaDescribedBy,
2176
+ "aria-invalid": ariaInvalid
2177
+ }, ref) {
2178
+ const generatedId = useId();
2179
+ const switchId = id ?? generatedId;
2180
+ const resolvedChecked = checked ?? (value === void 0 ? void 0 : Boolean(value));
2181
+ const handleCheckedChange = useCallback(
2182
+ (next) => {
2183
+ onCheckedChange?.(next);
2184
+ if (onChange) {
2185
+ const synthetic = {
2186
+ target: { checked: next, value: next, name },
2187
+ currentTarget: { checked: next, value: next, name },
2188
+ type: "change"
2189
+ };
2190
+ onChange(synthetic);
2191
+ }
2192
+ },
2193
+ [onCheckedChange, onChange, name]
2194
+ );
2195
+ return /* @__PURE__ */ jsx(
2196
+ RadixSwitch.Root,
2197
+ {
2198
+ ref,
2199
+ id: switchId,
2200
+ checked: resolvedChecked,
2201
+ defaultChecked,
2202
+ onCheckedChange: handleCheckedChange,
2203
+ onBlur,
2204
+ disabled,
2205
+ required,
2206
+ name,
2207
+ "aria-label": ariaLabel,
2208
+ "aria-invalid": ariaInvalid,
2209
+ "aria-describedby": ariaDescribedBy,
2210
+ "data-slot": "switch-track",
2211
+ className: cn(switchTrackBaseClass, switchTrackClass[switchSize], className),
2212
+ children: /* @__PURE__ */ jsx(
2213
+ RadixSwitch.Thumb,
2214
+ {
2215
+ "data-slot": "switch-thumb",
2216
+ className: cn(switchThumbBaseClass, switchThumbClass[switchSize])
2217
+ }
2218
+ )
2219
+ }
2220
+ );
2221
+ });
1827
2222
 
1828
2223
  // src/components/textarea/textareaVariants.ts
1829
2224
  var textareaVariantClass = {
@@ -1891,6 +2286,6 @@ var Textarea = forwardRef(function Textarea2({
1891
2286
  );
1892
2287
  });
1893
2288
 
1894
- export { AppShell, Avatar, Button, Checkbox, DashboardContent, DashboardHeader, DashboardLayout, DashboardMain, Field, HeaderActions, HeaderCollapseTrigger, HeaderMobileTrigger, HeaderSearch, HeaderTitle, Input, LanguageSwitcher, RadioGroup, RadioGroupItem, Select, Sidebar, SidebarFooter, SidebarGroup, SidebarHeader, SidebarNav, SidebarNavGroup, SidebarNavItem, Switch, Table, Textarea, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, inputBaseClass, inputSizeClass, inputVariantClass, 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, useDashboardLayout, useDirection };
2289
+ export { AppShell, Avatar, Badge, Button, Checkbox, DashboardContent, DashboardHeader, DashboardLayout, DashboardMain, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, EmptyState, Field, HeaderActions, HeaderCollapseTrigger, HeaderMobileTrigger, HeaderSearch, HeaderTitle, Input, LanguageSwitcher, ListPage, PageHeader, RadioGroup, RadioGroupItem, Select, Sidebar, SidebarFooter, SidebarGroup, SidebarHeader, SidebarNav, SidebarNavGroup, SidebarNavItem, Switch, Table, Textarea, badgeBaseClass, badgeDotSizeClass, badgeSizeClass, badgeVariantClass, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, dropdownMenuContentClass, dropdownMenuItemBaseClass, dropdownMenuItemInsetClass, dropdownMenuItemVariantClass, dropdownMenuLabelClass, dropdownMenuSeparatorClass, dropdownMenuShortcutClass, emptyStateActionsSpacingClass, emptyStateBaseClass, emptyStateContainerSizeClass, emptyStateDescriptionSizeClass, emptyStateIconWrapperBaseClass, emptyStateIconWrapperSizeClass, emptyStateTitleSizeClass, 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, useDashboardLayout, useDirection };
1895
2290
  //# sourceMappingURL=index.js.map
1896
2291
  //# sourceMappingURL=index.js.map