Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/docs/src/app/playground/debug-control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export function DebugControl() {
if (typeof localStorage === 'undefined') {
return false
}
if (typeof localStorage.getItem !== 'function') {
return false
}
return localStorage.getItem('debug')?.includes('nuqs') ?? false
})
const update = React.useCallback(() => {
Expand Down
49 changes: 49 additions & 0 deletions packages/docs/src/registry/items/use-date-range.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"type": "registry:item",
"name": "use-date-range",
"title": "Date Range Hook",
"description": "Date range selection with URL synchronization and preset support. Includes common presets like last 7 days, last 30 days, and custom ranges.",
"dependencies": ["nuqs", "date-fns@^4.1.0"],
"files": [
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/types/index.ts",
"target": "~/hooks/types/index.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/types/common.ts",
"target": "~/hooks/types/common.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/utils/date.ts",
"target": "~/lib/utils/date.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/date-range/index.ts",
"target": "~/hooks/date-range/index.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/date-range/types.ts",
"target": "~/hooks/date-range/types.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/date-range/useDateRange.ts",
"target": "~/hooks/date-range/useDateRange.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/date-range/utils.ts",
"target": "~/hooks/date-range/utils.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/date-range/presets.ts",
"target": "~/hooks/date-range/presets.ts"
}
]
}
99 changes: 99 additions & 0 deletions packages/docs/src/registry/items/use-date-range.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
```tsx
'use client'

import { useDateRange } from '@/hooks/date-range'

export function DateRangePicker() {
const {
startDate, // Start date
endDate, // End date
setRange, // Set both dates
setStartDate, // Set start only
setEndDate, // Set end only
clearRange, // Clear both
presets, // Quick preset functions
daysInRange, // Number of days
isValid, // Valid range (start <= end)
} = useDateRange({
defaultPreset: 'last7days',
})

return (
<div>
<div>
<button onClick={() => presets.last7days()}>Last 7 Days</button>
<button onClick={() => presets.last30days()}>Last 30 Days</button>
<button onClick={() => presets.thisMonth()}>This Month</button>
<button onClick={() => presets.lastMonth()}>Last Month</button>
</div>

<div>
<input
type="date"
value={startDate ?? ''}
onChange={(e) => setStartDate(e.target.value)}
/>
<span>to</span>
<input
type="date"
value={endDate ?? ''}
onChange={(e) => setEndDate(e.target.value)}
/>
</div>

{isValid && (
<p>{daysInRange} days selected</p>
)}

<button onClick={clearRange}>Clear</button>
</div>
)
}
```

## API Reference

### Options

```typescript
interface UseDateRangeOptions {
defaultStartDate?: string // ISO date string
defaultEndDate?: string // ISO date string
defaultPreset?: PresetKey // Apply preset on mount
shallow?: boolean
history?: 'push' | 'replace'
scroll?: boolean
}
```

### Presets

Available preset functions:
- `presets.today()` - Today only
- `presets.yesterday()` - Yesterday only
- `presets.last7days()` - Last 7 days
- `presets.last30days()` - Last 30 days
- `presets.thisMonth()` - Current month
- `presets.lastMonth()` - Previous month

### Return Value

```typescript
interface UseDateRangeResult {
startDate: string | null
endDate: string | null
setStartDate: (date: string | null) => void
setEndDate: (date: string | null) => void
setRange: (start: string | null, end: string | null) => void
clearRange: () => void
presets: DateRangePresets
daysInRange: number | null // Days between dates
isValid: boolean // startDate <= endDate
}
```

## More Information

- **GitHub**: [nuqs-presets](https://github.com/iHiteshAgrawal/nuqs-presets)
- **npm**: [nuqs-presets](https://www.npmjs.com/package/nuqs-presets)
- **Examples**: See the [examples directory](https://github.com/iHiteshAgrawal/nuqs-presets/tree/main/examples)
39 changes: 39 additions & 0 deletions packages/docs/src/registry/items/use-filters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"type": "registry:item",
"name": "use-filters",
"title": "Filters Hook",
"description": "Type-safe multi-filter state management with URL synchronization. Uses nuqs parsers for strong typing and validation.",
"dependencies": ["nuqs"],
"files": [
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/types/index.ts",
"target": "~/hooks/types/index.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/types/common.ts",
"target": "~/hooks/types/common.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/filtering/index.ts",
"target": "~/hooks/filtering/index.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/filtering/types.ts",
"target": "~/hooks/filtering/types.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/filtering/useFilters.ts",
"target": "~/hooks/filtering/useFilters.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/filtering/utils.ts",
"target": "~/hooks/filtering/utils.ts"
}
]
}
97 changes: 97 additions & 0 deletions packages/docs/src/registry/items/use-filters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
```tsx
'use client'

import { useFilters } from '@/hooks/filtering'
import { parseAsString, parseAsFloat, parseAsBoolean } from 'nuqs'

const filterParsers = {
category: parseAsString,
minPrice: parseAsFloat,
maxPrice: parseAsFloat,
inStock: parseAsBoolean,
}

export function FilterPanel() {
const {
filters, // Current filters (type-safe)
setFilter, // Set single filter
setFilters, // Set multiple filters
clearFilters, // Clear all filters
clearFilter, // Clear single filter
hasFilters, // Any filters active?
} = useFilters({
parsers: filterParsers,
})

// filters.category is string | null
// filters.minPrice is number | null
// filters.inStock is boolean | null

return (
<div>
<select
value={filters.category ?? ''}
onChange={(e) => setFilter('category', e.target.value || null)}
>
<option value="">All Categories</option>
<option value="electronics">Electronics</option>
<option value="books">Books</option>
</select>

<input
type="number"
placeholder="Min price"
value={filters.minPrice ?? ''}
onChange={(e) => setFilter('minPrice', e.target.value ? Number(e.target.value) : null)}
/>

<label>
<input
type="checkbox"
checked={filters.inStock ?? false}
onChange={(e) => setFilter('inStock', e.target.checked || null)}
/>
In Stock Only
</label>

{hasFilters && (
<button onClick={clearFilters}>
Clear All Filters
</button>
)}
</div>
)
}
```

## API Reference

### Options

```typescript
interface UseFiltersOptions<T extends Record<string, any>> {
parsers: T // nuqs parser map
shallow?: boolean
history?: 'push' | 'replace'
scroll?: boolean
}
```

### Return Value

```typescript
interface UseFiltersResult<T> {
filters: ParsedFilters<T> // Current filters (type-safe)
setFilter: <K extends keyof T>(key: K, value: T[K]) => void
setFilters: (filters: Partial<ParsedFilters<T>>) => void
clearFilter: (key: keyof T) => void
clearFilters: () => void
hasFilters: boolean // Any active filters?
}
```

## More Information

- **GitHub**: [nuqs-presets](https://github.com/iHiteshAgrawal/nuqs-presets)
- **npm**: [nuqs-presets](https://www.npmjs.com/package/nuqs-presets)
- **Examples**: See the [examples directory](https://github.com/iHiteshAgrawal/nuqs-presets/tree/main/examples)
39 changes: 39 additions & 0 deletions packages/docs/src/registry/items/use-multi-select.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"type": "registry:item",
"name": "use-multi-select",
"title": "Multi-Select Hook",
"description": "Array-based multi-selection state management with URL synchronization. Supports toggle, select all, and deselect all operations.",
"dependencies": ["nuqs"],
"files": [
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/types/index.ts",
"target": "~/hooks/types/index.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/types/common.ts",
"target": "~/hooks/types/common.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/multi-select/index.ts",
"target": "~/hooks/multi-select/index.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/multi-select/types.ts",
"target": "~/hooks/multi-select/types.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/multi-select/useMultiSelect.ts",
"target": "~/hooks/multi-select/useMultiSelect.ts"
},
{
"type": "registry:file",
"path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/main/registry/default/multi-select/utils.ts",
"target": "~/hooks/multi-select/utils.ts"
}
]
}
Loading