@yca-software/yca-react-core 0.0.1 → 0.0.2

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.
@@ -1,4 +1,4 @@
1
- import { FormField, FormItem, FormLabel, FormControl, Textarea, FormMessage, Select, Tooltip, Checkbox, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from './chunk-PLSNCPEC.js';
1
+ import { FormField, FormItem, FormLabel, FormControl, Textarea, FormMessage, Select, Tooltip, Checkbox, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from './chunk-YIUHUCIF.js';
2
2
  import { Input } from './chunk-3AYG73DK.js';
3
3
  import { cn } from './chunk-GXWVFQCK.js';
4
4
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -335,5 +335,5 @@ function RoleSelectField({
335
335
  }
336
336
 
337
337
  export { DescriptionField, EmailField, ExpiresAtField, FirstNameField, LastNameField, NameField, PasswordField, PermissionsField, RoleSelectField };
338
- //# sourceMappingURL=chunk-2HJO2ICF.js.map
339
- //# sourceMappingURL=chunk-2HJO2ICF.js.map
338
+ //# sourceMappingURL=chunk-2HDSOEW3.js.map
339
+ //# sourceMappingURL=chunk-2HDSOEW3.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/forms/description-field/index.tsx","../src/components/forms/email-field/index.tsx","../src/components/forms/expires-at-field/index.tsx","../src/components/forms/first-name-field/index.tsx","../src/components/forms/last-name-field/index.tsx","../src/components/forms/name-field/index.tsx","../src/components/forms/password-field/index.tsx","../src/components/forms/permissions-field/index.tsx","../src/components/forms/role-select-field/index.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"chunk-2HJO2ICF.js","sourcesContent":["import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Textarea } from '../../ui';\n\ntype DescriptionFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n};\n\nexport function DescriptionField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n disabled,\n}: DescriptionFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Textarea placeholder={placeholder} disabled={disabled} {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype EmailFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n description?: string;\n autoComplete?: 'email' | 'username';\n className?: string;\n};\n\nexport function EmailField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n description,\n autoComplete = 'email',\n className,\n}: EmailFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n {description && <p className=\"text-sm text-muted-foreground mt-0.5\">{description}</p>}\n <FormControl>\n <Input type=\"email\" placeholder={placeholder} autoComplete={autoComplete} {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormField, FormItem, FormLabel, FormMessage, Select } from '../../ui';\n\ntype ExpiresAtOption = {\n value: string;\n label: string;\n};\n\ntype ExpiresAtFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n ariaLabel?: string;\n options: ExpiresAtOption[];\n};\n\nexport function ExpiresAtField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n ariaLabel,\n options,\n}: ExpiresAtFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem>\n <FormLabel>{label}</FormLabel>\n <Select\n value={(field.value as string) ?? ''}\n onValueChange={(next) => {\n field.onChange(next);\n }}\n options={options}\n placeholder={placeholder}\n aria-label={ariaLabel ?? label}\n />\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype FirstNameFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n};\n\nexport function FirstNameField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n}: FirstNameFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Input placeholder={placeholder} autoComplete=\"given-name\" {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype LastNameFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n};\n\nexport function LastNameField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n}: LastNameFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Input placeholder={placeholder} autoComplete=\"family-name\" {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype NameFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n};\n\nexport function NameField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n disabled,\n}: NameFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Input placeholder={placeholder} disabled={disabled} autoComplete=\"off\" {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { ReactNode } from 'react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype PasswordFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n autoComplete?: 'current-password' | 'new-password';\n /** Optional node to show on the right of the label (e.g. \"Forgot password?\" link) */\n rightLabel?: ReactNode;\n className?: string;\n};\n\nexport function PasswordField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n autoComplete = 'current-password',\n rightLabel,\n className,\n}: PasswordFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <div className=\"flex items-center justify-between\">\n <FormLabel>{label}</FormLabel>\n {rightLabel}\n </div>\n <FormControl>\n <Input\n type=\"password\"\n placeholder={placeholder}\n autoComplete={autoComplete}\n {...field}\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import { Info } from 'lucide-react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport type { PermissionGroup, PermissionOption } from '../../../types';\nimport { Checkbox, FormField, FormItem, FormLabel, FormMessage, Tooltip } from '../../ui';\n\nexport type {\n PermissionAction,\n PermissionGroup,\n PermissionOption,\n} from '../../../types';\n\ntype PermissionsFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n groups: PermissionGroup[];\n t: (key: string) => string;\n disabled?: boolean;\n};\n\nexport function PermissionsField<T extends FieldValues>({\n control,\n name,\n label,\n groups,\n t,\n disabled = false,\n}: PermissionsFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => {\n const selected = (field.value as string[]) ?? [];\n\n const togglePermission = (key: string, group: PermissionOption[]) => {\n const readKey = getReadKeyForGroup(group);\n const opt = group.find((p) => p.key === key);\n if (!opt) return;\n\n const next = selected.includes(key)\n ? selected.filter((k) => k !== key)\n : [...selected, key];\n\n if (opt.action === 'write' || opt.action === 'delete') {\n if (next.includes(key) && readKey && !next.includes(readKey)) {\n next.push(readKey);\n }\n }\n if (opt.action === 'delete') {\n const writeKey = getWriteKeyForGroup(group);\n if (next.includes(key) && writeKey && !next.includes(writeKey)) {\n next.push(writeKey);\n }\n }\n\n field.onChange(next);\n };\n\n return (\n <FormItem>\n <FormLabel>{label}</FormLabel>\n <div className=\"space-y-4\">\n {groups.map((group) => {\n const readKey = getReadKeyForGroup(group.permissions);\n const writeKey = getWriteKeyForGroup(group.permissions);\n const readDisabled = readKey\n ? hasWriteOrDelete(group.permissions, selected)\n : false;\n const writeDisabled = writeKey ? hasDelete(group.permissions, selected) : false;\n const readChecked =\n readKey !== null && (selected.includes(readKey) || readDisabled);\n const writeChecked =\n writeKey !== null && (selected.includes(writeKey) || writeDisabled);\n\n return (\n <div key={group.contextKey} className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5\">\n <p className=\"text-sm font-medium\">{t(group.labelKey)}</p>\n <Tooltip content={t(group.descriptionKey)} side=\"top\" align=\"start\">\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground cursor-help inline-flex rounded p-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={t(group.descriptionKey)}\n >\n <Info className=\"size-3.5\" aria-hidden />\n </button>\n </Tooltip>\n </div>\n <div className=\"flex flex-wrap gap-4 pl-2\">\n {group.permissions.map((perm) => {\n const isRead = perm.action === 'read';\n const isWrite = perm.action === 'write';\n const checked = isRead\n ? readChecked\n : isWrite\n ? writeChecked\n : selected.includes(perm.key);\n const permissionDisabled =\n (isRead && readDisabled) || (isWrite && writeDisabled);\n const globallyDisabled = disabled || permissionDisabled;\n\n return (\n <div key={perm.key} className=\"flex items-center space-x-2\">\n <Checkbox\n id={perm.key}\n checked={isRead ? readChecked : checked}\n disabled={globallyDisabled}\n onCheckedChange={() =>\n !globallyDisabled && togglePermission(perm.key, group.permissions)\n }\n />\n <label\n htmlFor={perm.key}\n className=\"text-sm font-normal leading-none cursor-pointer peer-disabled:opacity-70\"\n >\n {t(perm.labelKey)}\n </label>\n </div>\n );\n })}\n </div>\n </div>\n );\n })}\n </div>\n <FormMessage />\n </FormItem>\n );\n }}\n />\n );\n}\n\nfunction getReadKeyForGroup(permissions: PermissionOption[]): string | null {\n const readOpt = permissions.find((p) => p.action === 'read');\n return readOpt?.key ?? null;\n}\n\nfunction getWriteKeyForGroup(permissions: PermissionOption[]): string | null {\n const writeOpt = permissions.find((p) => p.action === 'write');\n return writeOpt?.key ?? null;\n}\n\nfunction hasWriteOrDelete(permissions: PermissionOption[], selected: string[]): boolean {\n return permissions.some(\n (p) => (p.action === 'write' || p.action === 'delete') && selected.includes(p.key),\n );\n}\n\nfunction hasDelete(permissions: PermissionOption[], selected: string[]): boolean {\n return permissions.some((p) => p.action === 'delete' && selected.includes(p.key));\n}\n","import { ChevronDown } from 'lucide-react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { cn } from '../../../lib/utils';\nimport type { RoleOption } from '../../../types';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '../../ui';\n\nexport type { RoleOption } from '../../../types';\n\ntype RoleSelectFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n options: RoleOption[];\n className?: string;\n};\n\nexport function RoleSelectField<T extends FieldValues>({\n control,\n name,\n label,\n options,\n className,\n}: RoleSelectFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => {\n const selectedOption = options.find((opt) => opt.value === field.value);\n const displayValue = selectedOption?.label ?? label;\n\n return (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n role=\"combobox\"\n aria-label={label}\n onBlur={field.onBlur}\n className={cn(\n 'flex h-9 w-full cursor-pointer items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none transition-colors',\n 'hover:bg-accent/50 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'aria-invalid:ring-destructive/20 aria-invalid:border-destructive',\n !field.value && 'text-muted-foreground',\n )}\n >\n <span className=\"min-w-0 truncate text-left\">{displayValue}</span>\n <ChevronDown className=\"ml-2 h-4 w-4 shrink-0 text-muted-foreground\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"start\"\n sideOffset={0}\n className={cn('min-w-(--radix-dropdown-menu-trigger-width) z-101')}\n >\n {options.map((opt) => (\n <DropdownMenuItem key={opt.value} onClick={() => field.onChange(opt.value)}>\n {opt.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </FormControl>\n <FormMessage />\n </FormItem>\n );\n }}\n />\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/forms/description-field/index.tsx","../src/components/forms/email-field/index.tsx","../src/components/forms/expires-at-field/index.tsx","../src/components/forms/first-name-field/index.tsx","../src/components/forms/last-name-field/index.tsx","../src/components/forms/name-field/index.tsx","../src/components/forms/password-field/index.tsx","../src/components/forms/permissions-field/index.tsx","../src/components/forms/role-select-field/index.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"chunk-2HDSOEW3.js","sourcesContent":["import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Textarea } from '../../ui';\n\ntype DescriptionFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n};\n\nexport function DescriptionField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n disabled,\n}: DescriptionFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Textarea placeholder={placeholder} disabled={disabled} {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype EmailFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n description?: string;\n autoComplete?: 'email' | 'username';\n className?: string;\n};\n\nexport function EmailField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n description,\n autoComplete = 'email',\n className,\n}: EmailFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n {description && <p className=\"text-sm text-muted-foreground mt-0.5\">{description}</p>}\n <FormControl>\n <Input type=\"email\" placeholder={placeholder} autoComplete={autoComplete} {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormField, FormItem, FormLabel, FormMessage, Select } from '../../ui';\n\ntype ExpiresAtOption = {\n value: string;\n label: string;\n};\n\ntype ExpiresAtFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n ariaLabel?: string;\n options: ExpiresAtOption[];\n};\n\nexport function ExpiresAtField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n ariaLabel,\n options,\n}: ExpiresAtFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem>\n <FormLabel>{label}</FormLabel>\n <Select\n value={(field.value as string) ?? ''}\n onValueChange={(next) => {\n field.onChange(next);\n }}\n options={options}\n placeholder={placeholder}\n aria-label={ariaLabel ?? label}\n />\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype FirstNameFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n};\n\nexport function FirstNameField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n}: FirstNameFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Input placeholder={placeholder} autoComplete=\"given-name\" {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype LastNameFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n};\n\nexport function LastNameField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n}: LastNameFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Input placeholder={placeholder} autoComplete=\"family-name\" {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype NameFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n};\n\nexport function NameField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n disabled,\n}: NameFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Input placeholder={placeholder} disabled={disabled} autoComplete=\"off\" {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { ReactNode } from 'react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype PasswordFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n autoComplete?: 'current-password' | 'new-password';\n /** Optional node to show on the right of the label (e.g. \"Forgot password?\" link) */\n rightLabel?: ReactNode;\n className?: string;\n};\n\nexport function PasswordField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n autoComplete = 'current-password',\n rightLabel,\n className,\n}: PasswordFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <div className=\"flex items-center justify-between\">\n <FormLabel>{label}</FormLabel>\n {rightLabel}\n </div>\n <FormControl>\n <Input\n type=\"password\"\n placeholder={placeholder}\n autoComplete={autoComplete}\n {...field}\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import { Info } from 'lucide-react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport type { PermissionGroup, PermissionOption } from '../../../types';\nimport { Checkbox, FormField, FormItem, FormLabel, FormMessage, Tooltip } from '../../ui';\n\nexport type {\n PermissionAction,\n PermissionGroup,\n PermissionOption,\n} from '../../../types';\n\ntype PermissionsFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n groups: PermissionGroup[];\n t: (key: string) => string;\n disabled?: boolean;\n};\n\nexport function PermissionsField<T extends FieldValues>({\n control,\n name,\n label,\n groups,\n t,\n disabled = false,\n}: PermissionsFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => {\n const selected = (field.value as string[]) ?? [];\n\n const togglePermission = (key: string, group: PermissionOption[]) => {\n const readKey = getReadKeyForGroup(group);\n const opt = group.find((p) => p.key === key);\n if (!opt) return;\n\n const next = selected.includes(key)\n ? selected.filter((k) => k !== key)\n : [...selected, key];\n\n if (opt.action === 'write' || opt.action === 'delete') {\n if (next.includes(key) && readKey && !next.includes(readKey)) {\n next.push(readKey);\n }\n }\n if (opt.action === 'delete') {\n const writeKey = getWriteKeyForGroup(group);\n if (next.includes(key) && writeKey && !next.includes(writeKey)) {\n next.push(writeKey);\n }\n }\n\n field.onChange(next);\n };\n\n return (\n <FormItem>\n <FormLabel>{label}</FormLabel>\n <div className=\"space-y-4\">\n {groups.map((group) => {\n const readKey = getReadKeyForGroup(group.permissions);\n const writeKey = getWriteKeyForGroup(group.permissions);\n const readDisabled = readKey\n ? hasWriteOrDelete(group.permissions, selected)\n : false;\n const writeDisabled = writeKey ? hasDelete(group.permissions, selected) : false;\n const readChecked =\n readKey !== null && (selected.includes(readKey) || readDisabled);\n const writeChecked =\n writeKey !== null && (selected.includes(writeKey) || writeDisabled);\n\n return (\n <div key={group.contextKey} className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5\">\n <p className=\"text-sm font-medium\">{t(group.labelKey)}</p>\n <Tooltip content={t(group.descriptionKey)} side=\"top\" align=\"start\">\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground cursor-help inline-flex rounded p-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={t(group.descriptionKey)}\n >\n <Info className=\"size-3.5\" aria-hidden />\n </button>\n </Tooltip>\n </div>\n <div className=\"flex flex-wrap gap-4 pl-2\">\n {group.permissions.map((perm) => {\n const isRead = perm.action === 'read';\n const isWrite = perm.action === 'write';\n const checked = isRead\n ? readChecked\n : isWrite\n ? writeChecked\n : selected.includes(perm.key);\n const permissionDisabled =\n (isRead && readDisabled) || (isWrite && writeDisabled);\n const globallyDisabled = disabled || permissionDisabled;\n\n return (\n <div key={perm.key} className=\"flex items-center space-x-2\">\n <Checkbox\n id={perm.key}\n checked={isRead ? readChecked : checked}\n disabled={globallyDisabled}\n onCheckedChange={() =>\n !globallyDisabled && togglePermission(perm.key, group.permissions)\n }\n />\n <label\n htmlFor={perm.key}\n className=\"text-sm font-normal leading-none cursor-pointer peer-disabled:opacity-70\"\n >\n {t(perm.labelKey)}\n </label>\n </div>\n );\n })}\n </div>\n </div>\n );\n })}\n </div>\n <FormMessage />\n </FormItem>\n );\n }}\n />\n );\n}\n\nfunction getReadKeyForGroup(permissions: PermissionOption[]): string | null {\n const readOpt = permissions.find((p) => p.action === 'read');\n return readOpt?.key ?? null;\n}\n\nfunction getWriteKeyForGroup(permissions: PermissionOption[]): string | null {\n const writeOpt = permissions.find((p) => p.action === 'write');\n return writeOpt?.key ?? null;\n}\n\nfunction hasWriteOrDelete(permissions: PermissionOption[], selected: string[]): boolean {\n return permissions.some(\n (p) => (p.action === 'write' || p.action === 'delete') && selected.includes(p.key),\n );\n}\n\nfunction hasDelete(permissions: PermissionOption[], selected: string[]): boolean {\n return permissions.some((p) => p.action === 'delete' && selected.includes(p.key));\n}\n","import { ChevronDown } from 'lucide-react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { cn } from '../../../lib/utils';\nimport type { RoleOption } from '../../../types';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '../../ui';\n\nexport type { RoleOption } from '../../../types';\n\ntype RoleSelectFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n options: RoleOption[];\n className?: string;\n};\n\nexport function RoleSelectField<T extends FieldValues>({\n control,\n name,\n label,\n options,\n className,\n}: RoleSelectFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => {\n const selectedOption = options.find((opt) => opt.value === field.value);\n const displayValue = selectedOption?.label ?? label;\n\n return (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n role=\"combobox\"\n aria-label={label}\n onBlur={field.onBlur}\n className={cn(\n 'flex h-9 w-full cursor-pointer items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none transition-colors',\n 'hover:bg-accent/50 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'aria-invalid:ring-destructive/20 aria-invalid:border-destructive',\n !field.value && 'text-muted-foreground',\n )}\n >\n <span className=\"min-w-0 truncate text-left\">{displayValue}</span>\n <ChevronDown className=\"ml-2 h-4 w-4 shrink-0 text-muted-foreground\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"start\"\n sideOffset={0}\n className={cn('min-w-(--radix-dropdown-menu-trigger-width) z-101')}\n >\n {options.map((opt) => (\n <DropdownMenuItem key={opt.value} onClick={() => field.onChange(opt.value)}>\n {opt.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </FormControl>\n <FormMessage />\n </FormItem>\n );\n }}\n />\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Select, Alert, AlertDescription, DateRangePicker, Tooltip, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from './chunk-PLSNCPEC.js';
1
+ import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Select, Alert, AlertDescription, DateRangePicker, Tooltip, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from './chunk-YIUHUCIF.js';
2
2
  import { Button, Card, CardHeader, CardTitle, CardDescription, Input, CardContent } from './chunk-3AYG73DK.js';
3
3
  import { dateRangePickerTranslations } from './chunk-UCJ76BEC.js';
4
4
  import { cn } from './chunk-GXWVFQCK.js';
@@ -579,5 +579,5 @@ function ThemeToggle({
579
579
  }
580
580
 
581
581
  export { AdminDetailPage, AdminListPage, AuditLogListFilters, DateRangeFilter, DetailFieldList, EntityRow, PageLoader, QueryState, RouteSuspense, ThemeProvider, ThemeToggle, createBoundQueryState, useDefaultThemeStore, useThemeStoreContext };
582
- //# sourceMappingURL=chunk-EVZBADFR.js.map
583
- //# sourceMappingURL=chunk-EVZBADFR.js.map
582
+ //# sourceMappingURL=chunk-OYMZUZW3.js.map
583
+ //# sourceMappingURL=chunk-OYMZUZW3.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/spa/page-loader/index.tsx","../src/components/spa/admin-detail-page/index.tsx","../src/components/spa/admin-list-page/index.tsx","../src/components/spa/audit-log-list-filters/index.tsx","../src/components/spa/query-state/index.tsx","../src/components/spa/create-bound-query-state/index.tsx","../src/components/spa/date-range-filter/index.tsx","../src/components/spa/detail-field-list/index.tsx","../src/components/spa/entity-row/index.tsx","../src/components/spa/route-suspense/index.tsx","../src/components/spa/theme-provider/index.tsx","../src/components/spa/theme-toggle/index.tsx"],"names":["jsx","jsxs","Loader2","Search","Fragment"],"mappings":"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","file":"chunk-EVZBADFR.js","sourcesContent":["import { Loader2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\n\nimport { cn } from '../../../lib/utils';\n\nexport interface PageLoaderProps {\n className?: string;\n spinnerClassName?: string;\n /**\n * - `page`: full-screen route guard\n * - `route`: lazy route / admin detail suspense (`min-h-[40vh]`)\n * - `section`: in-page block (`py-12`)\n * - `inline`: compact centered spinner (auth cards, nested panels)\n */\n variant?: 'page' | 'route' | 'section' | 'inline';\n /** Accessible loading text; defaults to i18n `common.loading`. */\n loadingLabel?: string;\n}\n\nexport function PageLoader({\n className,\n spinnerClassName,\n variant = 'section',\n loadingLabel,\n}: PageLoaderProps) {\n const { t } = useTranslation('common');\n const label = loadingLabel ?? t('loading');\n const spinnerSize =\n variant === 'inline'\n ? 'h-6 w-6 animate-spin text-primary'\n : 'h-8 w-8 animate-spin text-primary';\n\n const content = (\n <>\n <Loader2 className={cn(spinnerSize, spinnerClassName)} aria-hidden />\n <span className=\"sr-only\">{label}</span>\n </>\n );\n\n if (variant === 'page') {\n return (\n <div\n className={cn('min-h-screen flex items-center justify-center bg-background', className)}\n role=\"status\"\n aria-live=\"polite\"\n >\n {content}\n </div>\n );\n }\n\n if (variant === 'route') {\n return (\n <div\n className={cn('flex min-h-[40vh] items-center justify-center', className)}\n role=\"status\"\n aria-live=\"polite\"\n >\n {content}\n </div>\n );\n }\n\n if (variant === 'inline') {\n return (\n <div\n className={cn('flex items-center justify-center', className)}\n role=\"status\"\n aria-live=\"polite\"\n >\n {content}\n </div>\n );\n }\n\n return (\n <div\n className={cn('flex items-center justify-center py-12', className)}\n role=\"status\"\n aria-live=\"polite\"\n >\n {content}\n </div>\n );\n}\n","import { ArrowLeft } from 'lucide-react';\nimport { Link } from 'react-router';\nimport type { AdminDetailErrorKind } from '../../../types/admin';\nimport { Button } from '../../ui';\nimport { PageLoader } from '../page-loader';\n\nexport type { AdminDetailErrorKind };\n\nexport interface AdminDetailPageProps {\n backHref: string;\n backLabel: string;\n isLoading: boolean;\n errorKind?: AdminDetailErrorKind;\n error?: unknown;\n notFoundMessage: string;\n forbiddenMessage: string;\n loadErrorMessage: string;\n /** App-bound API error formatter (e.g. formatApiError from SPA helpers). */\n formatError?: (error: unknown) => string;\n children: React.ReactNode;\n headerActions?: React.ReactNode;\n}\n\n/** Reusable admin detail page: back button, loading/error states, content. */\nexport function AdminDetailPage({\n backHref,\n backLabel,\n isLoading,\n errorKind,\n error,\n notFoundMessage,\n forbiddenMessage,\n loadErrorMessage,\n formatError,\n children,\n headerActions,\n}: AdminDetailPageProps) {\n if (isLoading) {\n return <PageLoader variant=\"route\" />;\n }\n\n if (errorKind) {\n const message =\n errorKind === 'forbidden'\n ? forbiddenMessage\n : errorKind === 'load'\n ? formatError?.(error) || loadErrorMessage\n : notFoundMessage;\n\n return (\n <div className=\"space-y-4 sm:space-y-6\">\n <p className=\"text-destructive\">{message}</p>\n <Link to={backHref}>\n <Button variant=\"outline\">{backLabel}</Button>\n </Link>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4 sm:space-y-6\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <Link to={backHref}>\n <Button variant=\"ghost\" size=\"sm\">\n <ArrowLeft className=\"mr-2 h-4 w-4\" aria-hidden />\n {backLabel}\n </Button>\n </Link>\n {headerActions}\n </div>\n {children}\n </div>\n );\n}\n","import { Loader2, Search, X } from 'lucide-react';\n\nimport type { AdminListSearchMode } from '../../../hooks/useAdminListPage';\nimport { cn } from '../../../lib/utils';\nimport {\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Input,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '../../ui';\nimport { PageLoader } from '../page-loader';\n\nexport type { AdminListSearchMode };\n\nexport interface AdminListPageColumn<T> {\n key: string;\n header: string;\n render: (item: T) => React.ReactNode;\n /** Column class for alignment/width */\n className?: string;\n}\n\nexport interface AdminListPageProps<T> {\n title: string;\n description: string;\n /** Optional actions (e.g. \"Create\" button) rendered next to the page title. */\n headerActions?: React.ReactNode;\n /** Card header title (e.g. \"All Users\") */\n cardTitle: string;\n searchPlaceholder: string;\n emptyMessage: string;\n columns: AdminListPageColumn<T>[];\n items: T[];\n isLoading: boolean;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n loadMoreRef: React.RefObject<HTMLTableRowElement | null>;\n search: string;\n onSearchChange: (value: string) => void;\n onRowClick: (item: T) => void;\n getRowKey: (item: T) => string;\n /** Accessible label for the loading spinner (app i18n). */\n loadingAriaLabel?: string;\n /** `instant` updates query on debounced typing; `submit` requires Search/Clear actions. */\n searchMode?: AdminListSearchMode;\n /** Label for the Search button when `searchMode` is `submit`. */\n searchButtonLabel?: string;\n /** Label for the Clear button when `searchMode` is `submit`. */\n clearButtonLabel?: string;\n /** Called when the user clicks Search or presses Enter in submit mode. */\n onSearchSubmit?: () => void;\n /** Called when the user clicks Clear in submit mode. */\n onSearchClear?: () => void;\n /** Enter-key handler for submit mode (typically from `useAdminListPage().onSearchKeyDown`). */\n onSearchKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n}\n\n/**\n * Reusable admin list page: search + card + table + infinite scroll.\n */\nexport function AdminListPage<T>({\n title,\n description,\n headerActions,\n cardTitle,\n searchPlaceholder,\n emptyMessage,\n columns,\n items,\n isLoading,\n hasNextPage,\n isFetchingNextPage,\n loadMoreRef,\n search,\n onSearchChange,\n onRowClick,\n getRowKey,\n loadingAriaLabel = 'Loading...',\n searchMode = 'instant',\n searchButtonLabel = 'Search',\n clearButtonLabel = 'Clear',\n onSearchSubmit,\n onSearchClear,\n onSearchKeyDown,\n}: AdminListPageProps<T>) {\n const safeItems = items.filter((item): item is T => item != null && typeof item === 'object');\n const isSubmitMode = searchMode === 'submit';\n const hasSearchText = search.trim().length > 0;\n\n const handleSearchInputKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {\n if (isSubmitMode && event.key === 'Enter') {\n event.preventDefault();\n onSearchSubmit?.();\n }\n onSearchKeyDown?.(event);\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold sm:text-3xl\">{title}</h1>\n <p className=\"mt-1 text-sm text-muted-foreground sm:text-base\">{description}</p>\n </div>\n {headerActions}\n </div>\n\n <Card>\n <CardHeader className=\"gap-4\">\n <div className=\"space-y-2\">\n <CardTitle>{cardTitle}</CardTitle>\n {!isSubmitMode ? <CardDescription>{searchPlaceholder}</CardDescription> : null}\n </div>\n {isSubmitMode ? (\n <div\n className={cn(\n 'flex h-9 w-full min-w-0 max-w-full overflow-hidden rounded-md border border-input bg-background shadow-xs sm:max-w-sm',\n 'transition-[border-color,box-shadow] focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/20',\n )}\n >\n <div className=\"relative flex min-w-0 flex-1 items-center\">\n <Input\n placeholder={searchPlaceholder}\n value={search}\n onChange={(e) => onSearchChange(e.target.value)}\n onKeyDown={handleSearchInputKeyDown}\n className={cn(\n 'h-9 rounded-none rounded-l-md border-0 bg-transparent px-3 shadow-none',\n 'focus-visible:border-transparent focus-visible:ring-0',\n hasSearchText && 'pr-9',\n )}\n aria-label={searchPlaceholder}\n />\n {hasSearchText ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={onSearchClear}\n aria-label={clearButtonLabel}\n className=\"absolute right-1 top-1/2 -translate-y-1/2 text-muted-foreground hover:bg-muted/60 hover:text-foreground\"\n >\n <X className=\"h-4 w-4\" aria-hidden />\n </Button>\n ) : null}\n </div>\n <Button\n type=\"button\"\n variant=\"default\"\n onClick={onSearchSubmit}\n aria-label={searchButtonLabel}\n className={cn(\n 'h-full w-10 shrink-0 rounded-none rounded-r-md border-0 border-l border-primary-foreground/15 px-0 shadow-none',\n 'hover:bg-primary/90 active:bg-primary/95',\n 'shadow-[inset_0_1px_0_0_color-mix(in_oklch,var(--primary-foreground)_20%,transparent)]',\n )}\n >\n <Search className=\"h-4 w-4\" aria-hidden />\n </Button>\n </div>\n ) : (\n <div className=\"relative max-w-full sm:max-w-sm\">\n <Search\n className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\"\n aria-hidden\n />\n <Input\n placeholder={searchPlaceholder}\n value={search}\n onChange={(e) => onSearchChange(e.target.value)}\n className=\"pl-9\"\n aria-label={searchPlaceholder}\n />\n </div>\n )}\n </CardHeader>\n <CardContent>\n {isLoading ? (\n <PageLoader loadingLabel={loadingAriaLabel} />\n ) : safeItems.length === 0 ? (\n <p className=\"py-12 text-center text-muted-foreground\">{emptyMessage}</p>\n ) : (\n <div className=\"-mx-4 overflow-x-auto sm:mx-0\">\n <Table className=\"min-w-[400px]\">\n <TableHeader>\n <TableRow className=\"bg-muted/50 hover:bg-muted/50\">\n {columns.map((col) => (\n <TableHead key={col.key} className={col.className}>\n {col.header}\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {safeItems.map((item, index) => (\n <TableRow\n key={getRowKey(item) || `row-${index}`}\n role=\"button\"\n tabIndex={0}\n onClick={() => onRowClick(item)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onRowClick(item);\n }\n }}\n className=\"cursor-pointer hover:bg-muted/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\"\n >\n {columns.map((col) => (\n <TableCell\n key={col.key}\n className={cn(col.className ?? 'text-muted-foreground')}\n >\n {col.render(item)}\n </TableCell>\n ))}\n </TableRow>\n ))}\n {hasNextPage && (\n <TableRow ref={loadMoreRef}>\n <TableCell\n colSpan={columns.length}\n className=\"text-center text-muted-foreground\"\n >\n {isFetchingNextPage ? (\n <Loader2 className=\"inline-block h-5 w-5 animate-spin\" aria-hidden />\n ) : null}\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n","import { Search } from 'lucide-react';\n\nimport { Input } from '../../ui/input';\nimport { Select } from '../../ui/select';\n\nexport type AuditLogFilterOption = {\n value: string;\n label: string;\n};\n\nexport type AuditLogListFiltersProps = {\n search: string;\n onSearchChange: (value: string) => void;\n action: string;\n onActionChange: (value: string) => void;\n resourceType: string;\n onResourceTypeChange: (value: string) => void;\n actionOptions: AuditLogFilterOption[];\n resourceOptions: AuditLogFilterOption[];\n searchPlaceholder: string;\n actionFilterLabel: string;\n resourceFilterLabel: string;\n};\n\nexport function AuditLogListFilters({\n search,\n onSearchChange,\n action,\n onActionChange,\n resourceType,\n onResourceTypeChange,\n actionOptions,\n resourceOptions,\n searchPlaceholder,\n actionFilterLabel,\n resourceFilterLabel,\n}: AuditLogListFiltersProps) {\n return (\n <div className=\"flex flex-col gap-2 lg:flex-row lg:flex-wrap lg:items-center\">\n <div className=\"relative w-full lg:max-w-md\">\n <Search\n className=\"pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground\"\n aria-hidden\n />\n <Input\n className=\"pl-9\"\n placeholder={searchPlaceholder}\n value={search}\n onChange={(event) => onSearchChange(event.target.value)}\n aria-label={searchPlaceholder}\n />\n </div>\n <Select\n className=\"w-full lg:w-44\"\n value={action}\n onValueChange={onActionChange}\n options={actionOptions}\n aria-label={actionFilterLabel}\n />\n <Select\n className=\"w-full lg:w-52\"\n value={resourceType}\n onValueChange={onResourceTypeChange}\n options={resourceOptions}\n aria-label={resourceFilterLabel}\n />\n </div>\n );\n}\n","import { Alert, AlertDescription, Button } from '../../ui';\nimport { PageLoader } from '../page-loader';\n\nexport interface QueryStateProps {\n isLoading: boolean;\n isError?: boolean;\n error?: unknown;\n onRetry?: () => void;\n loadingClassName?: string;\n children: React.ReactNode;\n /** App-bound API error formatter (e.g. formatApiError from SPA helpers). */\n formatError?: (error: unknown) => string;\n /** Fallback copy when formatError returns empty. */\n errorDescription?: string;\n retryLabel?: string;\n loadingLabel?: string;\n}\n\n/** Renders loading/error states for TanStack Query results, then children on success. */\nexport function QueryState({\n isLoading,\n isError,\n error,\n onRetry,\n loadingClassName,\n children,\n formatError,\n errorDescription = 'We could not load this data. Please try again.',\n retryLabel = 'Try again',\n loadingLabel = 'Loading...',\n}: QueryStateProps) {\n if (isLoading) {\n return (\n <PageLoader variant=\"section\" className={loadingClassName} loadingLabel={loadingLabel} />\n );\n }\n\n if (isError) {\n const message = formatError?.(error) || errorDescription;\n return (\n <Alert variant=\"destructive\" className=\"max-w-xl\">\n <AlertDescription className=\"space-y-3\">\n <p>{message}</p>\n {onRetry ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={onRetry}>\n {retryLabel}\n </Button>\n ) : null}\n </AlertDescription>\n </Alert>\n );\n }\n\n return <>{children}</>;\n}\n","import { QueryState, type QueryStateProps } from '../query-state';\n\nexport type QueryStateBindings = Pick<\n QueryStateProps,\n 'formatError' | 'errorDescription' | 'retryLabel' | 'loadingLabel'\n>;\n\nexport type BoundQueryStateProps = Omit<QueryStateProps, keyof QueryStateBindings>;\n\n/** Factory for SPA-local i18n/error bindings around shared QueryState. */\nexport function createBoundQueryState(useBindings: () => QueryStateBindings) {\n function BoundQueryState(props: BoundQueryStateProps) {\n const bindings = useBindings();\n return <QueryState {...bindings} {...props} />;\n }\n\n BoundQueryState.displayName = 'BoundQueryState';\n return BoundQueryState;\n}\n","import type { DateRange } from 'react-day-picker';\n\nimport { dateRangePickerTranslations } from '../../../lib/dateRangePickerTranslations';\nimport { cn } from '../../../lib/utils';\nimport { DateRangePicker } from '../../ui/date-range-picker';\n\nexport interface DateRangeFilterProps {\n label: string;\n value: DateRange | undefined;\n onChange: (value: DateRange | undefined) => void;\n onApply: (value: DateRange | undefined) => void;\n minDate?: Date;\n maxDate?: Date;\n className?: string;\n hint?: string;\n /** Layout variant for toolbar vs panel contexts. */\n variant?: 'panel' | 'inline' | 'toolbar';\n /** i18n translate function (e.g. from useTranslationNamespace). */\n t: (key: string) => string;\n /** Namespace prefix for dateRange keys (default: `common`). */\n translationNs?: string;\n}\n\nexport function DateRangeFilter({\n label,\n value,\n onChange,\n onApply,\n minDate,\n maxDate,\n className,\n hint,\n variant = 'panel',\n t,\n translationNs = 'common',\n}: DateRangeFilterProps) {\n const inline = variant === 'inline';\n const toolbar = variant === 'toolbar';\n\n const picker = (\n <DateRangePicker\n className={cn(\n 'w-full min-w-0 border-border/80 bg-background',\n toolbar ? 'w-full min-w-0' : inline ? 'sm:max-w-[280px]' : 'sm:max-w-[320px]',\n )}\n value={value}\n onChange={onChange}\n minDate={minDate}\n maxDate={maxDate}\n translations={dateRangePickerTranslations(t, translationNs)}\n onApply={onApply}\n />\n );\n\n if (toolbar) {\n return (\n <div className={cn('min-w-0 w-full', className)}>\n <p className=\"mb-1 text-xs font-medium text-muted-foreground\">{label}</p>\n {picker}\n </div>\n );\n }\n\n if (inline) {\n return (\n <div className={cn('w-full shrink-0 sm:w-auto', className)}>\n <p className=\"mb-1 text-xs font-medium text-muted-foreground\">{label}</p>\n {picker}\n {hint ? <p className=\"mt-1 text-[0.65rem] text-muted-foreground\">{hint}</p> : null}\n </div>\n );\n }\n\n return (\n <div className={cn('rounded-lg border border-border/80 bg-muted/25 p-3 shadow-sm', className)}>\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between\">\n <div className=\"min-w-0 space-y-1\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {label}\n </p>\n {hint ? <p className=\"text-xs text-muted-foreground\">{hint}</p> : null}\n </div>\n {picker}\n </div>\n </div>\n );\n}\n\nexport { dateRangePickerTranslations };\n","import { cn } from '../../../lib/utils';\n\nexport interface DetailField {\n label: string;\n value: React.ReactNode;\n /** Span 2 columns on sm+ */\n span?: 1 | 2;\n}\n\nexport type DetailFieldVariant = 'plain' | 'bordered';\n\nexport interface DetailFieldListProps {\n fields: DetailField[];\n className?: string;\n /** When `bordered`, each label/value group is shown in a subtle framed cell. */\n fieldVariant?: DetailFieldVariant;\n}\n\n/** Definition list for detail views. Responsive two-column grid on sm+. */\nexport function DetailFieldList({\n fields,\n className,\n fieldVariant = 'plain',\n}: DetailFieldListProps) {\n return (\n <dl className={cn('grid gap-4 sm:grid-cols-2', className)}>\n {fields.map((field, i) => (\n <div\n key={`${field.label}-${i}`}\n className={cn(\n 'space-y-1',\n fieldVariant === 'bordered' && 'rounded-lg border bg-muted/20 px-3 py-2.5',\n field.span === 2 && 'sm:col-span-2',\n )}\n >\n <dt className=\"text-sm font-medium text-muted-foreground\">{field.label}</dt>\n <dd className=\"text-sm break-words\">{field.value}</dd>\n </div>\n ))}\n </dl>\n );\n}\n","import type { LucideIcon } from 'lucide-react';\nimport { MoreVertical } from 'lucide-react';\n\nimport { cn } from '../../../lib/utils';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Tooltip,\n} from '../../ui';\n\nexport interface EntityRowAction {\n label: string;\n icon: LucideIcon;\n onClick: () => void;\n variant?: 'default' | 'destructive';\n}\n\nexport interface EntityRowProps {\n icon: LucideIcon;\n title: React.ReactNode;\n /** Tooltip for title (when title is truncated). Omit when title is a ReactNode. */\n titleTooltip?: string;\n description?: string;\n /** Secondary line below title (e.g. created date, email) */\n subtitle?: string;\n onClick?: () => void;\n actions?: EntityRowAction[];\n /** Muted styling for archived items */\n archived?: boolean;\n /** Extra content below main block (e.g. key prefix, metadata) */\n children?: React.ReactNode;\n className?: string;\n}\n\n/**\n * Reusable row for settings entity lists (roles, teams, members, API keys).\n * Consistent layout: icon + title + optional description/subtitle + actions dropdown.\n */\nexport function EntityRow({\n icon: Icon,\n title,\n titleTooltip = typeof title === 'string' ? title : undefined,\n description,\n subtitle,\n onClick,\n actions = [],\n archived = false,\n children,\n className,\n}: EntityRowProps) {\n const hasActions = actions.length > 0;\n const isClickable = !!onClick;\n\n return (\n <div\n role={isClickable ? 'button' : undefined}\n tabIndex={isClickable ? 0 : undefined}\n onClick={onClick}\n onKeyDown={\n isClickable\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onClick?.();\n }\n }\n : undefined\n }\n className={cn(\n 'flex flex-col gap-2 rounded-lg border p-4 transition-colors',\n archived ? 'bg-muted/30' : 'hover:bg-muted/40',\n isClickable &&\n 'cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n className,\n )}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n <div\n className={cn(\n 'flex h-10 w-10 shrink-0 items-center justify-center rounded-lg',\n archived ? 'bg-muted' : 'bg-primary/10',\n )}\n >\n <Icon\n className={cn('h-5 w-5', archived ? 'text-muted-foreground' : 'text-primary')}\n aria-hidden\n />\n </div>\n <div className=\"min-w-0 flex-1\">\n {titleTooltip ? (\n <Tooltip content={titleTooltip} side=\"top\" align=\"start\">\n <p className=\"truncate font-medium max-w-full sm:max-w-md\">{title}</p>\n </Tooltip>\n ) : (\n <p className=\"truncate font-medium max-w-full sm:max-w-md\">{title}</p>\n )}\n {subtitle && (\n <p className=\"mt-0.5 truncate text-xs text-muted-foreground max-w-full sm:max-w-md\">\n {subtitle}\n </p>\n )}\n </div>\n </div>\n {hasActions && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"shrink-0 -mr-1\"\n onClick={(e) => e.stopPropagation()}\n aria-label=\"Open menu\"\n >\n <MoreVertical className=\"h-4 w-4\" aria-hidden />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" sideOffset={4} onClick={(e) => e.stopPropagation()}>\n {actions.map((action) => {\n const ActionIcon = action.icon;\n return (\n <DropdownMenuItem\n key={action.label}\n onClick={action.onClick}\n className={\n action.variant === 'destructive'\n ? 'text-destructive focus:text-destructive'\n : undefined\n }\n >\n <ActionIcon className=\"mr-2 h-4 w-4\" aria-hidden />\n {action.label}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n {description && (\n <Tooltip content={description} side=\"top\" align=\"start\">\n <p className=\"text-sm text-muted-foreground overflow-hidden line-clamp-2 [display:-webkit-box] [-webkit-line-clamp:2] [-webkit-box-orient:vertical]\">\n {description}\n </p>\n </Tooltip>\n )}\n {children}\n </div>\n );\n}\n","import { type ReactNode, Suspense } from 'react';\n\nimport { PageLoader } from '../page-loader';\n\nexport interface RouteSuspenseProps {\n children: ReactNode;\n loadingLabel?: string;\n}\n\n/** Suspense boundary for lazy route modules with shared loading UX. */\nexport function RouteSuspense({ children, loadingLabel }: RouteSuspenseProps) {\n return (\n <Suspense fallback={<PageLoader variant=\"route\" loadingLabel={loadingLabel} />}>\n {children}\n </Suspense>\n );\n}\n","import React, { useEffect, useState } from 'react';\n\n/**\n * Theme store interface for theme state management.\n */\nexport interface ThemeStore {\n /** Current theme mode */\n theme: 'light' | 'dark';\n /** Function to update theme */\n setTheme: (theme: 'light' | 'dark') => void;\n}\n\n/** Default in-memory theme store when no external store is provided. */\nexport function useDefaultThemeStore(): ThemeStore {\n const [theme, setTheme] = useState<'light' | 'dark'>('light');\n return { theme, setTheme };\n}\n\nconst ThemeStoreContext = React.createContext<ThemeStore | null>(null);\n\n/** Hook to read theme store from ThemeProvider context. */\nexport function useThemeStoreContext(): ThemeStore | null {\n return React.useContext(ThemeStoreContext);\n}\n\n/**\n * Props for the ThemeProvider component.\n */\nexport interface ThemeProviderProps {\n /** Child components */\n children: React.ReactNode;\n /** Hook function that returns the theme store (e.g., from Zustand) */\n useThemeStore?: () => ThemeStore;\n}\n\n/**\n * Theme provider component that applies theme classes to the document root.\n * Works with any state management solution via the `useThemeStore` prop.\n * When `useThemeStore` is not provided, uses an internal default store so hooks are always called unconditionally.\n *\n * @example\n * ```tsx\n * // With Zustand\n * const useThemeStore = () => {\n * const theme = useStore((state) => state.theme);\n * const setTheme = useStore((state) => state.setTheme);\n * return { theme, setTheme };\n * };\n *\n * <ThemeProvider useThemeStore={useThemeStore}>\n * <App />\n * </ThemeProvider>\n * ```\n */\nexport function ThemeProvider({ children, useThemeStore: useThemeStoreProp }: ThemeProviderProps) {\n const useResolvedStore = useThemeStoreProp ?? useDefaultThemeStore;\n const store = useResolvedStore();\n\n useEffect(() => {\n const root = window.document.documentElement;\n root.classList.remove('light', 'dark');\n root.classList.add(store.theme);\n }, [store.theme]);\n\n return <ThemeStoreContext.Provider value={store}>{children}</ThemeStoreContext.Provider>;\n}\n","import { Moon, Sun } from 'lucide-react';\nimport { Button } from '../../ui/button';\nimport type { ThemeStore } from '../theme-provider';\nimport { useDefaultThemeStore, useThemeStoreContext } from '../theme-provider';\n\n/**\n * Props for the ThemeToggle component.\n */\nexport interface ThemeToggleProps {\n /** Hook function that returns the theme store (e.g., from Zustand) */\n useThemeStore?: () => ThemeStore;\n /** Accessible label for the toggle button */\n ariaLabel?: string;\n}\n\nfunction ThemeToggleWithStore({\n useThemeStore,\n ariaLabel,\n}: {\n useThemeStore: () => ThemeStore;\n ariaLabel: string;\n}) {\n const { theme, setTheme } = useThemeStore();\n const toggleTheme = () => setTheme(theme === 'dark' ? 'light' : 'dark');\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={toggleTheme}\n aria-label={ariaLabel}\n className=\"cursor-pointer\"\n >\n {theme === 'dark' ? <Moon className=\"h-4 w-4\" /> : <Sun className=\"h-4 w-4\" />}\n </Button>\n );\n}\n\nfunction ThemeToggleWithContext({ ariaLabel }: { ariaLabel: string }) {\n const fromContext = useThemeStoreContext();\n const defaultStore = useDefaultThemeStore();\n const store = fromContext ?? defaultStore;\n const toggleTheme = () => store.setTheme(store.theme === 'dark' ? 'light' : 'dark');\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={toggleTheme}\n aria-label={ariaLabel}\n className=\"cursor-pointer\"\n >\n {store.theme === 'dark' ? <Moon className=\"h-4 w-4\" /> : <Sun className=\"h-4 w-4\" />}\n </Button>\n );\n}\n\n/**\n * Theme toggle button component.\n * Displays a sun icon in dark mode and moon icon in light mode.\n * Toggles between light and dark themes when clicked.\n * When useThemeStore is passed, uses that store; otherwise uses ThemeProvider context or internal default (no conditional hook calls).\n *\n * @example\n * ```tsx\n * const useThemeStore = () => {\n * const theme = useStore((state) => state.theme);\n * const setTheme = useStore((state) => state.setTheme);\n * return { theme, setTheme };\n * };\n *\n * <ThemeToggle useThemeStore={useThemeStore} ariaLabel=\"Toggle theme\" />\n * ```\n */\nexport function ThemeToggle({\n useThemeStore: useThemeStoreProp,\n ariaLabel = 'Toggle theme',\n}: ThemeToggleProps) {\n if (useThemeStoreProp) {\n return <ThemeToggleWithStore useThemeStore={useThemeStoreProp} ariaLabel={ariaLabel} />;\n }\n return <ThemeToggleWithContext ariaLabel={ariaLabel} />;\n}\n"]}
1
+ {"version":3,"sources":["../src/components/spa/page-loader/index.tsx","../src/components/spa/admin-detail-page/index.tsx","../src/components/spa/admin-list-page/index.tsx","../src/components/spa/audit-log-list-filters/index.tsx","../src/components/spa/query-state/index.tsx","../src/components/spa/create-bound-query-state/index.tsx","../src/components/spa/date-range-filter/index.tsx","../src/components/spa/detail-field-list/index.tsx","../src/components/spa/entity-row/index.tsx","../src/components/spa/route-suspense/index.tsx","../src/components/spa/theme-provider/index.tsx","../src/components/spa/theme-toggle/index.tsx"],"names":["jsx","jsxs","Loader2","Search","Fragment"],"mappings":"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","file":"chunk-OYMZUZW3.js","sourcesContent":["import { Loader2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\n\nimport { cn } from '../../../lib/utils';\n\nexport interface PageLoaderProps {\n className?: string;\n spinnerClassName?: string;\n /**\n * - `page`: full-screen route guard\n * - `route`: lazy route / admin detail suspense (`min-h-[40vh]`)\n * - `section`: in-page block (`py-12`)\n * - `inline`: compact centered spinner (auth cards, nested panels)\n */\n variant?: 'page' | 'route' | 'section' | 'inline';\n /** Accessible loading text; defaults to i18n `common.loading`. */\n loadingLabel?: string;\n}\n\nexport function PageLoader({\n className,\n spinnerClassName,\n variant = 'section',\n loadingLabel,\n}: PageLoaderProps) {\n const { t } = useTranslation('common');\n const label = loadingLabel ?? t('loading');\n const spinnerSize =\n variant === 'inline'\n ? 'h-6 w-6 animate-spin text-primary'\n : 'h-8 w-8 animate-spin text-primary';\n\n const content = (\n <>\n <Loader2 className={cn(spinnerSize, spinnerClassName)} aria-hidden />\n <span className=\"sr-only\">{label}</span>\n </>\n );\n\n if (variant === 'page') {\n return (\n <div\n className={cn('min-h-screen flex items-center justify-center bg-background', className)}\n role=\"status\"\n aria-live=\"polite\"\n >\n {content}\n </div>\n );\n }\n\n if (variant === 'route') {\n return (\n <div\n className={cn('flex min-h-[40vh] items-center justify-center', className)}\n role=\"status\"\n aria-live=\"polite\"\n >\n {content}\n </div>\n );\n }\n\n if (variant === 'inline') {\n return (\n <div\n className={cn('flex items-center justify-center', className)}\n role=\"status\"\n aria-live=\"polite\"\n >\n {content}\n </div>\n );\n }\n\n return (\n <div\n className={cn('flex items-center justify-center py-12', className)}\n role=\"status\"\n aria-live=\"polite\"\n >\n {content}\n </div>\n );\n}\n","import { ArrowLeft } from 'lucide-react';\nimport { Link } from 'react-router';\nimport type { AdminDetailErrorKind } from '../../../types/admin';\nimport { Button } from '../../ui';\nimport { PageLoader } from '../page-loader';\n\nexport type { AdminDetailErrorKind };\n\nexport interface AdminDetailPageProps {\n backHref: string;\n backLabel: string;\n isLoading: boolean;\n errorKind?: AdminDetailErrorKind;\n error?: unknown;\n notFoundMessage: string;\n forbiddenMessage: string;\n loadErrorMessage: string;\n /** App-bound API error formatter (e.g. formatApiError from SPA helpers). */\n formatError?: (error: unknown) => string;\n children: React.ReactNode;\n headerActions?: React.ReactNode;\n}\n\n/** Reusable admin detail page: back button, loading/error states, content. */\nexport function AdminDetailPage({\n backHref,\n backLabel,\n isLoading,\n errorKind,\n error,\n notFoundMessage,\n forbiddenMessage,\n loadErrorMessage,\n formatError,\n children,\n headerActions,\n}: AdminDetailPageProps) {\n if (isLoading) {\n return <PageLoader variant=\"route\" />;\n }\n\n if (errorKind) {\n const message =\n errorKind === 'forbidden'\n ? forbiddenMessage\n : errorKind === 'load'\n ? formatError?.(error) || loadErrorMessage\n : notFoundMessage;\n\n return (\n <div className=\"space-y-4 sm:space-y-6\">\n <p className=\"text-destructive\">{message}</p>\n <Link to={backHref}>\n <Button variant=\"outline\">{backLabel}</Button>\n </Link>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4 sm:space-y-6\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <Link to={backHref}>\n <Button variant=\"ghost\" size=\"sm\">\n <ArrowLeft className=\"mr-2 h-4 w-4\" aria-hidden />\n {backLabel}\n </Button>\n </Link>\n {headerActions}\n </div>\n {children}\n </div>\n );\n}\n","import { Loader2, Search, X } from 'lucide-react';\n\nimport type { AdminListSearchMode } from '../../../hooks/useAdminListPage';\nimport { cn } from '../../../lib/utils';\nimport {\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Input,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '../../ui';\nimport { PageLoader } from '../page-loader';\n\nexport type { AdminListSearchMode };\n\nexport interface AdminListPageColumn<T> {\n key: string;\n header: string;\n render: (item: T) => React.ReactNode;\n /** Column class for alignment/width */\n className?: string;\n}\n\nexport interface AdminListPageProps<T> {\n title: string;\n description: string;\n /** Optional actions (e.g. \"Create\" button) rendered next to the page title. */\n headerActions?: React.ReactNode;\n /** Card header title (e.g. \"All Users\") */\n cardTitle: string;\n searchPlaceholder: string;\n emptyMessage: string;\n columns: AdminListPageColumn<T>[];\n items: T[];\n isLoading: boolean;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n loadMoreRef: React.RefObject<HTMLTableRowElement | null>;\n search: string;\n onSearchChange: (value: string) => void;\n onRowClick: (item: T) => void;\n getRowKey: (item: T) => string;\n /** Accessible label for the loading spinner (app i18n). */\n loadingAriaLabel?: string;\n /** `instant` updates query on debounced typing; `submit` requires Search/Clear actions. */\n searchMode?: AdminListSearchMode;\n /** Label for the Search button when `searchMode` is `submit`. */\n searchButtonLabel?: string;\n /** Label for the Clear button when `searchMode` is `submit`. */\n clearButtonLabel?: string;\n /** Called when the user clicks Search or presses Enter in submit mode. */\n onSearchSubmit?: () => void;\n /** Called when the user clicks Clear in submit mode. */\n onSearchClear?: () => void;\n /** Enter-key handler for submit mode (typically from `useAdminListPage().onSearchKeyDown`). */\n onSearchKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n}\n\n/**\n * Reusable admin list page: search + card + table + infinite scroll.\n */\nexport function AdminListPage<T>({\n title,\n description,\n headerActions,\n cardTitle,\n searchPlaceholder,\n emptyMessage,\n columns,\n items,\n isLoading,\n hasNextPage,\n isFetchingNextPage,\n loadMoreRef,\n search,\n onSearchChange,\n onRowClick,\n getRowKey,\n loadingAriaLabel = 'Loading...',\n searchMode = 'instant',\n searchButtonLabel = 'Search',\n clearButtonLabel = 'Clear',\n onSearchSubmit,\n onSearchClear,\n onSearchKeyDown,\n}: AdminListPageProps<T>) {\n const safeItems = items.filter((item): item is T => item != null && typeof item === 'object');\n const isSubmitMode = searchMode === 'submit';\n const hasSearchText = search.trim().length > 0;\n\n const handleSearchInputKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {\n if (isSubmitMode && event.key === 'Enter') {\n event.preventDefault();\n onSearchSubmit?.();\n }\n onSearchKeyDown?.(event);\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold sm:text-3xl\">{title}</h1>\n <p className=\"mt-1 text-sm text-muted-foreground sm:text-base\">{description}</p>\n </div>\n {headerActions}\n </div>\n\n <Card>\n <CardHeader className=\"gap-4\">\n <div className=\"space-y-2\">\n <CardTitle>{cardTitle}</CardTitle>\n {!isSubmitMode ? <CardDescription>{searchPlaceholder}</CardDescription> : null}\n </div>\n {isSubmitMode ? (\n <div\n className={cn(\n 'flex h-9 w-full min-w-0 max-w-full overflow-hidden rounded-md border border-input bg-background shadow-xs sm:max-w-sm',\n 'transition-[border-color,box-shadow] focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/20',\n )}\n >\n <div className=\"relative flex min-w-0 flex-1 items-center\">\n <Input\n placeholder={searchPlaceholder}\n value={search}\n onChange={(e) => onSearchChange(e.target.value)}\n onKeyDown={handleSearchInputKeyDown}\n className={cn(\n 'h-9 rounded-none rounded-l-md border-0 bg-transparent px-3 shadow-none',\n 'focus-visible:border-transparent focus-visible:ring-0',\n hasSearchText && 'pr-9',\n )}\n aria-label={searchPlaceholder}\n />\n {hasSearchText ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={onSearchClear}\n aria-label={clearButtonLabel}\n className=\"absolute right-1 top-1/2 -translate-y-1/2 text-muted-foreground hover:bg-muted/60 hover:text-foreground\"\n >\n <X className=\"h-4 w-4\" aria-hidden />\n </Button>\n ) : null}\n </div>\n <Button\n type=\"button\"\n variant=\"default\"\n onClick={onSearchSubmit}\n aria-label={searchButtonLabel}\n className={cn(\n 'h-full w-10 shrink-0 rounded-none rounded-r-md border-0 border-l border-primary-foreground/15 px-0 shadow-none',\n 'hover:bg-primary/90 active:bg-primary/95',\n 'shadow-[inset_0_1px_0_0_color-mix(in_oklch,var(--primary-foreground)_20%,transparent)]',\n )}\n >\n <Search className=\"h-4 w-4\" aria-hidden />\n </Button>\n </div>\n ) : (\n <div className=\"relative max-w-full sm:max-w-sm\">\n <Search\n className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\"\n aria-hidden\n />\n <Input\n placeholder={searchPlaceholder}\n value={search}\n onChange={(e) => onSearchChange(e.target.value)}\n className=\"pl-9\"\n aria-label={searchPlaceholder}\n />\n </div>\n )}\n </CardHeader>\n <CardContent>\n {isLoading ? (\n <PageLoader loadingLabel={loadingAriaLabel} />\n ) : safeItems.length === 0 ? (\n <p className=\"py-12 text-center text-muted-foreground\">{emptyMessage}</p>\n ) : (\n <div className=\"-mx-4 overflow-x-auto sm:mx-0\">\n <Table className=\"min-w-[400px]\">\n <TableHeader>\n <TableRow className=\"bg-muted/50 hover:bg-muted/50\">\n {columns.map((col) => (\n <TableHead key={col.key} className={col.className}>\n {col.header}\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {safeItems.map((item, index) => (\n <TableRow\n key={getRowKey(item) || `row-${index}`}\n role=\"button\"\n tabIndex={0}\n onClick={() => onRowClick(item)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onRowClick(item);\n }\n }}\n className=\"cursor-pointer hover:bg-muted/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\"\n >\n {columns.map((col) => (\n <TableCell\n key={col.key}\n className={cn(col.className ?? 'text-muted-foreground')}\n >\n {col.render(item)}\n </TableCell>\n ))}\n </TableRow>\n ))}\n {hasNextPage && (\n <TableRow ref={loadMoreRef}>\n <TableCell\n colSpan={columns.length}\n className=\"text-center text-muted-foreground\"\n >\n {isFetchingNextPage ? (\n <Loader2 className=\"inline-block h-5 w-5 animate-spin\" aria-hidden />\n ) : null}\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n","import { Search } from 'lucide-react';\n\nimport { Input } from '../../ui/input';\nimport { Select } from '../../ui/select';\n\nexport type AuditLogFilterOption = {\n value: string;\n label: string;\n};\n\nexport type AuditLogListFiltersProps = {\n search: string;\n onSearchChange: (value: string) => void;\n action: string;\n onActionChange: (value: string) => void;\n resourceType: string;\n onResourceTypeChange: (value: string) => void;\n actionOptions: AuditLogFilterOption[];\n resourceOptions: AuditLogFilterOption[];\n searchPlaceholder: string;\n actionFilterLabel: string;\n resourceFilterLabel: string;\n};\n\nexport function AuditLogListFilters({\n search,\n onSearchChange,\n action,\n onActionChange,\n resourceType,\n onResourceTypeChange,\n actionOptions,\n resourceOptions,\n searchPlaceholder,\n actionFilterLabel,\n resourceFilterLabel,\n}: AuditLogListFiltersProps) {\n return (\n <div className=\"flex flex-col gap-2 lg:flex-row lg:flex-wrap lg:items-center\">\n <div className=\"relative w-full lg:max-w-md\">\n <Search\n className=\"pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground\"\n aria-hidden\n />\n <Input\n className=\"pl-9\"\n placeholder={searchPlaceholder}\n value={search}\n onChange={(event) => onSearchChange(event.target.value)}\n aria-label={searchPlaceholder}\n />\n </div>\n <Select\n className=\"w-full lg:w-44\"\n value={action}\n onValueChange={onActionChange}\n options={actionOptions}\n aria-label={actionFilterLabel}\n />\n <Select\n className=\"w-full lg:w-52\"\n value={resourceType}\n onValueChange={onResourceTypeChange}\n options={resourceOptions}\n aria-label={resourceFilterLabel}\n />\n </div>\n );\n}\n","import { Alert, AlertDescription, Button } from '../../ui';\nimport { PageLoader } from '../page-loader';\n\nexport interface QueryStateProps {\n isLoading: boolean;\n isError?: boolean;\n error?: unknown;\n onRetry?: () => void;\n loadingClassName?: string;\n children: React.ReactNode;\n /** App-bound API error formatter (e.g. formatApiError from SPA helpers). */\n formatError?: (error: unknown) => string;\n /** Fallback copy when formatError returns empty. */\n errorDescription?: string;\n retryLabel?: string;\n loadingLabel?: string;\n}\n\n/** Renders loading/error states for TanStack Query results, then children on success. */\nexport function QueryState({\n isLoading,\n isError,\n error,\n onRetry,\n loadingClassName,\n children,\n formatError,\n errorDescription = 'We could not load this data. Please try again.',\n retryLabel = 'Try again',\n loadingLabel = 'Loading...',\n}: QueryStateProps) {\n if (isLoading) {\n return (\n <PageLoader variant=\"section\" className={loadingClassName} loadingLabel={loadingLabel} />\n );\n }\n\n if (isError) {\n const message = formatError?.(error) || errorDescription;\n return (\n <Alert variant=\"destructive\" className=\"max-w-xl\">\n <AlertDescription className=\"space-y-3\">\n <p>{message}</p>\n {onRetry ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={onRetry}>\n {retryLabel}\n </Button>\n ) : null}\n </AlertDescription>\n </Alert>\n );\n }\n\n return <>{children}</>;\n}\n","import { QueryState, type QueryStateProps } from '../query-state';\n\nexport type QueryStateBindings = Pick<\n QueryStateProps,\n 'formatError' | 'errorDescription' | 'retryLabel' | 'loadingLabel'\n>;\n\nexport type BoundQueryStateProps = Omit<QueryStateProps, keyof QueryStateBindings>;\n\n/** Factory for SPA-local i18n/error bindings around shared QueryState. */\nexport function createBoundQueryState(useBindings: () => QueryStateBindings) {\n function BoundQueryState(props: BoundQueryStateProps) {\n const bindings = useBindings();\n return <QueryState {...bindings} {...props} />;\n }\n\n BoundQueryState.displayName = 'BoundQueryState';\n return BoundQueryState;\n}\n","import type { DateRange } from 'react-day-picker';\n\nimport { dateRangePickerTranslations } from '../../../lib/dateRangePickerTranslations';\nimport { cn } from '../../../lib/utils';\nimport { DateRangePicker } from '../../ui/date-range-picker';\n\nexport interface DateRangeFilterProps {\n label: string;\n value: DateRange | undefined;\n onChange: (value: DateRange | undefined) => void;\n onApply: (value: DateRange | undefined) => void;\n minDate?: Date;\n maxDate?: Date;\n className?: string;\n hint?: string;\n /** Layout variant for toolbar vs panel contexts. */\n variant?: 'panel' | 'inline' | 'toolbar';\n /** i18n translate function (e.g. from useTranslationNamespace). */\n t: (key: string) => string;\n /** Namespace prefix for dateRange keys (default: `common`). */\n translationNs?: string;\n}\n\nexport function DateRangeFilter({\n label,\n value,\n onChange,\n onApply,\n minDate,\n maxDate,\n className,\n hint,\n variant = 'panel',\n t,\n translationNs = 'common',\n}: DateRangeFilterProps) {\n const inline = variant === 'inline';\n const toolbar = variant === 'toolbar';\n\n const picker = (\n <DateRangePicker\n className={cn(\n 'w-full min-w-0 border-border/80 bg-background',\n toolbar ? 'w-full min-w-0' : inline ? 'sm:max-w-[280px]' : 'sm:max-w-[320px]',\n )}\n value={value}\n onChange={onChange}\n minDate={minDate}\n maxDate={maxDate}\n translations={dateRangePickerTranslations(t, translationNs)}\n onApply={onApply}\n />\n );\n\n if (toolbar) {\n return (\n <div className={cn('min-w-0 w-full', className)}>\n <p className=\"mb-1 text-xs font-medium text-muted-foreground\">{label}</p>\n {picker}\n </div>\n );\n }\n\n if (inline) {\n return (\n <div className={cn('w-full shrink-0 sm:w-auto', className)}>\n <p className=\"mb-1 text-xs font-medium text-muted-foreground\">{label}</p>\n {picker}\n {hint ? <p className=\"mt-1 text-[0.65rem] text-muted-foreground\">{hint}</p> : null}\n </div>\n );\n }\n\n return (\n <div className={cn('rounded-lg border border-border/80 bg-muted/25 p-3 shadow-sm', className)}>\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between\">\n <div className=\"min-w-0 space-y-1\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {label}\n </p>\n {hint ? <p className=\"text-xs text-muted-foreground\">{hint}</p> : null}\n </div>\n {picker}\n </div>\n </div>\n );\n}\n\nexport { dateRangePickerTranslations };\n","import { cn } from '../../../lib/utils';\n\nexport interface DetailField {\n label: string;\n value: React.ReactNode;\n /** Span 2 columns on sm+ */\n span?: 1 | 2;\n}\n\nexport type DetailFieldVariant = 'plain' | 'bordered';\n\nexport interface DetailFieldListProps {\n fields: DetailField[];\n className?: string;\n /** When `bordered`, each label/value group is shown in a subtle framed cell. */\n fieldVariant?: DetailFieldVariant;\n}\n\n/** Definition list for detail views. Responsive two-column grid on sm+. */\nexport function DetailFieldList({\n fields,\n className,\n fieldVariant = 'plain',\n}: DetailFieldListProps) {\n return (\n <dl className={cn('grid gap-4 sm:grid-cols-2', className)}>\n {fields.map((field, i) => (\n <div\n key={`${field.label}-${i}`}\n className={cn(\n 'space-y-1',\n fieldVariant === 'bordered' && 'rounded-lg border bg-muted/20 px-3 py-2.5',\n field.span === 2 && 'sm:col-span-2',\n )}\n >\n <dt className=\"text-sm font-medium text-muted-foreground\">{field.label}</dt>\n <dd className=\"text-sm break-words\">{field.value}</dd>\n </div>\n ))}\n </dl>\n );\n}\n","import type { LucideIcon } from 'lucide-react';\nimport { MoreVertical } from 'lucide-react';\n\nimport { cn } from '../../../lib/utils';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Tooltip,\n} from '../../ui';\n\nexport interface EntityRowAction {\n label: string;\n icon: LucideIcon;\n onClick: () => void;\n variant?: 'default' | 'destructive';\n}\n\nexport interface EntityRowProps {\n icon: LucideIcon;\n title: React.ReactNode;\n /** Tooltip for title (when title is truncated). Omit when title is a ReactNode. */\n titleTooltip?: string;\n description?: string;\n /** Secondary line below title (e.g. created date, email) */\n subtitle?: string;\n onClick?: () => void;\n actions?: EntityRowAction[];\n /** Muted styling for archived items */\n archived?: boolean;\n /** Extra content below main block (e.g. key prefix, metadata) */\n children?: React.ReactNode;\n className?: string;\n}\n\n/**\n * Reusable row for settings entity lists (roles, teams, members, API keys).\n * Consistent layout: icon + title + optional description/subtitle + actions dropdown.\n */\nexport function EntityRow({\n icon: Icon,\n title,\n titleTooltip = typeof title === 'string' ? title : undefined,\n description,\n subtitle,\n onClick,\n actions = [],\n archived = false,\n children,\n className,\n}: EntityRowProps) {\n const hasActions = actions.length > 0;\n const isClickable = !!onClick;\n\n return (\n <div\n role={isClickable ? 'button' : undefined}\n tabIndex={isClickable ? 0 : undefined}\n onClick={onClick}\n onKeyDown={\n isClickable\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onClick?.();\n }\n }\n : undefined\n }\n className={cn(\n 'flex flex-col gap-2 rounded-lg border p-4 transition-colors',\n archived ? 'bg-muted/30' : 'hover:bg-muted/40',\n isClickable &&\n 'cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n className,\n )}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n <div\n className={cn(\n 'flex h-10 w-10 shrink-0 items-center justify-center rounded-lg',\n archived ? 'bg-muted' : 'bg-primary/10',\n )}\n >\n <Icon\n className={cn('h-5 w-5', archived ? 'text-muted-foreground' : 'text-primary')}\n aria-hidden\n />\n </div>\n <div className=\"min-w-0 flex-1\">\n {titleTooltip ? (\n <Tooltip content={titleTooltip} side=\"top\" align=\"start\">\n <p className=\"truncate font-medium max-w-full sm:max-w-md\">{title}</p>\n </Tooltip>\n ) : (\n <p className=\"truncate font-medium max-w-full sm:max-w-md\">{title}</p>\n )}\n {subtitle && (\n <p className=\"mt-0.5 truncate text-xs text-muted-foreground max-w-full sm:max-w-md\">\n {subtitle}\n </p>\n )}\n </div>\n </div>\n {hasActions && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"shrink-0 -mr-1\"\n onClick={(e) => e.stopPropagation()}\n aria-label=\"Open menu\"\n >\n <MoreVertical className=\"h-4 w-4\" aria-hidden />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" sideOffset={4} onClick={(e) => e.stopPropagation()}>\n {actions.map((action) => {\n const ActionIcon = action.icon;\n return (\n <DropdownMenuItem\n key={action.label}\n onClick={action.onClick}\n className={\n action.variant === 'destructive'\n ? 'text-destructive focus:text-destructive'\n : undefined\n }\n >\n <ActionIcon className=\"mr-2 h-4 w-4\" aria-hidden />\n {action.label}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n {description && (\n <Tooltip content={description} side=\"top\" align=\"start\">\n <p className=\"text-sm text-muted-foreground overflow-hidden line-clamp-2 [display:-webkit-box] [-webkit-line-clamp:2] [-webkit-box-orient:vertical]\">\n {description}\n </p>\n </Tooltip>\n )}\n {children}\n </div>\n );\n}\n","import { type ReactNode, Suspense } from 'react';\n\nimport { PageLoader } from '../page-loader';\n\nexport interface RouteSuspenseProps {\n children: ReactNode;\n loadingLabel?: string;\n}\n\n/** Suspense boundary for lazy route modules with shared loading UX. */\nexport function RouteSuspense({ children, loadingLabel }: RouteSuspenseProps) {\n return (\n <Suspense fallback={<PageLoader variant=\"route\" loadingLabel={loadingLabel} />}>\n {children}\n </Suspense>\n );\n}\n","import React, { useEffect, useState } from 'react';\n\n/**\n * Theme store interface for theme state management.\n */\nexport interface ThemeStore {\n /** Current theme mode */\n theme: 'light' | 'dark';\n /** Function to update theme */\n setTheme: (theme: 'light' | 'dark') => void;\n}\n\n/** Default in-memory theme store when no external store is provided. */\nexport function useDefaultThemeStore(): ThemeStore {\n const [theme, setTheme] = useState<'light' | 'dark'>('light');\n return { theme, setTheme };\n}\n\nconst ThemeStoreContext = React.createContext<ThemeStore | null>(null);\n\n/** Hook to read theme store from ThemeProvider context. */\nexport function useThemeStoreContext(): ThemeStore | null {\n return React.useContext(ThemeStoreContext);\n}\n\n/**\n * Props for the ThemeProvider component.\n */\nexport interface ThemeProviderProps {\n /** Child components */\n children: React.ReactNode;\n /** Hook function that returns the theme store (e.g., from Zustand) */\n useThemeStore?: () => ThemeStore;\n}\n\n/**\n * Theme provider component that applies theme classes to the document root.\n * Works with any state management solution via the `useThemeStore` prop.\n * When `useThemeStore` is not provided, uses an internal default store so hooks are always called unconditionally.\n *\n * @example\n * ```tsx\n * // With Zustand\n * const useThemeStore = () => {\n * const theme = useStore((state) => state.theme);\n * const setTheme = useStore((state) => state.setTheme);\n * return { theme, setTheme };\n * };\n *\n * <ThemeProvider useThemeStore={useThemeStore}>\n * <App />\n * </ThemeProvider>\n * ```\n */\nexport function ThemeProvider({ children, useThemeStore: useThemeStoreProp }: ThemeProviderProps) {\n const useResolvedStore = useThemeStoreProp ?? useDefaultThemeStore;\n const store = useResolvedStore();\n\n useEffect(() => {\n const root = window.document.documentElement;\n root.classList.remove('light', 'dark');\n root.classList.add(store.theme);\n }, [store.theme]);\n\n return <ThemeStoreContext.Provider value={store}>{children}</ThemeStoreContext.Provider>;\n}\n","import { Moon, Sun } from 'lucide-react';\nimport { Button } from '../../ui/button';\nimport type { ThemeStore } from '../theme-provider';\nimport { useDefaultThemeStore, useThemeStoreContext } from '../theme-provider';\n\n/**\n * Props for the ThemeToggle component.\n */\nexport interface ThemeToggleProps {\n /** Hook function that returns the theme store (e.g., from Zustand) */\n useThemeStore?: () => ThemeStore;\n /** Accessible label for the toggle button */\n ariaLabel?: string;\n}\n\nfunction ThemeToggleWithStore({\n useThemeStore,\n ariaLabel,\n}: {\n useThemeStore: () => ThemeStore;\n ariaLabel: string;\n}) {\n const { theme, setTheme } = useThemeStore();\n const toggleTheme = () => setTheme(theme === 'dark' ? 'light' : 'dark');\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={toggleTheme}\n aria-label={ariaLabel}\n className=\"cursor-pointer\"\n >\n {theme === 'dark' ? <Moon className=\"h-4 w-4\" /> : <Sun className=\"h-4 w-4\" />}\n </Button>\n );\n}\n\nfunction ThemeToggleWithContext({ ariaLabel }: { ariaLabel: string }) {\n const fromContext = useThemeStoreContext();\n const defaultStore = useDefaultThemeStore();\n const store = fromContext ?? defaultStore;\n const toggleTheme = () => store.setTheme(store.theme === 'dark' ? 'light' : 'dark');\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={toggleTheme}\n aria-label={ariaLabel}\n className=\"cursor-pointer\"\n >\n {store.theme === 'dark' ? <Moon className=\"h-4 w-4\" /> : <Sun className=\"h-4 w-4\" />}\n </Button>\n );\n}\n\n/**\n * Theme toggle button component.\n * Displays a sun icon in dark mode and moon icon in light mode.\n * Toggles between light and dark themes when clicked.\n * When useThemeStore is passed, uses that store; otherwise uses ThemeProvider context or internal default (no conditional hook calls).\n *\n * @example\n * ```tsx\n * const useThemeStore = () => {\n * const theme = useStore((state) => state.theme);\n * const setTheme = useStore((state) => state.setTheme);\n * return { theme, setTheme };\n * };\n *\n * <ThemeToggle useThemeStore={useThemeStore} ariaLabel=\"Toggle theme\" />\n * ```\n */\nexport function ThemeToggle({\n useThemeStore: useThemeStoreProp,\n ariaLabel = 'Toggle theme',\n}: ThemeToggleProps) {\n if (useThemeStoreProp) {\n return <ThemeToggleWithStore useThemeStore={useThemeStoreProp} ariaLabel={ariaLabel} />;\n }\n return <ThemeToggleWithContext ariaLabel={ariaLabel} />;\n}\n"]}
@@ -1283,7 +1283,7 @@ function DateRangePicker({
1283
1283
  )
1284
1284
  ] });
1285
1285
  }
1286
- var dropdownMenuSelectOptionsMaxHeightClassName = "max-h-[min(var(--radix-dropdown-menu-content-available-height),13rem)]";
1286
+ var dropdownMenuSelectOptionsMaxHeightClassName = "max-h-[min(var(--radix-dropdown-menu-content-available-height),17rem)]";
1287
1287
  function DropdownMenu({ ...props }) {
1288
1288
  return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
1289
1289
  }
@@ -1974,7 +1974,7 @@ function Select({
1974
1974
  {
1975
1975
  grow: false,
1976
1976
  scrollAreaClassName: cn(
1977
- "overflow-y-auto overscroll-y-contain p-1",
1977
+ "overflow-y-auto overscroll-y-contain p-1 pb-6",
1978
1978
  dropdownMenuSelectOptionsMaxHeightClassName
1979
1979
  ),
1980
1980
  scrollKey: `${filteredOptions.length}-${open ? 1 : 0}-${search}`,
@@ -2503,5 +2503,5 @@ function UploadDropzone(props) {
2503
2503
  }
2504
2504
 
2505
2505
  export { Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarFallback, AvatarImage, Badge, Calendar, Checkbox, ConfirmDialog, DatePicker, DateRangePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownScrollableList, DropdownSelectSearchInput, Form, FormControl, FormDescription, FormDrawer, FormField, FormItem, FormLabel, FormMessage, H3, Heading, Label, Link, MultiSelect, Paragraph, Popover, PopoverContent, PopoverTrigger, SEARCHABLE_SELECT_MIN_OPTIONS, ScrollArea, ScrollBar, Select, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Tooltip, TooltipProvider, UploadDropzone, badgeVariants, dropdownMenuSelectOptionsMaxHeightClassName, filterSelectOptions, headingVariants, isSelectSearchable, linkStyles, paragraphVariants, useFormField };
2506
- //# sourceMappingURL=chunk-PLSNCPEC.js.map
2507
- //# sourceMappingURL=chunk-PLSNCPEC.js.map
2506
+ //# sourceMappingURL=chunk-YIUHUCIF.js.map
2507
+ //# sourceMappingURL=chunk-YIUHUCIF.js.map