From c06e550c45e0f3c515626354ef51790ffcbcdede Mon Sep 17 00:00:00 2001 From: sadmann7 Date: Thu, 3 Jul 2025 18:03:16 +0600 Subject: [PATCH 1/2] chore: update biome config --- .vscode/settings.json | 7 ++++++- README.md | 8 ++++++++ biome.json | 6 ++++-- public/r/data-table-filter-list.json | 2 +- public/r/data-table-filter-menu.json | 2 +- src/components/data-table/data-table-filter-list.tsx | 5 +++-- src/components/data-table/data-table-filter-menu.tsx | 5 +++-- 7 files changed, 26 insertions(+), 9 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index c78dfac6..4dd8b82e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,5 +9,10 @@ ["clsx\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], ["cva\\(((?:[^()]|\\([^()]*\\))*)\\)", "[\"'`]?([^\"'`]+)[\"'`]?"], ["cn\\(((?:[^()]|\\([^()]*\\))*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"] - ] + ], + "markdownlint.config": { + "MD033": { + "allowed_elements": ["div", "a", "img", "br"] + } + } } diff --git a/README.md b/README.md index dd104d28..cacb17c6 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,14 @@ This is a shadcn table component with server-side sorting, filtering, and pagina [![Shadcn Table](./public/images/screenshot.png)](https://tablecn.com) +
+ + Vercel OSS Program + +
+ +
+ ## Documentation See the [documentation](https://diceui.com/docs/components/data-table) to get started. diff --git a/biome.json b/biome.json index 136ec409..26bda140 100644 --- a/biome.json +++ b/biome.json @@ -30,13 +30,15 @@ }, "correctness": { "noUnusedVariables": "warn", - "useExhaustiveDependencies": "warn" + "useExhaustiveDependencies": "warn", + "useHookAtTopLevel": "warn" }, "complexity": { "noBannedTypes": "off" }, "style": { - "useImportType": "warn" + "useImportType": "warn", + "useSelfClosingElements": "off" }, "security": { "noDangerouslySetInnerHtml": "off" diff --git a/public/r/data-table-filter-list.json b/public/r/data-table-filter-list.json index 9c12b7cd..c6261f64 100644 --- a/public/r/data-table-filter-list.json +++ b/public/r/data-table-filter-list.json @@ -22,7 +22,7 @@ "files": [ { "path": "src/components/data-table/data-table-filter-list.tsx", - "content": "\"use client\";\n\nimport type { Column, ColumnMeta, Table } from \"@tanstack/react-table\";\nimport {\n CalendarIcon,\n Check,\n ChevronsUpDown,\n GripVertical,\n ListFilter,\n Trash2,\n} from \"lucide-react\";\nimport { parseAsStringEnum, useQueryState } from \"nuqs\";\nimport * as React from \"react\";\n\nimport { DataTableRangeFilter } from \"@/components/data-table/data-table-range-filter\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Calendar } from \"@/components/ui/calendar\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/components/ui/command\";\nimport {\n Faceted,\n FacetedBadgeList,\n FacetedContent,\n FacetedEmpty,\n FacetedGroup,\n FacetedInput,\n FacetedItem,\n FacetedList,\n FacetedTrigger,\n} from \"@/components/ui/faceted\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport {\n Sortable,\n SortableContent,\n SortableItem,\n SortableItemHandle,\n SortableOverlay,\n} from \"@/components/ui/sortable\";\nimport { dataTableConfig } from \"@/config/data-table\";\nimport { useDebouncedCallback } from \"@/hooks/use-debounced-callback\";\nimport { getDefaultFilterOperator, getFilterOperators } from \"@/lib/data-table\";\nimport { formatDate } from \"@/lib/format\";\nimport { generateId } from \"@/lib/id\";\nimport { getFiltersStateParser } from \"@/lib/parsers\";\nimport { cn } from \"@/lib/utils\";\nimport type {\n ExtendedColumnFilter,\n FilterOperator,\n JoinOperator,\n} from \"@/types/data-table\";\n\nconst FILTERS_KEY = \"filters\";\nconst JOIN_OPERATOR_KEY = \"joinOperator\";\nconst DEBOUNCE_MS = 300;\nconst THROTTLE_MS = 50;\nconst OPEN_MENU_SHORTCUT = \"f\";\nconst REMOVE_FILTER_SHORTCUTS = [\"backspace\", \"delete\"];\n\ninterface DataTableFilterListProps\n extends React.ComponentProps {\n table: Table;\n debounceMs?: number;\n throttleMs?: number;\n shallow?: boolean;\n}\n\nexport function DataTableFilterList({\n table,\n debounceMs = DEBOUNCE_MS,\n throttleMs = THROTTLE_MS,\n shallow = true,\n ...props\n}: DataTableFilterListProps) {\n const id = React.useId();\n const labelId = React.useId();\n const descriptionId = React.useId();\n const [open, setOpen] = React.useState(false);\n const addButtonRef = React.useRef(null);\n\n const columns = React.useMemo(() => {\n return table\n .getAllColumns()\n .filter((column) => column.columnDef.enableColumnFilter);\n }, [table]);\n\n const [filters, setFilters] = useQueryState(\n FILTERS_KEY,\n getFiltersStateParser(columns.map((field) => field.id))\n .withDefault([])\n .withOptions({\n clearOnDefault: true,\n shallow,\n throttleMs,\n }),\n );\n const debouncedSetFilters = useDebouncedCallback(setFilters, debounceMs);\n\n const [joinOperator, setJoinOperator] = useQueryState(\n JOIN_OPERATOR_KEY,\n parseAsStringEnum([\"and\", \"or\"]).withDefault(\"and\").withOptions({\n clearOnDefault: true,\n shallow,\n }),\n );\n\n const onFilterAdd = React.useCallback(() => {\n const column = columns[0];\n\n if (!column) return;\n\n debouncedSetFilters([\n ...filters,\n {\n id: column.id as Extract,\n value: \"\",\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n filterId: generateId({ length: 8 }),\n },\n ]);\n }, [columns, filters, debouncedSetFilters]);\n\n const onFilterUpdate = React.useCallback(\n (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => {\n debouncedSetFilters((prevFilters) => {\n const updatedFilters = prevFilters.map((filter) => {\n if (filter.filterId === filterId) {\n return { ...filter, ...updates } as ExtendedColumnFilter;\n }\n return filter;\n });\n return updatedFilters;\n });\n },\n [debouncedSetFilters],\n );\n\n const onFilterRemove = React.useCallback(\n (filterId: string) => {\n const updatedFilters = filters.filter(\n (filter) => filter.filterId !== filterId,\n );\n void setFilters(updatedFilters);\n requestAnimationFrame(() => {\n addButtonRef.current?.focus();\n });\n },\n [filters, setFilters],\n );\n\n const onFiltersReset = React.useCallback(() => {\n void setFilters(null);\n void setJoinOperator(\"and\");\n }, [setFilters, setJoinOperator]);\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey\n ) {\n event.preventDefault();\n setOpen(true);\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n event.shiftKey &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [filters, onFilterRemove]);\n\n const onTriggerKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase()) &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n },\n [filters, onFilterRemove],\n );\n\n return (\n item.filterId}\n >\n \n \n \n \n \n
\n

\n {filters.length > 0 ? \"Filters\" : \"No filters applied\"}\n

\n 0 && \"sr-only\",\n )}\n >\n {filters.length > 0\n ? \"Modify filters to refine your rows.\"\n : \"Add filters to refine your rows.\"}\n

\n
\n {filters.length > 0 ? (\n \n \n {filters.map((filter, index) => (\n \n key={filter.filterId}\n filter={filter}\n index={index}\n filterItemId={`${id}-filter-${filter.filterId}`}\n joinOperator={joinOperator}\n setJoinOperator={setJoinOperator}\n columns={columns}\n onFilterUpdate={onFilterUpdate}\n onFilterRemove={onFilterRemove}\n />\n ))}\n \n \n ) : null}\n
\n \n Add filter\n \n {filters.length > 0 ? (\n \n Reset filters\n \n ) : null}\n
\n \n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n \n \n );\n}\n\ninterface DataTableFilterItemProps {\n filter: ExtendedColumnFilter;\n index: number;\n filterItemId: string;\n joinOperator: JoinOperator;\n setJoinOperator: (value: JoinOperator) => void;\n columns: Column[];\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n onFilterRemove: (filterId: string) => void;\n}\n\nfunction DataTableFilterItem({\n filter,\n index,\n filterItemId,\n joinOperator,\n setJoinOperator,\n columns,\n onFilterUpdate,\n onFilterRemove,\n}: DataTableFilterItemProps) {\n const [showFieldSelector, setShowFieldSelector] = React.useState(false);\n const [showOperatorSelector, setShowOperatorSelector] = React.useState(false);\n const [showValueSelector, setShowValueSelector] = React.useState(false);\n\n const column = columns.find((column) => column.id === filter.id);\n if (!column) return null;\n\n const joinOperatorListboxId = `${filterItemId}-join-operator-listbox`;\n const fieldListboxId = `${filterItemId}-field-listbox`;\n const operatorListboxId = `${filterItemId}-operator-listbox`;\n const inputId = `${filterItemId}-input`;\n\n const columnMeta = column.columnDef.meta;\n const filterOperators = getFilterOperators(filter.variant);\n\n const onItemKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (showFieldSelector || showOperatorSelector || showValueSelector) {\n return;\n }\n\n if (REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase())) {\n event.preventDefault();\n onFilterRemove(filter.filterId);\n }\n },\n [\n filter.filterId,\n showFieldSelector,\n showOperatorSelector,\n showValueSelector,\n onFilterRemove,\n ],\n );\n\n return (\n \n \n
\n {index === 0 ? (\n Where\n ) : index === 1 ? (\n setJoinOperator(value)}\n >\n \n \n \n \n {dataTableConfig.joinOperators.map((joinOperator) => (\n \n {joinOperator}\n \n ))}\n \n \n ) : (\n \n {joinOperator}\n \n )}\n
\n \n \n \n \n {columns.find((column) => column.id === filter.id)?.columnDef\n .meta?.label ?? \"Select field\"}\n \n \n \n \n \n \n \n \n No fields found.\n \n {columns.map((column) => (\n {\n onFilterUpdate(filter.filterId, {\n id: value as Extract,\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n value: \"\",\n });\n\n setShowFieldSelector(false);\n }}\n >\n \n {column.columnDef.meta?.label}\n \n \n \n ))}\n \n \n \n \n \n \n onFilterUpdate(filter.filterId, {\n operator: value,\n value:\n value === \"isEmpty\" || value === \"isNotEmpty\"\n ? \"\"\n : filter.value,\n })\n }\n >\n \n
\n \n
\n \n \n {filterOperators.map((operator) => (\n \n {operator.label}\n \n ))}\n \n \n
\n {onFilterInputRender({\n filter,\n inputId,\n column,\n columnMeta,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n })}\n
\n onFilterRemove(filter.filterId)}\n >\n \n \n \n \n \n
\n \n );\n}\n\nfunction onFilterInputRender({\n filter,\n inputId,\n column,\n columnMeta,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n}: {\n filter: ExtendedColumnFilter;\n inputId: string;\n column: Column;\n columnMeta?: ColumnMeta;\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n showValueSelector: boolean;\n setShowValueSelector: (value: boolean) => void;\n}) {\n if (filter.operator === \"isEmpty\" || filter.operator === \"isNotEmpty\") {\n return (\n \n );\n }\n\n switch (filter.variant) {\n case \"text\":\n case \"number\":\n case \"range\": {\n if (\n (filter.variant === \"range\" && filter.operator === \"isBetween\") ||\n filter.operator === \"isBetween\"\n ) {\n return (\n \n );\n }\n\n const isNumber =\n filter.variant === \"number\" || filter.variant === \"range\";\n\n return (\n \n onFilterUpdate(filter.filterId, {\n value: event.target.value,\n })\n }\n />\n );\n }\n\n case \"boolean\": {\n if (Array.isArray(filter.value)) return null;\n\n const inputListboxId = `${inputId}-listbox`;\n\n return (\n \n onFilterUpdate(filter.filterId, {\n value,\n })\n }\n >\n \n \n \n \n True\n False\n \n \n );\n }\n\n case \"select\":\n case \"multiSelect\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const multiple = filter.variant === \"multiSelect\";\n const selectedValues = multiple\n ? Array.isArray(filter.value)\n ? filter.value\n : []\n : typeof filter.value === \"string\"\n ? filter.value\n : undefined;\n\n return (\n {\n onFilterUpdate(filter.filterId, {\n value,\n });\n }}\n multiple={multiple}\n >\n \n \n \n \n \n \n \n \n No options found.\n \n {columnMeta?.options?.map((option) => (\n \n {option.icon && }\n {option.label}\n {option.count && (\n \n {option.count}\n \n )}\n \n ))}\n \n \n \n \n );\n }\n\n case \"date\":\n case \"dateRange\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const dateValue = Array.isArray(filter.value)\n ? filter.value.filter(Boolean)\n : [filter.value, filter.value].filter(Boolean);\n\n const displayValue =\n filter.operator === \"isBetween\" && dateValue.length === 2\n ? `${formatDate(new Date(Number(dateValue[0])))} - ${formatDate(\n new Date(Number(dateValue[1])),\n )}`\n : dateValue[0]\n ? formatDate(new Date(Number(dateValue[0])))\n : \"Pick a date\";\n\n return (\n \n \n \n \n {displayValue}\n \n \n \n {filter.operator === \"isBetween\" ? (\n {\n onFilterUpdate(filter.filterId, {\n value: date\n ? [\n (date.from?.getTime() ?? \"\").toString(),\n (date.to?.getTime() ?? \"\").toString(),\n ]\n : [],\n });\n }}\n />\n ) : (\n {\n onFilterUpdate(filter.filterId, {\n value: (date?.getTime() ?? \"\").toString(),\n });\n }}\n />\n )}\n \n \n );\n }\n\n default:\n return null;\n }\n}\n", + "content": "\"use client\";\n\nimport type { Column, ColumnMeta, Table } from \"@tanstack/react-table\";\nimport {\n CalendarIcon,\n Check,\n ChevronsUpDown,\n GripVertical,\n ListFilter,\n Trash2,\n} from \"lucide-react\";\nimport { parseAsStringEnum, useQueryState } from \"nuqs\";\nimport * as React from \"react\";\n\nimport { DataTableRangeFilter } from \"@/components/data-table/data-table-range-filter\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Calendar } from \"@/components/ui/calendar\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/components/ui/command\";\nimport {\n Faceted,\n FacetedBadgeList,\n FacetedContent,\n FacetedEmpty,\n FacetedGroup,\n FacetedInput,\n FacetedItem,\n FacetedList,\n FacetedTrigger,\n} from \"@/components/ui/faceted\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport {\n Sortable,\n SortableContent,\n SortableItem,\n SortableItemHandle,\n SortableOverlay,\n} from \"@/components/ui/sortable\";\nimport { dataTableConfig } from \"@/config/data-table\";\nimport { useDebouncedCallback } from \"@/hooks/use-debounced-callback\";\nimport { getDefaultFilterOperator, getFilterOperators } from \"@/lib/data-table\";\nimport { formatDate } from \"@/lib/format\";\nimport { generateId } from \"@/lib/id\";\nimport { getFiltersStateParser } from \"@/lib/parsers\";\nimport { cn } from \"@/lib/utils\";\nimport type {\n ExtendedColumnFilter,\n FilterOperator,\n JoinOperator,\n} from \"@/types/data-table\";\n\nconst FILTERS_KEY = \"filters\";\nconst JOIN_OPERATOR_KEY = \"joinOperator\";\nconst DEBOUNCE_MS = 300;\nconst THROTTLE_MS = 50;\nconst OPEN_MENU_SHORTCUT = \"f\";\nconst REMOVE_FILTER_SHORTCUTS = [\"backspace\", \"delete\"];\n\ninterface DataTableFilterListProps\n extends React.ComponentProps {\n table: Table;\n debounceMs?: number;\n throttleMs?: number;\n shallow?: boolean;\n}\n\nexport function DataTableFilterList({\n table,\n debounceMs = DEBOUNCE_MS,\n throttleMs = THROTTLE_MS,\n shallow = true,\n ...props\n}: DataTableFilterListProps) {\n const id = React.useId();\n const labelId = React.useId();\n const descriptionId = React.useId();\n const [open, setOpen] = React.useState(false);\n const addButtonRef = React.useRef(null);\n\n const columns = React.useMemo(() => {\n return table\n .getAllColumns()\n .filter((column) => column.columnDef.enableColumnFilter);\n }, [table]);\n\n const [filters, setFilters] = useQueryState(\n FILTERS_KEY,\n getFiltersStateParser(columns.map((field) => field.id))\n .withDefault([])\n .withOptions({\n clearOnDefault: true,\n shallow,\n throttleMs,\n }),\n );\n const debouncedSetFilters = useDebouncedCallback(setFilters, debounceMs);\n\n const [joinOperator, setJoinOperator] = useQueryState(\n JOIN_OPERATOR_KEY,\n parseAsStringEnum([\"and\", \"or\"]).withDefault(\"and\").withOptions({\n clearOnDefault: true,\n shallow,\n }),\n );\n\n const onFilterAdd = React.useCallback(() => {\n const column = columns[0];\n\n if (!column) return;\n\n debouncedSetFilters([\n ...filters,\n {\n id: column.id as Extract,\n value: \"\",\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n filterId: generateId({ length: 8 }),\n },\n ]);\n }, [columns, filters, debouncedSetFilters]);\n\n const onFilterUpdate = React.useCallback(\n (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => {\n debouncedSetFilters((prevFilters) => {\n const updatedFilters = prevFilters.map((filter) => {\n if (filter.filterId === filterId) {\n return { ...filter, ...updates } as ExtendedColumnFilter;\n }\n return filter;\n });\n return updatedFilters;\n });\n },\n [debouncedSetFilters],\n );\n\n const onFilterRemove = React.useCallback(\n (filterId: string) => {\n const updatedFilters = filters.filter(\n (filter) => filter.filterId !== filterId,\n );\n void setFilters(updatedFilters);\n requestAnimationFrame(() => {\n addButtonRef.current?.focus();\n });\n },\n [filters, setFilters],\n );\n\n const onFiltersReset = React.useCallback(() => {\n void setFilters(null);\n void setJoinOperator(\"and\");\n }, [setFilters, setJoinOperator]);\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey\n ) {\n event.preventDefault();\n setOpen(true);\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n event.shiftKey &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [filters, onFilterRemove]);\n\n const onTriggerKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase()) &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n },\n [filters, onFilterRemove],\n );\n\n return (\n item.filterId}\n >\n \n \n \n \n \n
\n

\n {filters.length > 0 ? \"Filters\" : \"No filters applied\"}\n

\n 0 && \"sr-only\",\n )}\n >\n {filters.length > 0\n ? \"Modify filters to refine your rows.\"\n : \"Add filters to refine your rows.\"}\n

\n
\n {filters.length > 0 ? (\n \n \n {filters.map((filter, index) => (\n \n key={filter.filterId}\n filter={filter}\n index={index}\n filterItemId={`${id}-filter-${filter.filterId}`}\n joinOperator={joinOperator}\n setJoinOperator={setJoinOperator}\n columns={columns}\n onFilterUpdate={onFilterUpdate}\n onFilterRemove={onFilterRemove}\n />\n ))}\n
\n \n ) : null}\n
\n \n Add filter\n \n {filters.length > 0 ? (\n \n Reset filters\n \n ) : null}\n
\n \n \n \n
\n
\n
\n
\n
\n
\n
\n
\n \n \n );\n}\n\ninterface DataTableFilterItemProps {\n filter: ExtendedColumnFilter;\n index: number;\n filterItemId: string;\n joinOperator: JoinOperator;\n setJoinOperator: (value: JoinOperator) => void;\n columns: Column[];\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n onFilterRemove: (filterId: string) => void;\n}\n\nfunction DataTableFilterItem({\n filter,\n index,\n filterItemId,\n joinOperator,\n setJoinOperator,\n columns,\n onFilterUpdate,\n onFilterRemove,\n}: DataTableFilterItemProps) {\n const [showFieldSelector, setShowFieldSelector] = React.useState(false);\n const [showOperatorSelector, setShowOperatorSelector] = React.useState(false);\n const [showValueSelector, setShowValueSelector] = React.useState(false);\n\n const column = columns.find((column) => column.id === filter.id);\n\n const joinOperatorListboxId = `${filterItemId}-join-operator-listbox`;\n const fieldListboxId = `${filterItemId}-field-listbox`;\n const operatorListboxId = `${filterItemId}-operator-listbox`;\n const inputId = `${filterItemId}-input`;\n\n const columnMeta = column?.columnDef.meta;\n const filterOperators = getFilterOperators(filter.variant);\n\n const onItemKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (showFieldSelector || showOperatorSelector || showValueSelector) {\n return;\n }\n\n if (REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase())) {\n event.preventDefault();\n onFilterRemove(filter.filterId);\n }\n },\n [\n filter.filterId,\n showFieldSelector,\n showOperatorSelector,\n showValueSelector,\n onFilterRemove,\n ],\n );\n\n if (!column) return null;\n\n return (\n \n \n
\n {index === 0 ? (\n Where\n ) : index === 1 ? (\n setJoinOperator(value)}\n >\n \n \n \n \n {dataTableConfig.joinOperators.map((joinOperator) => (\n \n {joinOperator}\n \n ))}\n \n \n ) : (\n \n {joinOperator}\n \n )}\n
\n \n \n \n \n {columns.find((column) => column.id === filter.id)?.columnDef\n .meta?.label ?? \"Select field\"}\n \n \n \n \n \n \n \n \n No fields found.\n \n {columns.map((column) => (\n {\n onFilterUpdate(filter.filterId, {\n id: value as Extract,\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n value: \"\",\n });\n\n setShowFieldSelector(false);\n }}\n >\n \n {column.columnDef.meta?.label}\n \n \n \n ))}\n \n \n \n \n \n \n onFilterUpdate(filter.filterId, {\n operator: value,\n value:\n value === \"isEmpty\" || value === \"isNotEmpty\"\n ? \"\"\n : filter.value,\n })\n }\n >\n \n
\n \n
\n \n \n {filterOperators.map((operator) => (\n \n {operator.label}\n \n ))}\n \n \n
\n {onFilterInputRender({\n filter,\n inputId,\n column,\n columnMeta,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n })}\n
\n onFilterRemove(filter.filterId)}\n >\n \n \n \n \n \n
\n \n );\n}\n\nfunction onFilterInputRender({\n filter,\n inputId,\n column,\n columnMeta,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n}: {\n filter: ExtendedColumnFilter;\n inputId: string;\n column: Column;\n columnMeta?: ColumnMeta;\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n showValueSelector: boolean;\n setShowValueSelector: (value: boolean) => void;\n}) {\n if (filter.operator === \"isEmpty\" || filter.operator === \"isNotEmpty\") {\n return (\n \n );\n }\n\n switch (filter.variant) {\n case \"text\":\n case \"number\":\n case \"range\": {\n if (\n (filter.variant === \"range\" && filter.operator === \"isBetween\") ||\n filter.operator === \"isBetween\"\n ) {\n return (\n \n );\n }\n\n const isNumber =\n filter.variant === \"number\" || filter.variant === \"range\";\n\n return (\n \n onFilterUpdate(filter.filterId, {\n value: event.target.value,\n })\n }\n />\n );\n }\n\n case \"boolean\": {\n if (Array.isArray(filter.value)) return null;\n\n const inputListboxId = `${inputId}-listbox`;\n\n return (\n \n onFilterUpdate(filter.filterId, {\n value,\n })\n }\n >\n \n \n \n \n True\n False\n \n \n );\n }\n\n case \"select\":\n case \"multiSelect\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const multiple = filter.variant === \"multiSelect\";\n const selectedValues = multiple\n ? Array.isArray(filter.value)\n ? filter.value\n : []\n : typeof filter.value === \"string\"\n ? filter.value\n : undefined;\n\n return (\n {\n onFilterUpdate(filter.filterId, {\n value,\n });\n }}\n multiple={multiple}\n >\n \n \n \n \n \n \n \n \n No options found.\n \n {columnMeta?.options?.map((option) => (\n \n {option.icon && }\n {option.label}\n {option.count && (\n \n {option.count}\n \n )}\n \n ))}\n \n \n \n \n );\n }\n\n case \"date\":\n case \"dateRange\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const dateValue = Array.isArray(filter.value)\n ? filter.value.filter(Boolean)\n : [filter.value, filter.value].filter(Boolean);\n\n const displayValue =\n filter.operator === \"isBetween\" && dateValue.length === 2\n ? `${formatDate(new Date(Number(dateValue[0])))} - ${formatDate(\n new Date(Number(dateValue[1])),\n )}`\n : dateValue[0]\n ? formatDate(new Date(Number(dateValue[0])))\n : \"Pick a date\";\n\n return (\n \n \n \n \n {displayValue}\n \n \n \n {filter.operator === \"isBetween\" ? (\n {\n onFilterUpdate(filter.filterId, {\n value: date\n ? [\n (date.from?.getTime() ?? \"\").toString(),\n (date.to?.getTime() ?? \"\").toString(),\n ]\n : [],\n });\n }}\n />\n ) : (\n {\n onFilterUpdate(filter.filterId, {\n value: (date?.getTime() ?? \"\").toString(),\n });\n }}\n />\n )}\n \n \n );\n }\n\n default:\n return null;\n }\n}\n", "type": "registry:component", "target": "src/components/data-table/data-table-filter-list.tsx" }, diff --git a/public/r/data-table-filter-menu.json b/public/r/data-table-filter-menu.json index 94b664bf..c14cdcb6 100644 --- a/public/r/data-table-filter-menu.json +++ b/public/r/data-table-filter-menu.json @@ -23,7 +23,7 @@ "files": [ { "path": "src/components/data-table/data-table-filter-menu.tsx", - "content": "\"use client\";\n\nimport type { Column, Table } from \"@tanstack/react-table\";\nimport {\n BadgeCheck,\n CalendarIcon,\n Check,\n ListFilter,\n Text,\n X,\n} from \"lucide-react\";\nimport { useQueryState } from \"nuqs\";\nimport * as React from \"react\";\n\nimport { DataTableRangeFilter } from \"@/components/data-table/data-table-range-filter\";\nimport { Button } from \"@/components/ui/button\";\nimport { Calendar } from \"@/components/ui/calendar\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/components/ui/command\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { useDebouncedCallback } from \"@/hooks/use-debounced-callback\";\nimport { getDefaultFilterOperator, getFilterOperators } from \"@/lib/data-table\";\nimport { formatDate } from \"@/lib/format\";\nimport { generateId } from \"@/lib/id\";\nimport { getFiltersStateParser } from \"@/lib/parsers\";\nimport { cn } from \"@/lib/utils\";\nimport type { ExtendedColumnFilter, FilterOperator } from \"@/types/data-table\";\n\nconst FILTERS_KEY = \"filters\";\nconst DEBOUNCE_MS = 300;\nconst THROTTLE_MS = 50;\nconst OPEN_MENU_SHORTCUT = \"f\";\nconst REMOVE_FILTER_SHORTCUTS = [\"backspace\", \"delete\"];\n\ninterface DataTableFilterMenuProps\n extends React.ComponentProps {\n table: Table;\n debounceMs?: number;\n throttleMs?: number;\n shallow?: boolean;\n}\n\nexport function DataTableFilterMenu({\n table,\n debounceMs = DEBOUNCE_MS,\n throttleMs = THROTTLE_MS,\n shallow = true,\n align = \"start\",\n ...props\n}: DataTableFilterMenuProps) {\n const id = React.useId();\n\n const columns = React.useMemo(() => {\n return table\n .getAllColumns()\n .filter((column) => column.columnDef.enableColumnFilter);\n }, [table]);\n\n const [open, setOpen] = React.useState(false);\n const [selectedColumn, setSelectedColumn] =\n React.useState | null>(null);\n const [inputValue, setInputValue] = React.useState(\"\");\n const triggerRef = React.useRef(null);\n const inputRef = React.useRef(null);\n\n const onOpenChange = React.useCallback((open: boolean) => {\n setOpen(open);\n\n if (!open) {\n setTimeout(() => {\n setSelectedColumn(null);\n setInputValue(\"\");\n }, 100);\n }\n }, []);\n\n const onInputKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase()) &&\n !inputValue &&\n selectedColumn\n ) {\n event.preventDefault();\n setSelectedColumn(null);\n }\n },\n [inputValue, selectedColumn],\n );\n\n const [filters, setFilters] = useQueryState(\n FILTERS_KEY,\n getFiltersStateParser(columns.map((field) => field.id))\n .withDefault([])\n .withOptions({\n clearOnDefault: true,\n shallow,\n throttleMs,\n }),\n );\n const debouncedSetFilters = useDebouncedCallback(setFilters, debounceMs);\n\n const onFilterAdd = React.useCallback(\n (column: Column, value: string) => {\n if (!value.trim() && column.columnDef.meta?.variant !== \"boolean\") {\n return;\n }\n\n const filterValue =\n column.columnDef.meta?.variant === \"multiSelect\" ? [value] : value;\n\n const newFilter: ExtendedColumnFilter = {\n id: column.id as Extract,\n value: filterValue,\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n filterId: generateId({ length: 8 }),\n };\n\n debouncedSetFilters([...filters, newFilter]);\n setOpen(false);\n\n setTimeout(() => {\n setSelectedColumn(null);\n setInputValue(\"\");\n }, 100);\n },\n [filters, debouncedSetFilters],\n );\n\n const onFilterRemove = React.useCallback(\n (filterId: string) => {\n const updatedFilters = filters.filter(\n (filter) => filter.filterId !== filterId,\n );\n debouncedSetFilters(updatedFilters);\n requestAnimationFrame(() => {\n triggerRef.current?.focus();\n });\n },\n [filters, debouncedSetFilters],\n );\n\n const onFilterUpdate = React.useCallback(\n (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => {\n debouncedSetFilters((prevFilters) => {\n const updatedFilters = prevFilters.map((filter) => {\n if (filter.filterId === filterId) {\n return { ...filter, ...updates } as ExtendedColumnFilter;\n }\n return filter;\n });\n return updatedFilters;\n });\n },\n [debouncedSetFilters],\n );\n\n const onFiltersReset = React.useCallback(() => {\n debouncedSetFilters([]);\n }, [debouncedSetFilters]);\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey\n ) {\n event.preventDefault();\n setOpen(true);\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n event.shiftKey &&\n !open &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [open, filters, onFilterRemove]);\n\n const onTriggerKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase()) &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n },\n [filters, onFilterRemove],\n );\n\n return (\n
\n {filters.map((filter) => (\n \n ))}\n {filters.length > 0 && (\n \n \n \n )}\n \n \n 0 ? \"icon\" : \"sm\"}\n className={cn(filters.length > 0 && \"size-8\", \"h-8\")}\n ref={triggerRef}\n onKeyDown={onTriggerKeyDown}\n >\n \n {filters.length > 0 ? null : \"Filter\"}\n \n \n \n \n \n \n {selectedColumn ? (\n <>\n {selectedColumn.columnDef.meta?.options && (\n No options found.\n )}\n onFilterAdd(selectedColumn, value)}\n />\n \n ) : (\n <>\n No fields found.\n \n {columns.map((column) => (\n {\n setSelectedColumn(column);\n setInputValue(\"\");\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n }}\n >\n {column.columnDef.meta?.icon && (\n \n )}\n \n {column.columnDef.meta?.label ?? column.id}\n \n \n ))}\n \n \n )}\n \n \n \n \n
\n );\n}\n\ninterface DataTableFilterItemProps {\n filter: ExtendedColumnFilter;\n filterItemId: string;\n columns: Column[];\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n onFilterRemove: (filterId: string) => void;\n}\n\nfunction DataTableFilterItem({\n filter,\n filterItemId,\n columns,\n onFilterUpdate,\n onFilterRemove,\n}: DataTableFilterItemProps) {\n {\n const [showFieldSelector, setShowFieldSelector] = React.useState(false);\n const [showOperatorSelector, setShowOperatorSelector] =\n React.useState(false);\n const [showValueSelector, setShowValueSelector] = React.useState(false);\n\n const column = columns.find((column) => column.id === filter.id);\n if (!column) return null;\n\n const operatorListboxId = `${filterItemId}-operator-listbox`;\n const inputId = `${filterItemId}-input`;\n\n const columnMeta = column.columnDef.meta;\n const filterOperators = getFilterOperators(filter.variant);\n\n const onItemKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (showFieldSelector || showOperatorSelector || showValueSelector) {\n return;\n }\n\n if (REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase())) {\n event.preventDefault();\n onFilterRemove(filter.filterId);\n }\n },\n [\n filter.filterId,\n showFieldSelector,\n showOperatorSelector,\n showValueSelector,\n onFilterRemove,\n ],\n );\n\n return (\n \n \n \n \n {columnMeta?.icon && (\n \n )}\n {columnMeta?.label ?? column.id}\n \n \n \n \n \n \n No fields found.\n \n {columns.map((column) => (\n {\n onFilterUpdate(filter.filterId, {\n id: column.id as Extract,\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n value: \"\",\n });\n\n setShowFieldSelector(false);\n }}\n >\n {column.columnDef.meta?.icon && (\n \n )}\n \n {column.columnDef.meta?.label ?? column.id}\n \n \n \n ))}\n \n \n \n \n \n \n onFilterUpdate(filter.filterId, {\n operator: value,\n value:\n value === \"isEmpty\" || value === \"isNotEmpty\"\n ? \"\"\n : filter.value,\n })\n }\n >\n \n \n \n \n {filterOperators.map((operator) => (\n \n {operator.label}\n \n ))}\n \n \n {onFilterInputRender({\n filter,\n column,\n inputId,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n })}\n onFilterRemove(filter.filterId)}\n >\n \n \n
\n );\n }\n}\n\ninterface FilterValueSelectorProps {\n column: Column;\n value: string;\n onSelect: (value: string) => void;\n}\n\nfunction FilterValueSelector({\n column,\n value,\n onSelect,\n}: FilterValueSelectorProps) {\n const variant = column.columnDef.meta?.variant ?? \"text\";\n\n switch (variant) {\n case \"boolean\":\n return (\n \n onSelect(\"true\")}>\n True\n \n onSelect(\"false\")}>\n False\n \n \n );\n\n case \"select\":\n case \"multiSelect\":\n return (\n \n {column.columnDef.meta?.options?.map((option) => (\n onSelect(option.value)}\n >\n {option.icon && }\n {option.label}\n {option.count && (\n \n {option.count}\n \n )}\n \n ))}\n \n );\n\n case \"date\":\n case \"dateRange\":\n return (\n onSelect(date?.getTime().toString() ?? \"\")}\n />\n );\n\n default: {\n const isEmpty = !value.trim();\n\n return (\n \n onSelect(value)}\n disabled={isEmpty}\n >\n {isEmpty ? (\n <>\n \n Type to add filter...\n \n ) : (\n <>\n \n Filter by "{value}"\n \n )}\n \n \n );\n }\n }\n}\n\nfunction onFilterInputRender({\n filter,\n column,\n inputId,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n}: {\n filter: ExtendedColumnFilter;\n column: Column;\n inputId: string;\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n showValueSelector: boolean;\n setShowValueSelector: (value: boolean) => void;\n}) {\n if (filter.operator === \"isEmpty\" || filter.operator === \"isNotEmpty\") {\n return (\n \n );\n }\n\n switch (filter.variant) {\n case \"text\":\n case \"number\":\n case \"range\": {\n if (\n (filter.variant === \"range\" && filter.operator === \"isBetween\") ||\n filter.operator === \"isBetween\"\n ) {\n return (\n \n );\n }\n\n const isNumber =\n filter.variant === \"number\" || filter.variant === \"range\";\n\n return (\n \n onFilterUpdate(filter.filterId, { value: event.target.value })\n }\n />\n );\n }\n\n case \"boolean\": {\n const inputListboxId = `${inputId}-listbox`;\n\n return (\n \n onFilterUpdate(filter.filterId, { value })\n }\n >\n \n \n \n \n True\n False\n \n \n );\n }\n\n case \"select\":\n case \"multiSelect\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const options = column.columnDef.meta?.options ?? [];\n const selectedValues = Array.isArray(filter.value)\n ? filter.value\n : [filter.value];\n\n const selectedOptions = options.filter((option) =>\n selectedValues.includes(option.value),\n );\n\n return (\n \n \n \n {selectedOptions.length === 0 ? (\n filter.variant === \"multiSelect\" ? (\n \"Select options...\"\n ) : (\n \"Select option...\"\n )\n ) : (\n <>\n
\n {selectedOptions.map((selectedOption) =>\n selectedOption.icon ? (\n \n \n
\n ) : null,\n )}\n
\n \n {selectedOptions.length > 1\n ? `${selectedOptions.length} selected`\n : selectedOptions[0]?.label}\n \n \n )}\n \n \n \n \n \n \n No options found.\n \n {options.map((option) => (\n {\n const value =\n filter.variant === \"multiSelect\"\n ? selectedValues.includes(option.value)\n ? selectedValues.filter((v) => v !== option.value)\n : [...selectedValues, option.value]\n : option.value;\n onFilterUpdate(filter.filterId, { value });\n }}\n >\n {option.icon && }\n {option.label}\n {filter.variant === \"multiSelect\" && (\n \n )}\n \n ))}\n \n \n \n \n \n );\n }\n\n case \"date\":\n case \"dateRange\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const dateValue = Array.isArray(filter.value)\n ? filter.value.filter(Boolean)\n : [filter.value, filter.value].filter(Boolean);\n\n const displayValue =\n filter.operator === \"isBetween\" && dateValue.length === 2\n ? `${formatDate(new Date(Number(dateValue[0])))} - ${formatDate(\n new Date(Number(dateValue[1])),\n )}`\n : dateValue[0]\n ? formatDate(new Date(Number(dateValue[0])))\n : \"Pick date...\";\n\n return (\n \n \n \n \n {displayValue}\n \n \n \n {filter.operator === \"isBetween\" ? (\n {\n onFilterUpdate(filter.filterId, {\n value: date\n ? [\n (date.from?.getTime() ?? \"\").toString(),\n (date.to?.getTime() ?? \"\").toString(),\n ]\n : [],\n });\n }}\n />\n ) : (\n {\n onFilterUpdate(filter.filterId, {\n value: (date?.getTime() ?? \"\").toString(),\n });\n }}\n />\n )}\n \n \n );\n }\n\n default:\n return null;\n }\n}\n", + "content": "\"use client\";\n\nimport type { Column, Table } from \"@tanstack/react-table\";\nimport {\n BadgeCheck,\n CalendarIcon,\n Check,\n ListFilter,\n Text,\n X,\n} from \"lucide-react\";\nimport { useQueryState } from \"nuqs\";\nimport * as React from \"react\";\n\nimport { DataTableRangeFilter } from \"@/components/data-table/data-table-range-filter\";\nimport { Button } from \"@/components/ui/button\";\nimport { Calendar } from \"@/components/ui/calendar\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/components/ui/command\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { useDebouncedCallback } from \"@/hooks/use-debounced-callback\";\nimport { getDefaultFilterOperator, getFilterOperators } from \"@/lib/data-table\";\nimport { formatDate } from \"@/lib/format\";\nimport { generateId } from \"@/lib/id\";\nimport { getFiltersStateParser } from \"@/lib/parsers\";\nimport { cn } from \"@/lib/utils\";\nimport type { ExtendedColumnFilter, FilterOperator } from \"@/types/data-table\";\n\nconst FILTERS_KEY = \"filters\";\nconst DEBOUNCE_MS = 300;\nconst THROTTLE_MS = 50;\nconst OPEN_MENU_SHORTCUT = \"f\";\nconst REMOVE_FILTER_SHORTCUTS = [\"backspace\", \"delete\"];\n\ninterface DataTableFilterMenuProps\n extends React.ComponentProps {\n table: Table;\n debounceMs?: number;\n throttleMs?: number;\n shallow?: boolean;\n}\n\nexport function DataTableFilterMenu({\n table,\n debounceMs = DEBOUNCE_MS,\n throttleMs = THROTTLE_MS,\n shallow = true,\n align = \"start\",\n ...props\n}: DataTableFilterMenuProps) {\n const id = React.useId();\n\n const columns = React.useMemo(() => {\n return table\n .getAllColumns()\n .filter((column) => column.columnDef.enableColumnFilter);\n }, [table]);\n\n const [open, setOpen] = React.useState(false);\n const [selectedColumn, setSelectedColumn] =\n React.useState | null>(null);\n const [inputValue, setInputValue] = React.useState(\"\");\n const triggerRef = React.useRef(null);\n const inputRef = React.useRef(null);\n\n const onOpenChange = React.useCallback((open: boolean) => {\n setOpen(open);\n\n if (!open) {\n setTimeout(() => {\n setSelectedColumn(null);\n setInputValue(\"\");\n }, 100);\n }\n }, []);\n\n const onInputKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase()) &&\n !inputValue &&\n selectedColumn\n ) {\n event.preventDefault();\n setSelectedColumn(null);\n }\n },\n [inputValue, selectedColumn],\n );\n\n const [filters, setFilters] = useQueryState(\n FILTERS_KEY,\n getFiltersStateParser(columns.map((field) => field.id))\n .withDefault([])\n .withOptions({\n clearOnDefault: true,\n shallow,\n throttleMs,\n }),\n );\n const debouncedSetFilters = useDebouncedCallback(setFilters, debounceMs);\n\n const onFilterAdd = React.useCallback(\n (column: Column, value: string) => {\n if (!value.trim() && column.columnDef.meta?.variant !== \"boolean\") {\n return;\n }\n\n const filterValue =\n column.columnDef.meta?.variant === \"multiSelect\" ? [value] : value;\n\n const newFilter: ExtendedColumnFilter = {\n id: column.id as Extract,\n value: filterValue,\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n filterId: generateId({ length: 8 }),\n };\n\n debouncedSetFilters([...filters, newFilter]);\n setOpen(false);\n\n setTimeout(() => {\n setSelectedColumn(null);\n setInputValue(\"\");\n }, 100);\n },\n [filters, debouncedSetFilters],\n );\n\n const onFilterRemove = React.useCallback(\n (filterId: string) => {\n const updatedFilters = filters.filter(\n (filter) => filter.filterId !== filterId,\n );\n debouncedSetFilters(updatedFilters);\n requestAnimationFrame(() => {\n triggerRef.current?.focus();\n });\n },\n [filters, debouncedSetFilters],\n );\n\n const onFilterUpdate = React.useCallback(\n (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => {\n debouncedSetFilters((prevFilters) => {\n const updatedFilters = prevFilters.map((filter) => {\n if (filter.filterId === filterId) {\n return { ...filter, ...updates } as ExtendedColumnFilter;\n }\n return filter;\n });\n return updatedFilters;\n });\n },\n [debouncedSetFilters],\n );\n\n const onFiltersReset = React.useCallback(() => {\n debouncedSetFilters([]);\n }, [debouncedSetFilters]);\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey\n ) {\n event.preventDefault();\n setOpen(true);\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n event.shiftKey &&\n !open &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [open, filters, onFilterRemove]);\n\n const onTriggerKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase()) &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n },\n [filters, onFilterRemove],\n );\n\n return (\n
\n {filters.map((filter) => (\n \n ))}\n {filters.length > 0 && (\n \n \n \n )}\n \n \n 0 ? \"icon\" : \"sm\"}\n className={cn(filters.length > 0 && \"size-8\", \"h-8\")}\n ref={triggerRef}\n onKeyDown={onTriggerKeyDown}\n >\n \n {filters.length > 0 ? null : \"Filter\"}\n \n \n \n \n \n \n {selectedColumn ? (\n <>\n {selectedColumn.columnDef.meta?.options && (\n No options found.\n )}\n onFilterAdd(selectedColumn, value)}\n />\n \n ) : (\n <>\n No fields found.\n \n {columns.map((column) => (\n {\n setSelectedColumn(column);\n setInputValue(\"\");\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n }}\n >\n {column.columnDef.meta?.icon && (\n \n )}\n \n {column.columnDef.meta?.label ?? column.id}\n \n \n ))}\n \n \n )}\n \n \n \n \n
\n );\n}\n\ninterface DataTableFilterItemProps {\n filter: ExtendedColumnFilter;\n filterItemId: string;\n columns: Column[];\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n onFilterRemove: (filterId: string) => void;\n}\n\nfunction DataTableFilterItem({\n filter,\n filterItemId,\n columns,\n onFilterUpdate,\n onFilterRemove,\n}: DataTableFilterItemProps) {\n {\n const [showFieldSelector, setShowFieldSelector] = React.useState(false);\n const [showOperatorSelector, setShowOperatorSelector] =\n React.useState(false);\n const [showValueSelector, setShowValueSelector] = React.useState(false);\n\n const column = columns.find((column) => column.id === filter.id);\n\n const operatorListboxId = `${filterItemId}-operator-listbox`;\n const inputId = `${filterItemId}-input`;\n\n const columnMeta = column?.columnDef.meta;\n const filterOperators = getFilterOperators(filter.variant);\n\n const onItemKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (showFieldSelector || showOperatorSelector || showValueSelector) {\n return;\n }\n\n if (REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase())) {\n event.preventDefault();\n onFilterRemove(filter.filterId);\n }\n },\n [\n filter.filterId,\n showFieldSelector,\n showOperatorSelector,\n showValueSelector,\n onFilterRemove,\n ],\n );\n\n if (!column) return null;\n\n return (\n \n \n \n \n {columnMeta?.icon && (\n \n )}\n {columnMeta?.label ?? column.id}\n \n \n \n \n \n \n No fields found.\n \n {columns.map((column) => (\n {\n onFilterUpdate(filter.filterId, {\n id: column.id as Extract,\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n value: \"\",\n });\n\n setShowFieldSelector(false);\n }}\n >\n {column.columnDef.meta?.icon && (\n \n )}\n \n {column.columnDef.meta?.label ?? column.id}\n \n \n \n ))}\n \n \n \n \n \n \n onFilterUpdate(filter.filterId, {\n operator: value,\n value:\n value === \"isEmpty\" || value === \"isNotEmpty\"\n ? \"\"\n : filter.value,\n })\n }\n >\n \n \n \n \n {filterOperators.map((operator) => (\n \n {operator.label}\n \n ))}\n \n \n {onFilterInputRender({\n filter,\n column,\n inputId,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n })}\n onFilterRemove(filter.filterId)}\n >\n \n \n
\n );\n }\n}\n\ninterface FilterValueSelectorProps {\n column: Column;\n value: string;\n onSelect: (value: string) => void;\n}\n\nfunction FilterValueSelector({\n column,\n value,\n onSelect,\n}: FilterValueSelectorProps) {\n const variant = column.columnDef.meta?.variant ?? \"text\";\n\n switch (variant) {\n case \"boolean\":\n return (\n \n onSelect(\"true\")}>\n True\n \n onSelect(\"false\")}>\n False\n \n \n );\n\n case \"select\":\n case \"multiSelect\":\n return (\n \n {column.columnDef.meta?.options?.map((option) => (\n onSelect(option.value)}\n >\n {option.icon && }\n {option.label}\n {option.count && (\n \n {option.count}\n \n )}\n \n ))}\n \n );\n\n case \"date\":\n case \"dateRange\":\n return (\n onSelect(date?.getTime().toString() ?? \"\")}\n />\n );\n\n default: {\n const isEmpty = !value.trim();\n\n return (\n \n onSelect(value)}\n disabled={isEmpty}\n >\n {isEmpty ? (\n <>\n \n Type to add filter...\n \n ) : (\n <>\n \n Filter by "{value}"\n \n )}\n \n \n );\n }\n }\n}\n\nfunction onFilterInputRender({\n filter,\n column,\n inputId,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n}: {\n filter: ExtendedColumnFilter;\n column: Column;\n inputId: string;\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n showValueSelector: boolean;\n setShowValueSelector: (value: boolean) => void;\n}) {\n if (filter.operator === \"isEmpty\" || filter.operator === \"isNotEmpty\") {\n return (\n \n );\n }\n\n switch (filter.variant) {\n case \"text\":\n case \"number\":\n case \"range\": {\n if (\n (filter.variant === \"range\" && filter.operator === \"isBetween\") ||\n filter.operator === \"isBetween\"\n ) {\n return (\n \n );\n }\n\n const isNumber =\n filter.variant === \"number\" || filter.variant === \"range\";\n\n return (\n \n onFilterUpdate(filter.filterId, { value: event.target.value })\n }\n />\n );\n }\n\n case \"boolean\": {\n const inputListboxId = `${inputId}-listbox`;\n\n return (\n \n onFilterUpdate(filter.filterId, { value })\n }\n >\n \n \n \n \n True\n False\n \n \n );\n }\n\n case \"select\":\n case \"multiSelect\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const options = column.columnDef.meta?.options ?? [];\n const selectedValues = Array.isArray(filter.value)\n ? filter.value\n : [filter.value];\n\n const selectedOptions = options.filter((option) =>\n selectedValues.includes(option.value),\n );\n\n return (\n \n \n \n {selectedOptions.length === 0 ? (\n filter.variant === \"multiSelect\" ? (\n \"Select options...\"\n ) : (\n \"Select option...\"\n )\n ) : (\n <>\n
\n {selectedOptions.map((selectedOption) =>\n selectedOption.icon ? (\n \n \n
\n ) : null,\n )}\n
\n \n {selectedOptions.length > 1\n ? `${selectedOptions.length} selected`\n : selectedOptions[0]?.label}\n \n \n )}\n \n \n \n \n \n \n No options found.\n \n {options.map((option) => (\n {\n const value =\n filter.variant === \"multiSelect\"\n ? selectedValues.includes(option.value)\n ? selectedValues.filter((v) => v !== option.value)\n : [...selectedValues, option.value]\n : option.value;\n onFilterUpdate(filter.filterId, { value });\n }}\n >\n {option.icon && }\n {option.label}\n {filter.variant === \"multiSelect\" && (\n \n )}\n \n ))}\n \n \n \n \n \n );\n }\n\n case \"date\":\n case \"dateRange\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const dateValue = Array.isArray(filter.value)\n ? filter.value.filter(Boolean)\n : [filter.value, filter.value].filter(Boolean);\n\n const displayValue =\n filter.operator === \"isBetween\" && dateValue.length === 2\n ? `${formatDate(new Date(Number(dateValue[0])))} - ${formatDate(\n new Date(Number(dateValue[1])),\n )}`\n : dateValue[0]\n ? formatDate(new Date(Number(dateValue[0])))\n : \"Pick date...\";\n\n return (\n \n \n \n \n {displayValue}\n \n \n \n {filter.operator === \"isBetween\" ? (\n {\n onFilterUpdate(filter.filterId, {\n value: date\n ? [\n (date.from?.getTime() ?? \"\").toString(),\n (date.to?.getTime() ?? \"\").toString(),\n ]\n : [],\n });\n }}\n />\n ) : (\n {\n onFilterUpdate(filter.filterId, {\n value: (date?.getTime() ?? \"\").toString(),\n });\n }}\n />\n )}\n \n \n );\n }\n\n default:\n return null;\n }\n}\n", "type": "registry:component", "target": "src/components/data-table/data-table-filter-menu.tsx" }, diff --git a/src/components/data-table/data-table-filter-list.tsx b/src/components/data-table/data-table-filter-list.tsx index 901f8a8c..269c5f34 100644 --- a/src/components/data-table/data-table-filter-list.tsx +++ b/src/components/data-table/data-table-filter-list.tsx @@ -353,14 +353,13 @@ function DataTableFilterItem({ const [showValueSelector, setShowValueSelector] = React.useState(false); const column = columns.find((column) => column.id === filter.id); - if (!column) return null; const joinOperatorListboxId = `${filterItemId}-join-operator-listbox`; const fieldListboxId = `${filterItemId}-field-listbox`; const operatorListboxId = `${filterItemId}-operator-listbox`; const inputId = `${filterItemId}-input`; - const columnMeta = column.columnDef.meta; + const columnMeta = column?.columnDef.meta; const filterOperators = getFilterOperators(filter.variant); const onItemKeyDown = React.useCallback( @@ -390,6 +389,8 @@ function DataTableFilterItem({ ], ); + if (!column) return null; + return (
({ const [showValueSelector, setShowValueSelector] = React.useState(false); const column = columns.find((column) => column.id === filter.id); - if (!column) return null; const operatorListboxId = `${filterItemId}-operator-listbox`; const inputId = `${filterItemId}-input`; - const columnMeta = column.columnDef.meta; + const columnMeta = column?.columnDef.meta; const filterOperators = getFilterOperators(filter.variant); const onItemKeyDown = React.useCallback( @@ -391,6 +390,8 @@ function DataTableFilterItem({ ], ); + if (!column) return null; + return (
Date: Thu, 3 Jul 2025 18:37:00 +0600 Subject: [PATCH 2/2] chore: bump biome --- biome.json | 47 +- drizzle.config.ts | 2 +- package.json | 78 +- pnpm-lock.yaml | 3016 ++++++++++------- public/r/data-table-action-bar.json | 2 +- public/r/data-table-filter-list.json | 12 +- public/r/data-table-filter-menu.json | 4 +- public/r/data-table-sort-list.json | 10 +- public/r/data-table.json | 16 +- registry.json | 4 +- src/app/_components/delete-tasks-dialog.tsx | 3 +- src/app/_components/task-form.tsx | 3 +- .../_components/tasks-table-action-bar.tsx | 3 +- src/app/_components/tasks-table-columns.tsx | 5 +- .../tasks-table-toolbar-actions.tsx | 3 +- src/app/_components/tasks-table.tsx | 8 +- src/app/_components/update-task-sheet.tsx | 3 +- src/app/_lib/actions.ts | 6 +- src/app/_lib/queries.ts | 4 +- src/app/_lib/utils.ts | 2 +- src/app/_lib/validations.ts | 3 +- src/app/layout.tsx | 3 +- src/app/page.tsx | 3 +- .../data-table/data-table-action-bar.tsx | 10 +- .../data-table/data-table-column-header.tsx | 2 +- .../data-table/data-table-faceted-filter.tsx | 4 +- .../data-table/data-table-filter-list.tsx | 15 +- .../data-table/data-table-slider-filter.tsx | 3 +- .../data-table/data-table-sort-list.tsx | 15 +- .../data-table/data-table-view-options.tsx | 3 +- src/components/data-table/data-table.tsx | 2 +- src/components/dynamic-container.tsx | 3 +- src/components/shell.tsx | 2 +- src/components/ui/badge.tsx | 2 +- src/components/ui/button.tsx | 2 +- src/components/ui/calendar.tsx | 241 +- src/components/ui/sortable.tsx | 140 +- src/components/ui/toggle.tsx | 2 +- src/config/site.ts | 2 - src/db/index.ts | 2 +- src/db/schema.ts | 2 +- src/db/utils.ts | 2 +- src/hooks/use-data-table.ts | 16 +- src/lib/{composition.ts => compose-refs.ts} | 41 +- src/lib/data-table.ts | 5 +- src/lib/filter-columns.ts | 8 +- src/types/data-table.ts | 4 +- src/types/doc.ts | 7 +- 48 files changed, 2302 insertions(+), 1473 deletions(-) rename src/lib/{composition.ts => compose-refs.ts} (62%) diff --git a/biome.json b/biome.json index 26bda140..7b480cf8 100644 --- a/biome.json +++ b/biome.json @@ -1,20 +1,16 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", - "organizeImports": { - "enabled": true + "$schema": "https://biomejs.dev/schemas/2.0.6/schema.json", + "assist": { + "actions": { + "source": { + "organizeImports": "on" + } + } }, "formatter": { "enabled": true, "indentWidth": 2, - "indentStyle": "space", - "ignore": [ - "**/node_modules", - "**/dist", - "**/build", - "**/public", - "**/.turbo", - "**/.next" - ] + "indentStyle": "space" }, "linter": { "enabled": true, @@ -56,19 +52,11 @@ } } } - }, - "ignore": [ - "**/node_modules", - "**/dist", - "**/build", - "**/public", - "**/.turbo", - "**/.next" - ] + } }, "overrides": [ { - "include": ["**/*.test.ts"] + "includes": ["**/*.test.ts"] } ], "vcs": { @@ -77,13 +65,14 @@ "useIgnoreFile": true }, "files": { - "ignore": [ - "**/node_modules", - "**/dist", - "**/build", - "**/public", - "**/.turbo", - "**/.next" + "includes": [ + "**", + "!**/node_modules", + "!**/dist", + "!**/build", + "!**/public", + "!**/.turbo", + "!**/.next" ] } } diff --git a/drizzle.config.ts b/drizzle.config.ts index 0926a3b5..13d228a7 100644 --- a/drizzle.config.ts +++ b/drizzle.config.ts @@ -1,5 +1,5 @@ -import { env } from "@/env.js"; import type { Config } from "drizzle-kit"; +import { env } from "@/env.js"; import { databasePrefix } from "@/lib/constants"; diff --git a/package.json b/package.json index 2cdd224d..6c5457e2 100644 --- a/package.json +++ b/package.json @@ -27,63 +27,63 @@ "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", - "@hookform/resolvers": "^5.0.1", - "@radix-ui/react-checkbox": "^1.2.3", - "@radix-ui/react-dialog": "^1.1.11", - "@radix-ui/react-dropdown-menu": "^2.1.12", - "@radix-ui/react-label": "^2.1.4", - "@radix-ui/react-popover": "^1.1.11", - "@radix-ui/react-portal": "^1.1.6", - "@radix-ui/react-select": "^2.2.2", - "@radix-ui/react-separator": "^1.1.4", - "@radix-ui/react-slider": "^1.3.2", - "@radix-ui/react-slot": "^1.2.0", - "@radix-ui/react-toggle": "^1.1.6", - "@radix-ui/react-toggle-group": "^1.1.7", - "@radix-ui/react-tooltip": "^1.2.4", - "@t3-oss/env-nextjs": "^0.13.0", + "@hookform/resolvers": "^5.1.1", + "@radix-ui/react-checkbox": "^1.3.2", + "@radix-ui/react-dialog": "^1.1.14", + "@radix-ui/react-dropdown-menu": "^2.1.15", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-popover": "^1.1.14", + "@radix-ui/react-portal": "^1.1.9", + "@radix-ui/react-select": "^2.2.5", + "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-slider": "^1.3.5", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-toggle": "^1.1.9", + "@radix-ui/react-toggle-group": "^1.1.10", + "@radix-ui/react-tooltip": "^1.2.7", + "@t3-oss/env-nextjs": "^0.13.8", "@tanstack/react-table": "^8.21.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", "date-fns": "^4.1.0", - "drizzle-orm": "^0.43.1", + "drizzle-orm": "^0.44.2", "export-to-csv": "^1.4.0", - "geist": "^1.3.1", - "lucide-react": "^0.503.0", - "motion": "^12.9.2", + "geist": "^1.4.2", + "lucide-react": "^0.525.0", + "motion": "^12.23.0", "nanoid": "^5.1.5", - "next": "^15.3.1", + "next": "^15.3.4", "next-themes": "^0.4.6", "nuqs": "^2.4.3", - "postgres": "^3.4.5", + "postgres": "^3.4.7", "react": "^19.1.0", - "react-day-picker": "8.10.1", + "react-day-picker": "9.7.0", "react-dom": "^19.1.0", - "react-hook-form": "^7.56.1", + "react-hook-form": "^7.59.0", "server-only": "^0.0.1", - "shadcn": "2.5.0", - "sonner": "^2.0.3", - "tailwind-merge": "^3.2.0", + "shadcn": "2.7.0", + "sonner": "^2.0.5", + "tailwind-merge": "^3.3.1", "vaul": "^1.1.2", - "zod": "^3.24.3" + "zod": "^3.25.71" }, "devDependencies": { - "@biomejs/biome": "^1.9.4", - "@faker-js/faker": "^9.7.0", - "@tailwindcss/postcss": "^4.1.4", + "@biomejs/biome": "^2.0.6", + "@faker-js/faker": "^9.9.0", + "@tailwindcss/postcss": "^4.1.11", "@total-typescript/ts-reset": "^0.6.1", - "@types/node": "^22.15.2", - "@types/react": "^19.1.2", - "@types/react-dom": "^19.1.2", + "@types/node": "^24.0.10", + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", "dotenv-cli": "^8.0.0", - "drizzle-kit": "^0.31.0", - "pg": "^8.15.5", - "postcss": "^8.5.3", + "drizzle-kit": "^0.31.4", + "pg": "^8.16.3", + "postcss": "^8.5.6", "rimraf": "^6.0.1", - "tailwindcss": "^4.1.4", - "tsx": "^4.19.3", - "tw-animate-css": "^1.2.8", + "tailwindcss": "^4.1.11", + "tsx": "^4.20.3", + "tw-animate-css": "^1.3.4", "typescript": "^5.8.3" }, "ct3aMetadata": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d45db977..f3914279 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,50 +21,50 @@ importers: specifier: ^3.2.2 version: 3.2.2(react@19.1.0) '@hookform/resolvers': - specifier: ^5.0.1 - version: 5.0.1(react-hook-form@7.56.1(react@19.1.0)) + specifier: ^5.1.1 + version: 5.1.1(react-hook-form@7.59.0(react@19.1.0)) '@radix-ui/react-checkbox': - specifier: ^1.2.3 - version: 1.2.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^1.3.2 + version: 1.3.2(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-dialog': - specifier: ^1.1.11 - version: 1.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^1.1.14 + version: 1.1.14(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-dropdown-menu': - specifier: ^2.1.12 - version: 2.1.12(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^2.1.15 + version: 2.1.15(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-label': - specifier: ^2.1.4 - version: 2.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^2.1.7 + version: 2.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-popover': - specifier: ^1.1.11 - version: 1.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^1.1.14 + version: 1.1.14(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-portal': - specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^1.1.9 + version: 1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-select': - specifier: ^2.2.2 - version: 2.2.2(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^2.2.5 + version: 2.2.5(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-separator': - specifier: ^1.1.4 - version: 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^1.1.7 + version: 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-slider': - specifier: ^1.3.2 - version: 1.3.2(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^1.3.5 + version: 1.3.5(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-slot': - specifier: ^1.2.0 - version: 1.2.0(@types/react@19.1.2)(react@19.1.0) + specifier: ^1.2.3 + version: 1.2.3(@types/react@19.1.8)(react@19.1.0) '@radix-ui/react-toggle': - specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^1.1.9 + version: 1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-toggle-group': - specifier: ^1.1.7 - version: 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^1.1.10 + version: 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-tooltip': - specifier: ^1.2.4 - version: 1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^1.2.7 + version: 1.2.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@t3-oss/env-nextjs': - specifier: ^0.13.0 - version: 0.13.0(arktype@2.1.20)(typescript@5.8.3)(zod@3.24.3) + specifier: ^0.13.8 + version: 0.13.8(arktype@2.1.20)(typescript@5.8.3)(zod@3.25.71) '@tanstack/react-table': specifier: ^8.21.3 version: 8.21.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -76,116 +76,116 @@ importers: version: 2.1.1 cmdk: specifier: ^1.1.1 - version: 1.1.1(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 1.1.1(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) date-fns: specifier: ^4.1.0 version: 4.1.0 drizzle-orm: - specifier: ^0.43.1 - version: 0.43.1(gel@2.0.1)(pg@8.15.5)(postgres@3.4.5) + specifier: ^0.44.2 + version: 0.44.2(gel@2.0.1)(pg@8.16.3)(postgres@3.4.7) export-to-csv: specifier: ^1.4.0 version: 1.4.0 geist: - specifier: ^1.3.1 - version: 1.3.1(next@15.3.1(@babel/core@7.26.10)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) + specifier: ^1.4.2 + version: 1.4.2(next@15.3.4(@babel/core@7.28.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) lucide-react: - specifier: ^0.503.0 - version: 0.503.0(react@19.1.0) + specifier: ^0.525.0 + version: 0.525.0(react@19.1.0) motion: - specifier: ^12.9.2 - version: 12.9.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^12.23.0 + version: 12.23.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) nanoid: specifier: ^5.1.5 version: 5.1.5 next: - specifier: ^15.3.1 - version: 15.3.1(@babel/core@7.26.10)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^15.3.4 + version: 15.3.4(@babel/core@7.28.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) nuqs: specifier: ^2.4.3 - version: 2.4.3(next@15.3.1(@babel/core@7.26.10)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) + version: 2.4.3(next@15.3.4(@babel/core@7.28.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) postgres: - specifier: ^3.4.5 - version: 3.4.5 + specifier: ^3.4.7 + version: 3.4.7 react: specifier: ^19.1.0 version: 19.1.0 react-day-picker: - specifier: 8.10.1 - version: 8.10.1(date-fns@4.1.0)(react@19.1.0) + specifier: 9.7.0 + version: 9.7.0(react@19.1.0) react-dom: specifier: ^19.1.0 version: 19.1.0(react@19.1.0) react-hook-form: - specifier: ^7.56.1 - version: 7.56.1(react@19.1.0) + specifier: ^7.59.0 + version: 7.59.0(react@19.1.0) server-only: specifier: ^0.0.1 version: 0.0.1 shadcn: - specifier: 2.5.0 - version: 2.5.0(@types/node@22.15.2)(typescript@5.8.3) + specifier: 2.7.0 + version: 2.7.0(@types/node@24.0.10)(typescript@5.8.3) sonner: - specifier: ^2.0.3 - version: 2.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^2.0.5 + version: 2.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) tailwind-merge: - specifier: ^3.2.0 - version: 3.2.0 + specifier: ^3.3.1 + version: 3.3.1 vaul: specifier: ^1.1.2 - version: 1.1.2(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 1.1.2(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) zod: - specifier: ^3.24.3 - version: 3.24.3 + specifier: ^3.25.71 + version: 3.25.71 devDependencies: '@biomejs/biome': - specifier: ^1.9.4 - version: 1.9.4 + specifier: ^2.0.6 + version: 2.0.6 '@faker-js/faker': - specifier: ^9.7.0 - version: 9.7.0 + specifier: ^9.9.0 + version: 9.9.0 '@tailwindcss/postcss': - specifier: ^4.1.4 - version: 4.1.4 + specifier: ^4.1.11 + version: 4.1.11 '@total-typescript/ts-reset': specifier: ^0.6.1 version: 0.6.1 '@types/node': - specifier: ^22.15.2 - version: 22.15.2 + specifier: ^24.0.10 + version: 24.0.10 '@types/react': - specifier: ^19.1.2 - version: 19.1.2 + specifier: ^19.1.8 + version: 19.1.8 '@types/react-dom': - specifier: ^19.1.2 - version: 19.1.2(@types/react@19.1.2) + specifier: ^19.1.6 + version: 19.1.6(@types/react@19.1.8) dotenv-cli: specifier: ^8.0.0 version: 8.0.0 drizzle-kit: - specifier: ^0.31.0 - version: 0.31.0 + specifier: ^0.31.4 + version: 0.31.4 pg: - specifier: ^8.15.5 - version: 8.15.5 + specifier: ^8.16.3 + version: 8.16.3 postcss: - specifier: ^8.5.3 - version: 8.5.3 + specifier: ^8.5.6 + version: 8.5.6 rimraf: specifier: ^6.0.1 version: 6.0.1 tailwindcss: - specifier: ^4.1.4 - version: 4.1.4 + specifier: ^4.1.11 + version: 4.1.11 tsx: - specifier: ^4.19.3 - version: 4.19.3 + specifier: ^4.20.3 + version: 4.20.3 tw-animate-css: - specifier: ^1.2.8 - version: 1.2.8 + specifier: ^1.3.4 + version: 1.3.4 typescript: specifier: ^5.8.3 version: 5.8.3 @@ -210,162 +210,166 @@ packages: '@ark/util@0.46.0': resolution: {integrity: sha512-JPy/NGWn/lvf1WmGCPw2VGpBg5utZraE84I7wli18EDF3p3zc/e9WolT35tINeZO3l7C77SjqRJeAUoT0CvMRg==} - '@babel/code-frame@7.26.2': - resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.26.8': - resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} + '@babel/compat-data@7.28.0': + resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} engines: {node: '>=6.9.0'} - '@babel/core@7.26.10': - resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} + '@babel/core@7.28.0': + resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} engines: {node: '>=6.9.0'} - '@babel/generator@7.27.0': - resolution: {integrity: sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==} + '@babel/generator@7.28.0': + resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.25.9': - resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.27.0': - resolution: {integrity: sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==} + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.27.0': - resolution: {integrity: sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==} + '@babel/helper-create-class-features-plugin@7.27.1': + resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-member-expression-to-functions@7.25.9': - resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.25.9': - resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.26.0': - resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.27.3': + resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.25.9': - resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.26.5': - resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} - '@babel/helper-replace-supers@7.26.5': - resolution: {integrity: sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==} + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-skip-transparent-expression-wrappers@7.25.9': - resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.25.9': - resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.25.9': - resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.25.9': - resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.27.0': - resolution: {integrity: sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==} + '@babel/helpers@7.27.6': + resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} engines: {node: '>=6.9.0'} - '@babel/parser@7.27.0': - resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} + '@babel/parser@7.28.0': + resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-syntax-typescript@7.25.9': - resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.27.0': - resolution: {integrity: sha512-fRGGjO2UEGPjvEcyAZXRXAS8AfdaQoq7HnxAbJoAoW10B9xOKesmmndJv+Sym2a+9FHWZ9KbyyLCe9s0Sn5jtg==} + '@babel/plugin-transform-typescript@7.28.0': + resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/template@7.27.0': - resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.27.0': - resolution: {integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==} + '@babel/traverse@7.28.0': + resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} engines: {node: '>=6.9.0'} - '@babel/types@7.27.0': - resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} + '@babel/types@7.28.0': + resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==} engines: {node: '>=6.9.0'} - '@biomejs/biome@1.9.4': - resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} + '@biomejs/biome@2.0.6': + resolution: {integrity: sha512-RRP+9cdh5qwe2t0gORwXaa27oTOiQRQvrFf49x2PA1tnpsyU7FIHX4ZOFMtBC4QNtyWsN7Dqkf5EDbg4X+9iqA==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@1.9.4': - resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} + '@biomejs/cli-darwin-arm64@2.0.6': + resolution: {integrity: sha512-AzdiNNjNzsE6LfqWyBvcL29uWoIuZUkndu+wwlXW13EKcBHbbKjNQEZIJKYDc6IL+p7bmWGx3v9ZtcRyIoIz5A==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@1.9.4': - resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} + '@biomejs/cli-darwin-x64@2.0.6': + resolution: {integrity: sha512-wJjjP4E7bO4WJmiQaLnsdXMa516dbtC6542qeRkyJg0MqMXP0fvs4gdsHhZ7p9XWTAmGIjZHFKXdsjBvKGIJJQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@1.9.4': - resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} + '@biomejs/cli-linux-arm64-musl@2.0.6': + resolution: {integrity: sha512-CVPEMlin3bW49sBqLBg2x016Pws7eUXA27XYDFlEtponD0luYjg2zQaMJ2nOqlkKG9fqzzkamdYxHdMDc2gZFw==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-arm64@1.9.4': - resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} + '@biomejs/cli-linux-arm64@2.0.6': + resolution: {integrity: sha512-ZSVf6TYo5rNMUHIW1tww+rs/krol7U5A1Is/yzWyHVZguuB0lBnIodqyFuwCNqG9aJGyk7xIMS8HG0qGUPz0SA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-x64-musl@1.9.4': - resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} + '@biomejs/cli-linux-x64-musl@2.0.6': + resolution: {integrity: sha512-mKHE/e954hR/hSnAcJSjkf4xGqZc/53Kh39HVW1EgO5iFi0JutTN07TSjEMg616julRtfSNJi0KNyxvc30Y4rQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-linux-x64@1.9.4': - resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} + '@biomejs/cli-linux-x64@2.0.6': + resolution: {integrity: sha512-geM1MkHTV1Kh2Cs/Xzot9BOF3WBacihw6bkEmxkz4nSga8B9/hWy5BDiOG3gHDGIBa8WxT0nzsJs2f/hPqQIQw==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-win32-arm64@1.9.4': - resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} + '@biomejs/cli-win32-arm64@2.0.6': + resolution: {integrity: sha512-290V4oSFoKaprKE1zkYVsDfAdn0An5DowZ+GIABgjoq1ndhvNxkJcpxPsiYtT7slbVe3xmlT0ncdfOsN7KruzA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@1.9.4': - resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} + '@biomejs/cli-win32-x64@2.0.6': + resolution: {integrity: sha512-bfM1Bce0d69Ao7pjTjUS+AWSZ02+5UHdiAP85Th8e9yV5xzw6JrHXbL5YWlcEKQ84FIZMdDc7ncuti1wd2sdbw==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -379,6 +383,9 @@ packages: '@bundled-es-modules/tough-cookie@0.1.6': resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} + '@date-fns/tz@1.2.0': + resolution: {integrity: sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==} + '@dnd-kit/accessibility@3.1.1': resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==} peerDependencies: @@ -421,8 +428,8 @@ packages: resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} deprecated: 'Merged into tsx: https://tsx.is' - '@esbuild/aix-ppc64@0.25.3': - resolution: {integrity: sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==} + '@esbuild/aix-ppc64@0.25.5': + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -433,8 +440,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.3': - resolution: {integrity: sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==} + '@esbuild/android-arm64@0.25.5': + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -445,8 +452,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.3': - resolution: {integrity: sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==} + '@esbuild/android-arm@0.25.5': + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -457,8 +464,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.3': - resolution: {integrity: sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==} + '@esbuild/android-x64@0.25.5': + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -469,8 +476,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.3': - resolution: {integrity: sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==} + '@esbuild/darwin-arm64@0.25.5': + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -481,8 +488,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.3': - resolution: {integrity: sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==} + '@esbuild/darwin-x64@0.25.5': + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -493,8 +500,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.3': - resolution: {integrity: sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==} + '@esbuild/freebsd-arm64@0.25.5': + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -505,8 +512,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.3': - resolution: {integrity: sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==} + '@esbuild/freebsd-x64@0.25.5': + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -517,8 +524,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.3': - resolution: {integrity: sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==} + '@esbuild/linux-arm64@0.25.5': + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -529,8 +536,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.3': - resolution: {integrity: sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==} + '@esbuild/linux-arm@0.25.5': + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -541,8 +548,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.3': - resolution: {integrity: sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==} + '@esbuild/linux-ia32@0.25.5': + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -553,8 +560,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.3': - resolution: {integrity: sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==} + '@esbuild/linux-loong64@0.25.5': + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -565,8 +572,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.3': - resolution: {integrity: sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==} + '@esbuild/linux-mips64el@0.25.5': + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -577,8 +584,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.3': - resolution: {integrity: sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==} + '@esbuild/linux-ppc64@0.25.5': + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -589,8 +596,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.3': - resolution: {integrity: sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==} + '@esbuild/linux-riscv64@0.25.5': + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -601,8 +608,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.3': - resolution: {integrity: sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==} + '@esbuild/linux-s390x@0.25.5': + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -613,14 +620,14 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.3': - resolution: {integrity: sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==} + '@esbuild/linux-x64@0.25.5': + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.3': - resolution: {integrity: sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==} + '@esbuild/netbsd-arm64@0.25.5': + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -631,14 +638,14 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.3': - resolution: {integrity: sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==} + '@esbuild/netbsd-x64@0.25.5': + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.3': - resolution: {integrity: sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==} + '@esbuild/openbsd-arm64@0.25.5': + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -649,8 +656,8 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.3': - resolution: {integrity: sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==} + '@esbuild/openbsd-x64@0.25.5': + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -661,8 +668,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.3': - resolution: {integrity: sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==} + '@esbuild/sunos-x64@0.25.5': + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -673,8 +680,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.3': - resolution: {integrity: sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==} + '@esbuild/win32-arm64@0.25.5': + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -685,8 +692,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.3': - resolution: {integrity: sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==} + '@esbuild/win32-ia32@0.25.5': + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -697,44 +704,44 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.25.3': - resolution: {integrity: sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==} + '@esbuild/win32-x64@0.25.5': + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@faker-js/faker@9.7.0': - resolution: {integrity: sha512-aozo5vqjCmDoXLNUJarFZx2IN/GgGaogY4TMJ6so/WLZOWpSV7fvj2dmrV6sEAnUm1O7aCrhTibjpzeDFgNqbg==} + '@faker-js/faker@9.9.0': + resolution: {integrity: sha512-OEl393iCOoo/z8bMezRlJu+GlRGlsKbUAN7jKB6LhnKoqKve5DXRpalbItIIcwnCjs1k/FOPjFzcA6Qn+H+YbA==} engines: {node: '>=18.0.0', npm: '>=9.0.0'} - '@floating-ui/core@1.6.9': - resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} + '@floating-ui/core@1.7.2': + resolution: {integrity: sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==} - '@floating-ui/dom@1.6.13': - resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} + '@floating-ui/dom@1.7.2': + resolution: {integrity: sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==} - '@floating-ui/react-dom@2.1.2': - resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} + '@floating-ui/react-dom@2.1.4': + resolution: {integrity: sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' - '@floating-ui/utils@0.2.9': - resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} - '@hookform/resolvers@5.0.1': - resolution: {integrity: sha512-u/+Jp83luQNx9AdyW2fIPGY6Y7NG68eN2ZW8FOJYL+M0i4s49+refdJdOp/A9n9HFQtQs3HIDHQvX3ZET2o7YA==} + '@hookform/resolvers@5.1.1': + resolution: {integrity: sha512-J/NVING3LMAEvexJkyTLjruSm7aOFx7QX21pzkiJfMoNG0wl5aFEjLTl7ay7IQb9EWY6AkrBy7tHL2Alijpdcg==} peerDependencies: react-hook-form: ^7.55.0 - '@img/sharp-darwin-arm64@0.34.1': - resolution: {integrity: sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==} + '@img/sharp-darwin-arm64@0.34.2': + resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.34.1': - resolution: {integrity: sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==} + '@img/sharp-darwin-x64@0.34.2': + resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] @@ -784,61 +791,67 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-linux-arm64@0.34.1': - resolution: {integrity: sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==} + '@img/sharp-linux-arm64@0.34.2': + resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm@0.34.1': - resolution: {integrity: sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==} + '@img/sharp-linux-arm@0.34.2': + resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - '@img/sharp-linux-s390x@0.34.1': - resolution: {integrity: sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==} + '@img/sharp-linux-s390x@0.34.2': + resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] - '@img/sharp-linux-x64@0.34.1': - resolution: {integrity: sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==} + '@img/sharp-linux-x64@0.34.2': + resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.1': - resolution: {integrity: sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==} + '@img/sharp-linuxmusl-arm64@0.34.2': + resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-x64@0.34.1': - resolution: {integrity: sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==} + '@img/sharp-linuxmusl-x64@0.34.2': + resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.34.1': - resolution: {integrity: sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==} + '@img/sharp-wasm32@0.34.2': + resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-win32-ia32@0.34.1': - resolution: {integrity: sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==} + '@img/sharp-win32-arm64@0.34.2': + resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.2': + resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.34.1': - resolution: {integrity: sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==} + '@img/sharp-win32-x64@0.34.2': + resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] - '@inquirer/confirm@5.1.9': - resolution: {integrity: sha512-NgQCnHqFTjF7Ys2fsqK2WtnA8X1kHyInyG+nMIuHowVTIgIuS10T4AznI/PvbqSpJqjCUqNBlKGh1v3bwLFL4w==} + '@inquirer/confirm@5.1.13': + resolution: {integrity: sha512-EkCtvp67ICIVVzjsquUiVSd+V5HRGOGQfsqA4E4vMWhYnB7InUL0pa0TIWt1i+OfP16Gkds8CdIu6yGZwOM1Yw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -846,8 +859,8 @@ packages: '@types/node': optional: true - '@inquirer/core@10.1.10': - resolution: {integrity: sha512-roDaKeY1PYY0aCqhRmXihrHjoSW2A00pV3Ke5fTpMCkzcGF64R8e0lw3dK+eLEHwS4vB5RnW1wuQmvzoRul8Mw==} + '@inquirer/core@10.1.14': + resolution: {integrity: sha512-Ma+ZpOJPewtIYl6HZHZckeX1STvDnHTCB2GVINNUlSEn2Am6LddWwfPkIGY0IUFVjUUrr/93XlBwTK6mfLjf0A==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -855,12 +868,12 @@ packages: '@types/node': optional: true - '@inquirer/figures@1.0.11': - resolution: {integrity: sha512-eOg92lvrn/aRUqbxRyvpEWnrvRuTYRifixHkYVpJiygTgVSBIHDqLh0SrMQXkafvULg3ck11V7xvR+zcgvpHFw==} + '@inquirer/figures@1.0.12': + resolution: {integrity: sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==} engines: {node: '>=18'} - '@inquirer/type@3.0.6': - resolution: {integrity: sha512-/mKVCtVpyBu3IDarv0G+59KC4stsD5mDsGpYh+GKs1NZT88Jh52+cuoA1AtLk2Q0r/quNl+1cSUyLRHBFeD0XA==} + '@inquirer/type@3.0.7': + resolution: {integrity: sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -868,79 +881,90 @@ packages: '@types/node': optional: true + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@jridgewell/gen-mapping@0.3.8': - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} - engines: {node: '>=6.0.0'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@jridgewell/gen-mapping@0.3.12': + resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.5.4': + resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/trace-mapping@0.3.29': + resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@modelcontextprotocol/sdk@1.13.3': + resolution: {integrity: sha512-bGwA78F/U5G2jrnsdRkPY3IwIwZeWUEfb5o764b79lb0rJmMT76TLwKhdNZOWakOQtedYefwIR4emisEMvInKA==} + engines: {node: '>=18'} - '@mswjs/interceptors@0.37.6': - resolution: {integrity: sha512-wK+5pLK5XFmgtH3aQ2YVvA3HohS3xqV/OxuVOdNx9Wpnz7VE/fnC+e1A7ln6LFYeck7gOJ/dsZV6OLplOtAJ2w==} + '@mswjs/interceptors@0.39.2': + resolution: {integrity: sha512-RuzCup9Ct91Y7V79xwCb146RaBRHZ7NBbrIUySumd1rpKqHL5OonaqrGIbug5hNwP/fRyxFMA6ISgw4FTtYFYg==} engines: {node: '>=18'} - '@next/env@15.3.1': - resolution: {integrity: sha512-cwK27QdzrMblHSn9DZRV+DQscHXRuJv6MydlJRpFSqJWZrTYMLzKDeyueJNN9MGd8NNiUKzDQADAf+dMLXX7YQ==} + '@next/env@15.3.4': + resolution: {integrity: sha512-ZkdYzBseS6UjYzz6ylVKPOK+//zLWvD6Ta+vpoye8cW11AjiQjGYVibF0xuvT4L0iJfAPfZLFidaEzAOywyOAQ==} - '@next/swc-darwin-arm64@15.3.1': - resolution: {integrity: sha512-hjDw4f4/nla+6wysBL07z52Gs55Gttp5Bsk5/8AncQLJoisvTBP0pRIBK/B16/KqQyH+uN4Ww8KkcAqJODYH3w==} + '@next/swc-darwin-arm64@15.3.4': + resolution: {integrity: sha512-z0qIYTONmPRbwHWvpyrFXJd5F9YWLCsw3Sjrzj2ZvMYy9NPQMPZ1NjOJh4ojr4oQzcGYwgJKfidzehaNa1BpEg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@15.3.1': - resolution: {integrity: sha512-q+aw+cJ2ooVYdCEqZVk+T4Ni10jF6Fo5DfpEV51OupMaV5XL6pf3GCzrk6kSSZBsMKZtVC1Zm/xaNBFpA6bJ2g==} + '@next/swc-darwin-x64@15.3.4': + resolution: {integrity: sha512-Z0FYJM8lritw5Wq+vpHYuCIzIlEMjewG2aRkc3Hi2rcbULknYL/xqfpBL23jQnCSrDUGAo/AEv0Z+s2bff9Zkw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@15.3.1': - resolution: {integrity: sha512-wBQ+jGUI3N0QZyWmmvRHjXjTWFy8o+zPFLSOyAyGFI94oJi+kK/LIZFJXeykvgXUk1NLDAEFDZw/NVINhdk9FQ==} + '@next/swc-linux-arm64-gnu@15.3.4': + resolution: {integrity: sha512-l8ZQOCCg7adwmsnFm8m5q9eIPAHdaB2F3cxhufYtVo84pymwKuWfpYTKcUiFcutJdp9xGHC+F1Uq3xnFU1B/7g==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.3.1': - resolution: {integrity: sha512-IIxXEXRti/AulO9lWRHiCpUUR8AR/ZYLPALgiIg/9ENzMzLn3l0NSxVdva7R/VDcuSEBo0eGVCe3evSIHNz0Hg==} + '@next/swc-linux-arm64-musl@15.3.4': + resolution: {integrity: sha512-wFyZ7X470YJQtpKot4xCY3gpdn8lE9nTlldG07/kJYexCUpX1piX+MBfZdvulo+t1yADFVEuzFfVHfklfEx8kw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@15.3.1': - resolution: {integrity: sha512-bfI4AMhySJbyXQIKH5rmLJ5/BP7bPwuxauTvVEiJ/ADoddaA9fgyNNCcsbu9SlqfHDoZmfI6g2EjzLwbsVTr5A==} + '@next/swc-linux-x64-gnu@15.3.4': + resolution: {integrity: sha512-gEbH9rv9o7I12qPyvZNVTyP/PWKqOp8clvnoYZQiX800KkqsaJZuOXkWgMa7ANCCh/oEN2ZQheh3yH8/kWPSEg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.3.1': - resolution: {integrity: sha512-FeAbR7FYMWR+Z+M5iSGytVryKHiAsc0x3Nc3J+FD5NVbD5Mqz7fTSy8CYliXinn7T26nDMbpExRUI/4ekTvoiA==} + '@next/swc-linux-x64-musl@15.3.4': + resolution: {integrity: sha512-Cf8sr0ufuC/nu/yQ76AnarbSAXcwG/wj+1xFPNbyNo8ltA6kw5d5YqO8kQuwVIxk13SBdtgXrNyom3ZosHAy4A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@15.3.1': - resolution: {integrity: sha512-yP7FueWjphQEPpJQ2oKmshk/ppOt+0/bB8JC8svPUZNy0Pi3KbPx2Llkzv1p8CoQa+D2wknINlJpHf3vtChVBw==} + '@next/swc-win32-arm64-msvc@15.3.4': + resolution: {integrity: sha512-ay5+qADDN3rwRbRpEhTOreOn1OyJIXS60tg9WMYTWCy3fB6rGoyjLVxc4dR9PYjEdR2iDYsaF5h03NA+XuYPQQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@15.3.1': - resolution: {integrity: sha512-3PMvF2zRJAifcRNni9uMk/gulWfWS+qVI/pagd+4yLF5bcXPZPPH2xlYRYOsUjmCJOXSTAC2PjRzbhsRzR2fDQ==} + '@next/swc-win32-x64-msvc@15.3.4': + resolution: {integrity: sha512-4kDt31Bc9DGyYs41FTL1/kNpDeHyha2TC0j5sRRoKCyrhNcfZ/nRQkAUlF27mETwm8QyHqIjHJitfcza2Iykfg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -975,8 +999,8 @@ packages: '@radix-ui/primitive@1.1.2': resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} - '@radix-ui/react-arrow@1.1.4': - resolution: {integrity: sha512-qz+fxrqgNxG0dYew5l7qR3c7wdgRu1XVUHGnGYX7rg5HM4p9SWaRmJwfgR3J0SgyUKayLmzQIun+N6rWRgiRKw==} + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -988,8 +1012,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-checkbox@1.2.3': - resolution: {integrity: sha512-pHVzDYsnaDmBlAuwim45y3soIN8H4R7KbkSVirGhXO+R/kO2OLCe0eucUEbddaTcdMHHdzcIGHtZSMSQlA+apw==} + '@radix-ui/react-checkbox@1.3.2': + resolution: {integrity: sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1001,8 +1025,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-collection@1.1.4': - resolution: {integrity: sha512-cv4vSf7HttqXilDnAnvINd53OTl1/bjUYVZrkFnA7nwmY9Ob2POUy0WY0sfqBAe1s5FyKsyceQlqiEGPYNTadg==} + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1032,8 +1056,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-dialog@1.1.11': - resolution: {integrity: sha512-yI7S1ipkP5/+99qhSI6nthfo/tR6bL6Zgxi/+1UO6qPa6UeM6nlafWcQ65vB4rU2XjgjMfMhI3k9Y5MztA62VQ==} + '@radix-ui/react-dialog@1.1.14': + resolution: {integrity: sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1054,8 +1078,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-dismissable-layer@1.1.7': - resolution: {integrity: sha512-j5+WBUdhccJsmH5/H0K6RncjDtoALSEr6jbkaZu+bjw6hOPOhHycr6vEUujl+HBK8kjUfWcoCJXxP6e4lUlMZw==} + '@radix-ui/react-dismissable-layer@1.1.10': + resolution: {integrity: sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1067,8 +1091,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dropdown-menu@2.1.12': - resolution: {integrity: sha512-VJoMs+BWWE7YhzEQyVwvF9n22Eiyr83HotCVrMQzla/OwRovXCgah7AcaEr4hMNj4gJxSdtIbcHGvmJXOoJVHA==} + '@radix-ui/react-dropdown-menu@2.1.15': + resolution: {integrity: sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1089,8 +1113,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-focus-scope@1.1.4': - resolution: {integrity: sha512-r2annK27lIW5w9Ho5NyQgqs0MmgZSTIKXWpVCJaLC1q2kZrZkcqnmHkCHMEmv8XLvsLlurKMPT+kbKkRkm/xVA==} + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1111,8 +1135,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-label@2.1.4': - resolution: {integrity: sha512-wy3dqizZnZVV4ja0FNnUhIWNwWdoldXrneEyUcVtLYDAt8ovGS4ridtMAOGgXBBIfggL4BOveVWsjXDORdGEQg==} + '@radix-ui/react-label@2.1.7': + resolution: {integrity: sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1124,8 +1148,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-menu@2.1.12': - resolution: {integrity: sha512-+qYq6LfbiGo97Zz9fioX83HCiIYYFNs8zAsVCMQrIakoNYylIzWuoD/anAD3UzvvR6cnswmfRFJFq/zYYq/k7Q==} + '@radix-ui/react-menu@2.1.15': + resolution: {integrity: sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1137,8 +1161,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-popover@1.1.11': - resolution: {integrity: sha512-yFMfZkVA5G3GJnBgb2PxrrcLKm1ZLWXrbYVgdyTl//0TYEIHS9LJbnyz7WWcZ0qCq7hIlJZpRtxeSeIG5T5oJw==} + '@radix-ui/react-popover@1.1.14': + resolution: {integrity: sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1150,8 +1174,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-popper@1.2.4': - resolution: {integrity: sha512-3p2Rgm/a1cK0r/UVkx5F/K9v/EplfjAeIFCGOPYPO4lZ0jtg4iSQXt/YGTSLWaf4x7NG6Z4+uKFcylcTZjeqDA==} + '@radix-ui/react-popper@1.2.7': + resolution: {integrity: sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1163,8 +1187,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-portal@1.1.6': - resolution: {integrity: sha512-XmsIl2z1n/TsYFLIdYam2rmFwf9OC/Sh2avkbmVMDuBZIe7hSpM0cYnWPAo7nHOVx8zTuwDZGByfcqLdnzp3Vw==} + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1189,8 +1213,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-primitive@2.1.0': - resolution: {integrity: sha512-/J/FhLdK0zVcILOwt5g+dH4KnkonCtkVJsa2G6JmvbbtZfBEI1gMsO3QMjseL4F/SwfAMt1Vc/0XKYKq+xJ1sw==} + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1202,8 +1226,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-roving-focus@1.1.7': - resolution: {integrity: sha512-C6oAg451/fQT3EGbWHbCQjYTtbyjNO1uzQgMzwyivcHT3GKNEmu1q3UuREhN+HzHAVtv3ivMVK08QlC+PkYw9Q==} + '@radix-ui/react-roving-focus@1.1.10': + resolution: {integrity: sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1215,8 +1239,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-select@2.2.2': - resolution: {integrity: sha512-HjkVHtBkuq+r3zUAZ/CvNWUGKPfuicGDbgtZgiQuFmNcV5F+Tgy24ep2nsAW2nFgvhGPJVqeBZa6KyVN0EyrBA==} + '@radix-ui/react-select@2.2.5': + resolution: {integrity: sha512-HnMTdXEVuuyzx63ME0ut4+sEMYW6oouHWNGUZc7ddvUWIcfCva/AMoqEW/3wnEllriMWBa0RHspCYnfCWJQYmA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1228,8 +1252,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-separator@1.1.4': - resolution: {integrity: sha512-2fTm6PSiUm8YPq9W0E4reYuv01EE3aFSzt8edBiXqPHshF8N9+Kymt/k0/R+F3dkY5lQyB/zPtrP82phskLi7w==} + '@radix-ui/react-separator@1.1.7': + resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1241,8 +1265,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-slider@1.3.2': - resolution: {integrity: sha512-oQnqfgSiYkxZ1MrF6672jw2/zZvpB+PJsrIc3Zm1zof1JHf/kj7WhmROw7JahLfOwYQ5/+Ip0rFORgF1tjSiaQ==} + '@radix-ui/react-slider@1.3.5': + resolution: {integrity: sha512-rkfe2pU2NBAYfGaxa3Mqosi7VZEWX5CxKaanRv0vZd4Zhl9fvQrg0VM93dv3xGLGfrHuoTRF3JXH8nb9g+B3fw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1254,8 +1278,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-slot@1.2.0': - resolution: {integrity: sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==} + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -1263,8 +1287,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-toggle-group@1.1.7': - resolution: {integrity: sha512-GRaPJhxrRSOqAcmcX3MwRL/SZACkoYdmoY9/sg7Bd5DhBYsB2t4co0NxTvVW8H7jUmieQDQwRtUlZ5Ta8UbgJA==} + '@radix-ui/react-toggle-group@1.1.10': + resolution: {integrity: sha512-kiU694Km3WFLTC75DdqgM/3Jauf3rD9wxeS9XtyWFKsBUeZA337lC+6uUazT7I1DhanZ5gyD5Stf8uf2dbQxOQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1276,8 +1300,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-toggle@1.1.6': - resolution: {integrity: sha512-3SeJxKeO3TO1zVw1Nl++Cp0krYk6zHDHMCUXXVkosIzl6Nxcvb07EerQpyD2wXQSJ5RZajrYAmPaydU8Hk1IyQ==} + '@radix-ui/react-toggle@1.1.9': + resolution: {integrity: sha512-ZoFkBBz9zv9GWer7wIjvdRxmh2wyc2oKWw6C6CseWd6/yq1DK/l5lJ+wnsmFwJZbBYqr02mrf8A2q/CVCuM3ZA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1289,8 +1313,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-tooltip@1.2.4': - resolution: {integrity: sha512-DyW8VVeeMSSLFvAmnVnCwvI3H+1tpJFHT50r+tdOoMse9XqYDBCcyux8u3G2y+LOpt7fPQ6KKH0mhs+ce1+Z5w==} + '@radix-ui/react-tooltip@1.2.7': + resolution: {integrity: sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1374,8 +1398,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-visually-hidden@1.2.0': - resolution: {integrity: sha512-rQj0aAWOpCdCMRbI6pLQm8r7S2BM3YhTa0SzOYD55k+hJA8oo9J+H+9wLM9oMlZWOX/wJWPTzfDfmZkf7LvCfg==} + '@radix-ui/react-visually-hidden@1.2.3': + resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1399,14 +1423,16 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@t3-oss/env-core@0.13.0': - resolution: {integrity: sha512-bV7LAvwoeyigLXyjBnlgbKb8S9l+E29uSzWtU1GJYuKMQ6qF9dvFbjakkgoxR+tXFoxg7aGbg8DdEfwNihvF8Q==} + '@t3-oss/env-core@0.13.8': + resolution: {integrity: sha512-L1inmpzLQyYu4+Q1DyrXsGJYCXbtXjC4cICw1uAKv0ppYPQv656lhZPU91Qd1VS6SO/bou1/q5ufVzBGbNsUpw==} peerDependencies: arktype: ^2.1.0 typescript: '>=5.0.0' valibot: ^1.0.0-beta.7 || ^1.0.0 zod: ^3.24.0 || ^4.0.0-beta.0 peerDependenciesMeta: + arktype: + optional: true typescript: optional: true valibot: @@ -1414,13 +1440,16 @@ packages: zod: optional: true - '@t3-oss/env-nextjs@0.13.0': - resolution: {integrity: sha512-l+3H7w1rezfPhnfi5DPKeoLaMhsG8Os2WtoSA1Sq/+X+szccidazNmTAGKjp4v03IuUz4bsxYvU9DzQAX7atkg==} + '@t3-oss/env-nextjs@0.13.8': + resolution: {integrity: sha512-QmTLnsdQJ8BiQad2W2nvV6oUpH4oMZMqnFEjhVpzU0h3sI9hn8zb8crjWJ1Amq453mGZs6A4v4ihIeBFDOrLeQ==} peerDependencies: + arktype: ^2.1.0 typescript: '>=5.0.0' valibot: ^1.0.0-beta.7 || ^1.0.0 zod: ^3.24.0 || ^4.0.0-beta.0 peerDependenciesMeta: + arktype: + optional: true typescript: optional: true valibot: @@ -1428,65 +1457,65 @@ packages: zod: optional: true - '@tailwindcss/node@4.1.4': - resolution: {integrity: sha512-MT5118zaiO6x6hNA04OWInuAiP1YISXql8Z+/Y8iisV5nuhM8VXlyhRuqc2PEviPszcXI66W44bCIk500Oolhw==} + '@tailwindcss/node@4.1.11': + resolution: {integrity: sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==} - '@tailwindcss/oxide-android-arm64@4.1.4': - resolution: {integrity: sha512-xMMAe/SaCN/vHfQYui3fqaBDEXMu22BVwQ33veLc8ep+DNy7CWN52L+TTG9y1K397w9nkzv+Mw+mZWISiqhmlA==} + '@tailwindcss/oxide-android-arm64@4.1.11': + resolution: {integrity: sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.1.4': - resolution: {integrity: sha512-JGRj0SYFuDuAGilWFBlshcexev2hOKfNkoX+0QTksKYq2zgF9VY/vVMq9m8IObYnLna0Xlg+ytCi2FN2rOL0Sg==} + '@tailwindcss/oxide-darwin-arm64@4.1.11': + resolution: {integrity: sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.1.4': - resolution: {integrity: sha512-sdDeLNvs3cYeWsEJ4H1DvjOzaGios4QbBTNLVLVs0XQ0V95bffT3+scptzYGPMjm7xv4+qMhCDrkHwhnUySEzA==} + '@tailwindcss/oxide-darwin-x64@4.1.11': + resolution: {integrity: sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.1.4': - resolution: {integrity: sha512-VHxAqxqdghM83HslPhRsNhHo91McsxRJaEnShJOMu8mHmEj9Ig7ToHJtDukkuLWLzLboh2XSjq/0zO6wgvykNA==} + '@tailwindcss/oxide-freebsd-x64@4.1.11': + resolution: {integrity: sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4': - resolution: {integrity: sha512-OTU/m/eV4gQKxy9r5acuesqaymyeSCnsx1cFto/I1WhPmi5HDxX1nkzb8KYBiwkHIGg7CTfo/AcGzoXAJBxLfg==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11': + resolution: {integrity: sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.1.4': - resolution: {integrity: sha512-hKlLNvbmUC6z5g/J4H+Zx7f7w15whSVImokLPmP6ff1QqTVE+TxUM9PGuNsjHvkvlHUtGTdDnOvGNSEUiXI1Ww==} + '@tailwindcss/oxide-linux-arm64-gnu@4.1.11': + resolution: {integrity: sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.1.4': - resolution: {integrity: sha512-X3As2xhtgPTY/m5edUtddmZ8rCruvBvtxYLMw9OsZdH01L2gS2icsHRwxdU0dMItNfVmrBezueXZCHxVeeb7Aw==} + '@tailwindcss/oxide-linux-arm64-musl@4.1.11': + resolution: {integrity: sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.1.4': - resolution: {integrity: sha512-2VG4DqhGaDSmYIu6C4ua2vSLXnJsb/C9liej7TuSO04NK+JJJgJucDUgmX6sn7Gw3Cs5ZJ9ZLrnI0QRDOjLfNQ==} + '@tailwindcss/oxide-linux-x64-gnu@4.1.11': + resolution: {integrity: sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.1.4': - resolution: {integrity: sha512-v+mxVgH2kmur/X5Mdrz9m7TsoVjbdYQT0b4Z+dr+I4RvreCNXyCFELZL/DO0M1RsidZTrm6O1eMnV6zlgEzTMQ==} + '@tailwindcss/oxide-linux-x64-musl@4.1.11': + resolution: {integrity: sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-wasm32-wasi@4.1.4': - resolution: {integrity: sha512-2TLe9ir+9esCf6Wm+lLWTMbgklIjiF0pbmDnwmhR9MksVOq+e8aP3TSsXySnBDDvTTVd/vKu1aNttEGj3P6l8Q==} + '@tailwindcss/oxide-wasm32-wasi@4.1.11': + resolution: {integrity: sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -1497,24 +1526,24 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.1.4': - resolution: {integrity: sha512-VlnhfilPlO0ltxW9/BgfLI5547PYzqBMPIzRrk4W7uupgCt8z6Trw/tAj6QUtF2om+1MH281Pg+HHUJoLesmng==} + '@tailwindcss/oxide-win32-arm64-msvc@4.1.11': + resolution: {integrity: sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.1.4': - resolution: {integrity: sha512-+7S63t5zhYjslUGb8NcgLpFXD+Kq1F/zt5Xv5qTv7HaFTG/DHyHD9GA6ieNAxhgyA4IcKa/zy7Xx4Oad2/wuhw==} + '@tailwindcss/oxide-win32-x64-msvc@4.1.11': + resolution: {integrity: sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.1.4': - resolution: {integrity: sha512-p5wOpXyOJx7mKh5MXh5oKk+kqcz8T+bA3z/5VWWeQwFrmuBItGwz8Y2CHk/sJ+dNb9B0nYFfn0rj/cKHZyjahQ==} + '@tailwindcss/oxide@4.1.11': + resolution: {integrity: sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==} engines: {node: '>= 10'} - '@tailwindcss/postcss@4.1.4': - resolution: {integrity: sha512-bjV6sqycCEa+AQSt2Kr7wpGF1bOZJ5wsqnLEkqSbM/JEHxx/yhMH8wHmdkPyApF9xhHeMSwnnkDUUMMM/hYnXw==} + '@tailwindcss/postcss@4.1.11': + resolution: {integrity: sha512-q/EAIIpF6WpLhKEuQSEVMZNMIY8KhWoAemZ9eylNAih9jxMGAYPPWBn3I9QL/2jZ+e7OEz/tZkX5HwbBR4HohA==} '@tanstack/react-table@8.21.3': resolution: {integrity: sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww==} @@ -1536,27 +1565,34 @@ packages: '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - '@types/node@22.15.2': - resolution: {integrity: sha512-uKXqKN9beGoMdBfcaTY1ecwz6ctxuJAcUlwE55938g0ZJ8lRxwAZqRz2AJ4pzpt5dHdTPMB863UZ0ESiFUcP7A==} + '@types/node@24.0.10': + resolution: {integrity: sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==} - '@types/react-dom@19.1.2': - resolution: {integrity: sha512-XGJkWF41Qq305SKWEILa1O8vzhb3aOo3ogBlSmiqNko/WmRb6QIaweuZCXjKygVDXpzXb5wyxKTSOsmkuqj+Qw==} + '@types/react-dom@19.1.6': + resolution: {integrity: sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==} peerDependencies: '@types/react': ^19.0.0 - '@types/react@19.1.2': - resolution: {integrity: sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==} + '@types/react@19.1.8': + resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==} - '@types/statuses@2.0.5': - resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==} + '@types/statuses@2.0.6': + resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + agent-base@7.1.3: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -1580,8 +1616,8 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-hidden@1.2.4: - resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} arktype@2.1.20: @@ -1600,15 +1636,19 @@ packages: bl@5.1.0: resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + body-parser@2.2.0: + resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + engines: {node: '>=18'} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.24.4: - resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + browserslist@4.25.1: + resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1622,17 +1662,33 @@ packages: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001715: - resolution: {integrity: sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==} + caniuse-lite@1.0.30001726: + resolution: {integrity: sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==} chalk@5.4.1: resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -1690,13 +1746,29 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} + content-disposition@1.0.0: + resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + cosmiconfig@8.3.6: resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} engines: {node: '>=14'} @@ -1717,11 +1789,14 @@ packages: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} + date-fns-jalali@4.1.0-0: + resolution: {integrity: sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==} + date-fns@4.1.0: resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1736,6 +1811,10 @@ packages: defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + detect-libc@2.0.4: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} @@ -1755,16 +1834,16 @@ packages: resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} engines: {node: '>=12'} - dotenv@16.5.0: - resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} - drizzle-kit@0.31.0: - resolution: {integrity: sha512-pcKVT+GbfPA+bUovPIilgVOoq+onNBo/YQBG86sf3/GFHkN6lRJPm1l7dKN0IMAk57RQoIm4GUllRrasLlcaSg==} + drizzle-kit@0.31.4: + resolution: {integrity: sha512-tCPWVZWZqWVx2XUsVpJRnH9Mx0ClVOf5YUHerZ5so1OKSlqww4zy1R5ksEdGRcO3tM3zj0PYN6V48TbQCL1RfA==} hasBin: true - drizzle-orm@0.43.1: - resolution: {integrity: sha512-dUcDaZtE/zN4RV/xqGrVSMpnEczxd5cIaoDeor7Zst9wOe/HzC/7eAaulywWGYXdDEc9oBPMjayVEDg0ziTLJA==} + drizzle-orm@0.44.2: + resolution: {integrity: sha512-zGAqBzWWkVSFjZpwPOrmCrgO++1kZ5H/rZ4qTGeGOe18iXGVJWf3WPfHOVwFIbmi8kHjfJstC6rJomzGx8g/dQ==} peerDependencies: '@aws-sdk/client-rds-data': '>=3' '@cloudflare/workers-types': '>=4' @@ -1780,6 +1859,7 @@ packages: '@types/better-sqlite3': '*' '@types/pg': '*' '@types/sql.js': '*' + '@upstash/redis': '>=1.34.7' '@vercel/postgres': '>=0.8.0' '@xata.io/client': '*' better-sqlite3: '>=7' @@ -1823,6 +1903,8 @@ packages: optional: true '@types/sql.js': optional: true + '@upstash/redis': + optional: true '@vercel/postgres': optional: true '@xata.io/client': @@ -1852,11 +1934,18 @@ packages: sqlite3: optional: true + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.5.143: - resolution: {integrity: sha512-QqklJMOFBMqe46k8iIOwA9l2hz57V2OKMmP5eSWcUvwx+mASAsbU+wkF1pHjn9ZVSBPrsYWr4/W/95y5SwYg2g==} + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.179: + resolution: {integrity: sha512-UWKi/EbBopgfFsc5k61wFpV7WrnnSlSzW/e2XcBmS6qKYTivZlLtoll5/rdqRTxGglGHkmkW0j0pFNJG10EUIQ==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1864,8 +1953,12 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - enhanced-resolve@5.18.1: - resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + enhanced-resolve@5.18.2: + resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} engines: {node: '>=10.13.0'} env-paths@3.0.0: @@ -1875,6 +1968,18 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + esbuild-register@3.6.0: resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} peerDependencies: @@ -1885,8 +1990,8 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.25.3: - resolution: {integrity: sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==} + esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} engines: {node: '>=18'} hasBin: true @@ -1894,11 +1999,26 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventsource-parser@3.0.3: + resolution: {integrity: sha512-nVpZkTMM9rF6AQ9gPJpFsNAMt48wIzB5TQgiTLdHiuO8XEDhUgZEhqKlZWXbIzo9VmJ/HvysHqEaVeD5v9TPvA==} + engines: {node: '>=20.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + execa@7.2.0: resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} @@ -1907,10 +2027,26 @@ packages: resolution: {integrity: sha512-6CX17Cu+rC2Fi2CyZ4CkgVG3hLl6BFsdAxfXiZkmDFIDY4mRx2y2spdeH6dqPHI9rP+AsHEfGeKz84Uuw7+Pmg==} engines: {node: ^v12.20.0 || >=v14.13.0} + express-rate-limit@7.5.1: + resolution: {integrity: sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.1.0: + resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} + engines: {node: '>= 18'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -1922,6 +2058,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + finalhandler@2.1.0: + resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} + engines: {node: '>= 0.8'} + foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -1930,8 +2070,12 @@ packages: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} - framer-motion@12.9.2: - resolution: {integrity: sha512-R0O3Jdqbfwywpm45obP+8sTgafmdEcUoShQTAV+rB5pi+Y1Px/FYL5qLLRe5tPtBdN1J4jos7M+xN2VV2oEAbQ==} + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + framer-motion@12.23.0: + resolution: {integrity: sha512-xf6NxTGAyf7zR4r2KlnhFmsRfKIbjqeBupEDBAaEtVIBJX96sAon00kMlsKButSIRwPSHjbRrAPnYdJJ9kyhbA==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -1944,6 +2088,10 @@ packages: react-dom: optional: true + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + fs-extra@11.3.0: resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} engines: {node: '>=14.14'} @@ -1953,8 +2101,11 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - geist@1.3.1: - resolution: {integrity: sha512-Q4gC1pBVPN+D579pBaz0TRRnGA4p9UK6elDY/xizXdFk/g4EKR5g0I+4p/Kj6gM0SajDBZ/0FvDV9ey9ud7BWw==} + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + geist@1.4.2: + resolution: {integrity: sha512-OQUga/KUc8ueijck6EbtT07L4tZ5+TZgjw8PyWfxo16sL5FWk7gNViPNU8hgCFjy6bJi9yuTP+CRpywzaGN8zw==} peerDependencies: next: '>=13.2.0' @@ -1971,6 +2122,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + get-nonce@1.0.1: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} @@ -1979,25 +2134,29 @@ packages: resolution: {integrity: sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==} engines: {node: '>=14.16'} + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} - get-tsconfig@4.10.0: - resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - glob@11.0.2: - resolution: {integrity: sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==} + glob@11.0.3: + resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} engines: {node: 20 || >=22} hasBin: true - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -2006,9 +2165,21 @@ packages: resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + headers-polyfill@4.0.3: resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + https-proxy-agent@6.2.1: resolution: {integrity: sha512-ONsE3+yfZF2caH5+bJlcddtWqNI3Gvs5A38+ngvljxaBiRXRswym2c7yf8UAeFpRFKjFNHIFEHqR/OLAWJzyiA==} engines: {node: '>= 14'} @@ -2017,6 +2188,10 @@ packages: resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} engines: {node: '>=14.18.0'} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -2027,6 +2202,10 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -2060,6 +2239,9 @@ packages: resolution: {integrity: sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==} engines: {node: '>=12'} + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-regexp@3.1.0: resolution: {integrity: sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==} engines: {node: '>=12'} @@ -2079,8 +2261,8 @@ packages: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} - jackspeak@4.1.0: - resolution: {integrity: sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==} + jackspeak@4.1.1: + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} engines: {node: 20 || >=22} jiti@2.4.2: @@ -2102,6 +2284,9 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -2118,68 +2303,68 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} - lightningcss-darwin-arm64@1.29.2: - resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==} + lightningcss-darwin-arm64@1.30.1: + resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.29.2: - resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==} + lightningcss-darwin-x64@1.30.1: + resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.29.2: - resolution: {integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==} + lightningcss-freebsd-x64@1.30.1: + resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.29.2: - resolution: {integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==} + lightningcss-linux-arm-gnueabihf@1.30.1: + resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.29.2: - resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==} + lightningcss-linux-arm64-gnu@1.30.1: + resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-arm64-musl@1.29.2: - resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==} + lightningcss-linux-arm64-musl@1.30.1: + resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-x64-gnu@1.29.2: - resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==} + lightningcss-linux-x64-gnu@1.30.1: + resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-linux-x64-musl@1.29.2: - resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==} + lightningcss-linux-x64-musl@1.30.1: + resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-win32-arm64-msvc@1.29.2: - resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==} + lightningcss-win32-arm64-msvc@1.30.1: + resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] - lightningcss-win32-x64-msvc@1.29.2: - resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==} + lightningcss-win32-x64-msvc@1.30.1: + resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] - lightningcss@1.29.2: - resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==} + lightningcss@1.30.1: + resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} engines: {node: '>= 12.0.0'} lines-and-columns@1.2.4: @@ -2196,11 +2381,26 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lucide-react@0.503.0: - resolution: {integrity: sha512-HGGkdlPWQ0vTF8jJ5TdIqhQXZi6uh3LnNgfZ8MHiuxFfX3RZeA79r2MW2tHAZKlAVfoNE8esm3p+O6VkIvpj6w==} + lucide-react@0.525.0: + resolution: {integrity: sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -2212,6 +2412,14 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.1: + resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} + engines: {node: '>= 0.6'} + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -2220,8 +2428,8 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} - minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} engines: {node: 20 || >=22} minimatch@7.4.6: @@ -2235,6 +2443,10 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -2243,14 +2455,19 @@ packages: engines: {node: '>=10'} hasBin: true - motion-dom@12.9.1: - resolution: {integrity: sha512-xqXEwRLDYDTzOgXobSoWtytRtGlf7zdkRfFbrrdP7eojaGQZ5Go4OOKtgnx7uF8sAkfr1ZjMvbCJSCIT2h6fkQ==} + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + motion-dom@12.22.0: + resolution: {integrity: sha512-ooH7+/BPw9gOsL9VtPhEJHE2m4ltnhMlcGMhEqA0YGNhKof7jdaszvsyThXI6LVIKshJUZ9/CP6HNqQhJfV7kw==} - motion-utils@12.8.3: - resolution: {integrity: sha512-GYVauZEbca8/zOhEiYOY9/uJeedYQld6co/GJFKOy//0c/4lDqk0zB549sBYqqV2iMuX+uHrY1E5zd8A2L+1Lw==} + motion-utils@12.19.0: + resolution: {integrity: sha512-BuFTHINYmV07pdWs6lj6aI63vr2N4dg0vR+td0rtrdpWOhBzIkEklZyLcvKBoEtwSqx8Jg06vUB5RS0xDiUybw==} - motion@12.9.2: - resolution: {integrity: sha512-2hwi4wlOpt/zDHcDZATL2FFhYgj2n6t5Hd0UT91swMup6dx6KpFRkTydYJkkV0PUImT1QfC+WT5d0eRekTKpcg==} + motion@12.23.0: + resolution: {integrity: sha512-PPNwblArRH9GRC4F3KtOTiIaYd+mtp324vYq3HIL+ueseoAVqPRK5TPFTAQBcIprfVd0NWo3DLzZSiyWaYFXXQ==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -2266,8 +2483,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msw@2.7.5: - resolution: {integrity: sha512-00MyTlY3TJutBa5kiU+jWiz2z5pNJDYHn2TgPkGkh92kMmNH43RqvMXd8y/7HxNn8RjzUbvZWYZjcS36fdb6sw==} + msw@2.10.2: + resolution: {integrity: sha512-RCKM6IZseZQCWcSWlutdf590M8nVfRHG1ImwzOtwz8IYxgT4zhUO0rfTcTvDGiaFE0Rhcc+h43lcF3Jc9gFtwQ==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -2290,14 +2507,18 @@ packages: engines: {node: ^18 || >=20} hasBin: true + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + next-themes@0.4.6: resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} peerDependencies: react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - next@15.3.1: - resolution: {integrity: sha512-8+dDV0xNLOgHlyBxP1GwHGVaNXsmp+2NhZEYrXr24GWLHtt27YrBPbPuHvzlhi7kZNYjeJNR93IF5zfFu5UL0g==} + next@15.3.4: + resolution: {integrity: sha512-mHKd50C+mCjam/gcnwqL1T1vPx/XQNFlXqFIVdgQdVAFY9iIQtY0IfaVflEYzKiqjeA7B0cYYMaCrmAYFjs4rA==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -2351,6 +2572,21 @@ packages: react-router-dom: optional: true + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} @@ -2377,6 +2613,10 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} @@ -2395,35 +2635,39 @@ packages: path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - pg-cloudflare@1.2.5: - resolution: {integrity: sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg==} + pg-cloudflare@1.2.7: + resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} - pg-connection-string@2.8.5: - resolution: {integrity: sha512-Ni8FuZ8yAF+sWZzojvtLE2b03cqjO5jNULcHFfM9ZZ0/JXrgom5pBREbtnAw7oxsxJqHw9Nz/XWORUEL3/IFow==} + pg-connection-string@2.9.1: + resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==} pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} - pg-pool@3.9.5: - resolution: {integrity: sha512-DxyAlOgvUzRFpFAZjbCc8fUfG7BcETDHgepFPf724B0i08k9PAiZV1tkGGgQIL0jbMEuR9jW1YN7eX+WgXxCsQ==} + pg-pool@3.10.1: + resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==} peerDependencies: pg: '>=8.0' - pg-protocol@1.9.5: - resolution: {integrity: sha512-DYTWtWpfd5FOro3UnAfwvhD8jh59r2ig8bPtc9H8Ds7MscE/9NYruUQWFAOuraRl29jwcT2kyMFQ3MxeaVjUhg==} + pg-protocol@1.10.3: + resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} engines: {node: '>=4'} - pg@8.15.5: - resolution: {integrity: sha512-EpAhHFQc+aH9VfeffWIVC+XXk6lmAhS9W1FxtxcPXs94yxhrI1I6w/zkWfIOII/OkBv3Be04X3xMOj0kQ78l6w==} - engines: {node: '>= 8.0.0'} + pg@8.16.3: + resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==} + engines: {node: '>= 16.0.0'} peerDependencies: pg-native: '>=3.0.1' peerDependenciesMeta: @@ -2440,12 +2684,16 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + pkce-challenge@5.0.0: + resolution: {integrity: sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==} + engines: {node: '>=16.20.0'} + postcss@8.4.31: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.3: - resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} postgres-array@2.0.0: @@ -2464,14 +2712,18 @@ packages: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} - postgres@3.4.5: - resolution: {integrity: sha512-cDWgoah1Gez9rN3H4165peY9qfpEo+SA61oQv65O3cRUE1pOEoJWwddwcqKE8XZYjbblOJlYDlLV4h67HrEVDg==} + postgres@3.4.7: + resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==} engines: {node: '>=12'} prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + psl@1.15.0: resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} @@ -2479,25 +2731,37 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - react-day-picker@8.10.1: - resolution: {integrity: sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==} + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@3.0.0: + resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} + engines: {node: '>= 0.8'} + + react-day-picker@9.7.0: + resolution: {integrity: sha512-urlK4C9XJZVpQ81tmVgd2O7lZ0VQldZeHzNejbwLWZSkzHH498KnArT0EHNfKBOWwKc935iMLGZdxXPRISzUxQ==} + engines: {node: '>=18'} peerDependencies: - date-fns: ^2.28.0 || ^3.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: '>=16.8.0' react-dom@19.1.0: resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} peerDependencies: react: ^19.1.0 - react-hook-form@7.56.1: - resolution: {integrity: sha512-qWAVokhSpshhcEuQDSANHx3jiAEFzu2HAaaQIzi/r9FNPm1ioAvuJSD4EuZzWd7Al7nTRKcKPnBKO7sRn+zavQ==} + react-hook-form@7.59.0: + resolution: {integrity: sha512-kmkek2/8grqarTJExFNjy+RXDIP8yM+QTl3QL6m6Q8b2bih4ltmiXxH7T9n+yXNK477xPh5yZT/6vD8sYGzJTA==} engines: {node: '>=18.0.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 @@ -2512,8 +2776,8 @@ packages: '@types/react': optional: true - react-remove-scroll@2.6.3: - resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==} + react-remove-scroll@2.7.1: + resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==} engines: {node: '>=10'} peerDependencies: '@types/react': '*' @@ -2571,12 +2835,19 @@ packages: engines: {node: 20 || >=22} hasBin: true + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + scheduler@0.26.0: resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} @@ -2584,20 +2855,31 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} engines: {node: '>=10'} hasBin: true + send@1.2.0: + resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} + engines: {node: '>= 18'} + + serve-static@2.2.0: + resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} + engines: {node: '>= 18'} + server-only@0.0.1: resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} - shadcn@2.5.0: - resolution: {integrity: sha512-kqbTpDWIYE8spytMiJFoKyzOTHb+DzNLjMXzz+ifDFTBgTPv6gIydmirTZwwfFb23XvenrTSVHsZHUjGsllcHw==} + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shadcn@2.7.0: + resolution: {integrity: sha512-NzkUf58HI3AxcrdnmAgdN3oT0f2J5CyFKMi2exdVLtoRW+A5GxADxWqhWKRvBmdWoiPDuqYeb3ScZxhlS9aflA==} hasBin: true - sharp@0.34.1: - resolution: {integrity: sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==} + sharp@0.34.2: + resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@2.0.0: @@ -2608,8 +2890,24 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shell-quote@1.8.2: - resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==} + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} signal-exit@3.0.7: @@ -2625,8 +2923,8 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - sonner@2.0.3: - resolution: {integrity: sha512-njQ4Hht92m0sMqqHVDL32V2Oun9W1+PHO9NDv9FHfJjT3JT22IG4Jpo3FPQy+mouRKCXFWO+r67v6MrHX2zeIA==} + sonner@2.0.5: + resolution: {integrity: sha512-YwbHQO6cSso3HBXlbCkgrgzDNIhws14r4MO87Ofy+cV2X7ES4pOoAK3+veSmVTvqNx1BWUxlhPmZzP00Crk2aQ==} peerDependencies: react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc @@ -2650,6 +2948,10 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + stdin-discarder@0.1.0: resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2705,16 +3007,20 @@ packages: babel-plugin-macros: optional: true - tailwind-merge@3.2.0: - resolution: {integrity: sha512-FQT/OVqCD+7edmmJpsgCsY820RTD5AkBryuG5IUqR5YQZSdj5xlH5nLgH7YPths7WsLPSpSBNneJdM8aS8aeFA==} + tailwind-merge@3.3.1: + resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} - tailwindcss@4.1.4: - resolution: {integrity: sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A==} + tailwindcss@4.1.11: + resolution: {integrity: sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==} - tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + tapable@2.2.2: + resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} engines: {node: '>=6'} + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -2722,6 +3028,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -2736,29 +3046,33 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsx@4.19.3: - resolution: {integrity: sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==} + tsx@4.20.3: + resolution: {integrity: sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==} engines: {node: '>=18.0.0'} hasBin: true - tw-animate-css@1.2.8: - resolution: {integrity: sha512-AxSnYRvyFnAiZCUndS3zQZhNfV/B77ZhJ+O7d3K6wfg/jKJY+yv6ahuyXwnyaYA9UdLqnpCwhTRv9pPTBnPR2g==} + tw-animate-css@1.3.4: + resolution: {integrity: sha512-dd1Ht6/YQHcNbq0znIT6dG8uhO7Ce+VIIhZUhjsryXsMPJQz3bZg7Q2eNzLwipb25bRZslGb2myio5mScd1TFg==} type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - type-fest@4.40.1: - resolution: {integrity: sha512-9YvLNnORDpI+vghLU/Nf+zSv0kL47KbVJ1o3sKgoTefl6i+zebxbiDQWoe/oWWqPhIgQdRZRT1KA9sCPL810SA==} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + typescript@5.8.3: resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} @@ -2768,12 +3082,19 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} @@ -2800,6 +3121,10 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + vaul@1.1.2: resolution: {integrity: sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==} peerDependencies: @@ -2835,6 +3160,9 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -2846,6 +3174,10 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -2858,8 +3190,13 @@ packages: resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} engines: {node: '>=18'} - zod@3.24.3: - resolution: {integrity: sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==} + zod-to-json-schema@3.24.6: + resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==} + peerDependencies: + zod: ^3.24.1 + + zod@3.25.71: + resolution: {integrity: sha512-BsBc/NPk7h8WsUWYWYL+BajcJPY8YhjelaWu2NMLuzgraKAz4Lb4/6K11g9jpuDetjMiqhZ6YaexFLOC0Ogi3Q==} snapshots: @@ -2867,210 +3204,214 @@ snapshots: '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 '@antfu/ni@23.3.1': {} '@ark/schema@0.46.0': dependencies: '@ark/util': 0.46.0 + optional: true - '@ark/util@0.46.0': {} + '@ark/util@0.46.0': + optional: true - '@babel/code-frame@7.26.2': + '@babel/code-frame@7.27.1': dependencies: - '@babel/helper-validator-identifier': 7.25.9 + '@babel/helper-validator-identifier': 7.27.1 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.26.8': {} + '@babel/compat-data@7.28.0': {} - '@babel/core@7.26.10': + '@babel/core@7.28.0': dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.27.0 - '@babel/helper-compilation-targets': 7.27.0 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) - '@babel/helpers': 7.27.0 - '@babel/parser': 7.27.0 - '@babel/template': 7.27.0 - '@babel/traverse': 7.27.0 - '@babel/types': 7.27.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@babel/helpers': 7.27.6 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 convert-source-map: 2.0.0 - debug: 4.4.0 + debug: 4.4.1 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.27.0': + '@babel/generator@7.28.0': dependencies: - '@babel/parser': 7.27.0 - '@babel/types': 7.27.0 - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 jsesc: 3.1.0 - '@babel/helper-annotate-as-pure@7.25.9': + '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.27.0 + '@babel/types': 7.28.0 - '@babel/helper-compilation-targets@7.27.0': + '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.26.8 - '@babel/helper-validator-option': 7.25.9 - browserslist: 4.24.4 + '@babel/compat-data': 7.28.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.25.1 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.27.0(@babel/core@7.26.10)': + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-member-expression-to-functions': 7.25.9 - '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.10) - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/traverse': 7.27.0 + '@babel/core': 7.28.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-member-expression-to-functions@7.25.9': + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.27.0 - '@babel/types': 7.27.0 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@7.25.9': + '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.27.0 - '@babel/types': 7.27.0 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)': + '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.27.0 + '@babel/core': 7.28.0 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-optimise-call-expression@7.25.9': + '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.27.0 + '@babel/types': 7.28.0 - '@babel/helper-plugin-utils@7.26.5': {} + '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-replace-supers@7.26.5(@babel/core@7.26.10)': + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-member-expression-to-functions': 7.25.9 - '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/traverse': 7.27.0 + '@babel/core': 7.28.0 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.27.0 - '@babel/types': 7.27.0 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-option@7.25.9': {} + '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.27.0': + '@babel/helpers@7.27.6': dependencies: - '@babel/template': 7.27.0 - '@babel/types': 7.27.0 + '@babel/template': 7.27.2 + '@babel/types': 7.28.0 - '@babel/parser@7.27.0': + '@babel/parser@7.28.0': dependencies: - '@babel/types': 7.27.0 + '@babel/types': 7.28.0 - '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typescript@7.27.0(@babel/core@7.26.10)': + '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.10) + '@babel/core': 7.28.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.0) transitivePeerDependencies: - supports-color - '@babel/template@7.27.0': + '@babel/template@7.27.2': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/parser': 7.27.0 - '@babel/types': 7.27.0 + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 - '@babel/traverse@7.27.0': + '@babel/traverse@7.28.0': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.27.0 - '@babel/parser': 7.27.0 - '@babel/template': 7.27.0 - '@babel/types': 7.27.0 - debug: 4.4.0 - globals: 11.12.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/types': 7.28.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color - '@babel/types@7.27.0': + '@babel/types@7.28.0': dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 - '@biomejs/biome@1.9.4': + '@biomejs/biome@2.0.6': optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.9.4 - '@biomejs/cli-darwin-x64': 1.9.4 - '@biomejs/cli-linux-arm64': 1.9.4 - '@biomejs/cli-linux-arm64-musl': 1.9.4 - '@biomejs/cli-linux-x64': 1.9.4 - '@biomejs/cli-linux-x64-musl': 1.9.4 - '@biomejs/cli-win32-arm64': 1.9.4 - '@biomejs/cli-win32-x64': 1.9.4 - - '@biomejs/cli-darwin-arm64@1.9.4': + '@biomejs/cli-darwin-arm64': 2.0.6 + '@biomejs/cli-darwin-x64': 2.0.6 + '@biomejs/cli-linux-arm64': 2.0.6 + '@biomejs/cli-linux-arm64-musl': 2.0.6 + '@biomejs/cli-linux-x64': 2.0.6 + '@biomejs/cli-linux-x64-musl': 2.0.6 + '@biomejs/cli-win32-arm64': 2.0.6 + '@biomejs/cli-win32-x64': 2.0.6 + + '@biomejs/cli-darwin-arm64@2.0.6': optional: true - '@biomejs/cli-darwin-x64@1.9.4': + '@biomejs/cli-darwin-x64@2.0.6': optional: true - '@biomejs/cli-linux-arm64-musl@1.9.4': + '@biomejs/cli-linux-arm64-musl@2.0.6': optional: true - '@biomejs/cli-linux-arm64@1.9.4': + '@biomejs/cli-linux-arm64@2.0.6': optional: true - '@biomejs/cli-linux-x64-musl@1.9.4': + '@biomejs/cli-linux-x64-musl@2.0.6': optional: true - '@biomejs/cli-linux-x64@1.9.4': + '@biomejs/cli-linux-x64@2.0.6': optional: true - '@biomejs/cli-win32-arm64@1.9.4': + '@biomejs/cli-win32-arm64@2.0.6': optional: true - '@biomejs/cli-win32-x64@1.9.4': + '@biomejs/cli-win32-x64@2.0.6': optional: true '@bundled-es-modules/cookie@2.0.1': @@ -3079,13 +3420,15 @@ snapshots: '@bundled-es-modules/statuses@1.0.1': dependencies: - statuses: 2.0.1 + statuses: 2.0.2 '@bundled-es-modules/tough-cookie@0.1.6': dependencies: '@types/tough-cookie': 4.0.5 tough-cookie: 4.1.4 + '@date-fns/tz@1.2.0': {} + '@dnd-kit/accessibility@3.1.1(react@19.1.0)': dependencies: react: 19.1.0 @@ -3133,179 +3476,179 @@ snapshots: '@esbuild-kit/esm-loader@2.6.5': dependencies: '@esbuild-kit/core-utils': 3.3.2 - get-tsconfig: 4.10.0 + get-tsconfig: 4.10.1 - '@esbuild/aix-ppc64@0.25.3': + '@esbuild/aix-ppc64@0.25.5': optional: true '@esbuild/android-arm64@0.18.20': optional: true - '@esbuild/android-arm64@0.25.3': + '@esbuild/android-arm64@0.25.5': optional: true '@esbuild/android-arm@0.18.20': optional: true - '@esbuild/android-arm@0.25.3': + '@esbuild/android-arm@0.25.5': optional: true '@esbuild/android-x64@0.18.20': optional: true - '@esbuild/android-x64@0.25.3': + '@esbuild/android-x64@0.25.5': optional: true '@esbuild/darwin-arm64@0.18.20': optional: true - '@esbuild/darwin-arm64@0.25.3': + '@esbuild/darwin-arm64@0.25.5': optional: true '@esbuild/darwin-x64@0.18.20': optional: true - '@esbuild/darwin-x64@0.25.3': + '@esbuild/darwin-x64@0.25.5': optional: true '@esbuild/freebsd-arm64@0.18.20': optional: true - '@esbuild/freebsd-arm64@0.25.3': + '@esbuild/freebsd-arm64@0.25.5': optional: true '@esbuild/freebsd-x64@0.18.20': optional: true - '@esbuild/freebsd-x64@0.25.3': + '@esbuild/freebsd-x64@0.25.5': optional: true '@esbuild/linux-arm64@0.18.20': optional: true - '@esbuild/linux-arm64@0.25.3': + '@esbuild/linux-arm64@0.25.5': optional: true '@esbuild/linux-arm@0.18.20': optional: true - '@esbuild/linux-arm@0.25.3': + '@esbuild/linux-arm@0.25.5': optional: true '@esbuild/linux-ia32@0.18.20': optional: true - '@esbuild/linux-ia32@0.25.3': + '@esbuild/linux-ia32@0.25.5': optional: true '@esbuild/linux-loong64@0.18.20': optional: true - '@esbuild/linux-loong64@0.25.3': + '@esbuild/linux-loong64@0.25.5': optional: true '@esbuild/linux-mips64el@0.18.20': optional: true - '@esbuild/linux-mips64el@0.25.3': + '@esbuild/linux-mips64el@0.25.5': optional: true '@esbuild/linux-ppc64@0.18.20': optional: true - '@esbuild/linux-ppc64@0.25.3': + '@esbuild/linux-ppc64@0.25.5': optional: true '@esbuild/linux-riscv64@0.18.20': optional: true - '@esbuild/linux-riscv64@0.25.3': + '@esbuild/linux-riscv64@0.25.5': optional: true '@esbuild/linux-s390x@0.18.20': optional: true - '@esbuild/linux-s390x@0.25.3': + '@esbuild/linux-s390x@0.25.5': optional: true '@esbuild/linux-x64@0.18.20': optional: true - '@esbuild/linux-x64@0.25.3': + '@esbuild/linux-x64@0.25.5': optional: true - '@esbuild/netbsd-arm64@0.25.3': + '@esbuild/netbsd-arm64@0.25.5': optional: true '@esbuild/netbsd-x64@0.18.20': optional: true - '@esbuild/netbsd-x64@0.25.3': + '@esbuild/netbsd-x64@0.25.5': optional: true - '@esbuild/openbsd-arm64@0.25.3': + '@esbuild/openbsd-arm64@0.25.5': optional: true '@esbuild/openbsd-x64@0.18.20': optional: true - '@esbuild/openbsd-x64@0.25.3': + '@esbuild/openbsd-x64@0.25.5': optional: true '@esbuild/sunos-x64@0.18.20': optional: true - '@esbuild/sunos-x64@0.25.3': + '@esbuild/sunos-x64@0.25.5': optional: true '@esbuild/win32-arm64@0.18.20': optional: true - '@esbuild/win32-arm64@0.25.3': + '@esbuild/win32-arm64@0.25.5': optional: true '@esbuild/win32-ia32@0.18.20': optional: true - '@esbuild/win32-ia32@0.25.3': + '@esbuild/win32-ia32@0.25.5': optional: true '@esbuild/win32-x64@0.18.20': optional: true - '@esbuild/win32-x64@0.25.3': + '@esbuild/win32-x64@0.25.5': optional: true - '@faker-js/faker@9.7.0': {} + '@faker-js/faker@9.9.0': {} - '@floating-ui/core@1.6.9': + '@floating-ui/core@1.7.2': dependencies: - '@floating-ui/utils': 0.2.9 + '@floating-ui/utils': 0.2.10 - '@floating-ui/dom@1.6.13': + '@floating-ui/dom@1.7.2': dependencies: - '@floating-ui/core': 1.6.9 - '@floating-ui/utils': 0.2.9 + '@floating-ui/core': 1.7.2 + '@floating-ui/utils': 0.2.10 - '@floating-ui/react-dom@2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@floating-ui/react-dom@2.1.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@floating-ui/dom': 1.6.13 + '@floating-ui/dom': 1.7.2 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - '@floating-ui/utils@0.2.9': {} + '@floating-ui/utils@0.2.10': {} - '@hookform/resolvers@5.0.1(react-hook-form@7.56.1(react@19.1.0))': + '@hookform/resolvers@5.1.1(react-hook-form@7.59.0(react@19.1.0))': dependencies: '@standard-schema/utils': 0.3.0 - react-hook-form: 7.56.1(react@19.1.0) + react-hook-form: 7.59.0(react@19.1.0) - '@img/sharp-darwin-arm64@0.34.1': + '@img/sharp-darwin-arm64@0.34.2': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.1.0 optional: true - '@img/sharp-darwin-x64@0.34.1': + '@img/sharp-darwin-x64@0.34.2': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.1.0 optional: true @@ -3337,58 +3680,61 @@ snapshots: '@img/sharp-libvips-linuxmusl-x64@1.1.0': optional: true - '@img/sharp-linux-arm64@0.34.1': + '@img/sharp-linux-arm64@0.34.2': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.1.0 optional: true - '@img/sharp-linux-arm@0.34.1': + '@img/sharp-linux-arm@0.34.2': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.1.0 optional: true - '@img/sharp-linux-s390x@0.34.1': + '@img/sharp-linux-s390x@0.34.2': optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.1.0 optional: true - '@img/sharp-linux-x64@0.34.1': + '@img/sharp-linux-x64@0.34.2': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.1.0 optional: true - '@img/sharp-linuxmusl-arm64@0.34.1': + '@img/sharp-linuxmusl-arm64@0.34.2': optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 optional: true - '@img/sharp-linuxmusl-x64@0.34.1': + '@img/sharp-linuxmusl-x64@0.34.2': optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.1.0 optional: true - '@img/sharp-wasm32@0.34.1': + '@img/sharp-wasm32@0.34.2': dependencies: '@emnapi/runtime': 1.4.3 optional: true - '@img/sharp-win32-ia32@0.34.1': + '@img/sharp-win32-arm64@0.34.2': + optional: true + + '@img/sharp-win32-ia32@0.34.2': optional: true - '@img/sharp-win32-x64@0.34.1': + '@img/sharp-win32-x64@0.34.2': optional: true - '@inquirer/confirm@5.1.9(@types/node@22.15.2)': + '@inquirer/confirm@5.1.13(@types/node@24.0.10)': dependencies: - '@inquirer/core': 10.1.10(@types/node@22.15.2) - '@inquirer/type': 3.0.6(@types/node@22.15.2) + '@inquirer/core': 10.1.14(@types/node@24.0.10) + '@inquirer/type': 3.0.7(@types/node@24.0.10) optionalDependencies: - '@types/node': 22.15.2 + '@types/node': 24.0.10 - '@inquirer/core@10.1.10(@types/node@22.15.2)': + '@inquirer/core@10.1.14(@types/node@24.0.10)': dependencies: - '@inquirer/figures': 1.0.11 - '@inquirer/type': 3.0.6(@types/node@22.15.2) + '@inquirer/figures': 1.0.12 + '@inquirer/type': 3.0.7(@types/node@24.0.10) ansi-escapes: 4.3.2 cli-width: 4.1.0 mute-stream: 2.0.0 @@ -3396,13 +3742,19 @@ snapshots: wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.15.2 + '@types/node': 24.0.10 - '@inquirer/figures@1.0.11': {} + '@inquirer/figures@1.0.12': {} - '@inquirer/type@3.0.6(@types/node@22.15.2)': + '@inquirer/type@3.0.7(@types/node@24.0.10)': optionalDependencies: - '@types/node': 22.15.2 + '@types/node': 24.0.10 + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 '@isaacs/cliui@8.0.2': dependencies: @@ -3413,24 +3765,42 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@jridgewell/gen-mapping@0.3.8': + '@isaacs/fs-minipass@4.0.1': dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 + minipass: 7.1.2 - '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/gen-mapping@0.3.12': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/trace-mapping': 0.3.29 - '@jridgewell/set-array@1.2.1': {} + '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.4': {} - '@jridgewell/trace-mapping@0.3.25': + '@jridgewell/trace-mapping@0.3.29': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.4 + + '@modelcontextprotocol/sdk@1.13.3': + dependencies: + ajv: 6.12.6 + content-type: 1.0.5 + cors: 2.8.5 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.3 + express: 5.1.0 + express-rate-limit: 7.5.1(express@5.1.0) + pkce-challenge: 5.0.0 + raw-body: 3.0.0 + zod: 3.25.71 + zod-to-json-schema: 3.24.6(zod@3.25.71) + transitivePeerDependencies: + - supports-color - '@mswjs/interceptors@0.37.6': + '@mswjs/interceptors@0.39.2': dependencies: '@open-draft/deferred-promise': 2.2.0 '@open-draft/logger': 0.3.0 @@ -3439,30 +3809,30 @@ snapshots: outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@next/env@15.3.1': {} + '@next/env@15.3.4': {} - '@next/swc-darwin-arm64@15.3.1': + '@next/swc-darwin-arm64@15.3.4': optional: true - '@next/swc-darwin-x64@15.3.1': + '@next/swc-darwin-x64@15.3.4': optional: true - '@next/swc-linux-arm64-gnu@15.3.1': + '@next/swc-linux-arm64-gnu@15.3.4': optional: true - '@next/swc-linux-arm64-musl@15.3.1': + '@next/swc-linux-arm64-musl@15.3.4': optional: true - '@next/swc-linux-x64-gnu@15.3.1': + '@next/swc-linux-x64-gnu@15.3.4': optional: true - '@next/swc-linux-x64-musl@15.3.1': + '@next/swc-linux-x64-musl@15.3.4': optional: true - '@next/swc-win32-arm64-msvc@15.3.1': + '@next/swc-win32-arm64-msvc@15.3.4': optional: true - '@next/swc-win32-x64-msvc@15.3.1': + '@next/swc-win32-x64-msvc@15.3.4': optional: true '@nodelib/fs.scandir@2.1.5': @@ -3493,429 +3863,429 @@ snapshots: '@radix-ui/primitive@1.1.2': {} - '@radix-ui/react-arrow@1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-checkbox@1.2.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-checkbox@1.3.2(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-collection@1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.8)(react@19.1.0)': dependencies: react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-context@1.1.2(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-context@1.1.2(@types/react@19.1.8)(react@19.1.0)': dependencies: react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-dialog@1.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-dialog@1.1.14(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-dismissable-layer': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-focus-scope': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-portal': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0) - aria-hidden: 1.2.4 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + aria-hidden: 1.2.6 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - react-remove-scroll: 2.6.3(@types/react@19.1.2)(react@19.1.0) + react-remove-scroll: 2.7.1(@types/react@19.1.8)(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-direction@1.1.1(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-direction@1.1.1(@types/react@19.1.8)(react@19.1.0)': dependencies: react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-dismissable-layer@1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-dismissable-layer@1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-dropdown-menu@2.1.12(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-dropdown-menu@2.1.15(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-menu': 2.1.12(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-menu': 2.1.15(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-focus-guards@1.1.2(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-focus-guards@1.1.2(@types/react@19.1.8)(react@19.1.0)': dependencies: react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-focus-scope@1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-id@1.1.1(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-id@1.1.1(@types/react@19.1.8)(react@19.1.0)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-label@2.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-label@2.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-menu@2.1.12(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-menu@2.1.15(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-collection': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-dismissable-layer': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-focus-scope': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-popper': 1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-portal': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-roving-focus': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) - aria-hidden: 1.2.4 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-popper': 1.2.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + aria-hidden: 1.2.6 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - react-remove-scroll: 2.6.3(@types/react@19.1.2)(react@19.1.0) + react-remove-scroll: 2.7.1(@types/react@19.1.8)(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-popover@1.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-popover@1.1.14(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-dismissable-layer': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-focus-scope': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-popper': 1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-portal': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0) - aria-hidden: 1.2.4 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-popper': 1.2.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + aria-hidden: 1.2.6 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - react-remove-scroll: 2.6.3(@types/react@19.1.2)(react@19.1.0) + react-remove-scroll: 2.7.1(@types/react@19.1.8)(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) - - '@radix-ui/react-popper@1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': - dependencies: - '@floating-ui/react-dom': 2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-arrow': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-popper@1.2.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@floating-ui/react-dom': 2.1.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.8)(react@19.1.0) '@radix-ui/rect': 1.1.1 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-portal@1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-presence@1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-presence@1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-primitive@2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-roving-focus@1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-roving-focus@1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-collection': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-select@2.2.2(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-select@2.2.5(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-collection': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-dismissable-layer': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-focus-scope': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-popper': 1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-portal': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-visually-hidden': 1.2.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - aria-hidden: 1.2.4 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-popper': 1.2.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + aria-hidden: 1.2.6 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - react-remove-scroll: 2.6.3(@types/react@19.1.2)(react@19.1.0) + react-remove-scroll: 2.7.1(@types/react@19.1.8)(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-separator@1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-separator@1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-slider@1.3.2(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-slider@1.3.5(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-collection': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-slot@1.2.0(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-slot@1.2.3(@types/react@19.1.8)(react@19.1.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-toggle-group@1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-toggle-group@1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-roving-focus': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-toggle': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-toggle': 1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-toggle@1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-toggle@1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-tooltip@1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-tooltip@1.2.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-dismissable-layer': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-popper': 1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-portal': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-visually-hidden': 1.2.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-popper': 1.2.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.8)(react@19.1.0)': dependencies: react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.8)(react@19.1.0)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.8)(react@19.1.0)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.8)(react@19.1.0)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.8)(react@19.1.0)': dependencies: react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.8)(react@19.1.0)': dependencies: react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.8)(react@19.1.0)': dependencies: '@radix-ui/rect': 1.1.1 react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-use-size@1.1.1(@types/react@19.1.2)(react@19.1.0)': + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.8)(react@19.1.0)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) react: 19.1.0 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@radix-ui/react-visually-hidden@1.2.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 - '@types/react-dom': 19.1.2(@types/react@19.1.2) + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) '@radix-ui/rect@1.1.1': {} @@ -3927,87 +4297,91 @@ snapshots: dependencies: tslib: 2.8.1 - '@t3-oss/env-core@0.13.0(arktype@2.1.20)(typescript@5.8.3)(zod@3.24.3)': - dependencies: - arktype: 2.1.20 + '@t3-oss/env-core@0.13.8(arktype@2.1.20)(typescript@5.8.3)(zod@3.25.71)': optionalDependencies: + arktype: 2.1.20 typescript: 5.8.3 - zod: 3.24.3 + zod: 3.25.71 - '@t3-oss/env-nextjs@0.13.0(arktype@2.1.20)(typescript@5.8.3)(zod@3.24.3)': + '@t3-oss/env-nextjs@0.13.8(arktype@2.1.20)(typescript@5.8.3)(zod@3.25.71)': dependencies: - '@t3-oss/env-core': 0.13.0(arktype@2.1.20)(typescript@5.8.3)(zod@3.24.3) + '@t3-oss/env-core': 0.13.8(arktype@2.1.20)(typescript@5.8.3)(zod@3.25.71) optionalDependencies: + arktype: 2.1.20 typescript: 5.8.3 - zod: 3.24.3 - transitivePeerDependencies: - - arktype + zod: 3.25.71 - '@tailwindcss/node@4.1.4': + '@tailwindcss/node@4.1.11': dependencies: - enhanced-resolve: 5.18.1 + '@ampproject/remapping': 2.3.0 + enhanced-resolve: 5.18.2 jiti: 2.4.2 - lightningcss: 1.29.2 - tailwindcss: 4.1.4 + lightningcss: 1.30.1 + magic-string: 0.30.17 + source-map-js: 1.2.1 + tailwindcss: 4.1.11 - '@tailwindcss/oxide-android-arm64@4.1.4': + '@tailwindcss/oxide-android-arm64@4.1.11': optional: true - '@tailwindcss/oxide-darwin-arm64@4.1.4': + '@tailwindcss/oxide-darwin-arm64@4.1.11': optional: true - '@tailwindcss/oxide-darwin-x64@4.1.4': + '@tailwindcss/oxide-darwin-x64@4.1.11': optional: true - '@tailwindcss/oxide-freebsd-x64@4.1.4': + '@tailwindcss/oxide-freebsd-x64@4.1.11': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.1.4': + '@tailwindcss/oxide-linux-arm64-gnu@4.1.11': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.1.4': + '@tailwindcss/oxide-linux-arm64-musl@4.1.11': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.1.4': + '@tailwindcss/oxide-linux-x64-gnu@4.1.11': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.1.4': + '@tailwindcss/oxide-linux-x64-musl@4.1.11': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.1.4': + '@tailwindcss/oxide-wasm32-wasi@4.1.11': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.1.4': + '@tailwindcss/oxide-win32-arm64-msvc@4.1.11': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.1.4': + '@tailwindcss/oxide-win32-x64-msvc@4.1.11': optional: true - '@tailwindcss/oxide@4.1.4': + '@tailwindcss/oxide@4.1.11': + dependencies: + detect-libc: 2.0.4 + tar: 7.4.3 optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.1.4 - '@tailwindcss/oxide-darwin-arm64': 4.1.4 - '@tailwindcss/oxide-darwin-x64': 4.1.4 - '@tailwindcss/oxide-freebsd-x64': 4.1.4 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.4 - '@tailwindcss/oxide-linux-arm64-gnu': 4.1.4 - '@tailwindcss/oxide-linux-arm64-musl': 4.1.4 - '@tailwindcss/oxide-linux-x64-gnu': 4.1.4 - '@tailwindcss/oxide-linux-x64-musl': 4.1.4 - '@tailwindcss/oxide-wasm32-wasi': 4.1.4 - '@tailwindcss/oxide-win32-arm64-msvc': 4.1.4 - '@tailwindcss/oxide-win32-x64-msvc': 4.1.4 - - '@tailwindcss/postcss@4.1.4': + '@tailwindcss/oxide-android-arm64': 4.1.11 + '@tailwindcss/oxide-darwin-arm64': 4.1.11 + '@tailwindcss/oxide-darwin-x64': 4.1.11 + '@tailwindcss/oxide-freebsd-x64': 4.1.11 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.11 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.11 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.11 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.11 + '@tailwindcss/oxide-linux-x64-musl': 4.1.11 + '@tailwindcss/oxide-wasm32-wasi': 4.1.11 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.11 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.11 + + '@tailwindcss/postcss@4.1.11': dependencies: '@alloc/quick-lru': 5.2.0 - '@tailwindcss/node': 4.1.4 - '@tailwindcss/oxide': 4.1.4 - postcss: 8.5.3 - tailwindcss: 4.1.4 + '@tailwindcss/node': 4.1.11 + '@tailwindcss/oxide': 4.1.11 + postcss: 8.5.6 + tailwindcss: 4.1.11 '@tanstack/react-table@8.21.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: @@ -4028,24 +4402,36 @@ snapshots: '@types/cookie@0.6.0': {} - '@types/node@22.15.2': + '@types/node@24.0.10': dependencies: - undici-types: 6.21.0 + undici-types: 7.8.0 - '@types/react-dom@19.1.2(@types/react@19.1.2)': + '@types/react-dom@19.1.6(@types/react@19.1.8)': dependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - '@types/react@19.1.2': + '@types/react@19.1.8': dependencies: csstype: 3.1.3 - '@types/statuses@2.0.5': {} + '@types/statuses@2.0.6': {} '@types/tough-cookie@4.0.5': {} + accepts@2.0.0: + dependencies: + mime-types: 3.0.1 + negotiator: 1.0.0 + agent-base@7.1.3: {} + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -4062,7 +4448,7 @@ snapshots: argparse@2.0.1: {} - aria-hidden@1.2.4: + aria-hidden@1.2.6: dependencies: tslib: 2.8.1 @@ -4070,6 +4456,7 @@ snapshots: dependencies: '@ark/schema': 0.46.0 '@ark/util': 0.46.0 + optional: true ast-types@0.16.1: dependencies: @@ -4085,7 +4472,21 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - brace-expansion@2.0.1: + body-parser@2.2.0: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.1 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + on-finished: 2.4.1 + qs: 6.14.0 + raw-body: 3.0.0 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 @@ -4093,12 +4494,12 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.24.4: + browserslist@4.25.1: dependencies: - caniuse-lite: 1.0.30001715 - electron-to-chromium: 1.5.143 + caniuse-lite: 1.0.30001726 + electron-to-chromium: 1.5.179 node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.24.4) + update-browserslist-db: 1.1.3(browserslist@4.25.1) buffer-from@1.1.2: {} @@ -4111,12 +4512,26 @@ snapshots: dependencies: streamsearch: 1.1.0 + bytes@3.1.2: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} - caniuse-lite@1.0.30001715: {} + caniuse-lite@1.0.30001726: {} chalk@5.4.1: {} + chownr@3.0.0: {} + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -4141,12 +4556,12 @@ snapshots: clsx@2.1.1: {} - cmdk@1.1.1(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + cmdk@1.1.1(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-dialog': 1.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) - '@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-dialog': 1.1.14(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) transitivePeerDependencies: @@ -4175,10 +4590,23 @@ snapshots: commander@10.0.1: {} + content-disposition@1.0.0: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + convert-source-map@2.0.0: {} + cookie-signature@1.2.2: {} + cookie@0.7.2: {} + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + cosmiconfig@8.3.6(typescript@5.8.3): dependencies: import-fresh: 3.3.1 @@ -4198,9 +4626,11 @@ snapshots: data-uri-to-buffer@4.0.1: {} + date-fns-jalali@4.1.0-0: {} + date-fns@4.1.0: {} - debug@4.4.0: + debug@4.4.1: dependencies: ms: 2.1.3 @@ -4210,6 +4640,8 @@ snapshots: dependencies: clone: 1.0.4 + depd@2.0.0: {} + detect-libc@2.0.4: {} detect-node-es@1.1.0: {} @@ -4219,41 +4651,51 @@ snapshots: dotenv-cli@8.0.0: dependencies: cross-spawn: 7.0.6 - dotenv: 16.5.0 + dotenv: 16.6.1 dotenv-expand: 10.0.0 minimist: 1.2.8 dotenv-expand@10.0.0: {} - dotenv@16.5.0: {} + dotenv@16.6.1: {} - drizzle-kit@0.31.0: + drizzle-kit@0.31.4: dependencies: '@drizzle-team/brocli': 0.10.2 '@esbuild-kit/esm-loader': 2.6.5 - esbuild: 0.25.3 - esbuild-register: 3.6.0(esbuild@0.25.3) + esbuild: 0.25.5 + esbuild-register: 3.6.0(esbuild@0.25.5) transitivePeerDependencies: - supports-color - drizzle-orm@0.43.1(gel@2.0.1)(pg@8.15.5)(postgres@3.4.5): + drizzle-orm@0.44.2(gel@2.0.1)(pg@8.16.3)(postgres@3.4.7): optionalDependencies: gel: 2.0.1 - pg: 8.15.5 - postgres: 3.4.5 + pg: 8.16.3 + postgres: 3.4.7 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 eastasianwidth@0.2.0: {} - electron-to-chromium@1.5.143: {} + ee-first@1.1.1: {} + + electron-to-chromium@1.5.179: {} emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} - enhanced-resolve@5.18.1: + encodeurl@2.0.0: {} + + enhanced-resolve@5.18.2: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.2.2 env-paths@3.0.0: optional: true @@ -4262,10 +4704,18 @@ snapshots: dependencies: is-arrayish: 0.2.1 - esbuild-register@3.6.0(esbuild@0.25.3): + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + esbuild-register@3.6.0(esbuild@0.25.5): dependencies: - debug: 4.4.0 - esbuild: 0.25.3 + debug: 4.4.1 + esbuild: 0.25.5 transitivePeerDependencies: - supports-color @@ -4294,38 +4744,48 @@ snapshots: '@esbuild/win32-ia32': 0.18.20 '@esbuild/win32-x64': 0.18.20 - esbuild@0.25.3: + esbuild@0.25.5: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.3 - '@esbuild/android-arm': 0.25.3 - '@esbuild/android-arm64': 0.25.3 - '@esbuild/android-x64': 0.25.3 - '@esbuild/darwin-arm64': 0.25.3 - '@esbuild/darwin-x64': 0.25.3 - '@esbuild/freebsd-arm64': 0.25.3 - '@esbuild/freebsd-x64': 0.25.3 - '@esbuild/linux-arm': 0.25.3 - '@esbuild/linux-arm64': 0.25.3 - '@esbuild/linux-ia32': 0.25.3 - '@esbuild/linux-loong64': 0.25.3 - '@esbuild/linux-mips64el': 0.25.3 - '@esbuild/linux-ppc64': 0.25.3 - '@esbuild/linux-riscv64': 0.25.3 - '@esbuild/linux-s390x': 0.25.3 - '@esbuild/linux-x64': 0.25.3 - '@esbuild/netbsd-arm64': 0.25.3 - '@esbuild/netbsd-x64': 0.25.3 - '@esbuild/openbsd-arm64': 0.25.3 - '@esbuild/openbsd-x64': 0.25.3 - '@esbuild/sunos-x64': 0.25.3 - '@esbuild/win32-arm64': 0.25.3 - '@esbuild/win32-ia32': 0.25.3 - '@esbuild/win32-x64': 0.25.3 + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 escalade@3.2.0: {} + escape-html@1.0.3: {} + esprima@4.0.1: {} + etag@1.8.1: {} + + eventsource-parser@3.0.3: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.3 + execa@7.2.0: dependencies: cross-spawn: 7.0.6 @@ -4340,6 +4800,44 @@ snapshots: export-to-csv@1.4.0: {} + express-rate-limit@7.5.1(express@5.1.0): + dependencies: + express: 5.1.0 + + express@5.1.0: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.0 + content-disposition: 1.0.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.0 + fresh: 2.0.0 + http-errors: 2.0.0 + merge-descriptors: 2.0.0 + mime-types: 3.0.1 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.0 + serve-static: 2.2.0 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4348,6 +4846,8 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-json-stable-stringify@2.1.0: {} + fastq@1.19.1: dependencies: reusify: 1.1.0 @@ -4361,6 +4861,17 @@ snapshots: dependencies: to-regex-range: 5.0.1 + finalhandler@2.1.0: + dependencies: + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -4370,15 +4881,19 @@ snapshots: dependencies: fetch-blob: 3.2.0 - framer-motion@12.9.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + forwarded@0.2.0: {} + + framer-motion@12.23.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - motion-dom: 12.9.1 - motion-utils: 12.8.3 + motion-dom: 12.22.0 + motion-utils: 12.19.0 tslib: 2.8.1 optionalDependencies: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) + fresh@2.0.0: {} + fs-extra@11.3.0: dependencies: graceful-fs: 4.2.11 @@ -4388,17 +4903,19 @@ snapshots: fsevents@2.3.3: optional: true - geist@1.3.1(next@15.3.1(@babel/core@7.26.10)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)): + function-bind@1.1.2: {} + + geist@1.4.2(next@15.3.4(@babel/core@7.28.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)): dependencies: - next: 15.3.1(@babel/core@7.26.10)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next: 15.3.4(@babel/core@7.28.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) gel@2.0.1: dependencies: '@petamoriken/float16': 3.9.2 - debug: 4.4.0 + debug: 4.4.1 env-paths: 3.0.0 - semver: 7.7.1 - shell-quote: 1.8.2 + semver: 7.7.2 + shell-quote: 1.8.3 which: 4.0.0 transitivePeerDependencies: - supports-color @@ -4408,13 +4925,31 @@ snapshots: get-caller-file@2.0.5: {} + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + get-nonce@1.0.1: {} get-own-enumerable-keys@1.0.0: {} + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + get-stream@6.0.1: {} - get-tsconfig@4.10.0: + get-tsconfig@4.10.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -4422,32 +4957,50 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@11.0.2: + glob@11.0.3: dependencies: foreground-child: 3.3.1 - jackspeak: 4.1.0 - minimatch: 10.0.1 + jackspeak: 4.1.1 + minimatch: 10.0.3 minipass: 7.1.2 package-json-from-dist: 1.0.1 path-scurry: 2.0.0 - globals@11.12.0: {} + gopd@1.2.0: {} graceful-fs@4.2.11: {} graphql@16.11.0: {} + has-symbols@1.1.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + headers-polyfill@4.0.3: {} + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + https-proxy-agent@6.2.1: dependencies: agent-base: 7.1.3 - debug: 4.4.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color human-signals@4.3.1: {} + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + ieee754@1.2.1: {} import-fresh@3.3.1: @@ -4457,6 +5010,8 @@ snapshots: inherits@2.0.4: {} + ipaddr.js@1.9.1: {} + is-arrayish@0.2.1: {} is-arrayish@0.3.2: @@ -4478,6 +5033,8 @@ snapshots: is-obj@3.0.0: {} + is-promise@4.0.0: {} + is-regexp@3.1.0: {} is-stream@3.0.0: {} @@ -4489,7 +5046,7 @@ snapshots: isexe@3.1.1: optional: true - jackspeak@4.1.0: + jackspeak@4.1.1: dependencies: '@isaacs/cliui': 8.0.2 @@ -4505,6 +5062,8 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-schema-traverse@0.4.1: {} + json5@2.2.3: {} jsonfile@6.1.0: @@ -4517,50 +5076,50 @@ snapshots: kleur@4.1.5: {} - lightningcss-darwin-arm64@1.29.2: + lightningcss-darwin-arm64@1.30.1: optional: true - lightningcss-darwin-x64@1.29.2: + lightningcss-darwin-x64@1.30.1: optional: true - lightningcss-freebsd-x64@1.29.2: + lightningcss-freebsd-x64@1.30.1: optional: true - lightningcss-linux-arm-gnueabihf@1.29.2: + lightningcss-linux-arm-gnueabihf@1.30.1: optional: true - lightningcss-linux-arm64-gnu@1.29.2: + lightningcss-linux-arm64-gnu@1.30.1: optional: true - lightningcss-linux-arm64-musl@1.29.2: + lightningcss-linux-arm64-musl@1.30.1: optional: true - lightningcss-linux-x64-gnu@1.29.2: + lightningcss-linux-x64-gnu@1.30.1: optional: true - lightningcss-linux-x64-musl@1.29.2: + lightningcss-linux-x64-musl@1.30.1: optional: true - lightningcss-win32-arm64-msvc@1.29.2: + lightningcss-win32-arm64-msvc@1.30.1: optional: true - lightningcss-win32-x64-msvc@1.29.2: + lightningcss-win32-x64-msvc@1.30.1: optional: true - lightningcss@1.29.2: + lightningcss@1.30.1: dependencies: detect-libc: 2.0.4 optionalDependencies: - lightningcss-darwin-arm64: 1.29.2 - lightningcss-darwin-x64: 1.29.2 - lightningcss-freebsd-x64: 1.29.2 - lightningcss-linux-arm-gnueabihf: 1.29.2 - lightningcss-linux-arm64-gnu: 1.29.2 - lightningcss-linux-arm64-musl: 1.29.2 - lightningcss-linux-x64-gnu: 1.29.2 - lightningcss-linux-x64-musl: 1.29.2 - lightningcss-win32-arm64-msvc: 1.29.2 - lightningcss-win32-x64-msvc: 1.29.2 + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 lines-and-columns@1.2.4: {} @@ -4575,10 +5134,20 @@ snapshots: dependencies: yallist: 3.1.1 - lucide-react@0.503.0(react@19.1.0): + lucide-react@0.525.0(react@19.1.0): dependencies: react: 19.1.0 + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.4 + + math-intrinsics@1.1.0: {} + + media-typer@1.1.0: {} + + merge-descriptors@2.0.0: {} + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -4588,35 +5157,47 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.54.0: {} + + mime-types@3.0.1: + dependencies: + mime-db: 1.54.0 + mimic-fn@2.1.0: {} mimic-fn@4.0.0: {} - minimatch@10.0.1: + minimatch@10.0.3: dependencies: - brace-expansion: 2.0.1 + '@isaacs/brace-expansion': 5.0.0 minimatch@7.4.6: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 minimist@1.2.8: {} minipass@7.1.2: {} + minizlib@3.0.2: + dependencies: + minipass: 7.1.2 + mitt@3.0.1: {} mkdirp@2.1.6: {} - motion-dom@12.9.1: + mkdirp@3.0.1: {} + + motion-dom@12.22.0: dependencies: - motion-utils: 12.8.3 + motion-utils: 12.19.0 - motion-utils@12.8.3: {} + motion-utils@12.19.0: {} - motion@12.9.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + motion@12.23.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - framer-motion: 12.9.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + framer-motion: 12.23.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) tslib: 2.8.1 optionalDependencies: react: 19.1.0 @@ -4624,17 +5205,17 @@ snapshots: ms@2.1.3: {} - msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3): + msw@2.10.2(@types/node@24.0.10)(typescript@5.8.3): dependencies: '@bundled-es-modules/cookie': 2.0.1 '@bundled-es-modules/statuses': 1.0.1 '@bundled-es-modules/tough-cookie': 0.1.6 - '@inquirer/confirm': 5.1.9(@types/node@22.15.2) - '@mswjs/interceptors': 0.37.6 + '@inquirer/confirm': 5.1.13(@types/node@24.0.10) + '@mswjs/interceptors': 0.39.2 '@open-draft/deferred-promise': 2.2.0 '@open-draft/until': 2.1.0 '@types/cookie': 0.6.0 - '@types/statuses': 2.0.5 + '@types/statuses': 2.0.6 graphql: 16.11.0 headers-polyfill: 4.0.3 is-node-process: 1.2.0 @@ -4642,7 +5223,7 @@ snapshots: path-to-regexp: 6.3.0 picocolors: 1.1.1 strict-event-emitter: 0.5.1 - type-fest: 4.40.1 + type-fest: 4.41.0 yargs: 17.7.2 optionalDependencies: typescript: 5.8.3 @@ -4655,32 +5236,34 @@ snapshots: nanoid@5.1.5: {} + negotiator@1.0.0: {} + next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - next@15.3.1(@babel/core@7.26.10)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + next@15.3.4(@babel/core@7.28.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - '@next/env': 15.3.1 + '@next/env': 15.3.4 '@swc/counter': 0.1.3 '@swc/helpers': 0.5.15 busboy: 1.6.0 - caniuse-lite: 1.0.30001715 + caniuse-lite: 1.0.30001726 postcss: 8.4.31 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - styled-jsx: 5.1.6(@babel/core@7.26.10)(react@19.1.0) + styled-jsx: 5.1.6(@babel/core@7.28.0)(react@19.1.0) optionalDependencies: - '@next/swc-darwin-arm64': 15.3.1 - '@next/swc-darwin-x64': 15.3.1 - '@next/swc-linux-arm64-gnu': 15.3.1 - '@next/swc-linux-arm64-musl': 15.3.1 - '@next/swc-linux-x64-gnu': 15.3.1 - '@next/swc-linux-x64-musl': 15.3.1 - '@next/swc-win32-arm64-msvc': 15.3.1 - '@next/swc-win32-x64-msvc': 15.3.1 - sharp: 0.34.1 + '@next/swc-darwin-arm64': 15.3.4 + '@next/swc-darwin-x64': 15.3.4 + '@next/swc-linux-arm64-gnu': 15.3.4 + '@next/swc-linux-arm64-musl': 15.3.4 + '@next/swc-linux-x64-gnu': 15.3.4 + '@next/swc-linux-x64-musl': 15.3.4 + '@next/swc-win32-arm64-msvc': 15.3.4 + '@next/swc-win32-x64-msvc': 15.3.4 + sharp: 0.34.2 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -4699,12 +5282,24 @@ snapshots: dependencies: path-key: 4.0.0 - nuqs@2.4.3(next@15.3.1(@babel/core@7.26.10)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0): + nuqs@2.4.3(next@15.3.4(@babel/core@7.28.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0): dependencies: mitt: 3.0.1 react: 19.1.0 optionalDependencies: - next: 15.3.1(@babel/core@7.26.10)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next: 15.3.4(@babel/core@7.28.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 onetime@5.1.2: dependencies: @@ -4736,11 +5331,13 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.27.1 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parseurl@1.3.3: {} + path-browserify@1.0.1: {} path-key@3.1.1: {} @@ -4754,20 +5351,22 @@ snapshots: path-to-regexp@6.3.0: {} + path-to-regexp@8.2.0: {} + path-type@4.0.0: {} - pg-cloudflare@1.2.5: + pg-cloudflare@1.2.7: optional: true - pg-connection-string@2.8.5: {} + pg-connection-string@2.9.1: {} pg-int8@1.0.1: {} - pg-pool@3.9.5(pg@8.15.5): + pg-pool@3.10.1(pg@8.16.3): dependencies: - pg: 8.15.5 + pg: 8.16.3 - pg-protocol@1.9.5: {} + pg-protocol@1.10.3: {} pg-types@2.2.0: dependencies: @@ -4777,15 +5376,15 @@ snapshots: postgres-date: 1.0.7 postgres-interval: 1.2.0 - pg@8.15.5: + pg@8.16.3: dependencies: - pg-connection-string: 2.8.5 - pg-pool: 3.9.5(pg@8.15.5) - pg-protocol: 1.9.5 + pg-connection-string: 2.9.1 + pg-pool: 3.10.1(pg@8.16.3) + pg-protocol: 1.10.3 pg-types: 2.2.0 pgpass: 1.0.5 optionalDependencies: - pg-cloudflare: 1.2.5 + pg-cloudflare: 1.2.7 pgpass@1.0.5: dependencies: @@ -4795,13 +5394,15 @@ snapshots: picomatch@2.3.1: {} + pkce-challenge@5.0.0: {} + postcss@8.4.31: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 - postcss@8.5.3: + postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -4817,26 +5418,46 @@ snapshots: dependencies: xtend: 4.0.2 - postgres@3.4.5: {} + postgres@3.4.7: {} prompts@2.4.2: dependencies: kleur: 3.0.3 sisteransi: 1.0.5 + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + psl@1.15.0: dependencies: punycode: 2.3.1 punycode@2.3.1: {} + qs@6.14.0: + dependencies: + side-channel: 1.1.0 + querystringify@2.2.0: {} queue-microtask@1.2.3: {} - react-day-picker@8.10.1(date-fns@4.1.0)(react@19.1.0): + range-parser@1.2.1: {} + + raw-body@3.0.0: dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + unpipe: 1.0.0 + + react-day-picker@9.7.0(react@19.1.0): + dependencies: + '@date-fns/tz': 1.2.0 date-fns: 4.1.0 + date-fns-jalali: 4.1.0-0 react: 19.1.0 react-dom@19.1.0(react@19.1.0): @@ -4844,36 +5465,36 @@ snapshots: react: 19.1.0 scheduler: 0.26.0 - react-hook-form@7.56.1(react@19.1.0): + react-hook-form@7.59.0(react@19.1.0): dependencies: react: 19.1.0 - react-remove-scroll-bar@2.3.8(@types/react@19.1.2)(react@19.1.0): + react-remove-scroll-bar@2.3.8(@types/react@19.1.8)(react@19.1.0): dependencies: react: 19.1.0 - react-style-singleton: 2.2.3(@types/react@19.1.2)(react@19.1.0) + react-style-singleton: 2.2.3(@types/react@19.1.8)(react@19.1.0) tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - react-remove-scroll@2.6.3(@types/react@19.1.2)(react@19.1.0): + react-remove-scroll@2.7.1(@types/react@19.1.8)(react@19.1.0): dependencies: react: 19.1.0 - react-remove-scroll-bar: 2.3.8(@types/react@19.1.2)(react@19.1.0) - react-style-singleton: 2.2.3(@types/react@19.1.2)(react@19.1.0) + react-remove-scroll-bar: 2.3.8(@types/react@19.1.8)(react@19.1.0) + react-style-singleton: 2.2.3(@types/react@19.1.8)(react@19.1.0) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.1.2)(react@19.1.0) - use-sidecar: 1.1.3(@types/react@19.1.2)(react@19.1.0) + use-callback-ref: 1.3.3(@types/react@19.1.8)(react@19.1.0) + use-sidecar: 1.1.3(@types/react@19.1.8)(react@19.1.0) optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - react-style-singleton@2.2.3(@types/react@19.1.2)(react@19.1.0): + react-style-singleton@2.2.3(@types/react@19.1.8)(react@19.1.0): dependencies: get-nonce: 1.0.1 react: 19.1.0 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 react@19.1.0: {} @@ -4908,30 +5529,70 @@ snapshots: rimraf@6.0.1: dependencies: - glob: 11.0.2 + glob: 11.0.3 package-json-from-dist: 1.0.1 + router@2.2.0: + dependencies: + debug: 4.4.1 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.2.0 + transitivePeerDependencies: + - supports-color + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 safe-buffer@5.2.1: {} + safer-buffer@2.1.2: {} + scheduler@0.26.0: {} semver@6.3.1: {} - semver@7.7.1: + semver@7.7.2: optional: true + send@1.2.0: + dependencies: + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.0 + mime-types: 3.0.1 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.0: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.0 + transitivePeerDependencies: + - supports-color + server-only@0.0.1: {} - shadcn@2.5.0(@types/node@22.15.2)(typescript@5.8.3): + setprototypeof@1.2.0: {} + + shadcn@2.7.0(@types/node@24.0.10)(typescript@5.8.3): dependencies: '@antfu/ni': 23.3.1 - '@babel/core': 7.26.10 - '@babel/parser': 7.27.0 - '@babel/plugin-transform-typescript': 7.27.0(@babel/core@7.26.10) + '@babel/core': 7.28.0 + '@babel/parser': 7.28.0 + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.0) + '@modelcontextprotocol/sdk': 1.13.3 commander: 10.0.1 cosmiconfig: 8.3.6(typescript@5.8.3) deepmerge: 4.3.1 @@ -4941,29 +5602,30 @@ snapshots: fs-extra: 11.3.0 https-proxy-agent: 6.2.1 kleur: 4.1.5 - msw: 2.7.5(@types/node@22.15.2)(typescript@5.8.3) + msw: 2.10.2(@types/node@24.0.10)(typescript@5.8.3) node-fetch: 3.3.2 ora: 6.3.1 - postcss: 8.5.3 + postcss: 8.5.6 prompts: 2.4.2 recast: 0.23.11 stringify-object: 5.0.0 ts-morph: 18.0.0 tsconfig-paths: 4.2.0 - zod: 3.24.3 + zod: 3.25.71 + zod-to-json-schema: 3.24.6(zod@3.25.71) transitivePeerDependencies: - '@types/node' - supports-color - typescript - sharp@0.34.1: + sharp@0.34.2: dependencies: color: 4.2.3 detect-libc: 2.0.4 - semver: 7.7.1 + semver: 7.7.2 optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.1 - '@img/sharp-darwin-x64': 0.34.1 + '@img/sharp-darwin-arm64': 0.34.2 + '@img/sharp-darwin-x64': 0.34.2 '@img/sharp-libvips-darwin-arm64': 1.1.0 '@img/sharp-libvips-darwin-x64': 1.1.0 '@img/sharp-libvips-linux-arm': 1.1.0 @@ -4973,15 +5635,16 @@ snapshots: '@img/sharp-libvips-linux-x64': 1.1.0 '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 '@img/sharp-libvips-linuxmusl-x64': 1.1.0 - '@img/sharp-linux-arm': 0.34.1 - '@img/sharp-linux-arm64': 0.34.1 - '@img/sharp-linux-s390x': 0.34.1 - '@img/sharp-linux-x64': 0.34.1 - '@img/sharp-linuxmusl-arm64': 0.34.1 - '@img/sharp-linuxmusl-x64': 0.34.1 - '@img/sharp-wasm32': 0.34.1 - '@img/sharp-win32-ia32': 0.34.1 - '@img/sharp-win32-x64': 0.34.1 + '@img/sharp-linux-arm': 0.34.2 + '@img/sharp-linux-arm64': 0.34.2 + '@img/sharp-linux-s390x': 0.34.2 + '@img/sharp-linux-x64': 0.34.2 + '@img/sharp-linuxmusl-arm64': 0.34.2 + '@img/sharp-linuxmusl-x64': 0.34.2 + '@img/sharp-wasm32': 0.34.2 + '@img/sharp-win32-arm64': 0.34.2 + '@img/sharp-win32-ia32': 0.34.2 + '@img/sharp-win32-x64': 0.34.2 optional: true shebang-command@2.0.0: @@ -4990,9 +5653,37 @@ snapshots: shebang-regex@3.0.0: {} - shell-quote@1.8.2: + shell-quote@1.8.3: optional: true + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -5004,7 +5695,7 @@ snapshots: sisteransi@1.0.5: {} - sonner@2.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + sonner@2.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) @@ -5022,6 +5713,8 @@ snapshots: statuses@2.0.1: {} + statuses@2.0.2: {} + stdin-discarder@0.1.0: dependencies: bl: 5.1.0 @@ -5064,18 +5757,27 @@ snapshots: strip-final-newline@3.0.0: {} - styled-jsx@5.1.6(@babel/core@7.26.10)(react@19.1.0): + styled-jsx@5.1.6(@babel/core@7.28.0)(react@19.1.0): dependencies: client-only: 0.0.1 react: 19.1.0 optionalDependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 - tailwind-merge@3.2.0: {} + tailwind-merge@3.3.1: {} - tailwindcss@4.1.4: {} + tailwindcss@4.1.11: {} - tapable@2.2.1: {} + tapable@2.2.2: {} + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 tiny-invariant@1.3.3: {} @@ -5083,6 +5785,8 @@ snapshots: dependencies: is-number: 7.0.0 + toidentifier@1.0.1: {} + tough-cookie@4.1.4: dependencies: psl: 1.15.0 @@ -5103,58 +5807,72 @@ snapshots: tslib@2.8.1: {} - tsx@4.19.3: + tsx@4.20.3: dependencies: - esbuild: 0.25.3 - get-tsconfig: 4.10.0 + esbuild: 0.25.5 + get-tsconfig: 4.10.1 optionalDependencies: fsevents: 2.3.3 - tw-animate-css@1.2.8: {} + tw-animate-css@1.3.4: {} type-fest@0.21.3: {} - type-fest@4.40.1: {} + type-fest@4.41.0: {} + + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.1 typescript@5.8.3: {} - undici-types@6.21.0: {} + undici-types@7.8.0: {} universalify@0.2.0: {} universalify@2.0.1: {} - update-browserslist-db@1.1.3(browserslist@4.24.4): + unpipe@1.0.0: {} + + update-browserslist-db@1.1.3(browserslist@4.25.1): dependencies: - browserslist: 4.24.4 + browserslist: 4.25.1 escalade: 3.2.0 picocolors: 1.1.1 + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + url-parse@1.5.10: dependencies: querystringify: 2.2.0 requires-port: 1.0.0 - use-callback-ref@1.3.3(@types/react@19.1.2)(react@19.1.0): + use-callback-ref@1.3.3(@types/react@19.1.8)(react@19.1.0): dependencies: react: 19.1.0 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 - use-sidecar@1.1.3(@types/react@19.1.2)(react@19.1.0): + use-sidecar@1.1.3(@types/react@19.1.8)(react@19.1.0): dependencies: detect-node-es: 1.1.0 react: 19.1.0 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.8 util-deprecate@1.0.2: {} - vaul@1.1.2(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + vary@1.1.2: {} + + vaul@1.1.2(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - '@radix-ui/react-dialog': 1.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-dialog': 1.1.14(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) transitivePeerDependencies: @@ -5194,12 +5912,16 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 + wrappy@1.0.2: {} + xtend@4.0.2: {} y18n@5.0.8: {} yallist@3.1.1: {} + yallist@5.0.0: {} + yargs-parser@21.1.1: {} yargs@17.7.2: @@ -5214,4 +5936,8 @@ snapshots: yoctocolors-cjs@2.1.2: {} - zod@3.24.3: {} + zod-to-json-schema@3.24.6(zod@3.25.71): + dependencies: + zod: 3.25.71 + + zod@3.25.71: {} diff --git a/public/r/data-table-action-bar.json b/public/r/data-table-action-bar.json index 267dcdda..d4dea9b8 100644 --- a/public/r/data-table-action-bar.json +++ b/public/r/data-table-action-bar.json @@ -16,7 +16,7 @@ "files": [ { "path": "src/components/data-table/data-table-action-bar.tsx", - "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Separator } from \"@/components/ui/separator\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\nimport type { Table } from \"@tanstack/react-table\";\nimport { Loader, X } from \"lucide-react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\n\ninterface DataTableActionBarProps\n extends React.ComponentProps {\n table: Table;\n visible?: boolean;\n container?: Element | DocumentFragment | null;\n}\n\nfunction DataTableActionBar({\n table,\n visible: visibleProp,\n container: containerProp,\n children,\n className,\n ...props\n}: DataTableActionBarProps) {\n const [mounted, setMounted] = React.useState(false);\n\n React.useLayoutEffect(() => {\n setMounted(true);\n }, []);\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n table.toggleAllRowsSelected(false);\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [table]);\n\n const container =\n containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n const visible =\n visibleProp ?? table.getFilteredSelectedRowModel().rows.length > 0;\n\n return ReactDOM.createPortal(\n \n {visible && (\n \n {children}\n \n )}\n ,\n container,\n );\n}\n\ninterface DataTableActionBarActionProps\n extends React.ComponentProps {\n tooltip?: string;\n isPending?: boolean;\n}\n\nfunction DataTableActionBarAction({\n size = \"sm\",\n tooltip,\n isPending,\n disabled,\n className,\n children,\n ...props\n}: DataTableActionBarActionProps) {\n const trigger = (\n svg]:size-3.5\",\n size === \"icon\" ? \"size-7\" : \"h-7\",\n className,\n )}\n disabled={disabled || isPending}\n {...props}\n >\n {isPending ? : children}\n \n );\n\n if (!tooltip) return trigger;\n\n return (\n \n {trigger}\n span]:hidden\"\n >\n

{tooltip}

\n \n
\n );\n}\n\ninterface DataTableActionBarSelectionProps {\n table: Table;\n}\n\nfunction DataTableActionBarSelection({\n table,\n}: DataTableActionBarSelectionProps) {\n const onClearSelection = React.useCallback(() => {\n table.toggleAllRowsSelected(false);\n }, [table]);\n\n return (\n
\n \n {table.getFilteredSelectedRowModel().rows.length} selected\n \n \n \n \n \n \n \n \n span]:hidden\"\n >\n

Clear selection

\n \n \n Esc\n \n \n \n
\n
\n );\n}\n\nexport {\n DataTableActionBar,\n DataTableActionBarAction,\n DataTableActionBarSelection,\n};\n", + "content": "\"use client\";\n\nimport type { Table } from \"@tanstack/react-table\";\nimport { Loader, X } from \"lucide-react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { Button } from \"@/components/ui/button\";\nimport { Separator } from \"@/components/ui/separator\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\n\ninterface DataTableActionBarProps\n extends React.ComponentProps {\n table: Table;\n visible?: boolean;\n container?: Element | DocumentFragment | null;\n}\n\nfunction DataTableActionBar({\n table,\n visible: visibleProp,\n container: containerProp,\n children,\n className,\n ...props\n}: DataTableActionBarProps) {\n const [mounted, setMounted] = React.useState(false);\n\n React.useLayoutEffect(() => {\n setMounted(true);\n }, []);\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n table.toggleAllRowsSelected(false);\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [table]);\n\n const container =\n containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n const visible =\n visibleProp ?? table.getFilteredSelectedRowModel().rows.length > 0;\n\n return ReactDOM.createPortal(\n \n {visible && (\n \n {children}\n \n )}\n ,\n container,\n );\n}\n\ninterface DataTableActionBarActionProps\n extends React.ComponentProps {\n tooltip?: string;\n isPending?: boolean;\n}\n\nfunction DataTableActionBarAction({\n size = \"sm\",\n tooltip,\n isPending,\n disabled,\n className,\n children,\n ...props\n}: DataTableActionBarActionProps) {\n const trigger = (\n svg]:size-3.5\",\n size === \"icon\" ? \"size-7\" : \"h-7\",\n className,\n )}\n disabled={disabled || isPending}\n {...props}\n >\n {isPending ? : children}\n \n );\n\n if (!tooltip) return trigger;\n\n return (\n \n {trigger}\n span]:hidden\"\n >\n

{tooltip}

\n \n
\n );\n}\n\ninterface DataTableActionBarSelectionProps {\n table: Table;\n}\n\nfunction DataTableActionBarSelection({\n table,\n}: DataTableActionBarSelectionProps) {\n const onClearSelection = React.useCallback(() => {\n table.toggleAllRowsSelected(false);\n }, [table]);\n\n return (\n
\n \n {table.getFilteredSelectedRowModel().rows.length} selected\n \n \n \n \n \n \n \n \n span]:hidden\"\n >\n

Clear selection

\n \n \n Esc\n \n \n \n
\n
\n );\n}\n\nexport {\n DataTableActionBar,\n DataTableActionBarAction,\n DataTableActionBarSelection,\n};\n", "type": "registry:component", "target": "src/components/data-table/data-table-action-bar.tsx" } diff --git a/public/r/data-table-filter-list.json b/public/r/data-table-filter-list.json index c6261f64..040a92ad 100644 --- a/public/r/data-table-filter-list.json +++ b/public/r/data-table-filter-list.json @@ -22,7 +22,7 @@ "files": [ { "path": "src/components/data-table/data-table-filter-list.tsx", - "content": "\"use client\";\n\nimport type { Column, ColumnMeta, Table } from \"@tanstack/react-table\";\nimport {\n CalendarIcon,\n Check,\n ChevronsUpDown,\n GripVertical,\n ListFilter,\n Trash2,\n} from \"lucide-react\";\nimport { parseAsStringEnum, useQueryState } from \"nuqs\";\nimport * as React from \"react\";\n\nimport { DataTableRangeFilter } from \"@/components/data-table/data-table-range-filter\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Calendar } from \"@/components/ui/calendar\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/components/ui/command\";\nimport {\n Faceted,\n FacetedBadgeList,\n FacetedContent,\n FacetedEmpty,\n FacetedGroup,\n FacetedInput,\n FacetedItem,\n FacetedList,\n FacetedTrigger,\n} from \"@/components/ui/faceted\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport {\n Sortable,\n SortableContent,\n SortableItem,\n SortableItemHandle,\n SortableOverlay,\n} from \"@/components/ui/sortable\";\nimport { dataTableConfig } from \"@/config/data-table\";\nimport { useDebouncedCallback } from \"@/hooks/use-debounced-callback\";\nimport { getDefaultFilterOperator, getFilterOperators } from \"@/lib/data-table\";\nimport { formatDate } from \"@/lib/format\";\nimport { generateId } from \"@/lib/id\";\nimport { getFiltersStateParser } from \"@/lib/parsers\";\nimport { cn } from \"@/lib/utils\";\nimport type {\n ExtendedColumnFilter,\n FilterOperator,\n JoinOperator,\n} from \"@/types/data-table\";\n\nconst FILTERS_KEY = \"filters\";\nconst JOIN_OPERATOR_KEY = \"joinOperator\";\nconst DEBOUNCE_MS = 300;\nconst THROTTLE_MS = 50;\nconst OPEN_MENU_SHORTCUT = \"f\";\nconst REMOVE_FILTER_SHORTCUTS = [\"backspace\", \"delete\"];\n\ninterface DataTableFilterListProps\n extends React.ComponentProps {\n table: Table;\n debounceMs?: number;\n throttleMs?: number;\n shallow?: boolean;\n}\n\nexport function DataTableFilterList({\n table,\n debounceMs = DEBOUNCE_MS,\n throttleMs = THROTTLE_MS,\n shallow = true,\n ...props\n}: DataTableFilterListProps) {\n const id = React.useId();\n const labelId = React.useId();\n const descriptionId = React.useId();\n const [open, setOpen] = React.useState(false);\n const addButtonRef = React.useRef(null);\n\n const columns = React.useMemo(() => {\n return table\n .getAllColumns()\n .filter((column) => column.columnDef.enableColumnFilter);\n }, [table]);\n\n const [filters, setFilters] = useQueryState(\n FILTERS_KEY,\n getFiltersStateParser(columns.map((field) => field.id))\n .withDefault([])\n .withOptions({\n clearOnDefault: true,\n shallow,\n throttleMs,\n }),\n );\n const debouncedSetFilters = useDebouncedCallback(setFilters, debounceMs);\n\n const [joinOperator, setJoinOperator] = useQueryState(\n JOIN_OPERATOR_KEY,\n parseAsStringEnum([\"and\", \"or\"]).withDefault(\"and\").withOptions({\n clearOnDefault: true,\n shallow,\n }),\n );\n\n const onFilterAdd = React.useCallback(() => {\n const column = columns[0];\n\n if (!column) return;\n\n debouncedSetFilters([\n ...filters,\n {\n id: column.id as Extract,\n value: \"\",\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n filterId: generateId({ length: 8 }),\n },\n ]);\n }, [columns, filters, debouncedSetFilters]);\n\n const onFilterUpdate = React.useCallback(\n (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => {\n debouncedSetFilters((prevFilters) => {\n const updatedFilters = prevFilters.map((filter) => {\n if (filter.filterId === filterId) {\n return { ...filter, ...updates } as ExtendedColumnFilter;\n }\n return filter;\n });\n return updatedFilters;\n });\n },\n [debouncedSetFilters],\n );\n\n const onFilterRemove = React.useCallback(\n (filterId: string) => {\n const updatedFilters = filters.filter(\n (filter) => filter.filterId !== filterId,\n );\n void setFilters(updatedFilters);\n requestAnimationFrame(() => {\n addButtonRef.current?.focus();\n });\n },\n [filters, setFilters],\n );\n\n const onFiltersReset = React.useCallback(() => {\n void setFilters(null);\n void setJoinOperator(\"and\");\n }, [setFilters, setJoinOperator]);\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey\n ) {\n event.preventDefault();\n setOpen(true);\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n event.shiftKey &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [filters, onFilterRemove]);\n\n const onTriggerKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase()) &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n },\n [filters, onFilterRemove],\n );\n\n return (\n item.filterId}\n >\n \n \n \n \n \n
\n

\n {filters.length > 0 ? \"Filters\" : \"No filters applied\"}\n

\n 0 && \"sr-only\",\n )}\n >\n {filters.length > 0\n ? \"Modify filters to refine your rows.\"\n : \"Add filters to refine your rows.\"}\n

\n
\n {filters.length > 0 ? (\n \n \n {filters.map((filter, index) => (\n \n key={filter.filterId}\n filter={filter}\n index={index}\n filterItemId={`${id}-filter-${filter.filterId}`}\n joinOperator={joinOperator}\n setJoinOperator={setJoinOperator}\n columns={columns}\n onFilterUpdate={onFilterUpdate}\n onFilterRemove={onFilterRemove}\n />\n ))}\n
\n \n ) : null}\n
\n \n Add filter\n \n {filters.length > 0 ? (\n \n Reset filters\n \n ) : null}\n
\n \n \n \n
\n
\n
\n
\n
\n
\n
\n
\n \n \n );\n}\n\ninterface DataTableFilterItemProps {\n filter: ExtendedColumnFilter;\n index: number;\n filterItemId: string;\n joinOperator: JoinOperator;\n setJoinOperator: (value: JoinOperator) => void;\n columns: Column[];\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n onFilterRemove: (filterId: string) => void;\n}\n\nfunction DataTableFilterItem({\n filter,\n index,\n filterItemId,\n joinOperator,\n setJoinOperator,\n columns,\n onFilterUpdate,\n onFilterRemove,\n}: DataTableFilterItemProps) {\n const [showFieldSelector, setShowFieldSelector] = React.useState(false);\n const [showOperatorSelector, setShowOperatorSelector] = React.useState(false);\n const [showValueSelector, setShowValueSelector] = React.useState(false);\n\n const column = columns.find((column) => column.id === filter.id);\n\n const joinOperatorListboxId = `${filterItemId}-join-operator-listbox`;\n const fieldListboxId = `${filterItemId}-field-listbox`;\n const operatorListboxId = `${filterItemId}-operator-listbox`;\n const inputId = `${filterItemId}-input`;\n\n const columnMeta = column?.columnDef.meta;\n const filterOperators = getFilterOperators(filter.variant);\n\n const onItemKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (showFieldSelector || showOperatorSelector || showValueSelector) {\n return;\n }\n\n if (REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase())) {\n event.preventDefault();\n onFilterRemove(filter.filterId);\n }\n },\n [\n filter.filterId,\n showFieldSelector,\n showOperatorSelector,\n showValueSelector,\n onFilterRemove,\n ],\n );\n\n if (!column) return null;\n\n return (\n \n \n
\n {index === 0 ? (\n Where\n ) : index === 1 ? (\n setJoinOperator(value)}\n >\n \n \n \n \n {dataTableConfig.joinOperators.map((joinOperator) => (\n \n {joinOperator}\n \n ))}\n \n \n ) : (\n \n {joinOperator}\n \n )}\n
\n \n \n \n \n {columns.find((column) => column.id === filter.id)?.columnDef\n .meta?.label ?? \"Select field\"}\n \n \n \n \n \n \n \n \n No fields found.\n \n {columns.map((column) => (\n {\n onFilterUpdate(filter.filterId, {\n id: value as Extract,\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n value: \"\",\n });\n\n setShowFieldSelector(false);\n }}\n >\n \n {column.columnDef.meta?.label}\n \n \n \n ))}\n \n \n \n \n \n \n onFilterUpdate(filter.filterId, {\n operator: value,\n value:\n value === \"isEmpty\" || value === \"isNotEmpty\"\n ? \"\"\n : filter.value,\n })\n }\n >\n \n
\n \n
\n \n \n {filterOperators.map((operator) => (\n \n {operator.label}\n \n ))}\n \n \n
\n {onFilterInputRender({\n filter,\n inputId,\n column,\n columnMeta,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n })}\n
\n onFilterRemove(filter.filterId)}\n >\n \n \n \n \n \n
\n \n );\n}\n\nfunction onFilterInputRender({\n filter,\n inputId,\n column,\n columnMeta,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n}: {\n filter: ExtendedColumnFilter;\n inputId: string;\n column: Column;\n columnMeta?: ColumnMeta;\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n showValueSelector: boolean;\n setShowValueSelector: (value: boolean) => void;\n}) {\n if (filter.operator === \"isEmpty\" || filter.operator === \"isNotEmpty\") {\n return (\n \n );\n }\n\n switch (filter.variant) {\n case \"text\":\n case \"number\":\n case \"range\": {\n if (\n (filter.variant === \"range\" && filter.operator === \"isBetween\") ||\n filter.operator === \"isBetween\"\n ) {\n return (\n \n );\n }\n\n const isNumber =\n filter.variant === \"number\" || filter.variant === \"range\";\n\n return (\n \n onFilterUpdate(filter.filterId, {\n value: event.target.value,\n })\n }\n />\n );\n }\n\n case \"boolean\": {\n if (Array.isArray(filter.value)) return null;\n\n const inputListboxId = `${inputId}-listbox`;\n\n return (\n \n onFilterUpdate(filter.filterId, {\n value,\n })\n }\n >\n \n \n \n \n True\n False\n \n \n );\n }\n\n case \"select\":\n case \"multiSelect\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const multiple = filter.variant === \"multiSelect\";\n const selectedValues = multiple\n ? Array.isArray(filter.value)\n ? filter.value\n : []\n : typeof filter.value === \"string\"\n ? filter.value\n : undefined;\n\n return (\n {\n onFilterUpdate(filter.filterId, {\n value,\n });\n }}\n multiple={multiple}\n >\n \n \n \n \n \n \n \n \n No options found.\n \n {columnMeta?.options?.map((option) => (\n \n {option.icon && }\n {option.label}\n {option.count && (\n \n {option.count}\n \n )}\n \n ))}\n \n \n \n \n );\n }\n\n case \"date\":\n case \"dateRange\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const dateValue = Array.isArray(filter.value)\n ? filter.value.filter(Boolean)\n : [filter.value, filter.value].filter(Boolean);\n\n const displayValue =\n filter.operator === \"isBetween\" && dateValue.length === 2\n ? `${formatDate(new Date(Number(dateValue[0])))} - ${formatDate(\n new Date(Number(dateValue[1])),\n )}`\n : dateValue[0]\n ? formatDate(new Date(Number(dateValue[0])))\n : \"Pick a date\";\n\n return (\n \n \n \n \n {displayValue}\n \n \n \n {filter.operator === \"isBetween\" ? (\n {\n onFilterUpdate(filter.filterId, {\n value: date\n ? [\n (date.from?.getTime() ?? \"\").toString(),\n (date.to?.getTime() ?? \"\").toString(),\n ]\n : [],\n });\n }}\n />\n ) : (\n {\n onFilterUpdate(filter.filterId, {\n value: (date?.getTime() ?? \"\").toString(),\n });\n }}\n />\n )}\n \n \n );\n }\n\n default:\n return null;\n }\n}\n", + "content": "\"use client\";\n\nimport type { Column, ColumnMeta, Table } from \"@tanstack/react-table\";\nimport {\n CalendarIcon,\n Check,\n ChevronsUpDown,\n GripVertical,\n ListFilter,\n Trash2,\n} from \"lucide-react\";\nimport { parseAsStringEnum, useQueryState } from \"nuqs\";\nimport * as React from \"react\";\n\nimport { DataTableRangeFilter } from \"@/components/data-table/data-table-range-filter\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Calendar } from \"@/components/ui/calendar\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/components/ui/command\";\nimport {\n Faceted,\n FacetedBadgeList,\n FacetedContent,\n FacetedEmpty,\n FacetedGroup,\n FacetedInput,\n FacetedItem,\n FacetedList,\n FacetedTrigger,\n} from \"@/components/ui/faceted\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport {\n Sortable,\n SortableContent,\n SortableItem,\n SortableItemHandle,\n SortableOverlay,\n} from \"@/components/ui/sortable\";\nimport { dataTableConfig } from \"@/config/data-table\";\nimport { useDebouncedCallback } from \"@/hooks/use-debounced-callback\";\nimport { getDefaultFilterOperator, getFilterOperators } from \"@/lib/data-table\";\nimport { formatDate } from \"@/lib/format\";\nimport { generateId } from \"@/lib/id\";\nimport { getFiltersStateParser } from \"@/lib/parsers\";\nimport { cn } from \"@/lib/utils\";\nimport type {\n ExtendedColumnFilter,\n FilterOperator,\n JoinOperator,\n} from \"@/types/data-table\";\n\nconst FILTERS_KEY = \"filters\";\nconst JOIN_OPERATOR_KEY = \"joinOperator\";\nconst DEBOUNCE_MS = 300;\nconst THROTTLE_MS = 50;\nconst OPEN_MENU_SHORTCUT = \"f\";\nconst REMOVE_FILTER_SHORTCUTS = [\"backspace\", \"delete\"];\n\ninterface DataTableFilterListProps\n extends React.ComponentProps {\n table: Table;\n debounceMs?: number;\n throttleMs?: number;\n shallow?: boolean;\n}\n\nexport function DataTableFilterList({\n table,\n debounceMs = DEBOUNCE_MS,\n throttleMs = THROTTLE_MS,\n shallow = true,\n ...props\n}: DataTableFilterListProps) {\n const id = React.useId();\n const labelId = React.useId();\n const descriptionId = React.useId();\n const [open, setOpen] = React.useState(false);\n const addButtonRef = React.useRef(null);\n\n const columns = React.useMemo(() => {\n return table\n .getAllColumns()\n .filter((column) => column.columnDef.enableColumnFilter);\n }, [table]);\n\n const [filters, setFilters] = useQueryState(\n FILTERS_KEY,\n getFiltersStateParser(columns.map((field) => field.id))\n .withDefault([])\n .withOptions({\n clearOnDefault: true,\n shallow,\n throttleMs,\n }),\n );\n const debouncedSetFilters = useDebouncedCallback(setFilters, debounceMs);\n\n const [joinOperator, setJoinOperator] = useQueryState(\n JOIN_OPERATOR_KEY,\n parseAsStringEnum([\"and\", \"or\"]).withDefault(\"and\").withOptions({\n clearOnDefault: true,\n shallow,\n }),\n );\n\n const onFilterAdd = React.useCallback(() => {\n const column = columns[0];\n\n if (!column) return;\n\n debouncedSetFilters([\n ...filters,\n {\n id: column.id as Extract,\n value: \"\",\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n filterId: generateId({ length: 8 }),\n },\n ]);\n }, [columns, filters, debouncedSetFilters]);\n\n const onFilterUpdate = React.useCallback(\n (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => {\n debouncedSetFilters((prevFilters) => {\n const updatedFilters = prevFilters.map((filter) => {\n if (filter.filterId === filterId) {\n return { ...filter, ...updates } as ExtendedColumnFilter;\n }\n return filter;\n });\n return updatedFilters;\n });\n },\n [debouncedSetFilters],\n );\n\n const onFilterRemove = React.useCallback(\n (filterId: string) => {\n const updatedFilters = filters.filter(\n (filter) => filter.filterId !== filterId,\n );\n void setFilters(updatedFilters);\n requestAnimationFrame(() => {\n addButtonRef.current?.focus();\n });\n },\n [filters, setFilters],\n );\n\n const onFiltersReset = React.useCallback(() => {\n void setFilters(null);\n void setJoinOperator(\"and\");\n }, [setFilters, setJoinOperator]);\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey\n ) {\n event.preventDefault();\n setOpen(true);\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n event.shiftKey &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [filters, onFilterRemove]);\n\n const onTriggerKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase()) &&\n filters.length > 0\n ) {\n event.preventDefault();\n onFilterRemove(filters[filters.length - 1]?.filterId ?? \"\");\n }\n },\n [filters, onFilterRemove],\n );\n\n return (\n item.filterId}\n >\n \n \n \n \n \n
\n

\n {filters.length > 0 ? \"Filters\" : \"No filters applied\"}\n

\n 0 && \"sr-only\",\n )}\n >\n {filters.length > 0\n ? \"Modify filters to refine your rows.\"\n : \"Add filters to refine your rows.\"}\n

\n
\n {filters.length > 0 ? (\n \n
    \n {filters.map((filter, index) => (\n \n key={filter.filterId}\n filter={filter}\n index={index}\n filterItemId={`${id}-filter-${filter.filterId}`}\n joinOperator={joinOperator}\n setJoinOperator={setJoinOperator}\n columns={columns}\n onFilterUpdate={onFilterUpdate}\n onFilterRemove={onFilterRemove}\n />\n ))}\n
\n
\n ) : null}\n
\n \n Add filter\n \n {filters.length > 0 ? (\n \n Reset filters\n \n ) : null}\n
\n \n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n \n \n );\n}\n\ninterface DataTableFilterItemProps {\n filter: ExtendedColumnFilter;\n index: number;\n filterItemId: string;\n joinOperator: JoinOperator;\n setJoinOperator: (value: JoinOperator) => void;\n columns: Column[];\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n onFilterRemove: (filterId: string) => void;\n}\n\nfunction DataTableFilterItem({\n filter,\n index,\n filterItemId,\n joinOperator,\n setJoinOperator,\n columns,\n onFilterUpdate,\n onFilterRemove,\n}: DataTableFilterItemProps) {\n const [showFieldSelector, setShowFieldSelector] = React.useState(false);\n const [showOperatorSelector, setShowOperatorSelector] = React.useState(false);\n const [showValueSelector, setShowValueSelector] = React.useState(false);\n\n const column = columns.find((column) => column.id === filter.id);\n\n const joinOperatorListboxId = `${filterItemId}-join-operator-listbox`;\n const fieldListboxId = `${filterItemId}-field-listbox`;\n const operatorListboxId = `${filterItemId}-operator-listbox`;\n const inputId = `${filterItemId}-input`;\n\n const columnMeta = column?.columnDef.meta;\n const filterOperators = getFilterOperators(filter.variant);\n\n const onItemKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (showFieldSelector || showOperatorSelector || showValueSelector) {\n return;\n }\n\n if (REMOVE_FILTER_SHORTCUTS.includes(event.key.toLowerCase())) {\n event.preventDefault();\n onFilterRemove(filter.filterId);\n }\n },\n [\n filter.filterId,\n showFieldSelector,\n showOperatorSelector,\n showValueSelector,\n onFilterRemove,\n ],\n );\n\n if (!column) return null;\n\n return (\n \n \n
\n {index === 0 ? (\n Where\n ) : index === 1 ? (\n setJoinOperator(value)}\n >\n \n \n \n \n {dataTableConfig.joinOperators.map((joinOperator) => (\n \n {joinOperator}\n \n ))}\n \n \n ) : (\n \n {joinOperator}\n \n )}\n
\n \n \n \n \n {columns.find((column) => column.id === filter.id)?.columnDef\n .meta?.label ?? \"Select field\"}\n \n \n \n \n \n \n \n \n No fields found.\n \n {columns.map((column) => (\n {\n onFilterUpdate(filter.filterId, {\n id: value as Extract,\n variant: column.columnDef.meta?.variant ?? \"text\",\n operator: getDefaultFilterOperator(\n column.columnDef.meta?.variant ?? \"text\",\n ),\n value: \"\",\n });\n\n setShowFieldSelector(false);\n }}\n >\n \n {column.columnDef.meta?.label}\n \n \n \n ))}\n \n \n \n \n \n \n onFilterUpdate(filter.filterId, {\n operator: value,\n value:\n value === \"isEmpty\" || value === \"isNotEmpty\"\n ? \"\"\n : filter.value,\n })\n }\n >\n \n
\n \n
\n \n \n {filterOperators.map((operator) => (\n \n {operator.label}\n \n ))}\n \n \n
\n {onFilterInputRender({\n filter,\n inputId,\n column,\n columnMeta,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n })}\n
\n onFilterRemove(filter.filterId)}\n >\n \n \n \n \n \n \n
\n );\n}\n\nfunction onFilterInputRender({\n filter,\n inputId,\n column,\n columnMeta,\n onFilterUpdate,\n showValueSelector,\n setShowValueSelector,\n}: {\n filter: ExtendedColumnFilter;\n inputId: string;\n column: Column;\n columnMeta?: ColumnMeta;\n onFilterUpdate: (\n filterId: string,\n updates: Partial, \"filterId\">>,\n ) => void;\n showValueSelector: boolean;\n setShowValueSelector: (value: boolean) => void;\n}) {\n if (filter.operator === \"isEmpty\" || filter.operator === \"isNotEmpty\") {\n return (\n \n );\n }\n\n switch (filter.variant) {\n case \"text\":\n case \"number\":\n case \"range\": {\n if (\n (filter.variant === \"range\" && filter.operator === \"isBetween\") ||\n filter.operator === \"isBetween\"\n ) {\n return (\n \n );\n }\n\n const isNumber =\n filter.variant === \"number\" || filter.variant === \"range\";\n\n return (\n \n onFilterUpdate(filter.filterId, {\n value: event.target.value,\n })\n }\n />\n );\n }\n\n case \"boolean\": {\n if (Array.isArray(filter.value)) return null;\n\n const inputListboxId = `${inputId}-listbox`;\n\n return (\n \n onFilterUpdate(filter.filterId, {\n value,\n })\n }\n >\n \n \n \n \n True\n False\n \n \n );\n }\n\n case \"select\":\n case \"multiSelect\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const multiple = filter.variant === \"multiSelect\";\n const selectedValues = multiple\n ? Array.isArray(filter.value)\n ? filter.value\n : []\n : typeof filter.value === \"string\"\n ? filter.value\n : undefined;\n\n return (\n {\n onFilterUpdate(filter.filterId, {\n value,\n });\n }}\n multiple={multiple}\n >\n \n \n \n \n \n \n \n \n No options found.\n \n {columnMeta?.options?.map((option) => (\n \n {option.icon && }\n {option.label}\n {option.count && (\n \n {option.count}\n \n )}\n \n ))}\n \n \n \n \n );\n }\n\n case \"date\":\n case \"dateRange\": {\n const inputListboxId = `${inputId}-listbox`;\n\n const dateValue = Array.isArray(filter.value)\n ? filter.value.filter(Boolean)\n : [filter.value, filter.value].filter(Boolean);\n\n const displayValue =\n filter.operator === \"isBetween\" && dateValue.length === 2\n ? `${formatDate(new Date(Number(dateValue[0])))} - ${formatDate(\n new Date(Number(dateValue[1])),\n )}`\n : dateValue[0]\n ? formatDate(new Date(Number(dateValue[0])))\n : \"Pick a date\";\n\n return (\n \n \n \n \n {displayValue}\n \n \n \n {filter.operator === \"isBetween\" ? (\n {\n onFilterUpdate(filter.filterId, {\n value: date\n ? [\n (date.from?.getTime() ?? \"\").toString(),\n (date.to?.getTime() ?? \"\").toString(),\n ]\n : [],\n });\n }}\n />\n ) : (\n {\n onFilterUpdate(filter.filterId, {\n value: (date?.getTime() ?? \"\").toString(),\n });\n }}\n />\n )}\n \n \n );\n }\n\n default:\n return null;\n }\n}\n", "type": "registry:component", "target": "src/components/data-table/data-table-filter-list.tsx" }, @@ -40,7 +40,7 @@ }, { "path": "src/components/ui/sortable.tsx", - "content": "\"use client\";\n\nimport {\n type Announcements,\n DndContext,\n type DndContextProps,\n type DragEndEvent,\n DragOverlay,\n type DraggableSyntheticListeners,\n type DropAnimation,\n KeyboardSensor,\n MouseSensor,\n type ScreenReaderInstructions,\n TouchSensor,\n type UniqueIdentifier,\n closestCenter,\n closestCorners,\n defaultDropAnimationSideEffects,\n useSensor,\n useSensors,\n} from \"@dnd-kit/core\";\nimport {\n restrictToHorizontalAxis,\n restrictToParentElement,\n restrictToVerticalAxis,\n} from \"@dnd-kit/modifiers\";\nimport {\n SortableContext,\n type SortableContextProps,\n arrayMove,\n horizontalListSortingStrategy,\n sortableKeyboardCoordinates,\n useSortable,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\n\nimport { composeEventHandlers, useComposedRefs } from \"@/lib/composition\";\nimport { cn } from \"@/lib/utils\";\nimport * as ReactDOM from \"react-dom\";\n\nconst orientationConfig = {\n vertical: {\n modifiers: [restrictToVerticalAxis, restrictToParentElement],\n strategy: verticalListSortingStrategy,\n collisionDetection: closestCenter,\n },\n horizontal: {\n modifiers: [restrictToHorizontalAxis, restrictToParentElement],\n strategy: horizontalListSortingStrategy,\n collisionDetection: closestCenter,\n },\n mixed: {\n modifiers: [restrictToParentElement],\n strategy: undefined,\n collisionDetection: closestCorners,\n },\n};\n\nconst ROOT_NAME = \"Sortable\";\nconst CONTENT_NAME = \"SortableContent\";\nconst ITEM_NAME = \"SortableItem\";\nconst ITEM_HANDLE_NAME = \"SortableItemHandle\";\nconst OVERLAY_NAME = \"SortableOverlay\";\n\nconst SORTABLE_ERRORS = {\n [ROOT_NAME]: `\\`${ROOT_NAME}\\` components must be within \\`${ROOT_NAME}\\``,\n [CONTENT_NAME]: `\\`${CONTENT_NAME}\\` must be within \\`${ROOT_NAME}\\``,\n [ITEM_NAME]: `\\`${ITEM_NAME}\\` must be within \\`${CONTENT_NAME}\\``,\n [ITEM_HANDLE_NAME]: `\\`${ITEM_HANDLE_NAME}\\` must be within \\`${ITEM_NAME}\\``,\n [OVERLAY_NAME]: `\\`${OVERLAY_NAME}\\` must be within \\`${ROOT_NAME}\\``,\n} as const;\n\ninterface SortableRootContextValue {\n id: string;\n items: UniqueIdentifier[];\n modifiers: DndContextProps[\"modifiers\"];\n strategy: SortableContextProps[\"strategy\"];\n activeId: UniqueIdentifier | null;\n setActiveId: (id: UniqueIdentifier | null) => void;\n getItemValue: (item: T) => UniqueIdentifier;\n flatCursor: boolean;\n}\n\nconst SortableRootContext =\n React.createContext | null>(null);\nSortableRootContext.displayName = ROOT_NAME;\n\nfunction useSortableContext(name: keyof typeof SORTABLE_ERRORS) {\n const context = React.useContext(SortableRootContext);\n if (!context) {\n throw new Error(SORTABLE_ERRORS[name]);\n }\n return context;\n}\n\ninterface GetItemValue {\n /**\n * Callback that returns a unique identifier for each sortable item. Required for array of objects.\n * @example getItemValue={(item) => item.id}\n */\n getItemValue: (item: T) => UniqueIdentifier;\n}\n\ntype SortableProps = DndContextProps & {\n value: T[];\n onValueChange?: (items: T[]) => void;\n onMove?: (\n event: DragEndEvent & { activeIndex: number; overIndex: number },\n ) => void;\n strategy?: SortableContextProps[\"strategy\"];\n orientation?: \"vertical\" | \"horizontal\" | \"mixed\";\n flatCursor?: boolean;\n} & (T extends object ? GetItemValue : Partial>);\n\nfunction Sortable(props: SortableProps) {\n const {\n value,\n onValueChange,\n collisionDetection,\n modifiers,\n strategy,\n onMove,\n orientation = \"vertical\",\n flatCursor = false,\n getItemValue: getItemValueProp,\n accessibility,\n ...sortableProps\n } = props;\n const id = React.useId();\n const [activeId, setActiveId] = React.useState(null);\n\n const sensors = useSensors(\n useSensor(MouseSensor),\n useSensor(TouchSensor),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n }),\n );\n const config = React.useMemo(\n () => orientationConfig[orientation],\n [orientation],\n );\n\n const getItemValue = React.useCallback(\n (item: T): UniqueIdentifier => {\n if (typeof item === \"object\" && !getItemValueProp) {\n throw new Error(\n \"getItemValue is required when using array of objects.\",\n );\n }\n return getItemValueProp\n ? getItemValueProp(item)\n : (item as UniqueIdentifier);\n },\n [getItemValueProp],\n );\n\n const items = React.useMemo(() => {\n return value.map((item) => getItemValue(item));\n }, [value, getItemValue]);\n\n const onDragEnd = React.useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n if (over && active.id !== over?.id) {\n const activeIndex = value.findIndex(\n (item) => getItemValue(item) === active.id,\n );\n const overIndex = value.findIndex(\n (item) => getItemValue(item) === over.id,\n );\n\n if (onMove) {\n onMove({ ...event, activeIndex, overIndex });\n } else {\n onValueChange?.(arrayMove(value, activeIndex, overIndex));\n }\n }\n setActiveId(null);\n },\n [value, onValueChange, onMove, getItemValue],\n );\n\n const announcements: Announcements = React.useMemo(\n () => ({\n onDragStart({ active }) {\n const activeValue = active.id.toString();\n return `Grabbed sortable item \"${activeValue}\". Current position is ${active.data.current?.sortable.index + 1} of ${value.length}. Use arrow keys to move, space to drop.`;\n },\n onDragOver({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"down\" : \"up\";\n const activeValue = active.id.toString();\n return `Sortable item \"${activeValue}\" moved ${moveDirection} to position ${overIndex + 1} of ${value.length}.`;\n }\n return \"Sortable item is no longer over a droppable area. Press escape to cancel.\";\n },\n onDragEnd({ active, over }) {\n const activeValue = active.id.toString();\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n return `Sortable item \"${activeValue}\" dropped at position ${overIndex + 1} of ${value.length}.`;\n }\n return `Sortable item \"${activeValue}\" dropped. No changes were made.`;\n },\n onDragCancel({ active }) {\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const activeValue = active.id.toString();\n return `Sorting cancelled. Sortable item \"${activeValue}\" returned to position ${activeIndex + 1} of ${value.length}.`;\n },\n onDragMove({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"down\" : \"up\";\n const activeValue = active.id.toString();\n return `Sortable item \"${activeValue}\" is moving ${moveDirection} to position ${overIndex + 1} of ${value.length}.`;\n }\n return \"Sortable item is no longer over a droppable area. Press escape to cancel.\";\n },\n }),\n [value],\n );\n\n const screenReaderInstructions: ScreenReaderInstructions = React.useMemo(\n () => ({\n draggable: `\n To pick up a sortable item, press space or enter.\n While dragging, use the ${orientation === \"vertical\" ? \"up and down\" : orientation === \"horizontal\" ? \"left and right\" : \"arrow\"} keys to move the item.\n Press space or enter again to drop the item in its new position, or press escape to cancel.\n `,\n }),\n [orientation],\n );\n\n const contextValue = React.useMemo(\n () => ({\n id,\n items,\n modifiers: modifiers ?? config.modifiers,\n strategy: strategy ?? config.strategy,\n activeId,\n setActiveId,\n getItemValue,\n flatCursor,\n }),\n [\n id,\n items,\n modifiers,\n strategy,\n config.modifiers,\n config.strategy,\n activeId,\n getItemValue,\n flatCursor,\n ],\n );\n\n return (\n }\n >\n setActiveId(active.id),\n )}\n onDragEnd={composeEventHandlers(sortableProps.onDragEnd, onDragEnd)}\n onDragCancel={composeEventHandlers(sortableProps.onDragCancel, () =>\n setActiveId(null),\n )}\n accessibility={{\n announcements,\n screenReaderInstructions,\n ...accessibility,\n }}\n />\n \n );\n}\n\nconst SortableContentContext = React.createContext(false);\nSortableContentContext.displayName = CONTENT_NAME;\n\ninterface SortableContentProps extends React.ComponentPropsWithoutRef<\"div\"> {\n strategy?: SortableContextProps[\"strategy\"];\n children: React.ReactNode;\n asChild?: boolean;\n withoutSlot?: boolean;\n}\n\nconst SortableContent = React.forwardRef(\n (props, forwardedRef) => {\n const {\n strategy: strategyProp,\n asChild,\n withoutSlot,\n children,\n ...contentProps\n } = props;\n const context = useSortableContext(CONTENT_NAME);\n\n const ContentPrimitive = asChild ? Slot : \"div\";\n\n return (\n \n \n {withoutSlot ? (\n children\n ) : (\n \n {children}\n \n )}\n \n \n );\n },\n);\nSortableContent.displayName = CONTENT_NAME;\n\ninterface SortableItemContextValue {\n id: string;\n attributes: React.HTMLAttributes;\n listeners: DraggableSyntheticListeners | undefined;\n setActivatorNodeRef: (node: HTMLElement | null) => void;\n isDragging?: boolean;\n disabled?: boolean;\n}\n\nconst SortableItemContext =\n React.createContext(null);\nSortableItemContext.displayName = ITEM_NAME;\n\ninterface SortableItemProps extends React.ComponentPropsWithoutRef<\"div\"> {\n value: UniqueIdentifier;\n asHandle?: boolean;\n asChild?: boolean;\n disabled?: boolean;\n}\n\nconst SortableItem = React.forwardRef(\n (props, forwardedRef) => {\n const {\n value,\n style,\n asHandle,\n asChild,\n disabled,\n className,\n ...itemProps\n } = props;\n const inSortableContent = React.useContext(SortableContentContext);\n const inSortableOverlay = React.useContext(SortableOverlayContext);\n\n if (!inSortableContent && !inSortableOverlay) {\n throw new Error(SORTABLE_ERRORS[ITEM_NAME]);\n }\n\n if (value === \"\") {\n throw new Error(`\\`${ITEM_NAME}\\` value cannot be an empty string`);\n }\n\n const context = useSortableContext(ITEM_NAME);\n const id = React.useId();\n const {\n attributes,\n listeners,\n setNodeRef,\n setActivatorNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: value, disabled });\n\n const composedRef = useComposedRefs(forwardedRef, (node) => {\n if (disabled) return;\n setNodeRef(node);\n if (asHandle) setActivatorNodeRef(node);\n });\n\n const composedStyle = React.useMemo(() => {\n return {\n transform: CSS.Translate.toString(transform),\n transition,\n ...style,\n };\n }, [transform, transition, style]);\n\n const itemContext = React.useMemo(\n () => ({\n id,\n attributes,\n listeners,\n setActivatorNodeRef,\n isDragging,\n disabled,\n }),\n [id, attributes, listeners, setActivatorNodeRef, isDragging, disabled],\n );\n\n const ItemPrimitive = asChild ? Slot : \"div\";\n\n return (\n \n \n \n );\n },\n);\nSortableItem.displayName = ITEM_NAME;\n\ninterface SortableItemHandleProps\n extends React.ComponentPropsWithoutRef<\"button\"> {\n asChild?: boolean;\n}\n\nconst SortableItemHandle = React.forwardRef<\n HTMLButtonElement,\n SortableItemHandleProps\n>((props, forwardedRef) => {\n const { asChild, disabled, className, ...itemHandleProps } = props;\n const itemContext = React.useContext(SortableItemContext);\n if (!itemContext) {\n throw new Error(SORTABLE_ERRORS[ITEM_HANDLE_NAME]);\n }\n const context = useSortableContext(ITEM_HANDLE_NAME);\n\n const isDisabled = disabled ?? itemContext.disabled;\n\n const composedRef = useComposedRefs(forwardedRef, (node) => {\n if (!isDisabled) return;\n itemContext.setActivatorNodeRef(node);\n });\n\n const HandlePrimitive = asChild ? Slot : \"button\";\n\n return (\n \n );\n});\nSortableItemHandle.displayName = ITEM_HANDLE_NAME;\n\nconst SortableOverlayContext = React.createContext(false);\nSortableOverlayContext.displayName = OVERLAY_NAME;\n\nconst dropAnimation: DropAnimation = {\n sideEffects: defaultDropAnimationSideEffects({\n styles: {\n active: {\n opacity: \"0.4\",\n },\n },\n }),\n};\n\ninterface SortableOverlayProps\n extends Omit, \"children\"> {\n container?: Element | DocumentFragment | null;\n children?:\n | ((params: { value: UniqueIdentifier }) => React.ReactNode)\n | React.ReactNode;\n}\n\nfunction SortableOverlay(props: SortableOverlayProps) {\n const { container: containerProp, children, ...overlayProps } = props;\n const context = useSortableContext(OVERLAY_NAME);\n\n const [mounted, setMounted] = React.useState(false);\n React.useLayoutEffect(() => setMounted(true), []);\n\n const container =\n containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n return ReactDOM.createPortal(\n \n \n {context.activeId\n ? typeof children === \"function\"\n ? children({ value: context.activeId })\n : children\n : null}\n \n ,\n container,\n );\n}\n\nconst Root = Sortable;\nconst Content = SortableContent;\nconst Item = SortableItem;\nconst ItemHandle = SortableItemHandle;\nconst Overlay = SortableOverlay;\n\nexport {\n Root,\n Content,\n Item,\n ItemHandle,\n Overlay,\n //\n Sortable,\n SortableContent,\n SortableItem,\n SortableItemHandle,\n SortableOverlay,\n};\n", + "content": "\"use client\";\n\nimport {\n type Announcements,\n closestCenter,\n closestCorners,\n DndContext,\n type DndContextProps,\n type DragEndEvent,\n type DraggableAttributes,\n type DraggableSyntheticListeners,\n DragOverlay,\n type DragStartEvent,\n type DropAnimation,\n defaultDropAnimationSideEffects,\n KeyboardSensor,\n MouseSensor,\n type ScreenReaderInstructions,\n TouchSensor,\n type UniqueIdentifier,\n useSensor,\n useSensors,\n} from \"@dnd-kit/core\";\nimport {\n restrictToHorizontalAxis,\n restrictToParentElement,\n restrictToVerticalAxis,\n} from \"@dnd-kit/modifiers\";\nimport {\n arrayMove,\n horizontalListSortingStrategy,\n SortableContext,\n type SortableContextProps,\n sortableKeyboardCoordinates,\n useSortable,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\n\nimport { useComposedRefs } from \"@/lib/compose-refs\";\nimport { cn } from \"@/lib/utils\";\n\nconst orientationConfig = {\n vertical: {\n modifiers: [restrictToVerticalAxis, restrictToParentElement],\n strategy: verticalListSortingStrategy,\n collisionDetection: closestCenter,\n },\n horizontal: {\n modifiers: [restrictToHorizontalAxis, restrictToParentElement],\n strategy: horizontalListSortingStrategy,\n collisionDetection: closestCenter,\n },\n mixed: {\n modifiers: [restrictToParentElement],\n strategy: undefined,\n collisionDetection: closestCorners,\n },\n};\n\nconst ROOT_NAME = \"Sortable\";\nconst CONTENT_NAME = \"SortableContent\";\nconst ITEM_NAME = \"SortableItem\";\nconst ITEM_HANDLE_NAME = \"SortableItemHandle\";\nconst OVERLAY_NAME = \"SortableOverlay\";\n\ninterface SortableRootContextValue {\n id: string;\n items: UniqueIdentifier[];\n modifiers: DndContextProps[\"modifiers\"];\n strategy: SortableContextProps[\"strategy\"];\n activeId: UniqueIdentifier | null;\n setActiveId: (id: UniqueIdentifier | null) => void;\n getItemValue: (item: T) => UniqueIdentifier;\n flatCursor: boolean;\n}\n\nconst SortableRootContext =\n React.createContext | null>(null);\nSortableRootContext.displayName = ROOT_NAME;\n\nfunction useSortableContext(consumerName: string) {\n const context = React.useContext(SortableRootContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${ROOT_NAME}\\``);\n }\n return context;\n}\n\ninterface GetItemValue {\n /**\n * Callback that returns a unique identifier for each sortable item. Required for array of objects.\n * @example getItemValue={(item) => item.id}\n */\n getItemValue: (item: T) => UniqueIdentifier;\n}\n\ntype SortableRootProps = DndContextProps & {\n value: T[];\n onValueChange?: (items: T[]) => void;\n onMove?: (\n event: DragEndEvent & { activeIndex: number; overIndex: number },\n ) => void;\n strategy?: SortableContextProps[\"strategy\"];\n orientation?: \"vertical\" | \"horizontal\" | \"mixed\";\n flatCursor?: boolean;\n} & (T extends object ? GetItemValue : Partial>);\n\nfunction SortableRoot(props: SortableRootProps) {\n const {\n value,\n onValueChange,\n collisionDetection,\n modifiers,\n strategy,\n onMove,\n orientation = \"vertical\",\n flatCursor = false,\n getItemValue: getItemValueProp,\n accessibility,\n ...sortableProps\n } = props;\n\n const id = React.useId();\n const [activeId, setActiveId] = React.useState(null);\n\n const sensors = useSensors(\n useSensor(MouseSensor),\n useSensor(TouchSensor),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n }),\n );\n const config = React.useMemo(\n () => orientationConfig[orientation],\n [orientation],\n );\n\n const getItemValue = React.useCallback(\n (item: T): UniqueIdentifier => {\n if (typeof item === \"object\" && !getItemValueProp) {\n throw new Error(\"getItemValue is required when using array of objects\");\n }\n return getItemValueProp\n ? getItemValueProp(item)\n : (item as UniqueIdentifier);\n },\n [getItemValueProp],\n );\n\n const items = React.useMemo(() => {\n return value.map((item) => getItemValue(item));\n }, [value, getItemValue]);\n\n const onDragStart = React.useCallback(\n (event: DragStartEvent) => {\n sortableProps.onDragStart?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n setActiveId(event.active.id);\n },\n [sortableProps.onDragStart],\n );\n\n const onDragEnd = React.useCallback(\n (event: DragEndEvent) => {\n sortableProps.onDragEnd?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n const { active, over } = event;\n if (over && active.id !== over?.id) {\n const activeIndex = value.findIndex(\n (item) => getItemValue(item) === active.id,\n );\n const overIndex = value.findIndex(\n (item) => getItemValue(item) === over.id,\n );\n\n if (onMove) {\n onMove({ ...event, activeIndex, overIndex });\n } else {\n onValueChange?.(arrayMove(value, activeIndex, overIndex));\n }\n }\n setActiveId(null);\n },\n [value, onValueChange, onMove, getItemValue, sortableProps.onDragEnd],\n );\n\n const onDragCancel = React.useCallback(\n (event: DragEndEvent) => {\n sortableProps.onDragCancel?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n setActiveId(null);\n },\n [sortableProps.onDragCancel],\n );\n\n const announcements: Announcements = React.useMemo(\n () => ({\n onDragStart({ active }) {\n const activeValue = active.id.toString();\n return `Grabbed sortable item \"${activeValue}\". Current position is ${active.data.current?.sortable.index + 1} of ${value.length}. Use arrow keys to move, space to drop.`;\n },\n onDragOver({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"down\" : \"up\";\n const activeValue = active.id.toString();\n return `Sortable item \"${activeValue}\" moved ${moveDirection} to position ${overIndex + 1} of ${value.length}.`;\n }\n return \"Sortable item is no longer over a droppable area. Press escape to cancel.\";\n },\n onDragEnd({ active, over }) {\n const activeValue = active.id.toString();\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n return `Sortable item \"${activeValue}\" dropped at position ${overIndex + 1} of ${value.length}.`;\n }\n return `Sortable item \"${activeValue}\" dropped. No changes were made.`;\n },\n onDragCancel({ active }) {\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const activeValue = active.id.toString();\n return `Sorting cancelled. Sortable item \"${activeValue}\" returned to position ${activeIndex + 1} of ${value.length}.`;\n },\n onDragMove({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"down\" : \"up\";\n const activeValue = active.id.toString();\n return `Sortable item \"${activeValue}\" is moving ${moveDirection} to position ${overIndex + 1} of ${value.length}.`;\n }\n return \"Sortable item is no longer over a droppable area. Press escape to cancel.\";\n },\n }),\n [value],\n );\n\n const screenReaderInstructions: ScreenReaderInstructions = React.useMemo(\n () => ({\n draggable: `\n To pick up a sortable item, press space or enter.\n While dragging, use the ${orientation === \"vertical\" ? \"up and down\" : orientation === \"horizontal\" ? \"left and right\" : \"arrow\"} keys to move the item.\n Press space or enter again to drop the item in its new position, or press escape to cancel.\n `,\n }),\n [orientation],\n );\n\n const contextValue = React.useMemo(\n () => ({\n id,\n items,\n modifiers: modifiers ?? config.modifiers,\n strategy: strategy ?? config.strategy,\n activeId,\n setActiveId,\n getItemValue,\n flatCursor,\n }),\n [\n id,\n items,\n modifiers,\n strategy,\n config.modifiers,\n config.strategy,\n activeId,\n getItemValue,\n flatCursor,\n ],\n );\n\n return (\n }\n >\n \n \n );\n}\n\nconst SortableContentContext = React.createContext(false);\nSortableContentContext.displayName = CONTENT_NAME;\n\ninterface SortableContentProps extends React.ComponentPropsWithoutRef<\"div\"> {\n strategy?: SortableContextProps[\"strategy\"];\n children: React.ReactNode;\n asChild?: boolean;\n withoutSlot?: boolean;\n}\n\nconst SortableContent = React.forwardRef(\n (props, forwardedRef) => {\n const {\n strategy: strategyProp,\n asChild,\n withoutSlot,\n children,\n ...contentProps\n } = props;\n\n const context = useSortableContext(CONTENT_NAME);\n\n const ContentPrimitive = asChild ? Slot : \"div\";\n\n return (\n \n \n {withoutSlot ? (\n children\n ) : (\n \n {children}\n \n )}\n \n \n );\n },\n);\nSortableContent.displayName = CONTENT_NAME;\n\ninterface SortableItemContextValue {\n id: string;\n attributes: DraggableAttributes;\n listeners: DraggableSyntheticListeners | undefined;\n setActivatorNodeRef: (node: HTMLElement | null) => void;\n isDragging?: boolean;\n disabled?: boolean;\n}\n\nconst SortableItemContext =\n React.createContext(null);\nSortableItemContext.displayName = ITEM_NAME;\n\nfunction useSortableItemContext(consumerName: string) {\n const context = React.useContext(SortableItemContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${ITEM_NAME}\\``);\n }\n return context;\n}\n\ninterface SortableItemProps extends React.ComponentPropsWithoutRef<\"div\"> {\n value: UniqueIdentifier;\n asHandle?: boolean;\n asChild?: boolean;\n disabled?: boolean;\n}\n\nconst SortableItem = React.forwardRef(\n (props, forwardedRef) => {\n const {\n value,\n style,\n asHandle,\n asChild,\n disabled,\n className,\n ...itemProps\n } = props;\n\n const inSortableContent = React.useContext(SortableContentContext);\n const inSortableOverlay = React.useContext(SortableOverlayContext);\n\n if (!inSortableContent && !inSortableOverlay) {\n throw new Error(\n `\\`${ITEM_NAME}\\` must be used within \\`${CONTENT_NAME}\\` or \\`${OVERLAY_NAME}\\``,\n );\n }\n\n if (value === \"\") {\n throw new Error(`\\`${ITEM_NAME}\\` value cannot be an empty string`);\n }\n\n const context = useSortableContext(ITEM_NAME);\n const id = React.useId();\n const {\n attributes,\n listeners,\n setNodeRef,\n setActivatorNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: value, disabled });\n\n const composedRef = useComposedRefs(forwardedRef, (node) => {\n if (disabled) return;\n setNodeRef(node);\n if (asHandle) setActivatorNodeRef(node);\n });\n\n const composedStyle = React.useMemo(() => {\n return {\n transform: CSS.Translate.toString(transform),\n transition,\n ...style,\n };\n }, [transform, transition, style]);\n\n const itemContext = React.useMemo(\n () => ({\n id,\n attributes,\n listeners,\n setActivatorNodeRef,\n isDragging,\n disabled,\n }),\n [id, attributes, listeners, setActivatorNodeRef, isDragging, disabled],\n );\n\n const ItemPrimitive = asChild ? Slot : \"div\";\n\n return (\n \n \n \n );\n },\n);\nSortableItem.displayName = ITEM_NAME;\n\ninterface SortableItemHandleProps\n extends React.ComponentPropsWithoutRef<\"button\"> {\n asChild?: boolean;\n}\n\nconst SortableItemHandle = React.forwardRef<\n HTMLButtonElement,\n SortableItemHandleProps\n>((props, forwardedRef) => {\n const { asChild, disabled, className, ...itemHandleProps } = props;\n\n const context = useSortableContext(ITEM_HANDLE_NAME);\n const itemContext = useSortableItemContext(ITEM_HANDLE_NAME);\n\n const isDisabled = disabled ?? itemContext.disabled;\n\n const composedRef = useComposedRefs(forwardedRef, (node) => {\n if (!isDisabled) return;\n itemContext.setActivatorNodeRef(node);\n });\n\n const HandlePrimitive = asChild ? Slot : \"button\";\n\n return (\n \n );\n});\nSortableItemHandle.displayName = ITEM_HANDLE_NAME;\n\nconst SortableOverlayContext = React.createContext(false);\nSortableOverlayContext.displayName = OVERLAY_NAME;\n\nconst dropAnimation: DropAnimation = {\n sideEffects: defaultDropAnimationSideEffects({\n styles: {\n active: {\n opacity: \"0.4\",\n },\n },\n }),\n};\n\ninterface SortableOverlayProps\n extends Omit, \"children\"> {\n container?: Element | DocumentFragment | null;\n children?:\n | ((params: { value: UniqueIdentifier }) => React.ReactNode)\n | React.ReactNode;\n}\n\nfunction SortableOverlay(props: SortableOverlayProps) {\n const { container: containerProp, children, ...overlayProps } = props;\n\n const context = useSortableContext(OVERLAY_NAME);\n\n const [mounted, setMounted] = React.useState(false);\n React.useLayoutEffect(() => setMounted(true), []);\n\n const container =\n containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n return ReactDOM.createPortal(\n \n \n {context.activeId\n ? typeof children === \"function\"\n ? children({ value: context.activeId })\n : children\n : null}\n \n ,\n container,\n );\n}\n\nexport {\n SortableRoot as Sortable,\n SortableContent,\n SortableItem,\n SortableItemHandle,\n SortableOverlay,\n //\n SortableRoot as Root,\n SortableContent as Content,\n SortableItem as Item,\n SortableItemHandle as ItemHandle,\n SortableOverlay as Overlay,\n};\n", "type": "registry:ui", "target": "src/components/ui/sortable.tsx" }, @@ -61,13 +61,13 @@ "type": "registry:hook" }, { - "path": "src/lib/composition.ts", - "content": "import * as React from \"react\";\n\n/**\n * A utility to compose multiple event handlers into a single event handler.\n * Call originalEventHandler first, then ourEventHandler unless prevented.\n */\nfunction composeEventHandlers(\n originalEventHandler?: (event: E) => void,\n ourEventHandler?: (event: E) => void,\n { checkForDefaultPrevented = true } = {},\n) {\n return function handleEvent(event: E) {\n originalEventHandler?.(event);\n\n if (\n checkForDefaultPrevented === false ||\n !(event as unknown as Event).defaultPrevented\n ) {\n return ourEventHandler?.(event);\n }\n };\n}\n\n/**\n * @see https://github.com/radix-ui/primitives/blob/main/packages/react/compose-refs/src/compose-refs.tsx\n */\n\ntype PossibleRef = React.Ref | undefined;\n\n/**\n * Set a given ref to a given value.\n * This utility takes care of different types of refs: callback refs and RefObject(s).\n */\nfunction setRef(ref: PossibleRef, value: T) {\n if (typeof ref === \"function\") {\n return ref(value);\n }\n\n if (ref !== null && ref !== undefined) {\n ref.current = value;\n }\n}\n\n/**\n * A utility to compose multiple refs together.\n * Accepts callback refs and RefObject(s).\n */\nfunction composeRefs(...refs: PossibleRef[]): React.RefCallback {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup === \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n\n // React <19 will log an error to the console if a callback ref returns a\n // value. We don't use ref cleanups internally so this will only happen if a\n // user's ref callback returns a value, which we only expect if they are\n // using the cleanup functionality added in React 19.\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup === \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\n\n/**\n * A custom hook that composes multiple refs.\n * Accepts callback refs and RefObject(s).\n */\nfunction useComposedRefs(...refs: PossibleRef[]): React.RefCallback {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return React.useCallback(composeRefs(...refs), refs);\n}\n\nexport { composeEventHandlers, composeRefs, useComposedRefs };\n", + "path": "src/lib/compose-refs.ts", + "content": "/**\n * @see https://github.com/radix-ui/primitives/blob/main/packages/react/compose-refs/src/compose-refs.tsx\n */\n\nimport * as React from \"react\";\n\ntype PossibleRef = React.Ref | undefined;\n\n/**\n * Set a given ref to a given value\n * This utility takes care of different types of refs: callback refs and RefObject(s)\n */\nfunction setRef(ref: PossibleRef, value: T) {\n if (typeof ref === \"function\") {\n return ref(value);\n }\n\n if (ref !== null && ref !== undefined) {\n ref.current = value;\n }\n}\n\n/**\n * A utility to compose multiple refs together\n * Accepts callback refs and RefObject(s)\n */\nfunction composeRefs(...refs: PossibleRef[]): React.RefCallback {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup === \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n\n // React <19 will log an error to the console if a callback ref returns a\n // value. We don't use ref cleanups internally so this will only happen if a\n // user's ref callback returns a value, which we only expect if they are\n // using the cleanup functionality added in React 19.\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup === \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\n\n/**\n * A custom hook that composes multiple refs\n * Accepts callback refs and RefObject(s)\n */\nfunction useComposedRefs(...refs: PossibleRef[]): React.RefCallback {\n // biome-ignore lint/correctness/useExhaustiveDependencies: we don't want to re-run this callback when the refs change\n return React.useCallback(composeRefs(...refs), refs);\n}\n\nexport { composeRefs, useComposedRefs };\n", "type": "registry:lib" }, { "path": "src/lib/data-table.ts", - "content": "import type {\n ExtendedColumnFilter,\n FilterOperator,\n FilterVariant,\n} from \"@/types/data-table\";\nimport type { Column } from \"@tanstack/react-table\";\n\nimport { dataTableConfig } from \"@/config/data-table\";\n\nexport function getCommonPinningStyles({\n column,\n withBorder = false,\n}: {\n column: Column;\n withBorder?: boolean;\n}): React.CSSProperties {\n const isPinned = column.getIsPinned();\n const isLastLeftPinnedColumn =\n isPinned === \"left\" && column.getIsLastColumn(\"left\");\n const isFirstRightPinnedColumn =\n isPinned === \"right\" && column.getIsFirstColumn(\"right\");\n\n return {\n boxShadow: withBorder\n ? isLastLeftPinnedColumn\n ? \"-4px 0 4px -4px hsl(var(--border)) inset\"\n : isFirstRightPinnedColumn\n ? \"4px 0 4px -4px hsl(var(--border)) inset\"\n : undefined\n : undefined,\n left: isPinned === \"left\" ? `${column.getStart(\"left\")}px` : undefined,\n right: isPinned === \"right\" ? `${column.getAfter(\"right\")}px` : undefined,\n opacity: isPinned ? 0.97 : 1,\n position: isPinned ? \"sticky\" : \"relative\",\n background: isPinned ? \"hsl(var(--background))\" : \"hsl(var(--background))\",\n width: column.getSize(),\n zIndex: isPinned ? 1 : 0,\n };\n}\n\nexport function getFilterOperators(filterVariant: FilterVariant) {\n const operatorMap: Record<\n FilterVariant,\n { label: string; value: FilterOperator }[]\n > = {\n text: dataTableConfig.textOperators,\n number: dataTableConfig.numericOperators,\n range: dataTableConfig.numericOperators,\n date: dataTableConfig.dateOperators,\n dateRange: dataTableConfig.dateOperators,\n boolean: dataTableConfig.booleanOperators,\n select: dataTableConfig.selectOperators,\n multiSelect: dataTableConfig.multiSelectOperators,\n };\n\n return operatorMap[filterVariant] ?? dataTableConfig.textOperators;\n}\n\nexport function getDefaultFilterOperator(filterVariant: FilterVariant) {\n const operators = getFilterOperators(filterVariant);\n\n return operators[0]?.value ?? (filterVariant === \"text\" ? \"iLike\" : \"eq\");\n}\n\nexport function getValidFilters(\n filters: ExtendedColumnFilter[],\n): ExtendedColumnFilter[] {\n return filters.filter(\n (filter) =>\n filter.operator === \"isEmpty\" ||\n filter.operator === \"isNotEmpty\" ||\n (Array.isArray(filter.value)\n ? filter.value.length > 0\n : filter.value !== \"\" &&\n filter.value !== null &&\n filter.value !== undefined),\n );\n}\n", + "content": "import type { Column } from \"@tanstack/react-table\";\nimport { dataTableConfig } from \"@/config/data-table\";\nimport type {\n ExtendedColumnFilter,\n FilterOperator,\n FilterVariant,\n} from \"@/types/data-table\";\n\nexport function getCommonPinningStyles({\n column,\n withBorder = false,\n}: {\n column: Column;\n withBorder?: boolean;\n}): React.CSSProperties {\n const isPinned = column.getIsPinned();\n const isLastLeftPinnedColumn =\n isPinned === \"left\" && column.getIsLastColumn(\"left\");\n const isFirstRightPinnedColumn =\n isPinned === \"right\" && column.getIsFirstColumn(\"right\");\n\n return {\n boxShadow: withBorder\n ? isLastLeftPinnedColumn\n ? \"-4px 0 4px -4px hsl(var(--border)) inset\"\n : isFirstRightPinnedColumn\n ? \"4px 0 4px -4px hsl(var(--border)) inset\"\n : undefined\n : undefined,\n left: isPinned === \"left\" ? `${column.getStart(\"left\")}px` : undefined,\n right: isPinned === \"right\" ? `${column.getAfter(\"right\")}px` : undefined,\n opacity: isPinned ? 0.97 : 1,\n position: isPinned ? \"sticky\" : \"relative\",\n background: isPinned ? \"hsl(var(--background))\" : \"hsl(var(--background))\",\n width: column.getSize(),\n zIndex: isPinned ? 1 : 0,\n };\n}\n\nexport function getFilterOperators(filterVariant: FilterVariant) {\n const operatorMap: Record<\n FilterVariant,\n { label: string; value: FilterOperator }[]\n > = {\n text: dataTableConfig.textOperators,\n number: dataTableConfig.numericOperators,\n range: dataTableConfig.numericOperators,\n date: dataTableConfig.dateOperators,\n dateRange: dataTableConfig.dateOperators,\n boolean: dataTableConfig.booleanOperators,\n select: dataTableConfig.selectOperators,\n multiSelect: dataTableConfig.multiSelectOperators,\n };\n\n return operatorMap[filterVariant] ?? dataTableConfig.textOperators;\n}\n\nexport function getDefaultFilterOperator(filterVariant: FilterVariant) {\n const operators = getFilterOperators(filterVariant);\n\n return operators[0]?.value ?? (filterVariant === \"text\" ? \"iLike\" : \"eq\");\n}\n\nexport function getValidFilters(\n filters: ExtendedColumnFilter[],\n): ExtendedColumnFilter[] {\n return filters.filter(\n (filter) =>\n filter.operator === \"isEmpty\" ||\n filter.operator === \"isNotEmpty\" ||\n (Array.isArray(filter.value)\n ? filter.value.length > 0\n : filter.value !== \"\" &&\n filter.value !== null &&\n filter.value !== undefined),\n );\n}\n", "type": "registry:lib" }, { @@ -93,7 +93,7 @@ }, { "path": "src/types/data-table.ts", - "content": "import type { DataTableConfig } from \"@/config/data-table\";\nimport type { FilterItemSchema } from \"@/lib/parsers\";\nimport type { ColumnSort, Row, RowData } from \"@tanstack/react-table\";\n\ndeclare module \"@tanstack/react-table\" {\n // biome-ignore lint/correctness/noUnusedVariables: \n interface ColumnMeta {\n label?: string;\n placeholder?: string;\n variant?: FilterVariant;\n options?: Option[];\n range?: [number, number];\n unit?: string;\n icon?: React.FC>;\n }\n}\n\nexport interface Option {\n label: string;\n value: string;\n count?: number;\n icon?: React.FC>;\n}\n\nexport type FilterOperator = DataTableConfig[\"operators\"][number];\nexport type FilterVariant = DataTableConfig[\"filterVariants\"][number];\nexport type JoinOperator = DataTableConfig[\"joinOperators\"][number];\n\nexport interface ExtendedColumnSort extends Omit {\n id: Extract;\n}\n\nexport interface ExtendedColumnFilter extends FilterItemSchema {\n id: Extract;\n}\n\nexport interface DataTableRowAction {\n row: Row;\n variant: \"update\" | \"delete\";\n}\n", + "content": "import type { ColumnSort, Row, RowData } from \"@tanstack/react-table\";\nimport type { DataTableConfig } from \"@/config/data-table\";\nimport type { FilterItemSchema } from \"@/lib/parsers\";\n\ndeclare module \"@tanstack/react-table\" {\n // biome-ignore lint/correctness/noUnusedVariables: TValue is used in the ColumnMeta interface\n interface ColumnMeta {\n label?: string;\n placeholder?: string;\n variant?: FilterVariant;\n options?: Option[];\n range?: [number, number];\n unit?: string;\n icon?: React.FC>;\n }\n}\n\nexport interface Option {\n label: string;\n value: string;\n count?: number;\n icon?: React.FC>;\n}\n\nexport type FilterOperator = DataTableConfig[\"operators\"][number];\nexport type FilterVariant = DataTableConfig[\"filterVariants\"][number];\nexport type JoinOperator = DataTableConfig[\"joinOperators\"][number];\n\nexport interface ExtendedColumnSort extends Omit {\n id: Extract;\n}\n\nexport interface ExtendedColumnFilter extends FilterItemSchema {\n id: Extract;\n}\n\nexport interface DataTableRowAction {\n row: Row;\n variant: \"update\" | \"delete\";\n}\n", "type": "registry:file", "target": "src/types/data-table.ts" } diff --git a/public/r/data-table-filter-menu.json b/public/r/data-table-filter-menu.json index c14cdcb6..42ed145c 100644 --- a/public/r/data-table-filter-menu.json +++ b/public/r/data-table-filter-menu.json @@ -51,7 +51,7 @@ }, { "path": "src/lib/data-table.ts", - "content": "import type {\n ExtendedColumnFilter,\n FilterOperator,\n FilterVariant,\n} from \"@/types/data-table\";\nimport type { Column } from \"@tanstack/react-table\";\n\nimport { dataTableConfig } from \"@/config/data-table\";\n\nexport function getCommonPinningStyles({\n column,\n withBorder = false,\n}: {\n column: Column;\n withBorder?: boolean;\n}): React.CSSProperties {\n const isPinned = column.getIsPinned();\n const isLastLeftPinnedColumn =\n isPinned === \"left\" && column.getIsLastColumn(\"left\");\n const isFirstRightPinnedColumn =\n isPinned === \"right\" && column.getIsFirstColumn(\"right\");\n\n return {\n boxShadow: withBorder\n ? isLastLeftPinnedColumn\n ? \"-4px 0 4px -4px hsl(var(--border)) inset\"\n : isFirstRightPinnedColumn\n ? \"4px 0 4px -4px hsl(var(--border)) inset\"\n : undefined\n : undefined,\n left: isPinned === \"left\" ? `${column.getStart(\"left\")}px` : undefined,\n right: isPinned === \"right\" ? `${column.getAfter(\"right\")}px` : undefined,\n opacity: isPinned ? 0.97 : 1,\n position: isPinned ? \"sticky\" : \"relative\",\n background: isPinned ? \"hsl(var(--background))\" : \"hsl(var(--background))\",\n width: column.getSize(),\n zIndex: isPinned ? 1 : 0,\n };\n}\n\nexport function getFilterOperators(filterVariant: FilterVariant) {\n const operatorMap: Record<\n FilterVariant,\n { label: string; value: FilterOperator }[]\n > = {\n text: dataTableConfig.textOperators,\n number: dataTableConfig.numericOperators,\n range: dataTableConfig.numericOperators,\n date: dataTableConfig.dateOperators,\n dateRange: dataTableConfig.dateOperators,\n boolean: dataTableConfig.booleanOperators,\n select: dataTableConfig.selectOperators,\n multiSelect: dataTableConfig.multiSelectOperators,\n };\n\n return operatorMap[filterVariant] ?? dataTableConfig.textOperators;\n}\n\nexport function getDefaultFilterOperator(filterVariant: FilterVariant) {\n const operators = getFilterOperators(filterVariant);\n\n return operators[0]?.value ?? (filterVariant === \"text\" ? \"iLike\" : \"eq\");\n}\n\nexport function getValidFilters(\n filters: ExtendedColumnFilter[],\n): ExtendedColumnFilter[] {\n return filters.filter(\n (filter) =>\n filter.operator === \"isEmpty\" ||\n filter.operator === \"isNotEmpty\" ||\n (Array.isArray(filter.value)\n ? filter.value.length > 0\n : filter.value !== \"\" &&\n filter.value !== null &&\n filter.value !== undefined),\n );\n}\n", + "content": "import type { Column } from \"@tanstack/react-table\";\nimport { dataTableConfig } from \"@/config/data-table\";\nimport type {\n ExtendedColumnFilter,\n FilterOperator,\n FilterVariant,\n} from \"@/types/data-table\";\n\nexport function getCommonPinningStyles({\n column,\n withBorder = false,\n}: {\n column: Column;\n withBorder?: boolean;\n}): React.CSSProperties {\n const isPinned = column.getIsPinned();\n const isLastLeftPinnedColumn =\n isPinned === \"left\" && column.getIsLastColumn(\"left\");\n const isFirstRightPinnedColumn =\n isPinned === \"right\" && column.getIsFirstColumn(\"right\");\n\n return {\n boxShadow: withBorder\n ? isLastLeftPinnedColumn\n ? \"-4px 0 4px -4px hsl(var(--border)) inset\"\n : isFirstRightPinnedColumn\n ? \"4px 0 4px -4px hsl(var(--border)) inset\"\n : undefined\n : undefined,\n left: isPinned === \"left\" ? `${column.getStart(\"left\")}px` : undefined,\n right: isPinned === \"right\" ? `${column.getAfter(\"right\")}px` : undefined,\n opacity: isPinned ? 0.97 : 1,\n position: isPinned ? \"sticky\" : \"relative\",\n background: isPinned ? \"hsl(var(--background))\" : \"hsl(var(--background))\",\n width: column.getSize(),\n zIndex: isPinned ? 1 : 0,\n };\n}\n\nexport function getFilterOperators(filterVariant: FilterVariant) {\n const operatorMap: Record<\n FilterVariant,\n { label: string; value: FilterOperator }[]\n > = {\n text: dataTableConfig.textOperators,\n number: dataTableConfig.numericOperators,\n range: dataTableConfig.numericOperators,\n date: dataTableConfig.dateOperators,\n dateRange: dataTableConfig.dateOperators,\n boolean: dataTableConfig.booleanOperators,\n select: dataTableConfig.selectOperators,\n multiSelect: dataTableConfig.multiSelectOperators,\n };\n\n return operatorMap[filterVariant] ?? dataTableConfig.textOperators;\n}\n\nexport function getDefaultFilterOperator(filterVariant: FilterVariant) {\n const operators = getFilterOperators(filterVariant);\n\n return operators[0]?.value ?? (filterVariant === \"text\" ? \"iLike\" : \"eq\");\n}\n\nexport function getValidFilters(\n filters: ExtendedColumnFilter[],\n): ExtendedColumnFilter[] {\n return filters.filter(\n (filter) =>\n filter.operator === \"isEmpty\" ||\n filter.operator === \"isNotEmpty\" ||\n (Array.isArray(filter.value)\n ? filter.value.length > 0\n : filter.value !== \"\" &&\n filter.value !== null &&\n filter.value !== undefined),\n );\n}\n", "type": "registry:lib" }, { @@ -77,7 +77,7 @@ }, { "path": "src/types/data-table.ts", - "content": "import type { DataTableConfig } from \"@/config/data-table\";\nimport type { FilterItemSchema } from \"@/lib/parsers\";\nimport type { ColumnSort, Row, RowData } from \"@tanstack/react-table\";\n\ndeclare module \"@tanstack/react-table\" {\n // biome-ignore lint/correctness/noUnusedVariables: \n interface ColumnMeta {\n label?: string;\n placeholder?: string;\n variant?: FilterVariant;\n options?: Option[];\n range?: [number, number];\n unit?: string;\n icon?: React.FC>;\n }\n}\n\nexport interface Option {\n label: string;\n value: string;\n count?: number;\n icon?: React.FC>;\n}\n\nexport type FilterOperator = DataTableConfig[\"operators\"][number];\nexport type FilterVariant = DataTableConfig[\"filterVariants\"][number];\nexport type JoinOperator = DataTableConfig[\"joinOperators\"][number];\n\nexport interface ExtendedColumnSort extends Omit {\n id: Extract;\n}\n\nexport interface ExtendedColumnFilter extends FilterItemSchema {\n id: Extract;\n}\n\nexport interface DataTableRowAction {\n row: Row;\n variant: \"update\" | \"delete\";\n}\n", + "content": "import type { ColumnSort, Row, RowData } from \"@tanstack/react-table\";\nimport type { DataTableConfig } from \"@/config/data-table\";\nimport type { FilterItemSchema } from \"@/lib/parsers\";\n\ndeclare module \"@tanstack/react-table\" {\n // biome-ignore lint/correctness/noUnusedVariables: TValue is used in the ColumnMeta interface\n interface ColumnMeta {\n label?: string;\n placeholder?: string;\n variant?: FilterVariant;\n options?: Option[];\n range?: [number, number];\n unit?: string;\n icon?: React.FC>;\n }\n}\n\nexport interface Option {\n label: string;\n value: string;\n count?: number;\n icon?: React.FC>;\n}\n\nexport type FilterOperator = DataTableConfig[\"operators\"][number];\nexport type FilterVariant = DataTableConfig[\"filterVariants\"][number];\nexport type JoinOperator = DataTableConfig[\"joinOperators\"][number];\n\nexport interface ExtendedColumnSort extends Omit {\n id: Extract;\n}\n\nexport interface ExtendedColumnFilter extends FilterItemSchema {\n id: Extract;\n}\n\nexport interface DataTableRowAction {\n row: Row;\n variant: \"update\" | \"delete\";\n}\n", "type": "registry:file", "target": "src/types/data-table.ts" } diff --git a/public/r/data-table-sort-list.json b/public/r/data-table-sort-list.json index 670aa8a0..531379f9 100644 --- a/public/r/data-table-sort-list.json +++ b/public/r/data-table-sort-list.json @@ -18,19 +18,19 @@ "files": [ { "path": "src/components/data-table/data-table-sort-list.tsx", - "content": "\"use client\";\n\nimport type { ColumnSort, SortDirection, Table } from \"@tanstack/react-table\";\nimport {\n ArrowDownUp,\n ChevronsUpDown,\n GripVertical,\n Trash2,\n} from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/components/ui/command\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport {\n Sortable,\n SortableContent,\n SortableItem,\n SortableItemHandle,\n SortableOverlay,\n} from \"@/components/ui/sortable\";\nimport { dataTableConfig } from \"@/config/data-table\";\nimport { cn } from \"@/lib/utils\";\n\nconst OPEN_MENU_SHORTCUT = \"s\";\nconst REMOVE_SORT_SHORTCUTS = [\"backspace\", \"delete\"];\n\ninterface DataTableSortListProps\n extends React.ComponentProps {\n table: Table;\n}\n\nexport function DataTableSortList({\n table,\n ...props\n}: DataTableSortListProps) {\n const id = React.useId();\n const labelId = React.useId();\n const descriptionId = React.useId();\n const [open, setOpen] = React.useState(false);\n const addButtonRef = React.useRef(null);\n\n const sorting = table.getState().sorting;\n const onSortingChange = table.setSorting;\n\n const { columnLabels, columns } = React.useMemo(() => {\n const labels = new Map();\n const sortingIds = new Set(sorting.map((s) => s.id));\n const availableColumns: { id: string; label: string }[] = [];\n\n for (const column of table.getAllColumns()) {\n if (!column.getCanSort()) continue;\n\n const label = column.columnDef.meta?.label ?? column.id;\n labels.set(column.id, label);\n\n if (!sortingIds.has(column.id)) {\n availableColumns.push({ id: column.id, label });\n }\n }\n\n return {\n columnLabels: labels,\n columns: availableColumns,\n };\n }, [sorting, table]);\n\n const onSortAdd = React.useCallback(() => {\n const firstColumn = columns[0];\n if (!firstColumn) return;\n\n onSortingChange((prevSorting) => [\n ...prevSorting,\n { id: firstColumn.id, desc: false },\n ]);\n }, [columns, onSortingChange]);\n\n const onSortUpdate = React.useCallback(\n (sortId: string, updates: Partial) => {\n onSortingChange((prevSorting) => {\n if (!prevSorting) return prevSorting;\n return prevSorting.map((sort) =>\n sort.id === sortId ? { ...sort, ...updates } : sort,\n );\n });\n },\n [onSortingChange],\n );\n\n const onSortRemove = React.useCallback(\n (sortId: string) => {\n onSortingChange((prevSorting) =>\n prevSorting.filter((item) => item.id !== sortId),\n );\n },\n [onSortingChange],\n );\n\n const onSortingReset = React.useCallback(\n () => onSortingChange(table.initialState.sorting),\n [onSortingChange, table.initialState.sorting],\n );\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey\n ) {\n event.preventDefault();\n setOpen(true);\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n event.shiftKey &&\n sorting.length > 0\n ) {\n event.preventDefault();\n onSortingReset();\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [sorting.length, onSortingReset]);\n\n const onTriggerKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n REMOVE_SORT_SHORTCUTS.includes(event.key.toLowerCase()) &&\n sorting.length > 0\n ) {\n event.preventDefault();\n onSortingReset();\n }\n },\n [sorting.length, onSortingReset],\n );\n\n return (\n item.id}\n >\n \n \n \n \n \n
\n

\n {sorting.length > 0 ? \"Sort by\" : \"No sorting applied\"}\n

\n 0 && \"sr-only\",\n )}\n >\n {sorting.length > 0\n ? \"Modify sorting to organize your rows.\"\n : \"Add sorting to organize your rows.\"}\n

\n
\n {sorting.length > 0 && (\n \n \n {sorting.map((sort) => (\n \n ))}\n
\n \n )}\n
\n \n Add sort\n \n {sorting.length > 0 && (\n \n Reset sorting\n \n )}\n
\n \n \n \n
\n
\n
\n
\n
\n
\n \n \n );\n}\n\ninterface DataTableSortItemProps {\n sort: ColumnSort;\n sortItemId: string;\n columns: { id: string; label: string }[];\n columnLabels: Map;\n onSortUpdate: (sortId: string, updates: Partial) => void;\n onSortRemove: (sortId: string) => void;\n}\n\nfunction DataTableSortItem({\n sort,\n sortItemId,\n columns,\n columnLabels,\n onSortUpdate,\n onSortRemove,\n}: DataTableSortItemProps) {\n const fieldListboxId = `${sortItemId}-field-listbox`;\n const fieldTriggerId = `${sortItemId}-field-trigger`;\n const directionListboxId = `${sortItemId}-direction-listbox`;\n\n const [showFieldSelector, setShowFieldSelector] = React.useState(false);\n const [showDirectionSelector, setShowDirectionSelector] =\n React.useState(false);\n\n const onItemKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (showFieldSelector || showDirectionSelector) {\n return;\n }\n\n if (REMOVE_SORT_SHORTCUTS.includes(event.key.toLowerCase())) {\n event.preventDefault();\n onSortRemove(sort.id);\n }\n },\n [sort.id, showFieldSelector, showDirectionSelector, onSortRemove],\n );\n\n return (\n \n \n \n \n \n {columnLabels.get(sort.id)}\n \n \n \n \n \n \n \n No fields found.\n \n {columns.map((column) => (\n onSortUpdate(sort.id, { id: value })}\n >\n {column.label}\n \n ))}\n \n \n \n \n \n \n onSortUpdate(sort.id, { desc: value === \"desc\" })\n }\n >\n \n \n \n \n {dataTableConfig.sortOrders.map((order) => (\n \n {order.label}\n \n ))}\n \n \n onSortRemove(sort.id)}\n >\n \n \n \n \n \n \n \n
\n \n );\n}\n", + "content": "\"use client\";\n\nimport type { ColumnSort, SortDirection, Table } from \"@tanstack/react-table\";\nimport {\n ArrowDownUp,\n ChevronsUpDown,\n GripVertical,\n Trash2,\n} from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/components/ui/command\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport {\n Sortable,\n SortableContent,\n SortableItem,\n SortableItemHandle,\n SortableOverlay,\n} from \"@/components/ui/sortable\";\nimport { dataTableConfig } from \"@/config/data-table\";\nimport { cn } from \"@/lib/utils\";\n\nconst OPEN_MENU_SHORTCUT = \"s\";\nconst REMOVE_SORT_SHORTCUTS = [\"backspace\", \"delete\"];\n\ninterface DataTableSortListProps\n extends React.ComponentProps {\n table: Table;\n}\n\nexport function DataTableSortList({\n table,\n ...props\n}: DataTableSortListProps) {\n const id = React.useId();\n const labelId = React.useId();\n const descriptionId = React.useId();\n const [open, setOpen] = React.useState(false);\n const addButtonRef = React.useRef(null);\n\n const sorting = table.getState().sorting;\n const onSortingChange = table.setSorting;\n\n const { columnLabels, columns } = React.useMemo(() => {\n const labels = new Map();\n const sortingIds = new Set(sorting.map((s) => s.id));\n const availableColumns: { id: string; label: string }[] = [];\n\n for (const column of table.getAllColumns()) {\n if (!column.getCanSort()) continue;\n\n const label = column.columnDef.meta?.label ?? column.id;\n labels.set(column.id, label);\n\n if (!sortingIds.has(column.id)) {\n availableColumns.push({ id: column.id, label });\n }\n }\n\n return {\n columnLabels: labels,\n columns: availableColumns,\n };\n }, [sorting, table]);\n\n const onSortAdd = React.useCallback(() => {\n const firstColumn = columns[0];\n if (!firstColumn) return;\n\n onSortingChange((prevSorting) => [\n ...prevSorting,\n { id: firstColumn.id, desc: false },\n ]);\n }, [columns, onSortingChange]);\n\n const onSortUpdate = React.useCallback(\n (sortId: string, updates: Partial) => {\n onSortingChange((prevSorting) => {\n if (!prevSorting) return prevSorting;\n return prevSorting.map((sort) =>\n sort.id === sortId ? { ...sort, ...updates } : sort,\n );\n });\n },\n [onSortingChange],\n );\n\n const onSortRemove = React.useCallback(\n (sortId: string) => {\n onSortingChange((prevSorting) =>\n prevSorting.filter((item) => item.id !== sortId),\n );\n },\n [onSortingChange],\n );\n\n const onSortingReset = React.useCallback(\n () => onSortingChange(table.initialState.sorting),\n [onSortingChange, table.initialState.sorting],\n );\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey\n ) {\n event.preventDefault();\n setOpen(true);\n }\n\n if (\n event.key.toLowerCase() === OPEN_MENU_SHORTCUT &&\n event.shiftKey &&\n sorting.length > 0\n ) {\n event.preventDefault();\n onSortingReset();\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [sorting.length, onSortingReset]);\n\n const onTriggerKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n REMOVE_SORT_SHORTCUTS.includes(event.key.toLowerCase()) &&\n sorting.length > 0\n ) {\n event.preventDefault();\n onSortingReset();\n }\n },\n [sorting.length, onSortingReset],\n );\n\n return (\n item.id}\n >\n \n \n \n \n \n
\n

\n {sorting.length > 0 ? \"Sort by\" : \"No sorting applied\"}\n

\n 0 && \"sr-only\",\n )}\n >\n {sorting.length > 0\n ? \"Modify sorting to organize your rows.\"\n : \"Add sorting to organize your rows.\"}\n

\n
\n {sorting.length > 0 && (\n \n
    \n {sorting.map((sort) => (\n \n ))}\n
\n
\n )}\n
\n \n Add sort\n \n {sorting.length > 0 && (\n \n Reset sorting\n \n )}\n
\n \n
\n \n
\n
\n
\n
\n
\n
\n \n \n );\n}\n\ninterface DataTableSortItemProps {\n sort: ColumnSort;\n sortItemId: string;\n columns: { id: string; label: string }[];\n columnLabels: Map;\n onSortUpdate: (sortId: string, updates: Partial) => void;\n onSortRemove: (sortId: string) => void;\n}\n\nfunction DataTableSortItem({\n sort,\n sortItemId,\n columns,\n columnLabels,\n onSortUpdate,\n onSortRemove,\n}: DataTableSortItemProps) {\n const fieldListboxId = `${sortItemId}-field-listbox`;\n const fieldTriggerId = `${sortItemId}-field-trigger`;\n const directionListboxId = `${sortItemId}-direction-listbox`;\n\n const [showFieldSelector, setShowFieldSelector] = React.useState(false);\n const [showDirectionSelector, setShowDirectionSelector] =\n React.useState(false);\n\n const onItemKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (\n event.target instanceof HTMLInputElement ||\n event.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n if (showFieldSelector || showDirectionSelector) {\n return;\n }\n\n if (REMOVE_SORT_SHORTCUTS.includes(event.key.toLowerCase())) {\n event.preventDefault();\n onSortRemove(sort.id);\n }\n },\n [sort.id, showFieldSelector, showDirectionSelector, onSortRemove],\n );\n\n return (\n \n \n \n \n \n {columnLabels.get(sort.id)}\n \n \n \n \n \n \n \n No fields found.\n \n {columns.map((column) => (\n onSortUpdate(sort.id, { id: value })}\n >\n {column.label}\n \n ))}\n \n \n \n \n \n \n onSortUpdate(sort.id, { desc: value === \"desc\" })\n }\n >\n \n \n \n \n {dataTableConfig.sortOrders.map((order) => (\n \n {order.label}\n \n ))}\n \n \n onSortRemove(sort.id)}\n >\n \n \n \n \n \n \n \n \n \n );\n}\n", "type": "registry:component", "target": "src/components/data-table/data-table-sort-list.tsx" }, { "path": "src/components/ui/sortable.tsx", - "content": "\"use client\";\n\nimport {\n type Announcements,\n DndContext,\n type DndContextProps,\n type DragEndEvent,\n DragOverlay,\n type DraggableSyntheticListeners,\n type DropAnimation,\n KeyboardSensor,\n MouseSensor,\n type ScreenReaderInstructions,\n TouchSensor,\n type UniqueIdentifier,\n closestCenter,\n closestCorners,\n defaultDropAnimationSideEffects,\n useSensor,\n useSensors,\n} from \"@dnd-kit/core\";\nimport {\n restrictToHorizontalAxis,\n restrictToParentElement,\n restrictToVerticalAxis,\n} from \"@dnd-kit/modifiers\";\nimport {\n SortableContext,\n type SortableContextProps,\n arrayMove,\n horizontalListSortingStrategy,\n sortableKeyboardCoordinates,\n useSortable,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\n\nimport { composeEventHandlers, useComposedRefs } from \"@/lib/composition\";\nimport { cn } from \"@/lib/utils\";\nimport * as ReactDOM from \"react-dom\";\n\nconst orientationConfig = {\n vertical: {\n modifiers: [restrictToVerticalAxis, restrictToParentElement],\n strategy: verticalListSortingStrategy,\n collisionDetection: closestCenter,\n },\n horizontal: {\n modifiers: [restrictToHorizontalAxis, restrictToParentElement],\n strategy: horizontalListSortingStrategy,\n collisionDetection: closestCenter,\n },\n mixed: {\n modifiers: [restrictToParentElement],\n strategy: undefined,\n collisionDetection: closestCorners,\n },\n};\n\nconst ROOT_NAME = \"Sortable\";\nconst CONTENT_NAME = \"SortableContent\";\nconst ITEM_NAME = \"SortableItem\";\nconst ITEM_HANDLE_NAME = \"SortableItemHandle\";\nconst OVERLAY_NAME = \"SortableOverlay\";\n\nconst SORTABLE_ERRORS = {\n [ROOT_NAME]: `\\`${ROOT_NAME}\\` components must be within \\`${ROOT_NAME}\\``,\n [CONTENT_NAME]: `\\`${CONTENT_NAME}\\` must be within \\`${ROOT_NAME}\\``,\n [ITEM_NAME]: `\\`${ITEM_NAME}\\` must be within \\`${CONTENT_NAME}\\``,\n [ITEM_HANDLE_NAME]: `\\`${ITEM_HANDLE_NAME}\\` must be within \\`${ITEM_NAME}\\``,\n [OVERLAY_NAME]: `\\`${OVERLAY_NAME}\\` must be within \\`${ROOT_NAME}\\``,\n} as const;\n\ninterface SortableRootContextValue {\n id: string;\n items: UniqueIdentifier[];\n modifiers: DndContextProps[\"modifiers\"];\n strategy: SortableContextProps[\"strategy\"];\n activeId: UniqueIdentifier | null;\n setActiveId: (id: UniqueIdentifier | null) => void;\n getItemValue: (item: T) => UniqueIdentifier;\n flatCursor: boolean;\n}\n\nconst SortableRootContext =\n React.createContext | null>(null);\nSortableRootContext.displayName = ROOT_NAME;\n\nfunction useSortableContext(name: keyof typeof SORTABLE_ERRORS) {\n const context = React.useContext(SortableRootContext);\n if (!context) {\n throw new Error(SORTABLE_ERRORS[name]);\n }\n return context;\n}\n\ninterface GetItemValue {\n /**\n * Callback that returns a unique identifier for each sortable item. Required for array of objects.\n * @example getItemValue={(item) => item.id}\n */\n getItemValue: (item: T) => UniqueIdentifier;\n}\n\ntype SortableProps = DndContextProps & {\n value: T[];\n onValueChange?: (items: T[]) => void;\n onMove?: (\n event: DragEndEvent & { activeIndex: number; overIndex: number },\n ) => void;\n strategy?: SortableContextProps[\"strategy\"];\n orientation?: \"vertical\" | \"horizontal\" | \"mixed\";\n flatCursor?: boolean;\n} & (T extends object ? GetItemValue : Partial>);\n\nfunction Sortable(props: SortableProps) {\n const {\n value,\n onValueChange,\n collisionDetection,\n modifiers,\n strategy,\n onMove,\n orientation = \"vertical\",\n flatCursor = false,\n getItemValue: getItemValueProp,\n accessibility,\n ...sortableProps\n } = props;\n const id = React.useId();\n const [activeId, setActiveId] = React.useState(null);\n\n const sensors = useSensors(\n useSensor(MouseSensor),\n useSensor(TouchSensor),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n }),\n );\n const config = React.useMemo(\n () => orientationConfig[orientation],\n [orientation],\n );\n\n const getItemValue = React.useCallback(\n (item: T): UniqueIdentifier => {\n if (typeof item === \"object\" && !getItemValueProp) {\n throw new Error(\n \"getItemValue is required when using array of objects.\",\n );\n }\n return getItemValueProp\n ? getItemValueProp(item)\n : (item as UniqueIdentifier);\n },\n [getItemValueProp],\n );\n\n const items = React.useMemo(() => {\n return value.map((item) => getItemValue(item));\n }, [value, getItemValue]);\n\n const onDragEnd = React.useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n if (over && active.id !== over?.id) {\n const activeIndex = value.findIndex(\n (item) => getItemValue(item) === active.id,\n );\n const overIndex = value.findIndex(\n (item) => getItemValue(item) === over.id,\n );\n\n if (onMove) {\n onMove({ ...event, activeIndex, overIndex });\n } else {\n onValueChange?.(arrayMove(value, activeIndex, overIndex));\n }\n }\n setActiveId(null);\n },\n [value, onValueChange, onMove, getItemValue],\n );\n\n const announcements: Announcements = React.useMemo(\n () => ({\n onDragStart({ active }) {\n const activeValue = active.id.toString();\n return `Grabbed sortable item \"${activeValue}\". Current position is ${active.data.current?.sortable.index + 1} of ${value.length}. Use arrow keys to move, space to drop.`;\n },\n onDragOver({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"down\" : \"up\";\n const activeValue = active.id.toString();\n return `Sortable item \"${activeValue}\" moved ${moveDirection} to position ${overIndex + 1} of ${value.length}.`;\n }\n return \"Sortable item is no longer over a droppable area. Press escape to cancel.\";\n },\n onDragEnd({ active, over }) {\n const activeValue = active.id.toString();\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n return `Sortable item \"${activeValue}\" dropped at position ${overIndex + 1} of ${value.length}.`;\n }\n return `Sortable item \"${activeValue}\" dropped. No changes were made.`;\n },\n onDragCancel({ active }) {\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const activeValue = active.id.toString();\n return `Sorting cancelled. Sortable item \"${activeValue}\" returned to position ${activeIndex + 1} of ${value.length}.`;\n },\n onDragMove({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"down\" : \"up\";\n const activeValue = active.id.toString();\n return `Sortable item \"${activeValue}\" is moving ${moveDirection} to position ${overIndex + 1} of ${value.length}.`;\n }\n return \"Sortable item is no longer over a droppable area. Press escape to cancel.\";\n },\n }),\n [value],\n );\n\n const screenReaderInstructions: ScreenReaderInstructions = React.useMemo(\n () => ({\n draggable: `\n To pick up a sortable item, press space or enter.\n While dragging, use the ${orientation === \"vertical\" ? \"up and down\" : orientation === \"horizontal\" ? \"left and right\" : \"arrow\"} keys to move the item.\n Press space or enter again to drop the item in its new position, or press escape to cancel.\n `,\n }),\n [orientation],\n );\n\n const contextValue = React.useMemo(\n () => ({\n id,\n items,\n modifiers: modifiers ?? config.modifiers,\n strategy: strategy ?? config.strategy,\n activeId,\n setActiveId,\n getItemValue,\n flatCursor,\n }),\n [\n id,\n items,\n modifiers,\n strategy,\n config.modifiers,\n config.strategy,\n activeId,\n getItemValue,\n flatCursor,\n ],\n );\n\n return (\n }\n >\n setActiveId(active.id),\n )}\n onDragEnd={composeEventHandlers(sortableProps.onDragEnd, onDragEnd)}\n onDragCancel={composeEventHandlers(sortableProps.onDragCancel, () =>\n setActiveId(null),\n )}\n accessibility={{\n announcements,\n screenReaderInstructions,\n ...accessibility,\n }}\n />\n \n );\n}\n\nconst SortableContentContext = React.createContext(false);\nSortableContentContext.displayName = CONTENT_NAME;\n\ninterface SortableContentProps extends React.ComponentPropsWithoutRef<\"div\"> {\n strategy?: SortableContextProps[\"strategy\"];\n children: React.ReactNode;\n asChild?: boolean;\n withoutSlot?: boolean;\n}\n\nconst SortableContent = React.forwardRef(\n (props, forwardedRef) => {\n const {\n strategy: strategyProp,\n asChild,\n withoutSlot,\n children,\n ...contentProps\n } = props;\n const context = useSortableContext(CONTENT_NAME);\n\n const ContentPrimitive = asChild ? Slot : \"div\";\n\n return (\n \n \n {withoutSlot ? (\n children\n ) : (\n \n {children}\n \n )}\n \n \n );\n },\n);\nSortableContent.displayName = CONTENT_NAME;\n\ninterface SortableItemContextValue {\n id: string;\n attributes: React.HTMLAttributes;\n listeners: DraggableSyntheticListeners | undefined;\n setActivatorNodeRef: (node: HTMLElement | null) => void;\n isDragging?: boolean;\n disabled?: boolean;\n}\n\nconst SortableItemContext =\n React.createContext(null);\nSortableItemContext.displayName = ITEM_NAME;\n\ninterface SortableItemProps extends React.ComponentPropsWithoutRef<\"div\"> {\n value: UniqueIdentifier;\n asHandle?: boolean;\n asChild?: boolean;\n disabled?: boolean;\n}\n\nconst SortableItem = React.forwardRef(\n (props, forwardedRef) => {\n const {\n value,\n style,\n asHandle,\n asChild,\n disabled,\n className,\n ...itemProps\n } = props;\n const inSortableContent = React.useContext(SortableContentContext);\n const inSortableOverlay = React.useContext(SortableOverlayContext);\n\n if (!inSortableContent && !inSortableOverlay) {\n throw new Error(SORTABLE_ERRORS[ITEM_NAME]);\n }\n\n if (value === \"\") {\n throw new Error(`\\`${ITEM_NAME}\\` value cannot be an empty string`);\n }\n\n const context = useSortableContext(ITEM_NAME);\n const id = React.useId();\n const {\n attributes,\n listeners,\n setNodeRef,\n setActivatorNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: value, disabled });\n\n const composedRef = useComposedRefs(forwardedRef, (node) => {\n if (disabled) return;\n setNodeRef(node);\n if (asHandle) setActivatorNodeRef(node);\n });\n\n const composedStyle = React.useMemo(() => {\n return {\n transform: CSS.Translate.toString(transform),\n transition,\n ...style,\n };\n }, [transform, transition, style]);\n\n const itemContext = React.useMemo(\n () => ({\n id,\n attributes,\n listeners,\n setActivatorNodeRef,\n isDragging,\n disabled,\n }),\n [id, attributes, listeners, setActivatorNodeRef, isDragging, disabled],\n );\n\n const ItemPrimitive = asChild ? Slot : \"div\";\n\n return (\n \n \n \n );\n },\n);\nSortableItem.displayName = ITEM_NAME;\n\ninterface SortableItemHandleProps\n extends React.ComponentPropsWithoutRef<\"button\"> {\n asChild?: boolean;\n}\n\nconst SortableItemHandle = React.forwardRef<\n HTMLButtonElement,\n SortableItemHandleProps\n>((props, forwardedRef) => {\n const { asChild, disabled, className, ...itemHandleProps } = props;\n const itemContext = React.useContext(SortableItemContext);\n if (!itemContext) {\n throw new Error(SORTABLE_ERRORS[ITEM_HANDLE_NAME]);\n }\n const context = useSortableContext(ITEM_HANDLE_NAME);\n\n const isDisabled = disabled ?? itemContext.disabled;\n\n const composedRef = useComposedRefs(forwardedRef, (node) => {\n if (!isDisabled) return;\n itemContext.setActivatorNodeRef(node);\n });\n\n const HandlePrimitive = asChild ? Slot : \"button\";\n\n return (\n \n );\n});\nSortableItemHandle.displayName = ITEM_HANDLE_NAME;\n\nconst SortableOverlayContext = React.createContext(false);\nSortableOverlayContext.displayName = OVERLAY_NAME;\n\nconst dropAnimation: DropAnimation = {\n sideEffects: defaultDropAnimationSideEffects({\n styles: {\n active: {\n opacity: \"0.4\",\n },\n },\n }),\n};\n\ninterface SortableOverlayProps\n extends Omit, \"children\"> {\n container?: Element | DocumentFragment | null;\n children?:\n | ((params: { value: UniqueIdentifier }) => React.ReactNode)\n | React.ReactNode;\n}\n\nfunction SortableOverlay(props: SortableOverlayProps) {\n const { container: containerProp, children, ...overlayProps } = props;\n const context = useSortableContext(OVERLAY_NAME);\n\n const [mounted, setMounted] = React.useState(false);\n React.useLayoutEffect(() => setMounted(true), []);\n\n const container =\n containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n return ReactDOM.createPortal(\n \n \n {context.activeId\n ? typeof children === \"function\"\n ? children({ value: context.activeId })\n : children\n : null}\n \n ,\n container,\n );\n}\n\nconst Root = Sortable;\nconst Content = SortableContent;\nconst Item = SortableItem;\nconst ItemHandle = SortableItemHandle;\nconst Overlay = SortableOverlay;\n\nexport {\n Root,\n Content,\n Item,\n ItemHandle,\n Overlay,\n //\n Sortable,\n SortableContent,\n SortableItem,\n SortableItemHandle,\n SortableOverlay,\n};\n", + "content": "\"use client\";\n\nimport {\n type Announcements,\n closestCenter,\n closestCorners,\n DndContext,\n type DndContextProps,\n type DragEndEvent,\n type DraggableAttributes,\n type DraggableSyntheticListeners,\n DragOverlay,\n type DragStartEvent,\n type DropAnimation,\n defaultDropAnimationSideEffects,\n KeyboardSensor,\n MouseSensor,\n type ScreenReaderInstructions,\n TouchSensor,\n type UniqueIdentifier,\n useSensor,\n useSensors,\n} from \"@dnd-kit/core\";\nimport {\n restrictToHorizontalAxis,\n restrictToParentElement,\n restrictToVerticalAxis,\n} from \"@dnd-kit/modifiers\";\nimport {\n arrayMove,\n horizontalListSortingStrategy,\n SortableContext,\n type SortableContextProps,\n sortableKeyboardCoordinates,\n useSortable,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\n\nimport { useComposedRefs } from \"@/lib/compose-refs\";\nimport { cn } from \"@/lib/utils\";\n\nconst orientationConfig = {\n vertical: {\n modifiers: [restrictToVerticalAxis, restrictToParentElement],\n strategy: verticalListSortingStrategy,\n collisionDetection: closestCenter,\n },\n horizontal: {\n modifiers: [restrictToHorizontalAxis, restrictToParentElement],\n strategy: horizontalListSortingStrategy,\n collisionDetection: closestCenter,\n },\n mixed: {\n modifiers: [restrictToParentElement],\n strategy: undefined,\n collisionDetection: closestCorners,\n },\n};\n\nconst ROOT_NAME = \"Sortable\";\nconst CONTENT_NAME = \"SortableContent\";\nconst ITEM_NAME = \"SortableItem\";\nconst ITEM_HANDLE_NAME = \"SortableItemHandle\";\nconst OVERLAY_NAME = \"SortableOverlay\";\n\ninterface SortableRootContextValue {\n id: string;\n items: UniqueIdentifier[];\n modifiers: DndContextProps[\"modifiers\"];\n strategy: SortableContextProps[\"strategy\"];\n activeId: UniqueIdentifier | null;\n setActiveId: (id: UniqueIdentifier | null) => void;\n getItemValue: (item: T) => UniqueIdentifier;\n flatCursor: boolean;\n}\n\nconst SortableRootContext =\n React.createContext | null>(null);\nSortableRootContext.displayName = ROOT_NAME;\n\nfunction useSortableContext(consumerName: string) {\n const context = React.useContext(SortableRootContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${ROOT_NAME}\\``);\n }\n return context;\n}\n\ninterface GetItemValue {\n /**\n * Callback that returns a unique identifier for each sortable item. Required for array of objects.\n * @example getItemValue={(item) => item.id}\n */\n getItemValue: (item: T) => UniqueIdentifier;\n}\n\ntype SortableRootProps = DndContextProps & {\n value: T[];\n onValueChange?: (items: T[]) => void;\n onMove?: (\n event: DragEndEvent & { activeIndex: number; overIndex: number },\n ) => void;\n strategy?: SortableContextProps[\"strategy\"];\n orientation?: \"vertical\" | \"horizontal\" | \"mixed\";\n flatCursor?: boolean;\n} & (T extends object ? GetItemValue : Partial>);\n\nfunction SortableRoot(props: SortableRootProps) {\n const {\n value,\n onValueChange,\n collisionDetection,\n modifiers,\n strategy,\n onMove,\n orientation = \"vertical\",\n flatCursor = false,\n getItemValue: getItemValueProp,\n accessibility,\n ...sortableProps\n } = props;\n\n const id = React.useId();\n const [activeId, setActiveId] = React.useState(null);\n\n const sensors = useSensors(\n useSensor(MouseSensor),\n useSensor(TouchSensor),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n }),\n );\n const config = React.useMemo(\n () => orientationConfig[orientation],\n [orientation],\n );\n\n const getItemValue = React.useCallback(\n (item: T): UniqueIdentifier => {\n if (typeof item === \"object\" && !getItemValueProp) {\n throw new Error(\"getItemValue is required when using array of objects\");\n }\n return getItemValueProp\n ? getItemValueProp(item)\n : (item as UniqueIdentifier);\n },\n [getItemValueProp],\n );\n\n const items = React.useMemo(() => {\n return value.map((item) => getItemValue(item));\n }, [value, getItemValue]);\n\n const onDragStart = React.useCallback(\n (event: DragStartEvent) => {\n sortableProps.onDragStart?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n setActiveId(event.active.id);\n },\n [sortableProps.onDragStart],\n );\n\n const onDragEnd = React.useCallback(\n (event: DragEndEvent) => {\n sortableProps.onDragEnd?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n const { active, over } = event;\n if (over && active.id !== over?.id) {\n const activeIndex = value.findIndex(\n (item) => getItemValue(item) === active.id,\n );\n const overIndex = value.findIndex(\n (item) => getItemValue(item) === over.id,\n );\n\n if (onMove) {\n onMove({ ...event, activeIndex, overIndex });\n } else {\n onValueChange?.(arrayMove(value, activeIndex, overIndex));\n }\n }\n setActiveId(null);\n },\n [value, onValueChange, onMove, getItemValue, sortableProps.onDragEnd],\n );\n\n const onDragCancel = React.useCallback(\n (event: DragEndEvent) => {\n sortableProps.onDragCancel?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n setActiveId(null);\n },\n [sortableProps.onDragCancel],\n );\n\n const announcements: Announcements = React.useMemo(\n () => ({\n onDragStart({ active }) {\n const activeValue = active.id.toString();\n return `Grabbed sortable item \"${activeValue}\". Current position is ${active.data.current?.sortable.index + 1} of ${value.length}. Use arrow keys to move, space to drop.`;\n },\n onDragOver({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"down\" : \"up\";\n const activeValue = active.id.toString();\n return `Sortable item \"${activeValue}\" moved ${moveDirection} to position ${overIndex + 1} of ${value.length}.`;\n }\n return \"Sortable item is no longer over a droppable area. Press escape to cancel.\";\n },\n onDragEnd({ active, over }) {\n const activeValue = active.id.toString();\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n return `Sortable item \"${activeValue}\" dropped at position ${overIndex + 1} of ${value.length}.`;\n }\n return `Sortable item \"${activeValue}\" dropped. No changes were made.`;\n },\n onDragCancel({ active }) {\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const activeValue = active.id.toString();\n return `Sorting cancelled. Sortable item \"${activeValue}\" returned to position ${activeIndex + 1} of ${value.length}.`;\n },\n onDragMove({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"down\" : \"up\";\n const activeValue = active.id.toString();\n return `Sortable item \"${activeValue}\" is moving ${moveDirection} to position ${overIndex + 1} of ${value.length}.`;\n }\n return \"Sortable item is no longer over a droppable area. Press escape to cancel.\";\n },\n }),\n [value],\n );\n\n const screenReaderInstructions: ScreenReaderInstructions = React.useMemo(\n () => ({\n draggable: `\n To pick up a sortable item, press space or enter.\n While dragging, use the ${orientation === \"vertical\" ? \"up and down\" : orientation === \"horizontal\" ? \"left and right\" : \"arrow\"} keys to move the item.\n Press space or enter again to drop the item in its new position, or press escape to cancel.\n `,\n }),\n [orientation],\n );\n\n const contextValue = React.useMemo(\n () => ({\n id,\n items,\n modifiers: modifiers ?? config.modifiers,\n strategy: strategy ?? config.strategy,\n activeId,\n setActiveId,\n getItemValue,\n flatCursor,\n }),\n [\n id,\n items,\n modifiers,\n strategy,\n config.modifiers,\n config.strategy,\n activeId,\n getItemValue,\n flatCursor,\n ],\n );\n\n return (\n }\n >\n \n \n );\n}\n\nconst SortableContentContext = React.createContext(false);\nSortableContentContext.displayName = CONTENT_NAME;\n\ninterface SortableContentProps extends React.ComponentPropsWithoutRef<\"div\"> {\n strategy?: SortableContextProps[\"strategy\"];\n children: React.ReactNode;\n asChild?: boolean;\n withoutSlot?: boolean;\n}\n\nconst SortableContent = React.forwardRef(\n (props, forwardedRef) => {\n const {\n strategy: strategyProp,\n asChild,\n withoutSlot,\n children,\n ...contentProps\n } = props;\n\n const context = useSortableContext(CONTENT_NAME);\n\n const ContentPrimitive = asChild ? Slot : \"div\";\n\n return (\n \n \n {withoutSlot ? (\n children\n ) : (\n \n {children}\n \n )}\n \n \n );\n },\n);\nSortableContent.displayName = CONTENT_NAME;\n\ninterface SortableItemContextValue {\n id: string;\n attributes: DraggableAttributes;\n listeners: DraggableSyntheticListeners | undefined;\n setActivatorNodeRef: (node: HTMLElement | null) => void;\n isDragging?: boolean;\n disabled?: boolean;\n}\n\nconst SortableItemContext =\n React.createContext(null);\nSortableItemContext.displayName = ITEM_NAME;\n\nfunction useSortableItemContext(consumerName: string) {\n const context = React.useContext(SortableItemContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${ITEM_NAME}\\``);\n }\n return context;\n}\n\ninterface SortableItemProps extends React.ComponentPropsWithoutRef<\"div\"> {\n value: UniqueIdentifier;\n asHandle?: boolean;\n asChild?: boolean;\n disabled?: boolean;\n}\n\nconst SortableItem = React.forwardRef(\n (props, forwardedRef) => {\n const {\n value,\n style,\n asHandle,\n asChild,\n disabled,\n className,\n ...itemProps\n } = props;\n\n const inSortableContent = React.useContext(SortableContentContext);\n const inSortableOverlay = React.useContext(SortableOverlayContext);\n\n if (!inSortableContent && !inSortableOverlay) {\n throw new Error(\n `\\`${ITEM_NAME}\\` must be used within \\`${CONTENT_NAME}\\` or \\`${OVERLAY_NAME}\\``,\n );\n }\n\n if (value === \"\") {\n throw new Error(`\\`${ITEM_NAME}\\` value cannot be an empty string`);\n }\n\n const context = useSortableContext(ITEM_NAME);\n const id = React.useId();\n const {\n attributes,\n listeners,\n setNodeRef,\n setActivatorNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: value, disabled });\n\n const composedRef = useComposedRefs(forwardedRef, (node) => {\n if (disabled) return;\n setNodeRef(node);\n if (asHandle) setActivatorNodeRef(node);\n });\n\n const composedStyle = React.useMemo(() => {\n return {\n transform: CSS.Translate.toString(transform),\n transition,\n ...style,\n };\n }, [transform, transition, style]);\n\n const itemContext = React.useMemo(\n () => ({\n id,\n attributes,\n listeners,\n setActivatorNodeRef,\n isDragging,\n disabled,\n }),\n [id, attributes, listeners, setActivatorNodeRef, isDragging, disabled],\n );\n\n const ItemPrimitive = asChild ? Slot : \"div\";\n\n return (\n \n \n \n );\n },\n);\nSortableItem.displayName = ITEM_NAME;\n\ninterface SortableItemHandleProps\n extends React.ComponentPropsWithoutRef<\"button\"> {\n asChild?: boolean;\n}\n\nconst SortableItemHandle = React.forwardRef<\n HTMLButtonElement,\n SortableItemHandleProps\n>((props, forwardedRef) => {\n const { asChild, disabled, className, ...itemHandleProps } = props;\n\n const context = useSortableContext(ITEM_HANDLE_NAME);\n const itemContext = useSortableItemContext(ITEM_HANDLE_NAME);\n\n const isDisabled = disabled ?? itemContext.disabled;\n\n const composedRef = useComposedRefs(forwardedRef, (node) => {\n if (!isDisabled) return;\n itemContext.setActivatorNodeRef(node);\n });\n\n const HandlePrimitive = asChild ? Slot : \"button\";\n\n return (\n \n );\n});\nSortableItemHandle.displayName = ITEM_HANDLE_NAME;\n\nconst SortableOverlayContext = React.createContext(false);\nSortableOverlayContext.displayName = OVERLAY_NAME;\n\nconst dropAnimation: DropAnimation = {\n sideEffects: defaultDropAnimationSideEffects({\n styles: {\n active: {\n opacity: \"0.4\",\n },\n },\n }),\n};\n\ninterface SortableOverlayProps\n extends Omit, \"children\"> {\n container?: Element | DocumentFragment | null;\n children?:\n | ((params: { value: UniqueIdentifier }) => React.ReactNode)\n | React.ReactNode;\n}\n\nfunction SortableOverlay(props: SortableOverlayProps) {\n const { container: containerProp, children, ...overlayProps } = props;\n\n const context = useSortableContext(OVERLAY_NAME);\n\n const [mounted, setMounted] = React.useState(false);\n React.useLayoutEffect(() => setMounted(true), []);\n\n const container =\n containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n return ReactDOM.createPortal(\n \n \n {context.activeId\n ? typeof children === \"function\"\n ? children({ value: context.activeId })\n : children\n : null}\n \n ,\n container,\n );\n}\n\nexport {\n SortableRoot as Sortable,\n SortableContent,\n SortableItem,\n SortableItemHandle,\n SortableOverlay,\n //\n SortableRoot as Root,\n SortableContent as Content,\n SortableItem as Item,\n SortableItemHandle as ItemHandle,\n SortableOverlay as Overlay,\n};\n", "type": "registry:ui", "target": "src/components/ui/sortable.tsx" }, { - "path": "src/lib/composition.ts", - "content": "import * as React from \"react\";\n\n/**\n * A utility to compose multiple event handlers into a single event handler.\n * Call originalEventHandler first, then ourEventHandler unless prevented.\n */\nfunction composeEventHandlers(\n originalEventHandler?: (event: E) => void,\n ourEventHandler?: (event: E) => void,\n { checkForDefaultPrevented = true } = {},\n) {\n return function handleEvent(event: E) {\n originalEventHandler?.(event);\n\n if (\n checkForDefaultPrevented === false ||\n !(event as unknown as Event).defaultPrevented\n ) {\n return ourEventHandler?.(event);\n }\n };\n}\n\n/**\n * @see https://github.com/radix-ui/primitives/blob/main/packages/react/compose-refs/src/compose-refs.tsx\n */\n\ntype PossibleRef = React.Ref | undefined;\n\n/**\n * Set a given ref to a given value.\n * This utility takes care of different types of refs: callback refs and RefObject(s).\n */\nfunction setRef(ref: PossibleRef, value: T) {\n if (typeof ref === \"function\") {\n return ref(value);\n }\n\n if (ref !== null && ref !== undefined) {\n ref.current = value;\n }\n}\n\n/**\n * A utility to compose multiple refs together.\n * Accepts callback refs and RefObject(s).\n */\nfunction composeRefs(...refs: PossibleRef[]): React.RefCallback {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup === \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n\n // React <19 will log an error to the console if a callback ref returns a\n // value. We don't use ref cleanups internally so this will only happen if a\n // user's ref callback returns a value, which we only expect if they are\n // using the cleanup functionality added in React 19.\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup === \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\n\n/**\n * A custom hook that composes multiple refs.\n * Accepts callback refs and RefObject(s).\n */\nfunction useComposedRefs(...refs: PossibleRef[]): React.RefCallback {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return React.useCallback(composeRefs(...refs), refs);\n}\n\nexport { composeEventHandlers, composeRefs, useComposedRefs };\n", + "path": "src/lib/compose-refs.ts", + "content": "/**\n * @see https://github.com/radix-ui/primitives/blob/main/packages/react/compose-refs/src/compose-refs.tsx\n */\n\nimport * as React from \"react\";\n\ntype PossibleRef = React.Ref | undefined;\n\n/**\n * Set a given ref to a given value\n * This utility takes care of different types of refs: callback refs and RefObject(s)\n */\nfunction setRef(ref: PossibleRef, value: T) {\n if (typeof ref === \"function\") {\n return ref(value);\n }\n\n if (ref !== null && ref !== undefined) {\n ref.current = value;\n }\n}\n\n/**\n * A utility to compose multiple refs together\n * Accepts callback refs and RefObject(s)\n */\nfunction composeRefs(...refs: PossibleRef[]): React.RefCallback {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup === \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n\n // React <19 will log an error to the console if a callback ref returns a\n // value. We don't use ref cleanups internally so this will only happen if a\n // user's ref callback returns a value, which we only expect if they are\n // using the cleanup functionality added in React 19.\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup === \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\n\n/**\n * A custom hook that composes multiple refs\n * Accepts callback refs and RefObject(s)\n */\nfunction useComposedRefs(...refs: PossibleRef[]): React.RefCallback {\n // biome-ignore lint/correctness/useExhaustiveDependencies: we don't want to re-run this callback when the refs change\n return React.useCallback(composeRefs(...refs), refs);\n}\n\nexport { composeRefs, useComposedRefs };\n", "type": "registry:lib" }, { @@ -41,7 +41,7 @@ }, { "path": "src/types/data-table.ts", - "content": "import type { DataTableConfig } from \"@/config/data-table\";\nimport type { FilterItemSchema } from \"@/lib/parsers\";\nimport type { ColumnSort, Row, RowData } from \"@tanstack/react-table\";\n\ndeclare module \"@tanstack/react-table\" {\n // biome-ignore lint/correctness/noUnusedVariables: \n interface ColumnMeta {\n label?: string;\n placeholder?: string;\n variant?: FilterVariant;\n options?: Option[];\n range?: [number, number];\n unit?: string;\n icon?: React.FC>;\n }\n}\n\nexport interface Option {\n label: string;\n value: string;\n count?: number;\n icon?: React.FC>;\n}\n\nexport type FilterOperator = DataTableConfig[\"operators\"][number];\nexport type FilterVariant = DataTableConfig[\"filterVariants\"][number];\nexport type JoinOperator = DataTableConfig[\"joinOperators\"][number];\n\nexport interface ExtendedColumnSort extends Omit {\n id: Extract;\n}\n\nexport interface ExtendedColumnFilter extends FilterItemSchema {\n id: Extract;\n}\n\nexport interface DataTableRowAction {\n row: Row;\n variant: \"update\" | \"delete\";\n}\n", + "content": "import type { ColumnSort, Row, RowData } from \"@tanstack/react-table\";\nimport type { DataTableConfig } from \"@/config/data-table\";\nimport type { FilterItemSchema } from \"@/lib/parsers\";\n\ndeclare module \"@tanstack/react-table\" {\n // biome-ignore lint/correctness/noUnusedVariables: TValue is used in the ColumnMeta interface\n interface ColumnMeta {\n label?: string;\n placeholder?: string;\n variant?: FilterVariant;\n options?: Option[];\n range?: [number, number];\n unit?: string;\n icon?: React.FC>;\n }\n}\n\nexport interface Option {\n label: string;\n value: string;\n count?: number;\n icon?: React.FC>;\n}\n\nexport type FilterOperator = DataTableConfig[\"operators\"][number];\nexport type FilterVariant = DataTableConfig[\"filterVariants\"][number];\nexport type JoinOperator = DataTableConfig[\"joinOperators\"][number];\n\nexport interface ExtendedColumnSort extends Omit {\n id: Extract;\n}\n\nexport interface ExtendedColumnFilter extends FilterItemSchema {\n id: Extract;\n}\n\nexport interface DataTableRowAction {\n row: Row;\n variant: \"update\" | \"delete\";\n}\n", "type": "registry:file", "target": "src/types/data-table.ts" } diff --git a/public/r/data-table.json b/public/r/data-table.json index 1334f213..9ba6a020 100644 --- a/public/r/data-table.json +++ b/public/r/data-table.json @@ -25,13 +25,13 @@ "files": [ { "path": "src/components/data-table/data-table.tsx", - "content": "import { type Table as TanstackTable, flexRender } from \"@tanstack/react-table\";\nimport type * as React from \"react\";\n\nimport { DataTablePagination } from \"@/components/data-table/data-table-pagination\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"@/components/ui/table\";\nimport { getCommonPinningStyles } from \"@/lib/data-table\";\nimport { cn } from \"@/lib/utils\";\n\ninterface DataTableProps extends React.ComponentProps<\"div\"> {\n table: TanstackTable;\n actionBar?: React.ReactNode;\n}\n\nexport function DataTable({\n table,\n actionBar,\n children,\n className,\n ...props\n}: DataTableProps) {\n return (\n \n {children}\n
\n \n \n {table.getHeaderGroups().map((headerGroup) => (\n \n {headerGroup.headers.map((header) => (\n \n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n \n ))}\n \n ))}\n \n \n {table.getRowModel().rows?.length ? (\n table.getRowModel().rows.map((row) => (\n \n {row.getVisibleCells().map((cell) => (\n \n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n \n ))}\n \n ))\n ) : (\n \n \n No results.\n \n \n )}\n \n
\n
\n
\n \n {actionBar &&\n table.getFilteredSelectedRowModel().rows.length > 0 &&\n actionBar}\n
\n
\n );\n}\n", + "content": "import { flexRender, type Table as TanstackTable } from \"@tanstack/react-table\";\nimport type * as React from \"react\";\n\nimport { DataTablePagination } from \"@/components/data-table/data-table-pagination\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"@/components/ui/table\";\nimport { getCommonPinningStyles } from \"@/lib/data-table\";\nimport { cn } from \"@/lib/utils\";\n\ninterface DataTableProps extends React.ComponentProps<\"div\"> {\n table: TanstackTable;\n actionBar?: React.ReactNode;\n}\n\nexport function DataTable({\n table,\n actionBar,\n children,\n className,\n ...props\n}: DataTableProps) {\n return (\n \n {children}\n
\n \n \n {table.getHeaderGroups().map((headerGroup) => (\n \n {headerGroup.headers.map((header) => (\n \n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n \n ))}\n \n ))}\n \n \n {table.getRowModel().rows?.length ? (\n table.getRowModel().rows.map((row) => (\n \n {row.getVisibleCells().map((cell) => (\n \n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n \n ))}\n \n ))\n ) : (\n \n \n No results.\n \n \n )}\n \n
\n
\n
\n \n {actionBar &&\n table.getFilteredSelectedRowModel().rows.length > 0 &&\n actionBar}\n
\n
\n );\n}\n", "type": "registry:component", "target": "src/components/data-table/data-table.tsx" }, { "path": "src/components/data-table/data-table-column-header.tsx", - "content": "\"use client\";\n\nimport type { Column } from \"@tanstack/react-table\";\nimport {\n ChevronDown,\n ChevronUp,\n ChevronsUpDown,\n EyeOff,\n X,\n} from \"lucide-react\";\n\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { cn } from \"@/lib/utils\";\n\ninterface DataTableColumnHeaderProps\n extends React.ComponentProps {\n column: Column;\n title: string;\n}\n\nexport function DataTableColumnHeader({\n column,\n title,\n className,\n ...props\n}: DataTableColumnHeaderProps) {\n if (!column.getCanSort() && !column.getCanHide()) {\n return
{title}
;\n }\n\n return (\n \n \n {title}\n {column.getCanSort() &&\n (column.getIsSorted() === \"desc\" ? (\n \n ) : column.getIsSorted() === \"asc\" ? (\n \n ) : (\n \n ))}\n \n \n {column.getCanSort() && (\n <>\n span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground\"\n checked={column.getIsSorted() === \"asc\"}\n onClick={() => column.toggleSorting(false)}\n >\n \n Asc\n \n span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground\"\n checked={column.getIsSorted() === \"desc\"}\n onClick={() => column.toggleSorting(true)}\n >\n \n Desc\n \n {column.getIsSorted() && (\n column.clearSorting()}\n >\n \n Reset\n \n )}\n \n )}\n {column.getCanHide() && (\n span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground\"\n checked={!column.getIsVisible()}\n onClick={() => column.toggleVisibility(false)}\n >\n \n Hide\n \n )}\n \n \n );\n}\n", + "content": "\"use client\";\n\nimport type { Column } from \"@tanstack/react-table\";\nimport {\n ChevronDown,\n ChevronsUpDown,\n ChevronUp,\n EyeOff,\n X,\n} from \"lucide-react\";\n\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { cn } from \"@/lib/utils\";\n\ninterface DataTableColumnHeaderProps\n extends React.ComponentProps {\n column: Column;\n title: string;\n}\n\nexport function DataTableColumnHeader({\n column,\n title,\n className,\n ...props\n}: DataTableColumnHeaderProps) {\n if (!column.getCanSort() && !column.getCanHide()) {\n return
{title}
;\n }\n\n return (\n \n \n {title}\n {column.getCanSort() &&\n (column.getIsSorted() === \"desc\" ? (\n \n ) : column.getIsSorted() === \"asc\" ? (\n \n ) : (\n \n ))}\n \n \n {column.getCanSort() && (\n <>\n span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground\"\n checked={column.getIsSorted() === \"asc\"}\n onClick={() => column.toggleSorting(false)}\n >\n \n Asc\n \n span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground\"\n checked={column.getIsSorted() === \"desc\"}\n onClick={() => column.toggleSorting(true)}\n >\n \n Desc\n \n {column.getIsSorted() && (\n column.clearSorting()}\n >\n \n Reset\n \n )}\n \n )}\n {column.getCanHide() && (\n span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground\"\n checked={!column.getIsVisible()}\n onClick={() => column.toggleVisibility(false)}\n >\n \n Hide\n \n )}\n \n \n );\n}\n", "type": "registry:component", "target": "src/components/data-table/data-table-column-header.tsx" }, @@ -43,13 +43,13 @@ }, { "path": "src/components/data-table/data-table-view-options.tsx", - "content": "\"use client\";\n\nimport type { Table } from \"@tanstack/react-table\";\nimport { Check, ChevronsUpDown, Settings2 } from \"lucide-react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/components/ui/command\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\n\ninterface DataTableViewOptionsProps {\n table: Table;\n}\n\nexport function DataTableViewOptions({\n table,\n}: DataTableViewOptionsProps) {\n const columns = React.useMemo(\n () =>\n table\n .getAllColumns()\n .filter(\n (column) =>\n typeof column.accessorFn !== \"undefined\" && column.getCanHide(),\n ),\n [table],\n );\n\n return (\n \n \n \n \n \n \n \n No columns found.\n \n {columns.map((column) => (\n \n column.toggleVisibility(!column.getIsVisible())\n }\n >\n \n {column.columnDef.meta?.label ?? column.id}\n \n \n \n ))}\n \n \n \n \n \n );\n}\n", + "content": "\"use client\";\n\nimport type { Table } from \"@tanstack/react-table\";\nimport { Check, ChevronsUpDown, Settings2 } from \"lucide-react\";\nimport * as React from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/components/ui/command\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport { cn } from \"@/lib/utils\";\n\ninterface DataTableViewOptionsProps {\n table: Table;\n}\n\nexport function DataTableViewOptions({\n table,\n}: DataTableViewOptionsProps) {\n const columns = React.useMemo(\n () =>\n table\n .getAllColumns()\n .filter(\n (column) =>\n typeof column.accessorFn !== \"undefined\" && column.getCanHide(),\n ),\n [table],\n );\n\n return (\n \n \n \n \n \n \n \n No columns found.\n \n {columns.map((column) => (\n \n column.toggleVisibility(!column.getIsVisible())\n }\n >\n \n {column.columnDef.meta?.label ?? column.id}\n \n \n \n ))}\n \n \n \n \n \n );\n}\n", "type": "registry:component", "target": "src/components/data-table/data-table-view-options.tsx" }, { "path": "src/components/data-table/data-table-faceted-filter.tsx", - "content": "\"use client\";\n\nimport type { Option } from \"@/types/data-table\";\nimport type { Column } from \"@tanstack/react-table\";\nimport { Check, PlusCircle, XCircle } from \"lucide-react\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from \"@/components/ui/command\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\n\ninterface DataTableFacetedFilterProps {\n column?: Column;\n title?: string;\n options: Option[];\n multiple?: boolean;\n}\n\nexport function DataTableFacetedFilter({\n column,\n title,\n options,\n multiple,\n}: DataTableFacetedFilterProps) {\n const [open, setOpen] = React.useState(false);\n\n const columnFilterValue = column?.getFilterValue();\n const selectedValues = new Set(\n Array.isArray(columnFilterValue) ? columnFilterValue : [],\n );\n\n const onItemSelect = React.useCallback(\n (option: Option, isSelected: boolean) => {\n if (!column) return;\n\n if (multiple) {\n const newSelectedValues = new Set(selectedValues);\n if (isSelected) {\n newSelectedValues.delete(option.value);\n } else {\n newSelectedValues.add(option.value);\n }\n const filterValues = Array.from(newSelectedValues);\n column.setFilterValue(filterValues.length ? filterValues : undefined);\n } else {\n column.setFilterValue(isSelected ? undefined : [option.value]);\n setOpen(false);\n }\n },\n [column, multiple, selectedValues],\n );\n\n const onReset = React.useCallback(\n (event?: React.MouseEvent) => {\n event?.stopPropagation();\n column?.setFilterValue(undefined);\n },\n [column],\n );\n\n return (\n \n \n
\n ) : (\n \n )}\n {title}\n {selectedValues?.size > 0 && (\n <>\n \n \n {selectedValues.size}\n \n
\n {selectedValues.size > 2 ? (\n \n {selectedValues.size} selected\n \n ) : (\n options\n .filter((option) => selectedValues.has(option.value))\n .map((option) => (\n \n {option.label}\n \n ))\n )}\n
\n \n )}\n \n \n \n \n \n \n No results found.\n \n {options.map((option) => {\n const isSelected = selectedValues.has(option.value);\n\n return (\n onItemSelect(option, isSelected)}\n >\n \n \n
\n {option.icon && }\n {option.label}\n {option.count && (\n \n {option.count}\n \n )}\n \n );\n })}\n \n {selectedValues.size > 0 && (\n <>\n \n \n onReset()}\n className=\"justify-center text-center\"\n >\n Clear filters\n \n \n \n )}\n \n \n \n \n );\n}\n", + "content": "\"use client\";\n\nimport type { Column } from \"@tanstack/react-table\";\nimport { Check, PlusCircle, XCircle } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from \"@/components/ui/command\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { cn } from \"@/lib/utils\";\nimport type { Option } from \"@/types/data-table\";\n\ninterface DataTableFacetedFilterProps {\n column?: Column;\n title?: string;\n options: Option[];\n multiple?: boolean;\n}\n\nexport function DataTableFacetedFilter({\n column,\n title,\n options,\n multiple,\n}: DataTableFacetedFilterProps) {\n const [open, setOpen] = React.useState(false);\n\n const columnFilterValue = column?.getFilterValue();\n const selectedValues = new Set(\n Array.isArray(columnFilterValue) ? columnFilterValue : [],\n );\n\n const onItemSelect = React.useCallback(\n (option: Option, isSelected: boolean) => {\n if (!column) return;\n\n if (multiple) {\n const newSelectedValues = new Set(selectedValues);\n if (isSelected) {\n newSelectedValues.delete(option.value);\n } else {\n newSelectedValues.add(option.value);\n }\n const filterValues = Array.from(newSelectedValues);\n column.setFilterValue(filterValues.length ? filterValues : undefined);\n } else {\n column.setFilterValue(isSelected ? undefined : [option.value]);\n setOpen(false);\n }\n },\n [column, multiple, selectedValues],\n );\n\n const onReset = React.useCallback(\n (event?: React.MouseEvent) => {\n event?.stopPropagation();\n column?.setFilterValue(undefined);\n },\n [column],\n );\n\n return (\n \n \n
\n ) : (\n \n )}\n {title}\n {selectedValues?.size > 0 && (\n <>\n \n \n {selectedValues.size}\n \n
\n {selectedValues.size > 2 ? (\n \n {selectedValues.size} selected\n \n ) : (\n options\n .filter((option) => selectedValues.has(option.value))\n .map((option) => (\n \n {option.label}\n \n ))\n )}\n
\n \n )}\n \n \n \n \n \n \n No results found.\n \n {options.map((option) => {\n const isSelected = selectedValues.has(option.value);\n\n return (\n onItemSelect(option, isSelected)}\n >\n \n \n
\n {option.icon && }\n {option.label}\n {option.count && (\n \n {option.count}\n \n )}\n \n );\n })}\n \n {selectedValues.size > 0 && (\n <>\n \n \n onReset()}\n className=\"justify-center text-center\"\n >\n Clear filters\n \n \n \n )}\n \n \n \n \n );\n}\n", "type": "registry:component", "target": "src/components/data-table/data-table-faceted-filter.tsx" }, @@ -61,7 +61,7 @@ }, { "path": "src/components/data-table/data-table-slider-filter.tsx", - "content": "\"use client\";\n\nimport type { Column } from \"@tanstack/react-table\";\nimport * as React from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { Slider } from \"@/components/ui/slider\";\nimport { cn } from \"@/lib/utils\";\nimport { PlusCircle, XCircle } from \"lucide-react\";\n\ninterface Range {\n min: number;\n max: number;\n}\n\ntype RangeValue = [number, number];\n\nfunction getIsValidRange(value: unknown): value is RangeValue {\n return (\n Array.isArray(value) &&\n value.length === 2 &&\n typeof value[0] === \"number\" &&\n typeof value[1] === \"number\"\n );\n}\n\ninterface DataTableSliderFilterProps {\n column: Column;\n title?: string;\n}\n\nexport function DataTableSliderFilter({\n column,\n title,\n}: DataTableSliderFilterProps) {\n const id = React.useId();\n\n const columnFilterValue = getIsValidRange(column.getFilterValue())\n ? (column.getFilterValue() as RangeValue)\n : undefined;\n\n const defaultRange = column.columnDef.meta?.range;\n const unit = column.columnDef.meta?.unit;\n\n const { min, max, step } = React.useMemo(() => {\n let minValue = 0;\n let maxValue = 100;\n\n if (defaultRange && getIsValidRange(defaultRange)) {\n [minValue, maxValue] = defaultRange;\n } else {\n const values = column.getFacetedMinMaxValues();\n if (values && Array.isArray(values) && values.length === 2) {\n const [facetMinValue, facetMaxValue] = values;\n if (\n typeof facetMinValue === \"number\" &&\n typeof facetMaxValue === \"number\"\n ) {\n minValue = facetMinValue;\n maxValue = facetMaxValue;\n }\n }\n }\n\n const rangeSize = maxValue - minValue;\n const step =\n rangeSize <= 20\n ? 1\n : rangeSize <= 100\n ? Math.ceil(rangeSize / 20)\n : Math.ceil(rangeSize / 50);\n\n return { min: minValue, max: maxValue, step };\n }, [column, defaultRange]);\n\n const range = React.useMemo((): RangeValue => {\n return columnFilterValue ?? [min, max];\n }, [columnFilterValue, min, max]);\n\n const formatValue = React.useCallback((value: number) => {\n return value.toLocaleString(undefined, { maximumFractionDigits: 0 });\n }, []);\n\n const onFromInputChange = React.useCallback(\n (event: React.ChangeEvent) => {\n const numValue = Number(event.target.value);\n if (!Number.isNaN(numValue) && numValue >= min && numValue <= range[1]) {\n column.setFilterValue([numValue, range[1]]);\n }\n },\n [column, min, range],\n );\n\n const onToInputChange = React.useCallback(\n (event: React.ChangeEvent) => {\n const numValue = Number(event.target.value);\n if (!Number.isNaN(numValue) && numValue <= max && numValue >= range[0]) {\n column.setFilterValue([range[0], numValue]);\n }\n },\n [column, max, range],\n );\n\n const onSliderValueChange = React.useCallback(\n (value: RangeValue) => {\n if (Array.isArray(value) && value.length === 2) {\n column.setFilterValue(value);\n }\n },\n [column],\n );\n\n const onReset = React.useCallback(\n (event: React.MouseEvent) => {\n if (event.target instanceof HTMLDivElement) {\n event.stopPropagation();\n }\n column.setFilterValue(undefined);\n },\n [column],\n );\n\n return (\n \n \n
\n ) : (\n \n )}\n {title}\n {columnFilterValue ? (\n <>\n \n {formatValue(columnFilterValue[0])} -{\" \"}\n {formatValue(columnFilterValue[1])}\n {unit ? ` ${unit}` : \"\"}\n \n ) : null}\n \n \n \n
\n

\n {title}\n

\n
\n \n
\n \n {unit && (\n \n {unit}\n \n )}\n
\n \n
\n \n {unit && (\n \n {unit}\n \n )}\n
\n
\n \n \n
\n \n Clear\n \n
\n \n );\n}\n", + "content": "\"use client\";\n\nimport type { Column } from \"@tanstack/react-table\";\nimport { PlusCircle, XCircle } from \"lucide-react\";\nimport * as React from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { Slider } from \"@/components/ui/slider\";\nimport { cn } from \"@/lib/utils\";\n\ninterface Range {\n min: number;\n max: number;\n}\n\ntype RangeValue = [number, number];\n\nfunction getIsValidRange(value: unknown): value is RangeValue {\n return (\n Array.isArray(value) &&\n value.length === 2 &&\n typeof value[0] === \"number\" &&\n typeof value[1] === \"number\"\n );\n}\n\ninterface DataTableSliderFilterProps {\n column: Column;\n title?: string;\n}\n\nexport function DataTableSliderFilter({\n column,\n title,\n}: DataTableSliderFilterProps) {\n const id = React.useId();\n\n const columnFilterValue = getIsValidRange(column.getFilterValue())\n ? (column.getFilterValue() as RangeValue)\n : undefined;\n\n const defaultRange = column.columnDef.meta?.range;\n const unit = column.columnDef.meta?.unit;\n\n const { min, max, step } = React.useMemo(() => {\n let minValue = 0;\n let maxValue = 100;\n\n if (defaultRange && getIsValidRange(defaultRange)) {\n [minValue, maxValue] = defaultRange;\n } else {\n const values = column.getFacetedMinMaxValues();\n if (values && Array.isArray(values) && values.length === 2) {\n const [facetMinValue, facetMaxValue] = values;\n if (\n typeof facetMinValue === \"number\" &&\n typeof facetMaxValue === \"number\"\n ) {\n minValue = facetMinValue;\n maxValue = facetMaxValue;\n }\n }\n }\n\n const rangeSize = maxValue - minValue;\n const step =\n rangeSize <= 20\n ? 1\n : rangeSize <= 100\n ? Math.ceil(rangeSize / 20)\n : Math.ceil(rangeSize / 50);\n\n return { min: minValue, max: maxValue, step };\n }, [column, defaultRange]);\n\n const range = React.useMemo((): RangeValue => {\n return columnFilterValue ?? [min, max];\n }, [columnFilterValue, min, max]);\n\n const formatValue = React.useCallback((value: number) => {\n return value.toLocaleString(undefined, { maximumFractionDigits: 0 });\n }, []);\n\n const onFromInputChange = React.useCallback(\n (event: React.ChangeEvent) => {\n const numValue = Number(event.target.value);\n if (!Number.isNaN(numValue) && numValue >= min && numValue <= range[1]) {\n column.setFilterValue([numValue, range[1]]);\n }\n },\n [column, min, range],\n );\n\n const onToInputChange = React.useCallback(\n (event: React.ChangeEvent) => {\n const numValue = Number(event.target.value);\n if (!Number.isNaN(numValue) && numValue <= max && numValue >= range[0]) {\n column.setFilterValue([range[0], numValue]);\n }\n },\n [column, max, range],\n );\n\n const onSliderValueChange = React.useCallback(\n (value: RangeValue) => {\n if (Array.isArray(value) && value.length === 2) {\n column.setFilterValue(value);\n }\n },\n [column],\n );\n\n const onReset = React.useCallback(\n (event: React.MouseEvent) => {\n if (event.target instanceof HTMLDivElement) {\n event.stopPropagation();\n }\n column.setFilterValue(undefined);\n },\n [column],\n );\n\n return (\n \n \n
\n ) : (\n \n )}\n {title}\n {columnFilterValue ? (\n <>\n \n {formatValue(columnFilterValue[0])} -{\" \"}\n {formatValue(columnFilterValue[1])}\n {unit ? ` ${unit}` : \"\"}\n \n ) : null}\n \n \n \n
\n

\n {title}\n

\n
\n \n
\n \n {unit && (\n \n {unit}\n \n )}\n
\n \n
\n \n {unit && (\n \n {unit}\n \n )}\n
\n
\n \n \n
\n \n Clear\n \n
\n \n );\n}\n", "type": "registry:component", "target": "src/components/data-table/data-table-slider-filter.tsx" }, @@ -84,7 +84,7 @@ }, { "path": "src/hooks/use-data-table.ts", - "content": "\"use client\";\n\nimport {\n type ColumnFiltersState,\n type PaginationState,\n type RowSelectionState,\n type SortingState,\n type TableOptions,\n type TableState,\n type Updater,\n type VisibilityState,\n getCoreRowModel,\n getFacetedMinMaxValues,\n getFacetedRowModel,\n getFacetedUniqueValues,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n} from \"@tanstack/react-table\";\nimport {\n type Parser,\n type UseQueryStateOptions,\n parseAsArrayOf,\n parseAsInteger,\n parseAsString,\n useQueryState,\n useQueryStates,\n} from \"nuqs\";\nimport * as React from \"react\";\n\nimport { useDebouncedCallback } from \"@/hooks/use-debounced-callback\";\nimport { getSortingStateParser } from \"@/lib/parsers\";\nimport type { ExtendedColumnSort } from \"@/types/data-table\";\n\nconst PAGE_KEY = \"page\";\nconst PER_PAGE_KEY = \"perPage\";\nconst SORT_KEY = \"sort\";\nconst ARRAY_SEPARATOR = \",\";\nconst DEBOUNCE_MS = 300;\nconst THROTTLE_MS = 50;\n\ninterface UseDataTableProps\n extends Omit<\n TableOptions,\n | \"state\"\n | \"pageCount\"\n | \"getCoreRowModel\"\n | \"manualFiltering\"\n | \"manualPagination\"\n | \"manualSorting\"\n >,\n Required, \"pageCount\">> {\n initialState?: Omit, \"sorting\"> & {\n sorting?: ExtendedColumnSort[];\n };\n history?: \"push\" | \"replace\";\n debounceMs?: number;\n throttleMs?: number;\n clearOnDefault?: boolean;\n enableAdvancedFilter?: boolean;\n scroll?: boolean;\n shallow?: boolean;\n startTransition?: React.TransitionStartFunction;\n}\n\nexport function useDataTable(props: UseDataTableProps) {\n const {\n columns,\n pageCount = -1,\n initialState,\n history = \"replace\",\n debounceMs = DEBOUNCE_MS,\n throttleMs = THROTTLE_MS,\n clearOnDefault = false,\n enableAdvancedFilter = false,\n scroll = false,\n shallow = true,\n startTransition,\n ...tableProps\n } = props;\n\n const queryStateOptions = React.useMemo<\n Omit, \"parse\">\n >(\n () => ({\n history,\n scroll,\n shallow,\n throttleMs,\n debounceMs,\n clearOnDefault,\n startTransition,\n }),\n [\n history,\n scroll,\n shallow,\n throttleMs,\n debounceMs,\n clearOnDefault,\n startTransition,\n ],\n );\n\n const [rowSelection, setRowSelection] = React.useState(\n initialState?.rowSelection ?? {},\n );\n const [columnVisibility, setColumnVisibility] =\n React.useState(initialState?.columnVisibility ?? {});\n\n const [page, setPage] = useQueryState(\n PAGE_KEY,\n parseAsInteger.withOptions(queryStateOptions).withDefault(1),\n );\n const [perPage, setPerPage] = useQueryState(\n PER_PAGE_KEY,\n parseAsInteger\n .withOptions(queryStateOptions)\n .withDefault(initialState?.pagination?.pageSize ?? 10),\n );\n\n const pagination: PaginationState = React.useMemo(() => {\n return {\n pageIndex: page - 1, // zero-based index -> one-based index\n pageSize: perPage,\n };\n }, [page, perPage]);\n\n const onPaginationChange = React.useCallback(\n (updaterOrValue: Updater) => {\n if (typeof updaterOrValue === \"function\") {\n const newPagination = updaterOrValue(pagination);\n void setPage(newPagination.pageIndex + 1);\n void setPerPage(newPagination.pageSize);\n } else {\n void setPage(updaterOrValue.pageIndex + 1);\n void setPerPage(updaterOrValue.pageSize);\n }\n },\n [pagination, setPage, setPerPage],\n );\n\n const columnIds = React.useMemo(() => {\n return new Set(\n columns.map((column) => column.id).filter(Boolean) as string[],\n );\n }, [columns]);\n\n const [sorting, setSorting] = useQueryState(\n SORT_KEY,\n getSortingStateParser(columnIds)\n .withOptions(queryStateOptions)\n .withDefault(initialState?.sorting ?? []),\n );\n\n const onSortingChange = React.useCallback(\n (updaterOrValue: Updater) => {\n if (typeof updaterOrValue === \"function\") {\n const newSorting = updaterOrValue(sorting);\n setSorting(newSorting as ExtendedColumnSort[]);\n } else {\n setSorting(updaterOrValue as ExtendedColumnSort[]);\n }\n },\n [sorting, setSorting],\n );\n\n const filterableColumns = React.useMemo(() => {\n if (enableAdvancedFilter) return [];\n\n return columns.filter((column) => column.enableColumnFilter);\n }, [columns, enableAdvancedFilter]);\n\n const filterParsers = React.useMemo(() => {\n if (enableAdvancedFilter) return {};\n\n return filterableColumns.reduce<\n Record | Parser>\n >((acc, column) => {\n if (column.meta?.options) {\n acc[column.id ?? \"\"] = parseAsArrayOf(\n parseAsString,\n ARRAY_SEPARATOR,\n ).withOptions(queryStateOptions);\n } else {\n acc[column.id ?? \"\"] = parseAsString.withOptions(queryStateOptions);\n }\n return acc;\n }, {});\n }, [filterableColumns, queryStateOptions, enableAdvancedFilter]);\n\n const [filterValues, setFilterValues] = useQueryStates(filterParsers);\n\n const debouncedSetFilterValues = useDebouncedCallback(\n (values: typeof filterValues) => {\n void setPage(1);\n void setFilterValues(values);\n },\n debounceMs,\n );\n\n const initialColumnFilters: ColumnFiltersState = React.useMemo(() => {\n if (enableAdvancedFilter) return [];\n\n return Object.entries(filterValues).reduce(\n (filters, [key, value]) => {\n if (value !== null) {\n const processedValue = Array.isArray(value)\n ? value\n : typeof value === \"string\" && /[^a-zA-Z0-9]/.test(value)\n ? value.split(/[^a-zA-Z0-9]+/).filter(Boolean)\n : [value];\n\n filters.push({\n id: key,\n value: processedValue,\n });\n }\n return filters;\n },\n [],\n );\n }, [filterValues, enableAdvancedFilter]);\n\n const [columnFilters, setColumnFilters] =\n React.useState(initialColumnFilters);\n\n const onColumnFiltersChange = React.useCallback(\n (updaterOrValue: Updater) => {\n if (enableAdvancedFilter) return;\n\n setColumnFilters((prev) => {\n const next =\n typeof updaterOrValue === \"function\"\n ? updaterOrValue(prev)\n : updaterOrValue;\n\n const filterUpdates = next.reduce<\n Record\n >((acc, filter) => {\n if (filterableColumns.find((column) => column.id === filter.id)) {\n acc[filter.id] = filter.value as string | string[];\n }\n return acc;\n }, {});\n\n for (const prevFilter of prev) {\n if (!next.some((filter) => filter.id === prevFilter.id)) {\n filterUpdates[prevFilter.id] = null;\n }\n }\n\n debouncedSetFilterValues(filterUpdates);\n return next;\n });\n },\n [debouncedSetFilterValues, filterableColumns, enableAdvancedFilter],\n );\n\n const table = useReactTable({\n ...tableProps,\n columns,\n initialState,\n pageCount,\n state: {\n pagination,\n sorting,\n columnVisibility,\n rowSelection,\n columnFilters,\n },\n defaultColumn: {\n ...tableProps.defaultColumn,\n enableColumnFilter: false,\n },\n enableRowSelection: true,\n onRowSelectionChange: setRowSelection,\n onPaginationChange,\n onSortingChange,\n onColumnFiltersChange,\n onColumnVisibilityChange: setColumnVisibility,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFacetedRowModel: getFacetedRowModel(),\n getFacetedUniqueValues: getFacetedUniqueValues(),\n getFacetedMinMaxValues: getFacetedMinMaxValues(),\n manualPagination: true,\n manualSorting: true,\n manualFiltering: true,\n });\n\n return { table, shallow, debounceMs, throttleMs };\n}\n", + "content": "\"use client\";\n\nimport {\n type ColumnFiltersState,\n getCoreRowModel,\n getFacetedMinMaxValues,\n getFacetedRowModel,\n getFacetedUniqueValues,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n type PaginationState,\n type RowSelectionState,\n type SortingState,\n type TableOptions,\n type TableState,\n type Updater,\n useReactTable,\n type VisibilityState,\n} from \"@tanstack/react-table\";\nimport {\n type Parser,\n parseAsArrayOf,\n parseAsInteger,\n parseAsString,\n type UseQueryStateOptions,\n useQueryState,\n useQueryStates,\n} from \"nuqs\";\nimport * as React from \"react\";\n\nimport { useDebouncedCallback } from \"@/hooks/use-debounced-callback\";\nimport { getSortingStateParser } from \"@/lib/parsers\";\nimport type { ExtendedColumnSort } from \"@/types/data-table\";\n\nconst PAGE_KEY = \"page\";\nconst PER_PAGE_KEY = \"perPage\";\nconst SORT_KEY = \"sort\";\nconst ARRAY_SEPARATOR = \",\";\nconst DEBOUNCE_MS = 300;\nconst THROTTLE_MS = 50;\n\ninterface UseDataTableProps\n extends Omit<\n TableOptions,\n | \"state\"\n | \"pageCount\"\n | \"getCoreRowModel\"\n | \"manualFiltering\"\n | \"manualPagination\"\n | \"manualSorting\"\n >,\n Required, \"pageCount\">> {\n initialState?: Omit, \"sorting\"> & {\n sorting?: ExtendedColumnSort[];\n };\n history?: \"push\" | \"replace\";\n debounceMs?: number;\n throttleMs?: number;\n clearOnDefault?: boolean;\n enableAdvancedFilter?: boolean;\n scroll?: boolean;\n shallow?: boolean;\n startTransition?: React.TransitionStartFunction;\n}\n\nexport function useDataTable(props: UseDataTableProps) {\n const {\n columns,\n pageCount = -1,\n initialState,\n history = \"replace\",\n debounceMs = DEBOUNCE_MS,\n throttleMs = THROTTLE_MS,\n clearOnDefault = false,\n enableAdvancedFilter = false,\n scroll = false,\n shallow = true,\n startTransition,\n ...tableProps\n } = props;\n\n const queryStateOptions = React.useMemo<\n Omit, \"parse\">\n >(\n () => ({\n history,\n scroll,\n shallow,\n throttleMs,\n debounceMs,\n clearOnDefault,\n startTransition,\n }),\n [\n history,\n scroll,\n shallow,\n throttleMs,\n debounceMs,\n clearOnDefault,\n startTransition,\n ],\n );\n\n const [rowSelection, setRowSelection] = React.useState(\n initialState?.rowSelection ?? {},\n );\n const [columnVisibility, setColumnVisibility] =\n React.useState(initialState?.columnVisibility ?? {});\n\n const [page, setPage] = useQueryState(\n PAGE_KEY,\n parseAsInteger.withOptions(queryStateOptions).withDefault(1),\n );\n const [perPage, setPerPage] = useQueryState(\n PER_PAGE_KEY,\n parseAsInteger\n .withOptions(queryStateOptions)\n .withDefault(initialState?.pagination?.pageSize ?? 10),\n );\n\n const pagination: PaginationState = React.useMemo(() => {\n return {\n pageIndex: page - 1, // zero-based index -> one-based index\n pageSize: perPage,\n };\n }, [page, perPage]);\n\n const onPaginationChange = React.useCallback(\n (updaterOrValue: Updater) => {\n if (typeof updaterOrValue === \"function\") {\n const newPagination = updaterOrValue(pagination);\n void setPage(newPagination.pageIndex + 1);\n void setPerPage(newPagination.pageSize);\n } else {\n void setPage(updaterOrValue.pageIndex + 1);\n void setPerPage(updaterOrValue.pageSize);\n }\n },\n [pagination, setPage, setPerPage],\n );\n\n const columnIds = React.useMemo(() => {\n return new Set(\n columns.map((column) => column.id).filter(Boolean) as string[],\n );\n }, [columns]);\n\n const [sorting, setSorting] = useQueryState(\n SORT_KEY,\n getSortingStateParser(columnIds)\n .withOptions(queryStateOptions)\n .withDefault(initialState?.sorting ?? []),\n );\n\n const onSortingChange = React.useCallback(\n (updaterOrValue: Updater) => {\n if (typeof updaterOrValue === \"function\") {\n const newSorting = updaterOrValue(sorting);\n setSorting(newSorting as ExtendedColumnSort[]);\n } else {\n setSorting(updaterOrValue as ExtendedColumnSort[]);\n }\n },\n [sorting, setSorting],\n );\n\n const filterableColumns = React.useMemo(() => {\n if (enableAdvancedFilter) return [];\n\n return columns.filter((column) => column.enableColumnFilter);\n }, [columns, enableAdvancedFilter]);\n\n const filterParsers = React.useMemo(() => {\n if (enableAdvancedFilter) return {};\n\n return filterableColumns.reduce<\n Record | Parser>\n >((acc, column) => {\n if (column.meta?.options) {\n acc[column.id ?? \"\"] = parseAsArrayOf(\n parseAsString,\n ARRAY_SEPARATOR,\n ).withOptions(queryStateOptions);\n } else {\n acc[column.id ?? \"\"] = parseAsString.withOptions(queryStateOptions);\n }\n return acc;\n }, {});\n }, [filterableColumns, queryStateOptions, enableAdvancedFilter]);\n\n const [filterValues, setFilterValues] = useQueryStates(filterParsers);\n\n const debouncedSetFilterValues = useDebouncedCallback(\n (values: typeof filterValues) => {\n void setPage(1);\n void setFilterValues(values);\n },\n debounceMs,\n );\n\n const initialColumnFilters: ColumnFiltersState = React.useMemo(() => {\n if (enableAdvancedFilter) return [];\n\n return Object.entries(filterValues).reduce(\n (filters, [key, value]) => {\n if (value !== null) {\n const processedValue = Array.isArray(value)\n ? value\n : typeof value === \"string\" && /[^a-zA-Z0-9]/.test(value)\n ? value.split(/[^a-zA-Z0-9]+/).filter(Boolean)\n : [value];\n\n filters.push({\n id: key,\n value: processedValue,\n });\n }\n return filters;\n },\n [],\n );\n }, [filterValues, enableAdvancedFilter]);\n\n const [columnFilters, setColumnFilters] =\n React.useState(initialColumnFilters);\n\n const onColumnFiltersChange = React.useCallback(\n (updaterOrValue: Updater) => {\n if (enableAdvancedFilter) return;\n\n setColumnFilters((prev) => {\n const next =\n typeof updaterOrValue === \"function\"\n ? updaterOrValue(prev)\n : updaterOrValue;\n\n const filterUpdates = next.reduce<\n Record\n >((acc, filter) => {\n if (filterableColumns.find((column) => column.id === filter.id)) {\n acc[filter.id] = filter.value as string | string[];\n }\n return acc;\n }, {});\n\n for (const prevFilter of prev) {\n if (!next.some((filter) => filter.id === prevFilter.id)) {\n filterUpdates[prevFilter.id] = null;\n }\n }\n\n debouncedSetFilterValues(filterUpdates);\n return next;\n });\n },\n [debouncedSetFilterValues, filterableColumns, enableAdvancedFilter],\n );\n\n const table = useReactTable({\n ...tableProps,\n columns,\n initialState,\n pageCount,\n state: {\n pagination,\n sorting,\n columnVisibility,\n rowSelection,\n columnFilters,\n },\n defaultColumn: {\n ...tableProps.defaultColumn,\n enableColumnFilter: false,\n },\n enableRowSelection: true,\n onRowSelectionChange: setRowSelection,\n onPaginationChange,\n onSortingChange,\n onColumnFiltersChange,\n onColumnVisibilityChange: setColumnVisibility,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFacetedRowModel: getFacetedRowModel(),\n getFacetedUniqueValues: getFacetedUniqueValues(),\n getFacetedMinMaxValues: getFacetedMinMaxValues(),\n manualPagination: true,\n manualSorting: true,\n manualFiltering: true,\n });\n\n return { table, shallow, debounceMs, throttleMs };\n}\n", "type": "registry:hook" }, { @@ -94,7 +94,7 @@ }, { "path": "src/lib/data-table.ts", - "content": "import type {\n ExtendedColumnFilter,\n FilterOperator,\n FilterVariant,\n} from \"@/types/data-table\";\nimport type { Column } from \"@tanstack/react-table\";\n\nimport { dataTableConfig } from \"@/config/data-table\";\n\nexport function getCommonPinningStyles({\n column,\n withBorder = false,\n}: {\n column: Column;\n withBorder?: boolean;\n}): React.CSSProperties {\n const isPinned = column.getIsPinned();\n const isLastLeftPinnedColumn =\n isPinned === \"left\" && column.getIsLastColumn(\"left\");\n const isFirstRightPinnedColumn =\n isPinned === \"right\" && column.getIsFirstColumn(\"right\");\n\n return {\n boxShadow: withBorder\n ? isLastLeftPinnedColumn\n ? \"-4px 0 4px -4px hsl(var(--border)) inset\"\n : isFirstRightPinnedColumn\n ? \"4px 0 4px -4px hsl(var(--border)) inset\"\n : undefined\n : undefined,\n left: isPinned === \"left\" ? `${column.getStart(\"left\")}px` : undefined,\n right: isPinned === \"right\" ? `${column.getAfter(\"right\")}px` : undefined,\n opacity: isPinned ? 0.97 : 1,\n position: isPinned ? \"sticky\" : \"relative\",\n background: isPinned ? \"hsl(var(--background))\" : \"hsl(var(--background))\",\n width: column.getSize(),\n zIndex: isPinned ? 1 : 0,\n };\n}\n\nexport function getFilterOperators(filterVariant: FilterVariant) {\n const operatorMap: Record<\n FilterVariant,\n { label: string; value: FilterOperator }[]\n > = {\n text: dataTableConfig.textOperators,\n number: dataTableConfig.numericOperators,\n range: dataTableConfig.numericOperators,\n date: dataTableConfig.dateOperators,\n dateRange: dataTableConfig.dateOperators,\n boolean: dataTableConfig.booleanOperators,\n select: dataTableConfig.selectOperators,\n multiSelect: dataTableConfig.multiSelectOperators,\n };\n\n return operatorMap[filterVariant] ?? dataTableConfig.textOperators;\n}\n\nexport function getDefaultFilterOperator(filterVariant: FilterVariant) {\n const operators = getFilterOperators(filterVariant);\n\n return operators[0]?.value ?? (filterVariant === \"text\" ? \"iLike\" : \"eq\");\n}\n\nexport function getValidFilters(\n filters: ExtendedColumnFilter[],\n): ExtendedColumnFilter[] {\n return filters.filter(\n (filter) =>\n filter.operator === \"isEmpty\" ||\n filter.operator === \"isNotEmpty\" ||\n (Array.isArray(filter.value)\n ? filter.value.length > 0\n : filter.value !== \"\" &&\n filter.value !== null &&\n filter.value !== undefined),\n );\n}\n", + "content": "import type { Column } from \"@tanstack/react-table\";\nimport { dataTableConfig } from \"@/config/data-table\";\nimport type {\n ExtendedColumnFilter,\n FilterOperator,\n FilterVariant,\n} from \"@/types/data-table\";\n\nexport function getCommonPinningStyles({\n column,\n withBorder = false,\n}: {\n column: Column;\n withBorder?: boolean;\n}): React.CSSProperties {\n const isPinned = column.getIsPinned();\n const isLastLeftPinnedColumn =\n isPinned === \"left\" && column.getIsLastColumn(\"left\");\n const isFirstRightPinnedColumn =\n isPinned === \"right\" && column.getIsFirstColumn(\"right\");\n\n return {\n boxShadow: withBorder\n ? isLastLeftPinnedColumn\n ? \"-4px 0 4px -4px hsl(var(--border)) inset\"\n : isFirstRightPinnedColumn\n ? \"4px 0 4px -4px hsl(var(--border)) inset\"\n : undefined\n : undefined,\n left: isPinned === \"left\" ? `${column.getStart(\"left\")}px` : undefined,\n right: isPinned === \"right\" ? `${column.getAfter(\"right\")}px` : undefined,\n opacity: isPinned ? 0.97 : 1,\n position: isPinned ? \"sticky\" : \"relative\",\n background: isPinned ? \"hsl(var(--background))\" : \"hsl(var(--background))\",\n width: column.getSize(),\n zIndex: isPinned ? 1 : 0,\n };\n}\n\nexport function getFilterOperators(filterVariant: FilterVariant) {\n const operatorMap: Record<\n FilterVariant,\n { label: string; value: FilterOperator }[]\n > = {\n text: dataTableConfig.textOperators,\n number: dataTableConfig.numericOperators,\n range: dataTableConfig.numericOperators,\n date: dataTableConfig.dateOperators,\n dateRange: dataTableConfig.dateOperators,\n boolean: dataTableConfig.booleanOperators,\n select: dataTableConfig.selectOperators,\n multiSelect: dataTableConfig.multiSelectOperators,\n };\n\n return operatorMap[filterVariant] ?? dataTableConfig.textOperators;\n}\n\nexport function getDefaultFilterOperator(filterVariant: FilterVariant) {\n const operators = getFilterOperators(filterVariant);\n\n return operators[0]?.value ?? (filterVariant === \"text\" ? \"iLike\" : \"eq\");\n}\n\nexport function getValidFilters(\n filters: ExtendedColumnFilter[],\n): ExtendedColumnFilter[] {\n return filters.filter(\n (filter) =>\n filter.operator === \"isEmpty\" ||\n filter.operator === \"isNotEmpty\" ||\n (Array.isArray(filter.value)\n ? filter.value.length > 0\n : filter.value !== \"\" &&\n filter.value !== null &&\n filter.value !== undefined),\n );\n}\n", "type": "registry:lib" }, { @@ -115,7 +115,7 @@ }, { "path": "src/types/data-table.ts", - "content": "import type { DataTableConfig } from \"@/config/data-table\";\nimport type { FilterItemSchema } from \"@/lib/parsers\";\nimport type { ColumnSort, Row, RowData } from \"@tanstack/react-table\";\n\ndeclare module \"@tanstack/react-table\" {\n // biome-ignore lint/correctness/noUnusedVariables: \n interface ColumnMeta {\n label?: string;\n placeholder?: string;\n variant?: FilterVariant;\n options?: Option[];\n range?: [number, number];\n unit?: string;\n icon?: React.FC>;\n }\n}\n\nexport interface Option {\n label: string;\n value: string;\n count?: number;\n icon?: React.FC>;\n}\n\nexport type FilterOperator = DataTableConfig[\"operators\"][number];\nexport type FilterVariant = DataTableConfig[\"filterVariants\"][number];\nexport type JoinOperator = DataTableConfig[\"joinOperators\"][number];\n\nexport interface ExtendedColumnSort extends Omit {\n id: Extract;\n}\n\nexport interface ExtendedColumnFilter extends FilterItemSchema {\n id: Extract;\n}\n\nexport interface DataTableRowAction {\n row: Row;\n variant: \"update\" | \"delete\";\n}\n", + "content": "import type { ColumnSort, Row, RowData } from \"@tanstack/react-table\";\nimport type { DataTableConfig } from \"@/config/data-table\";\nimport type { FilterItemSchema } from \"@/lib/parsers\";\n\ndeclare module \"@tanstack/react-table\" {\n // biome-ignore lint/correctness/noUnusedVariables: TValue is used in the ColumnMeta interface\n interface ColumnMeta {\n label?: string;\n placeholder?: string;\n variant?: FilterVariant;\n options?: Option[];\n range?: [number, number];\n unit?: string;\n icon?: React.FC>;\n }\n}\n\nexport interface Option {\n label: string;\n value: string;\n count?: number;\n icon?: React.FC>;\n}\n\nexport type FilterOperator = DataTableConfig[\"operators\"][number];\nexport type FilterVariant = DataTableConfig[\"filterVariants\"][number];\nexport type JoinOperator = DataTableConfig[\"joinOperators\"][number];\n\nexport interface ExtendedColumnSort extends Omit {\n id: Extract;\n}\n\nexport interface ExtendedColumnFilter extends FilterItemSchema {\n id: Extract;\n}\n\nexport interface DataTableRowAction {\n row: Row;\n variant: \"update\" | \"delete\";\n}\n", "type": "registry:file", "target": "src/types/data-table.ts" } diff --git a/registry.json b/registry.json index 4cb94030..89726364 100644 --- a/registry.json +++ b/registry.json @@ -144,7 +144,7 @@ "target": "src/components/ui/sortable.tsx" }, { - "path": "src/lib/composition.ts", + "path": "src/lib/compose-refs.ts", "type": "registry:lib" }, { @@ -214,7 +214,7 @@ "type": "registry:hook" }, { - "path": "src/lib/composition.ts", + "path": "src/lib/compose-refs.ts", "type": "registry:lib" }, { diff --git a/src/app/_components/delete-tasks-dialog.tsx b/src/app/_components/delete-tasks-dialog.tsx index cc723615..263a444b 100644 --- a/src/app/_components/delete-tasks-dialog.tsx +++ b/src/app/_components/delete-tasks-dialog.tsx @@ -1,11 +1,9 @@ "use client"; -import type { Task } from "@/db/schema"; import type { Row } from "@tanstack/react-table"; import { Loader, Trash } from "lucide-react"; import * as React from "react"; import { toast } from "sonner"; - import { Button } from "@/components/ui/button"; import { Dialog, @@ -27,6 +25,7 @@ import { DrawerTitle, DrawerTrigger, } from "@/components/ui/drawer"; +import type { Task } from "@/db/schema"; import { useMediaQuery } from "@/hooks/use-media-query"; import { deleteTasks } from "../_lib/actions"; diff --git a/src/app/_components/task-form.tsx b/src/app/_components/task-form.tsx index cce36b9e..4279411b 100644 --- a/src/app/_components/task-form.tsx +++ b/src/app/_components/task-form.tsx @@ -1,9 +1,7 @@ "use client"; -import { tasks } from "@/db/schema"; import type * as React from "react"; import type { FieldPath, FieldValues, UseFormReturn } from "react-hook-form"; - import { Form, FormControl, @@ -22,6 +20,7 @@ import { SelectValue, } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; +import { tasks } from "@/db/schema"; interface TaskFormProps extends Omit, "onSubmit"> { diff --git a/src/app/_components/tasks-table-action-bar.tsx b/src/app/_components/tasks-table-action-bar.tsx index 94100ffc..469b2e6b 100644 --- a/src/app/_components/tasks-table-action-bar.tsx +++ b/src/app/_components/tasks-table-action-bar.tsx @@ -1,12 +1,10 @@ "use client"; -import { type Task, tasks } from "@/db/schema"; import { SelectTrigger } from "@radix-ui/react-select"; import type { Table } from "@tanstack/react-table"; import { ArrowUp, CheckCircle2, Download, Trash2 } from "lucide-react"; import * as React from "react"; import { toast } from "sonner"; - import { DataTableActionBar, DataTableActionBarAction, @@ -19,6 +17,7 @@ import { SelectItem, } from "@/components/ui/select"; import { Separator } from "@/components/ui/separator"; +import { type Task, tasks } from "@/db/schema"; import { exportTableToCSV } from "@/lib/export"; import { deleteTasks, updateTasks } from "../_lib/actions"; diff --git a/src/app/_components/tasks-table-columns.tsx b/src/app/_components/tasks-table-columns.tsx index 1634dc72..e8ccd5ba 100644 --- a/src/app/_components/tasks-table-columns.tsx +++ b/src/app/_components/tasks-table-columns.tsx @@ -1,7 +1,5 @@ "use client"; -import { type Task, tasks } from "@/db/schema"; -import type { DataTableRowAction } from "@/types/data-table"; import type { ColumnDef } from "@tanstack/react-table"; import { ArrowUpDown, @@ -13,7 +11,6 @@ import { } from "lucide-react"; import * as React from "react"; import { toast } from "sonner"; - import { DataTableColumnHeader } from "@/components/data-table/data-table-column-header"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; @@ -31,8 +28,10 @@ import { DropdownMenuSubTrigger, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { type Task, tasks } from "@/db/schema"; import { formatDate } from "@/lib/format"; import { getErrorMessage } from "@/lib/handle-error"; +import type { DataTableRowAction } from "@/types/data-table"; import { updateTask } from "../_lib/actions"; import { getPriorityIcon, getStatusIcon } from "../_lib/utils"; diff --git a/src/app/_components/tasks-table-toolbar-actions.tsx b/src/app/_components/tasks-table-toolbar-actions.tsx index f7d93cf2..a544b4fb 100644 --- a/src/app/_components/tasks-table-toolbar-actions.tsx +++ b/src/app/_components/tasks-table-toolbar-actions.tsx @@ -1,10 +1,9 @@ "use client"; -import type { Task } from "@/db/schema"; import type { Table } from "@tanstack/react-table"; import { Download } from "lucide-react"; - import { Button } from "@/components/ui/button"; +import type { Task } from "@/db/schema"; import { exportTableToCSV } from "@/lib/export"; import { CreateTaskSheet } from "./create-task-sheet"; diff --git a/src/app/_components/tasks-table.tsx b/src/app/_components/tasks-table.tsx index c6d196ae..f80757e5 100644 --- a/src/app/_components/tasks-table.tsx +++ b/src/app/_components/tasks-table.tsx @@ -1,17 +1,15 @@ "use client"; -import type { Task } from "@/db/schema"; -import type { DataTableRowAction } from "@/types/data-table"; import * as React from "react"; - import { DataTable } from "@/components/data-table/data-table"; -import { useDataTable } from "@/hooks/use-data-table"; - import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar"; import { DataTableFilterList } from "@/components/data-table/data-table-filter-list"; import { DataTableFilterMenu } from "@/components/data-table/data-table-filter-menu"; import { DataTableSortList } from "@/components/data-table/data-table-sort-list"; import { DataTableToolbar } from "@/components/data-table/data-table-toolbar"; +import type { Task } from "@/db/schema"; +import { useDataTable } from "@/hooks/use-data-table"; +import type { DataTableRowAction } from "@/types/data-table"; import type { getEstimatedHoursRange, getTaskPriorityCounts, diff --git a/src/app/_components/update-task-sheet.tsx b/src/app/_components/update-task-sheet.tsx index 8f1e132d..f4e94048 100644 --- a/src/app/_components/update-task-sheet.tsx +++ b/src/app/_components/update-task-sheet.tsx @@ -1,12 +1,10 @@ "use client"; -import type { Task } from "@/db/schema"; import { zodResolver } from "@hookform/resolvers/zod"; import { Loader } from "lucide-react"; import * as React from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; - import { Button } from "@/components/ui/button"; import { Sheet, @@ -17,6 +15,7 @@ import { SheetHeader, SheetTitle, } from "@/components/ui/sheet"; +import type { Task } from "@/db/schema"; import { updateTask } from "../_lib/actions"; import { type UpdateTaskSchema, updateTaskSchema } from "../_lib/validations"; diff --git a/src/app/_lib/actions.ts b/src/app/_lib/actions.ts index 6a048c67..d36d31f8 100644 --- a/src/app/_lib/actions.ts +++ b/src/app/_lib/actions.ts @@ -1,11 +1,11 @@ "use server"; -import { db } from "@/db/index"; -import { type Task, tasks } from "@/db/schema"; -import { takeFirstOrThrow } from "@/db/utils"; import { asc, eq, inArray, not } from "drizzle-orm"; import { customAlphabet } from "nanoid"; import { revalidateTag, unstable_noStore } from "next/cache"; +import { db } from "@/db/index"; +import { type Task, tasks } from "@/db/schema"; +import { takeFirstOrThrow } from "@/db/utils"; import { getErrorMessage } from "@/lib/handle-error"; diff --git a/src/app/_lib/queries.ts b/src/app/_lib/queries.ts index 5f7b512e..5b0e920b 100644 --- a/src/app/_lib/queries.ts +++ b/src/app/_lib/queries.ts @@ -1,7 +1,5 @@ import "server-only"; -import { db } from "@/db"; -import { tasks } from "@/db/schema"; import { and, asc, @@ -14,6 +12,8 @@ import { lte, sql, } from "drizzle-orm"; +import { db } from "@/db"; +import { tasks } from "@/db/schema"; import { filterColumns } from "@/lib/filter-columns"; import { unstable_cache } from "@/lib/unstable-cache"; diff --git a/src/app/_lib/utils.ts b/src/app/_lib/utils.ts index 1228f023..4866257f 100644 --- a/src/app/_lib/utils.ts +++ b/src/app/_lib/utils.ts @@ -1,4 +1,3 @@ -import { type Task, tasks } from "@/db/schema"; import { faker } from "@faker-js/faker"; import { ArrowDownIcon, @@ -11,6 +10,7 @@ import { Timer, } from "lucide-react"; import { customAlphabet } from "nanoid"; +import { type Task, tasks } from "@/db/schema"; import { generateId } from "@/lib/id"; diff --git a/src/app/_lib/validations.ts b/src/app/_lib/validations.ts index ccd74dac..78c84496 100644 --- a/src/app/_lib/validations.ts +++ b/src/app/_lib/validations.ts @@ -1,4 +1,3 @@ -import { type Task, tasks } from "@/db/schema"; import { createSearchParamsCache, parseAsArrayOf, @@ -7,8 +6,8 @@ import { parseAsStringEnum, } from "nuqs/server"; import * as z from "zod"; - import { flagConfig } from "@/config/flag"; +import { type Task, tasks } from "@/db/schema"; import { getFiltersStateParser, getSortingStateParser } from "@/lib/parsers"; export const searchParamsCache = createSearchParamsCache({ diff --git a/src/app/layout.tsx b/src/app/layout.tsx index f3e381b1..0fca1572 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -7,10 +7,9 @@ import { cn } from "@/lib/utils"; import "@/styles/globals.css"; import type { Metadata, Viewport } from "next"; - +import Script from "next/script"; import { Toaster } from "@/components/ui/sonner"; import { fontMono, fontSans } from "@/lib/fonts"; -import Script from "next/script"; export const metadata: Metadata = { metadataBase: new URL(siteConfig.url), diff --git a/src/app/page.tsx b/src/app/page.tsx index b0bd70ce..7364247b 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,9 +1,8 @@ -import type { SearchParams } from "@/types"; import * as React from "react"; - import { DataTableSkeleton } from "@/components/data-table/data-table-skeleton"; import { Shell } from "@/components/shell"; import { getValidFilters } from "@/lib/data-table"; +import type { SearchParams } from "@/types"; import { FeatureFlagsProvider } from "./_components/feature-flags-provider"; import { TasksTable } from "./_components/tasks-table"; diff --git a/src/components/data-table/data-table-action-bar.tsx b/src/components/data-table/data-table-action-bar.tsx index 7cd87858..aa1f107b 100644 --- a/src/components/data-table/data-table-action-bar.tsx +++ b/src/components/data-table/data-table-action-bar.tsx @@ -1,5 +1,10 @@ "use client"; +import type { Table } from "@tanstack/react-table"; +import { Loader, X } from "lucide-react"; +import { AnimatePresence, motion } from "motion/react"; +import * as React from "react"; +import * as ReactDOM from "react-dom"; import { Button } from "@/components/ui/button"; import { Separator } from "@/components/ui/separator"; import { @@ -8,11 +13,6 @@ import { TooltipTrigger, } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; -import type { Table } from "@tanstack/react-table"; -import { Loader, X } from "lucide-react"; -import { AnimatePresence, motion } from "motion/react"; -import * as React from "react"; -import * as ReactDOM from "react-dom"; interface DataTableActionBarProps extends React.ComponentProps { diff --git a/src/components/data-table/data-table-column-header.tsx b/src/components/data-table/data-table-column-header.tsx index 0b5b988f..1cfe107a 100644 --- a/src/components/data-table/data-table-column-header.tsx +++ b/src/components/data-table/data-table-column-header.tsx @@ -3,8 +3,8 @@ import type { Column } from "@tanstack/react-table"; import { ChevronDown, - ChevronUp, ChevronsUpDown, + ChevronUp, EyeOff, X, } from "lucide-react"; diff --git a/src/components/data-table/data-table-faceted-filter.tsx b/src/components/data-table/data-table-faceted-filter.tsx index 22e0fff3..eacea6fd 100644 --- a/src/components/data-table/data-table-faceted-filter.tsx +++ b/src/components/data-table/data-table-faceted-filter.tsx @@ -1,8 +1,8 @@ "use client"; -import type { Option } from "@/types/data-table"; import type { Column } from "@tanstack/react-table"; import { Check, PlusCircle, XCircle } from "lucide-react"; +import * as React from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; @@ -22,7 +22,7 @@ import { } from "@/components/ui/popover"; import { Separator } from "@/components/ui/separator"; import { cn } from "@/lib/utils"; -import * as React from "react"; +import type { Option } from "@/types/data-table"; interface DataTableFacetedFilterProps { column?: Column; diff --git a/src/components/data-table/data-table-filter-list.tsx b/src/components/data-table/data-table-filter-list.tsx index 269c5f34..10c8f995 100644 --- a/src/components/data-table/data-table-filter-list.tsx +++ b/src/components/data-table/data-table-filter-list.tsx @@ -268,10 +268,7 @@ export function DataTableFilterList({
{filters.length > 0 ? ( -
+
    {filters.map((filter, index) => ( key={filter.filterId} @@ -285,7 +282,7 @@ export function DataTableFilterList({ onFilterRemove={onFilterRemove} /> ))} -
+
) : null}
@@ -363,7 +360,7 @@ function DataTableFilterItem({ const filterOperators = getFilterOperators(filter.variant); const onItemKeyDown = React.useCallback( - (event: React.KeyboardEvent) => { + (event: React.KeyboardEvent) => { if ( event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement @@ -393,8 +390,7 @@ function DataTableFilterItem({ return ( -
({ -
+
); } diff --git a/src/components/data-table/data-table-slider-filter.tsx b/src/components/data-table/data-table-slider-filter.tsx index c165b17f..505d9346 100644 --- a/src/components/data-table/data-table-slider-filter.tsx +++ b/src/components/data-table/data-table-slider-filter.tsx @@ -1,8 +1,8 @@ "use client"; import type { Column } from "@tanstack/react-table"; +import { PlusCircle, XCircle } from "lucide-react"; import * as React from "react"; - import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; @@ -14,7 +14,6 @@ import { import { Separator } from "@/components/ui/separator"; import { Slider } from "@/components/ui/slider"; import { cn } from "@/lib/utils"; -import { PlusCircle, XCircle } from "lucide-react"; interface Range { min: number; diff --git a/src/components/data-table/data-table-sort-list.tsx b/src/components/data-table/data-table-sort-list.tsx index c7be95ef..b47bb6aa 100644 --- a/src/components/data-table/data-table-sort-list.tsx +++ b/src/components/data-table/data-table-sort-list.tsx @@ -211,10 +211,7 @@ export function DataTableSortList({
{sorting.length > 0 && ( -
+
    {sorting.map((sort) => ( ({ onSortRemove={onSortRemove} /> ))} -
+
)}
@@ -290,7 +287,7 @@ function DataTableSortItem({ React.useState(false); const onItemKeyDown = React.useCallback( - (event: React.KeyboardEvent) => { + (event: React.KeyboardEvent) => { if ( event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement @@ -312,8 +309,7 @@ function DataTableSortItem({ return ( -
-
+
); } diff --git a/src/components/data-table/data-table-view-options.tsx b/src/components/data-table/data-table-view-options.tsx index 01399e56..69b90eba 100644 --- a/src/components/data-table/data-table-view-options.tsx +++ b/src/components/data-table/data-table-view-options.tsx @@ -2,7 +2,7 @@ import type { Table } from "@tanstack/react-table"; import { Check, ChevronsUpDown, Settings2 } from "lucide-react"; - +import * as React from "react"; import { Button } from "@/components/ui/button"; import { Command, @@ -18,7 +18,6 @@ import { PopoverTrigger, } from "@/components/ui/popover"; import { cn } from "@/lib/utils"; -import * as React from "react"; interface DataTableViewOptionsProps { table: Table; diff --git a/src/components/data-table/data-table.tsx b/src/components/data-table/data-table.tsx index 2e911149..9b06dc23 100644 --- a/src/components/data-table/data-table.tsx +++ b/src/components/data-table/data-table.tsx @@ -1,4 +1,4 @@ -import { type Table as TanstackTable, flexRender } from "@tanstack/react-table"; +import { flexRender, type Table as TanstackTable } from "@tanstack/react-table"; import type * as React from "react"; import { DataTablePagination } from "@/components/data-table/data-table-pagination"; diff --git a/src/components/dynamic-container.tsx b/src/components/dynamic-container.tsx index 4fc90a9d..0d1743c0 100644 --- a/src/components/dynamic-container.tsx +++ b/src/components/dynamic-container.tsx @@ -4,10 +4,9 @@ * @see https://github.com/dubinc/dub/blob/main/packages/ui/src/animated-size-container.tsx */ +import { motion, type TargetAndTransition } from "motion/react"; import * as React from "react"; - import { cn } from "@/lib/utils"; -import { type TargetAndTransition, motion } from "motion/react"; interface Dimensions extends TargetAndTransition { width: string | number; diff --git a/src/components/shell.tsx b/src/components/shell.tsx index ceb4a028..ed136a00 100644 --- a/src/components/shell.tsx +++ b/src/components/shell.tsx @@ -1,4 +1,4 @@ -import { type VariantProps, cva } from "class-variance-authority"; +import { cva, type VariantProps } from "class-variance-authority"; import type * as React from "react"; import { cn } from "@/lib/utils"; diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx index 1b03a52d..ee117473 100644 --- a/src/components/ui/badge.tsx +++ b/src/components/ui/badge.tsx @@ -1,5 +1,5 @@ import { Slot } from "@radix-ui/react-slot"; -import { type VariantProps, cva } from "class-variance-authority"; +import { cva, type VariantProps } from "class-variance-authority"; import type * as React from "react"; import { cn } from "@/lib/utils"; diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index bb5125e2..194f7846 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -1,5 +1,5 @@ import { Slot } from "@radix-ui/react-slot"; -import { type VariantProps, cva } from "class-variance-authority"; +import { cva, type VariantProps } from "class-variance-authority"; import type * as React from "react"; import { cn } from "@/lib/utils"; diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx index bb16478d..f66fbe48 100644 --- a/src/components/ui/calendar.tsx +++ b/src/components/ui/calendar.tsx @@ -1,76 +1,213 @@ "use client"; -import { ChevronLeft, ChevronRight } from "lucide-react"; -import type * as React from "react"; -import { DayPicker } from "react-day-picker"; - -import { buttonVariants } from "@/components/ui/button"; +import { + ChevronDownIcon, + ChevronLeftIcon, + ChevronRightIcon, +} from "lucide-react"; +import * as React from "react"; +import { + type DayButton, + DayPicker, + getDefaultClassNames, +} from "react-day-picker"; +import { Button, buttonVariants } from "@/components/ui/button"; import { cn } from "@/lib/utils"; -export type CalendarProps = React.ComponentProps; - function Calendar({ className, classNames, showOutsideDays = true, + captionLayout = "label", + buttonVariant = "ghost", + formatters, + components, ...props -}: CalendarProps) { +}: React.ComponentProps & { + buttonVariant?: React.ComponentProps["variant"]; +}) { + const defaultClassNames = getDefaultClassNames(); + return ( svg]:rotate-180`, + String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`, + className, + )} + captionLayout={captionLayout} + formatters={{ + formatMonthDropdown: (date) => + date.toLocaleString("default", { month: "short" }), + ...formatters, + }} classNames={{ - months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0", - month: "space-y-4", - caption: "flex justify-center pt-1 relative items-center", - caption_label: "text-sm font-medium", - nav: "space-x-1 flex items-center", - nav_button: cn( - buttonVariants({ variant: "outline" }), - "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100", - ), - nav_button_previous: "absolute left-1", - nav_button_next: "absolute right-1", - table: "w-full border-collapse space-y-1", - head_row: "flex", - head_cell: - "text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]", - row: "flex w-full mt-2", - cell: cn( - "relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md", - props.mode === "range" - ? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" - : "[&:has([aria-selected])]:rounded-md", + root: cn("w-fit", defaultClassNames.root), + months: cn( + "flex gap-4 flex-col md:flex-row relative", + defaultClassNames.months, + ), + month: cn("flex flex-col w-full gap-4", defaultClassNames.month), + nav: cn( + "flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between", + defaultClassNames.nav, + ), + button_previous: cn( + buttonVariants({ variant: buttonVariant }), + "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none", + defaultClassNames.button_previous, + ), + button_next: cn( + buttonVariants({ variant: buttonVariant }), + "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none", + defaultClassNames.button_next, + ), + month_caption: cn( + "flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)", + defaultClassNames.month_caption, + ), + dropdowns: cn( + "w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5", + defaultClassNames.dropdowns, + ), + dropdown_root: cn( + "relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md", + defaultClassNames.dropdown_root, + ), + dropdown: cn("absolute inset-0 opacity-0", defaultClassNames.dropdown), + caption_label: cn( + "select-none font-medium", + captionLayout === "label" + ? "text-sm" + : "rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5", + defaultClassNames.caption_label, + ), + table: "w-full border-collapse", + weekdays: cn("flex", defaultClassNames.weekdays), + weekday: cn( + "text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none", + defaultClassNames.weekday, + ), + week: cn("flex w-full mt-2", defaultClassNames.week), + week_number_header: cn( + "select-none w-(--cell-size)", + defaultClassNames.week_number_header, + ), + week_number: cn( + "text-[0.8rem] select-none text-muted-foreground", + defaultClassNames.week_number, ), day: cn( - buttonVariants({ variant: "ghost" }), - "h-8 w-8 p-0 font-normal aria-selected:opacity-100", - ), - day_range_start: "day-range-start", - day_range_end: "day-range-end", - day_selected: - "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground", - day_today: "bg-accent text-accent-foreground", - day_outside: - "day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground", - day_disabled: "text-muted-foreground opacity-50", - day_range_middle: - "aria-selected:bg-accent aria-selected:text-accent-foreground", - day_hidden: "invisible", + "relative w-full h-full p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none", + defaultClassNames.day, + ), + range_start: cn( + "rounded-l-md bg-accent", + defaultClassNames.range_start, + ), + range_middle: cn("rounded-none", defaultClassNames.range_middle), + range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end), + today: cn( + "bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none", + defaultClassNames.today, + ), + outside: cn( + "text-muted-foreground aria-selected:text-muted-foreground", + defaultClassNames.outside, + ), + disabled: cn( + "text-muted-foreground opacity-50", + defaultClassNames.disabled, + ), + hidden: cn("invisible", defaultClassNames.hidden), ...classNames, }} components={{ - IconLeft: ({ className, ...props }) => ( - - ), - IconRight: ({ className, ...props }) => ( - - ), + Root: ({ className, rootRef, ...props }) => { + return ( +
+ ); + }, + Chevron: ({ className, orientation, ...props }) => { + if (orientation === "left") { + return ( + + ); + } + + if (orientation === "right") { + return ( + + ); + } + + return ( + + ); + }, + DayButton: CalendarDayButton, + WeekNumber: ({ children, ...props }) => { + return ( + +
+ {children} +
+ + ); + }, + ...components, }} {...props} /> ); } -Calendar.displayName = "Calendar"; -export { Calendar }; +function CalendarDayButton({ + className, + day, + modifiers, + ...props +}: React.ComponentProps) { + const defaultClassNames = getDefaultClassNames(); + + const ref = React.useRef(null); + React.useEffect(() => { + if (modifiers.focused) ref.current?.focus(); + }, [modifiers.focused]); + + return ( +