diff --git a/packages/docs/content/docs/parsers/community/tanstack-table-pagination.generator.tsx b/packages/docs/content/docs/parsers/community/tanstack-table-pagination.generator.tsx new file mode 100644 index 00000000..f41d682b --- /dev/null +++ b/packages/docs/content/docs/parsers/community/tanstack-table-pagination.generator.tsx @@ -0,0 +1,393 @@ +'use client' + +import { CodeBlock } from '@/src/components/code-block.client' +import { TsLogo } from '@/src/components/icons/ts-logo' +import { Querystring } from '@/src/components/querystring' +import { Label } from '@/src/components/ui/label' +import { + Pagination, + PaginationButton, + PaginationContent, + PaginationItem, + PaginationNext, + PaginationPrevious +} from '@/src/components/ui/pagination' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue +} from '@/src/components/ui/select' +import { Separator } from '@/src/components/ui/separator' +import { + createParser, + parseAsInteger, + parseAsString, + useQueryState +} from 'nuqs' +import { useDeferredValue } from 'react' + +const NUM_PAGES = 5 + +// The page index parser is zero-indexed internally, +// but one-indexed when rendered in the URL, +// to align with your UI and what users might expect. +const pageIndexParser = createParser({ + parse: query => { + const page = parseAsInteger.parse(query) + return page === null ? null : page - 1 + }, + serialize: value => { + return parseAsInteger.serialize(value + 1) + } +}) + +export function TanStackTablePagination() { + const [pageIndexUrlKey, setPageIndexUrlKey] = useQueryState( + 'pageIndexUrlKey', + parseAsString.withDefault('page') + ) + const [pageSizeUrlKey, setPageSizeUrlKey] = useQueryState( + 'pageSizeUrlKey', + parseAsString.withDefault('perPage') + ) + const [page, setPage] = useQueryState( + pageIndexUrlKey, + pageIndexParser.withDefault(0) + ) + const [pageSize, setPageSize] = useQueryState( + pageSizeUrlKey, + parseAsInteger.withDefault(10) + ) + const [separator, setSeparator] = useQueryState( + 'separator', + parseAsString.withDefault(',') + ) + const [paginationKey, setPaginationKey] = useQueryState( + 'paginationKey', + parseAsString.withDefault('pagination') + ) + + const queryStatesCode = + useDeferredValue(`import { parseAsInteger, useQueryStates } from 'nuqs' + +const paginationParsers = { + pageIndex: parseAsInteger.withDefault(1), + pageSize: parseAsInteger.withDefault(10) +} + +const paginationUrlKeys = { + pageIndex: '${pageIndexUrlKey}', + pageSize: '${pageSizeUrlKey}' +} + +export function usePaginationQuery() { + return useQueryStates(paginationParsers, { + urlKeys: paginationUrlKeys + }) +} +`) + + const queryStatesUsageCode = + useDeferredValue(`import { usePaginationQuery } from './search-params.pagination.ts' +import { + useReactTable, + type PaginationState, + type Updater +} from '@tanstack/react-table' + +const [paginationQuery, setPaginationQuery] = usePaginationQuery() + +function onPaginationChange(updaterOrValue: Updater) { + const newPagination = typeof updaterOrValue === "function" + ? updaterOrValue(pagination) + : updaterOrValue + void setPaginationQuery(newPagination) +} + +const pagination = { + pageIndex: paginationQuery.pageIndex - 1, + pageSize: paginationQuery.pageSize, +} + +const table = useReactTable({ + ...otherProps, + onPaginationChange, + state: { + ...otherState, + pagination, + } +}) + `) + + const internalState = useDeferredValue(`{ + // zero-indexed + pageIndex: ${page}, + pageSize: ${pageSize} +}`) + + const customParserCode = + useDeferredValue(`import { parseAsInteger, useQueryState } from 'nuqs' +import type { PaginationState } from '@tanstack/react-table' + +const defaultState: PaginationState = { + pageIndex: 1, + pageSize: 10 +} + +const paginationParser = createParser({ + parse: (value) => { + const [pageIndex, pageSize] = value.split('${separator}') + return { + pageIndex: parseInt(pageIndex ?? \`\${defaultState.pageIndex}\`) - 1, + pageSize: parseInt(pageSize ?? \`\${defaultState.pageSize}\`) + } + }, + serialize: (value) => { + return \`\${value.pageIndex + 1}${separator}\${value.pageSize}\` + }, +}) + +export function usePaginationQuery() { + return useQueryState('${paginationKey}', paginationParser + .withDefault(defaultState) + ) +}`) + + const customParserUsageCode = + useDeferredValue(`import { usePaginationQuery } from './search-params.pagination.ts' +import { + useReactTable, + type PaginationState, + type Updater +} from '@tanstack/react-table' + +const [pagination, setPagination] = usePaginationQuery() + +function onPaginationChange(updaterOrValue: Updater) { + const newPagination = typeof updaterOrValue === 'function' + ? updaterOrValue(pagination) + : updaterOrValue + void setPagination(newPagination) +} + +const table = useReactTable({ + ...otherProps, + onPaginationChange, + state: { + ...otherState, + pagination, + } +})`) + + return ( +
+

Pagination with custom url key names

+

+ This strategy uses 2 different url keys for pagination, you can use + custom names instead of the default `pageIndex` and `pageSize`. +

+
+ + + + setPage(p => Math.max(0, p - 1))} + /> + + {Array.from({ length: NUM_PAGES }, (_, index) => ( + + setPage(index)} + > + {index + 1} + + + ))} + + = NUM_PAGES - 1} + onClick={() => setPage(p => Math.min(NUM_PAGES - 1, p + 1))} + /> + + + + +
+
+
+ } + code={queryStatesCode} + /> + } + code={queryStatesUsageCode} + /> +
+ +
+ +

Pagination with custom url key and separator

+

+ This strategy uses a single url key for pagination, and uses a separator + to differentiate between the index and size. +

+
+ + + + setPage(p => Math.max(0, p - 1))} + /> + + {Array.from({ length: NUM_PAGES }, (_, index) => ( + + setPage(index)} + > + {index + 1} + + + ))} + + = NUM_PAGES - 1} + onClick={() => setPage(p => Math.min(NUM_PAGES - 1, p + 1))} + /> + + + + +
+
+
+ } + code={customParserCode} + /> + } + code={customParserUsageCode} + /> +
+ +
+
+ ) +} diff --git a/packages/docs/content/docs/parsers/community/tanstack-table-sorting.generator.tsx b/packages/docs/content/docs/parsers/community/tanstack-table-sorting.generator.tsx new file mode 100644 index 00000000..1b300db7 --- /dev/null +++ b/packages/docs/content/docs/parsers/community/tanstack-table-sorting.generator.tsx @@ -0,0 +1,77 @@ +'use client' + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@/src/components/ui/dropdown-menu' +import { parseAsJson, useQueryState } from 'nuqs' +import { Button } from '@/src/components/ui/button' +import { ArrowDown, ArrowUp, ChevronsUpDown } from 'lucide-react' +import { QuerySpy } from '@/src/components/query-spy' +import { z } from 'zod' + +const sortingSchema = z.object({ + id: z.string(), + desc: z.boolean() +}) + +const useSortingSearchParams = () => + useQueryState('sort', parseAsJson(sortingSchema.parse)) + +const TableSortingHeader = ({ name }: { name: string }) => { + const [sort, setSort] = useSortingSearchParams() + + const isActive = sort?.id === name + + return ( + + + + + + setSort({ id: name, desc: false })}> + + Asc + + setSort({ id: name, desc: true })}> + + Desc + + + + ) +} + +export function TanStackTableSorting() { + const [_, setSort] = useSortingSearchParams() + + return ( +
+ +
+
+ + +
+ +
+
+ ) +} diff --git a/packages/docs/content/docs/parsers/community/tanstack-table.generator.tsx b/packages/docs/content/docs/parsers/community/tanstack-table.generator.tsx deleted file mode 100644 index 0353b938..00000000 --- a/packages/docs/content/docs/parsers/community/tanstack-table.generator.tsx +++ /dev/null @@ -1,217 +0,0 @@ -'use client' - -import { CodeBlock } from '@/src/components/code-block.client' -import { Querystring } from '@/src/components/querystring' -import { Label } from '@/src/components/ui/label' -import { - Pagination, - PaginationButton, - PaginationContent, - PaginationItem, - PaginationNext, - PaginationPrevious -} from '@/src/components/ui/pagination' -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue -} from '@/src/components/ui/select' -import { Separator } from '@/src/components/ui/separator' -import { - createParser, - parseAsInteger, - parseAsString, - useQueryState -} from 'nuqs' -import { useDeferredValue } from 'react' - -const NUM_PAGES = 5 - -// The page index parser is zero-indexed internally, -// but one-indexed when rendered in the URL, -// to align with your UI and what users might expect. -const pageIndexParser = createParser({ - parse: query => { - const page = parseAsInteger.parse(query) - return page === null ? null : page - 1 - }, - serialize: value => { - return parseAsInteger.serialize(value + 1) - } -}) - -export function TanStackTablePagination() { - const [pageIndexUrlKey, setPageIndexUrlKey] = useQueryState( - 'pageIndexUrlKey', - parseAsString.withDefault('page') - ) - const [pageSizeUrlKey, setPageSizeUrlKey] = useQueryState( - 'pageSizeUrlKey', - parseAsString.withDefault('perPage') - ) - const [page, setPage] = useQueryState( - pageIndexUrlKey, - pageIndexParser.withDefault(0) - ) - const [pageSize, setPageSize] = useQueryState( - pageSizeUrlKey, - parseAsInteger.withDefault(10) - ) - - const parserCode = useDeferredValue(`import { - createParser, - parseAsInteger, - parseAsString, - useQueryStates -} from 'nuqs' - -// The page index parser is zero-indexed internally, -// but one-indexed when rendered in the URL, -// to align with your UI and what users might expect. -const pageIndexParser = createParser({ - parse: query => { - const page = parseAsInteger.parse(query) - return page === null ? null : page - 1 - }, - serialize: value => { - return parseAsInteger.serialize(value + 1) - } -}) - -const paginationParsers = { - pageIndex: pageIndexParser.withDefault(0), - pageSize: parseAsInteger.withDefault(10) -} -const paginationUrlKeys = { - pageIndex: '${pageIndexUrlKey}', - pageSize: '${pageSizeUrlKey}' -} - -export function usePaginationSearchParams() { - return useQueryStates(paginationParsers, { - urlKeys: paginationUrlKeys - }) -}`) - - const internalState = useDeferredValue(`{ - // zero-indexed - pageIndex: ${page}, - pageSize: ${pageSize} -}`) - - return ( -
-
- - - - setPage(p => Math.max(0, p - 1))} - /> - - {Array.from({ length: NUM_PAGES }, (_, index) => ( - - setPage(index)} - > - {index + 1} - - - ))} - - = NUM_PAGES - 1} - onClick={() => setPage(p => Math.min(NUM_PAGES - 1, p + 1))} - /> - - - - -
-

- Configure and copy-paste this parser into your application: -

-
- - - - - } - className="flex-grow" - code={parserCode} - /> - -
-
- ) -} diff --git a/packages/docs/content/docs/parsers/community/tanstack-table.mdx b/packages/docs/content/docs/parsers/community/tanstack-table.mdx index a395551f..ec185685 100644 --- a/packages/docs/content/docs/parsers/community/tanstack-table.mdx +++ b/packages/docs/content/docs/parsers/community/tanstack-table.mdx @@ -3,6 +3,9 @@ title: TanStack Table Parsers description: Store your table state in the URL, with style. --- +import { TanStackTablePagination } from './tanstack-table-pagination.generator' +import { TanStackTableSorting } from './tanstack-table-sorting.generator' + [TanStack Table](https://tanstack.com/table) is a popular library for managing tabular content in React (and other frameworks). @@ -10,6 +13,13 @@ By default, it will store its state in memory, losing all filters, sorts and pagination when the page is refreshed. This is a prime example where URL state shines. +Using URL state instead of in memory state requires providing the query state to +the `useReactTable` hook and then hooking in to the `onChange` event to update +query state. + +For a complete +example see [sadmann7/shadcn-table](https://github.com/sadmann7/shadcn-table) + ## Pagination TanStack Table stores pagination under two pieces of state: @@ -17,10 +27,6 @@ TanStack Table stores pagination under two pieces of state: - `pageIndex`: a zero-based integer representing the current page - `pageSize`: an integer representing the number of items per page -You will likely want the URL to follow your UI and be one-based for the page index: - -import { TanStackTablePagination } from './tanstack-table.generator' - @@ -33,6 +39,41 @@ import { TanStackTablePagination } from './tanstack-table.generator' ## Sorting - - This section is empty for now, [contributions](https://github.com/47ng/nuqs) are welcome! - +TanStack Table stores sorting in an an array of objects with keys: + +- `id`: a string with the column name +- `desc`: a boolean indicating if the sorting is descending (`true`) or ascending (`false`) + +```ts +import {useReactTable, type SortingState, type Updater} from "@tanstack/react-table" +import {useQueryState, parseAsJson} from 'nuqs' +import {z} from 'zod' + +// sorting schema to pase to `parseAsJson`. Any validation solution will work +const sortingSchema = z.object({ + id: z.string(), + desc: z.boolean(), +}) + +const [sorting, setSorting] = useQueryState("sort", parseAsJson(sortingSchema.parse)) + +// Handle on sort change callback from the table +function onSortingChange(updaterOrValue: Updater) { + const newSorting = typeof updaterOrValue === "function" ? updaterOrValue(sorting) : updaterOrValue + void setSorting(newSorting) +} + +// Create the table with manually provided state and callback +const table = useReactTable({ + ...otherProps, + onSortingChange, + state: { + ...otherState, + sorting, + } +}) +``` + + + + diff --git a/packages/docs/package.json b/packages/docs/package.json index c8c53937..c8d8f9e9 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -25,6 +25,7 @@ "@headlessui/tailwindcss": "^0.2.1", "@icons-pack/react-simple-icons": "^10.1.0", "@radix-ui/react-checkbox": "^1.1.2", + "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-select": "^2.1.2", "@radix-ui/react-separator": "^1.1.0", diff --git a/packages/docs/src/components/icons/ts-logo.tsx b/packages/docs/src/components/icons/ts-logo.tsx new file mode 100644 index 00000000..ad10178d --- /dev/null +++ b/packages/docs/src/components/icons/ts-logo.tsx @@ -0,0 +1,18 @@ +export function TsLogo() { + return ( + + + + + ) +} diff --git a/packages/docs/src/components/ui/dropdown-menu.tsx b/packages/docs/src/components/ui/dropdown-menu.tsx new file mode 100644 index 00000000..7d61b33a --- /dev/null +++ b/packages/docs/src/components/ui/dropdown-menu.tsx @@ -0,0 +1,200 @@ +"use client" + +import * as React from "react" +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import { Check, ChevronRight, Circle } from "lucide-react" + +import { cn } from "@/src/lib/utils" + +const DropdownMenu = DropdownMenuPrimitive.Root + +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger + +const DropdownMenuGroup = DropdownMenuPrimitive.Group + +const DropdownMenuPortal = DropdownMenuPrimitive.Portal + +const DropdownMenuSub = DropdownMenuPrimitive.Sub + +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup + +const DropdownMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +DropdownMenuSubTrigger.displayName = + DropdownMenuPrimitive.SubTrigger.displayName + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSubContent.displayName = + DropdownMenuPrimitive.SubContent.displayName + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + + + +)) +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuCheckboxItem.displayName = + DropdownMenuPrimitive.CheckboxItem.displayName + +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName + +const DropdownMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName + +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName + +const DropdownMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +DropdownMenuShortcut.displayName = "DropdownMenuShortcut" + +export { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup, +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6502d310..76fe17d3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,6 +62,9 @@ importers: '@radix-ui/react-checkbox': specifier: ^1.1.2 version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + '@radix-ui/react-dropdown-menu': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) '@radix-ui/react-label': specifier: ^2.1.0 version: 2.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) @@ -88,7 +91,7 @@ importers: version: 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) '@sentry/nextjs': specifier: ^8.38.0 - version: 8.38.0(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react@19.0.0-rc.1)(webpack@5.95.0) + version: 8.38.0(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react@19.0.0-rc.1)(webpack@5.95.0) '@tailwindcss/container-queries': specifier: ^0.1.1 version: 0.1.1(tailwindcss@3.4.14(ts-node@9.1.1(typescript@5.6.3))) @@ -109,19 +112,19 @@ importers: version: 1.11.13 fumadocs-core: specifier: ^14.4.0 - version: 14.4.0(@types/react@18.3.12)(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + version: 14.4.0(@types/react@18.3.12)(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) fumadocs-mdx: specifier: ^11.1.1 - version: 11.1.1(acorn@8.14.0)(fumadocs-core@14.4.0(@types/react@18.3.12)(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)) + version: 11.1.1(acorn@8.14.0)(fumadocs-core@14.4.0(@types/react@18.3.12)(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)) fumadocs-ui: specifier: ^14.4.0 - version: 14.4.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)(tailwindcss@3.4.14(ts-node@9.1.1(typescript@5.6.3))) + version: 14.4.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)(tailwindcss@3.4.14(ts-node@9.1.1(typescript@5.6.3))) lucide-react: specifier: ^0.456.0 version: 0.456.0(react@19.0.0-rc.1) next: specifier: 15.0.3 - version: 15.0.3(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.0.0-beta-a7bf2bd-20241110)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + version: 15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) nuqs: specifier: workspace:* version: link:../nuqs @@ -2262,6 +2265,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-dropdown-menu@2.1.2': + resolution: {integrity: sha512-GVZMR+eqK8/Kes0a36Qrv+i20bAPXSn8rCBTHx30w+3ECnR5o3xixAlqcVaYvLeyKUsm0aqyhWfmUcqufM8nYA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-focus-guards@1.1.1': resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} peerDependencies: @@ -2306,6 +2322,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-menu@2.1.2': + resolution: {integrity: sha512-lZ0R4qR2Al6fZ4yCCZzu/ReTFrylHFxIqy7OezIpWF4bL0o9biKo0pFIvkaew3TyZ9Fy5gYVrR5zCGZBVbO1zg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-navigation-menu@1.2.1': resolution: {integrity: sha512-egDo0yJD2IK8L17gC82vptkvW1jLeni1VuqCyzY727dSJdk5cDjINomouLoNk8RVF7g2aNIfENKWL4UzeU9c8Q==} peerDependencies: @@ -10637,6 +10666,21 @@ snapshots: '@types/react': 18.3.12 '@types/react-dom': 18.3.1 + '@radix-ui/react-dropdown-menu@2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@19.0.0-rc.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.12)(react@19.0.0-rc.1) + '@radix-ui/react-menu': 2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.12)(react@19.0.0-rc.1) + react: 19.0.0-rc.1 + react-dom: 19.0.0-rc.1(react@19.0.0-rc.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 + '@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.12)(react@19.0.0-rc.1)': dependencies: react: 19.0.0-rc.1 @@ -10670,6 +10714,32 @@ snapshots: '@types/react': 18.3.12 '@types/react-dom': 18.3.1 + '@radix-ui/react-menu@2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@19.0.0-rc.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.12)(react@19.0.0-rc.1) + '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.12)(react@19.0.0-rc.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.12)(react@19.0.0-rc.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.12)(react@19.0.0-rc.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@19.0.0-rc.1) + aria-hidden: 1.2.4 + react: 19.0.0-rc.1 + react-dom: 19.0.0-rc.1(react@19.0.0-rc.1) + react-remove-scroll: 2.6.0(@types/react@18.3.12)(react@19.0.0-rc.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 + '@radix-ui/react-navigation-menu@1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 @@ -11464,7 +11534,7 @@ snapshots: '@sentry/types': 8.38.0 '@sentry/utils': 8.38.0 - '@sentry/nextjs@8.38.0(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react@19.0.0-rc.1)(webpack@5.95.0)': + '@sentry/nextjs@8.38.0(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react@19.0.0-rc.1)(webpack@5.95.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation-http': 0.53.0(@opentelemetry/api@1.9.0) @@ -11480,7 +11550,7 @@ snapshots: '@sentry/vercel-edge': 8.38.0 '@sentry/webpack-plugin': 2.22.6(webpack@5.95.0) chalk: 3.0.0 - next: 15.0.3(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.0.0-beta-a7bf2bd-20241110)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + next: 15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) resolve: 1.22.8 rollup: 3.29.5 stacktrace-parser: 0.1.10 @@ -14150,7 +14220,7 @@ snapshots: fsevents@2.3.3: optional: true - fumadocs-core@14.4.0(@types/react@18.3.12)(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1): + fumadocs-core@14.4.0(@types/react@18.3.12)(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1): dependencies: '@formatjs/intl-localematcher': 0.5.7 '@orama/orama': 3.0.1 @@ -14167,14 +14237,14 @@ snapshots: shiki: 1.22.2 unist-util-visit: 5.0.0 optionalDependencies: - next: 15.0.3(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.0.0-beta-a7bf2bd-20241110)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + next: 15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) react: 19.0.0-rc.1 react-dom: 19.0.0-rc.1(react@19.0.0-rc.1) transitivePeerDependencies: - '@types/react' - supports-color - fumadocs-mdx@11.1.1(acorn@8.14.0)(fumadocs-core@14.4.0(@types/react@18.3.12)(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)): + fumadocs-mdx@11.1.1(acorn@8.14.0)(fumadocs-core@14.4.0(@types/react@18.3.12)(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)): dependencies: '@mdx-js/mdx': 3.1.0(acorn@8.14.0) chokidar: 4.0.1 @@ -14182,16 +14252,16 @@ snapshots: esbuild: 0.24.0 estree-util-value-to-estree: 3.1.2 fast-glob: 3.3.2 - fumadocs-core: 14.4.0(@types/react@18.3.12)(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + fumadocs-core: 14.4.0(@types/react@18.3.12)(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) gray-matter: 4.0.3 micromatch: 4.0.8 - next: 15.0.3(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.0.0-beta-a7bf2bd-20241110)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + next: 15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) zod: 3.23.8 transitivePeerDependencies: - acorn - supports-color - fumadocs-ui@14.4.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)(tailwindcss@3.4.14(ts-node@9.1.1(typescript@5.6.3))): + fumadocs-ui@14.4.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)(tailwindcss@3.4.14(ts-node@9.1.1(typescript@5.6.3))): dependencies: '@radix-ui/react-accordion': 1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) '@radix-ui/react-collapsible': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) @@ -14204,9 +14274,9 @@ snapshots: '@radix-ui/react-tabs': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@9.1.1(typescript@5.6.3))) class-variance-authority: 0.7.0 - fumadocs-core: 14.4.0(@types/react@18.3.12)(next@15.0.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + fumadocs-core: 14.4.0(@types/react@18.3.12)(next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1))(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) lucide-react: 0.456.0(react@19.0.0-rc.1) - next: 15.0.3(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.0.0-beta-a7bf2bd-20241110)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) + next: 15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) next-themes: 0.4.3(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) react: 19.0.0-rc.1 react-dom: 19.0.0-rc.1(react@19.0.0-rc.1) @@ -16165,6 +16235,32 @@ snapshots: react: 19.0.0-rc.1 react-dom: 19.0.0-rc.1(react@19.0.0-rc.1) + next@15.0.3(@babel/core@7.25.7)(@opentelemetry/api@1.9.0)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1): + dependencies: + '@next/env': 15.0.3 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.13 + busboy: 1.6.0 + caniuse-lite: 1.0.30001667 + postcss: 8.4.31 + react: 19.0.0-rc.1 + react-dom: 19.0.0-rc.1(react@19.0.0-rc.1) + styled-jsx: 5.1.6(@babel/core@7.25.7)(react@19.0.0-rc.1) + optionalDependencies: + '@next/swc-darwin-arm64': 15.0.3 + '@next/swc-darwin-x64': 15.0.3 + '@next/swc-linux-arm64-gnu': 15.0.3 + '@next/swc-linux-arm64-musl': 15.0.3 + '@next/swc-linux-x64-gnu': 15.0.3 + '@next/swc-linux-x64-musl': 15.0.3 + '@next/swc-win32-arm64-msvc': 15.0.3 + '@next/swc-win32-x64-msvc': 15.0.3 + '@opentelemetry/api': 1.9.0 + sharp: 0.33.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + next@15.0.3(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.0.0-beta-a7bf2bd-20241110)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1): dependencies: '@next/env': 15.0.3 @@ -16175,7 +16271,7 @@ snapshots: postcss: 8.4.31 react: 19.0.0-rc.1 react-dom: 19.0.0-rc.1(react@19.0.0-rc.1) - styled-jsx: 5.1.6(react@19.0.0-rc.1) + styled-jsx: 5.1.6(@babel/core@7.25.7)(react@19.0.0-rc.1) optionalDependencies: '@next/swc-darwin-arm64': 15.0.3 '@next/swc-darwin-x64': 15.0.3 @@ -17744,10 +17840,12 @@ snapshots: dependencies: inline-style-parser: 0.2.4 - styled-jsx@5.1.6(react@19.0.0-rc.1): + styled-jsx@5.1.6(@babel/core@7.25.7)(react@19.0.0-rc.1): dependencies: client-only: 0.0.1 react: 19.0.0-rc.1 + optionalDependencies: + '@babel/core': 7.25.7 sucrase@3.35.0: dependencies: