chore(dependencies): update multiple packages to latest versions (#342)
- Upgraded `@types/react` to `19.1.12` and `@types/react-dom` to `19.1.9` for improved type definitions. - Bumped `react-i18next` to `^15.7.3` for localization fixes. - Updated `@manypkg/cli` to `^0.25.1` for dependency management improvements. - Incremented `@sentry/nextjs` to `^10.8.0` and `stripe` to `^18.5.0` to incorporate recent enhancements. - Adjusted `ai` to `5.0.28` and `@ai-sdk/openai` to `^2.0.23` for AI-related updates. - Introduced sorting improvements and code examples in `DataTable` for server-side and client-side capabilities.
This commit is contained in:
committed by
GitHub
parent
9ce150609e
commit
caf86ce09b
@@ -68,6 +68,101 @@ interface DataTableControls {
|
||||
enableColumnVisibility: boolean;
|
||||
}
|
||||
|
||||
// Server-side sorting example component
|
||||
function ServerSideSortingExample({
|
||||
data,
|
||||
compact = false,
|
||||
}: {
|
||||
data: User[];
|
||||
compact?: boolean;
|
||||
}) {
|
||||
const [sorting, setSorting] = useState<{ id: string; desc: boolean }[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [lastSortAction, setLastSortAction] = useState<string>('');
|
||||
|
||||
const handleSortingChange = (newSorting: { id: string; desc: boolean }[]) => {
|
||||
setSorting(newSorting);
|
||||
setIsLoading(true);
|
||||
|
||||
// Simulate server request
|
||||
const sortInfo =
|
||||
newSorting.length > 0
|
||||
? `${newSorting[0].id} ${newSorting[0].desc ? 'DESC' : 'ASC'}`
|
||||
: 'No sorting';
|
||||
|
||||
setLastSortAction(`Server request would be: ORDER BY ${sortInfo}`);
|
||||
|
||||
// Simulate loading delay
|
||||
setTimeout(() => {
|
||||
setIsLoading(false);
|
||||
}, 800);
|
||||
};
|
||||
|
||||
const columns: ColumnDef<User>[] = [
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: 'Name',
|
||||
enableSorting: true,
|
||||
},
|
||||
{
|
||||
accessorKey: 'department',
|
||||
header: 'Department',
|
||||
enableSorting: true,
|
||||
},
|
||||
{
|
||||
accessorKey: 'salary',
|
||||
header: 'Salary',
|
||||
enableSorting: true,
|
||||
cell: ({ row }) => {
|
||||
const salary = row.getValue('salary') as number;
|
||||
return new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'USD',
|
||||
minimumFractionDigits: 0,
|
||||
}).format(salary);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
{!compact && (
|
||||
<div className="space-y-2 text-xs">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-semibold">Current Sort State:</span>
|
||||
<code className="rounded bg-slate-100 px-2 py-1 text-xs">
|
||||
{sorting.length > 0
|
||||
? `${sorting[0].id}: ${sorting[0].desc ? 'desc' : 'asc'}`
|
||||
: 'none'}
|
||||
</code>
|
||||
{isLoading && (
|
||||
<span className="animate-pulse text-blue-600">⏳ Loading...</span>
|
||||
)}
|
||||
</div>
|
||||
{lastSortAction && (
|
||||
<div className="text-xs text-slate-600">🔍 {lastSortAction}</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={compact ? 'h-full' : 'h-64 rounded border'}>
|
||||
<DataTable
|
||||
columns={columns}
|
||||
data={data}
|
||||
pageSize={data.length}
|
||||
pageCount={1}
|
||||
getRowId={(row) => row.id}
|
||||
manualSorting={true} // This is the key difference!
|
||||
sorting={sorting}
|
||||
onSortingChange={handleSortingChange}
|
||||
sticky={!compact}
|
||||
className={isLoading ? 'opacity-50' : ''}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function DataTableStory() {
|
||||
const { controls, updateControl } = useStoryControls<DataTableControls>({
|
||||
dataCount: 50,
|
||||
@@ -291,6 +386,7 @@ export function DataTableStory() {
|
||||
pageCount={Math.ceil(data.length / controls.pageSize)}
|
||||
sticky={controls.stickyHeader}
|
||||
forcePagination={true}
|
||||
manualSorting={false} // Enable client-side sorting for demo
|
||||
columnVisibility={
|
||||
controls.enableColumnVisibility
|
||||
? columnManagement.columnVisibility
|
||||
@@ -1397,6 +1493,154 @@ export function DataTableStory() {
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Server-Side Sorting (Manual Sorting)</CardTitle>
|
||||
<CardDescription>
|
||||
Demonstrates server-side sorting with manualSorting=true. Click
|
||||
headers to see sorting state, but data doesn't change (would
|
||||
require server integration).
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="rounded-lg border border-blue-200 bg-blue-50 p-3">
|
||||
<p className="text-sm text-blue-800">
|
||||
<strong>Server-Side Mode:</strong> This table has
|
||||
manualSorting=true (default). Clicking column headers triggers
|
||||
onSortingChange callback where you would fetch sorted data
|
||||
from your server. The table shows current sort state but
|
||||
doesn't modify data locally.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ServerSideSortingExample data={data.slice(0, 10)} />
|
||||
|
||||
<div className="text-muted-foreground space-y-2 text-xs">
|
||||
<p>💡 Server-side sorting pattern:</p>
|
||||
<ul className="ml-4 list-disc space-y-1">
|
||||
<li>
|
||||
Use onSortingChange to detect sort column/direction changes
|
||||
</li>
|
||||
<li>Send sorting parameters to your API endpoint</li>
|
||||
<li>Update data state with sorted results from server</li>
|
||||
<li>Show loading states during sort operations</li>
|
||||
<li>
|
||||
Handle sort state in URL for bookmarkable sorted views
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Client-Side vs Server-Side Sorting Comparison</CardTitle>
|
||||
<CardDescription>
|
||||
Side-by-side comparison of client-side and server-side sorting
|
||||
approaches
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-6">
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
<div className="space-y-3">
|
||||
<h4 className="text-sm font-semibold text-green-700">
|
||||
Client-Side Sorting (manualSorting=false)
|
||||
</h4>
|
||||
<div className="h-48 rounded border">
|
||||
<DataTable
|
||||
columns={[
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: 'Name',
|
||||
enableSorting: true,
|
||||
},
|
||||
{
|
||||
accessorKey: 'department',
|
||||
header: 'Department',
|
||||
enableSorting: true,
|
||||
},
|
||||
{
|
||||
accessorKey: 'salary',
|
||||
header: 'Salary',
|
||||
enableSorting: true,
|
||||
cell: ({ row }) => {
|
||||
const salary = row.getValue('salary') as number;
|
||||
return new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'USD',
|
||||
minimumFractionDigits: 0,
|
||||
}).format(salary);
|
||||
},
|
||||
},
|
||||
]}
|
||||
data={data.slice(0, 8)}
|
||||
pageSize={8}
|
||||
pageCount={1}
|
||||
getRowId={(row) => row.id}
|
||||
manualSorting={false}
|
||||
sticky={true}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs text-green-600">
|
||||
✅ Data sorts immediately when headers are clicked
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<h4 className="text-sm font-semibold text-blue-700">
|
||||
Server-Side Sorting (manualSorting=true - default)
|
||||
</h4>
|
||||
<div className="h-48 rounded border">
|
||||
<ServerSideSortingExample
|
||||
data={data.slice(0, 8)}
|
||||
compact={true}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs text-blue-600">
|
||||
ℹ️ Headers show sort state but data unchanged (awaits
|
||||
server)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border bg-slate-50 p-4">
|
||||
<h4 className="mb-3 text-sm font-semibold">
|
||||
When to use each approach:
|
||||
</h4>
|
||||
<div className="grid gap-4 text-xs md:grid-cols-2">
|
||||
<div>
|
||||
<h5 className="mb-2 font-semibold text-green-700">
|
||||
Client-Side (manualSorting=false)
|
||||
</h5>
|
||||
<ul className="ml-4 list-disc space-y-1">
|
||||
<li>Small to medium datasets (<1000 rows)</li>
|
||||
<li>All data already loaded</li>
|
||||
<li>Instant sorting feedback</li>
|
||||
<li>Works offline</li>
|
||||
<li>Simpler implementation</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="mb-2 font-semibold text-blue-700">
|
||||
Server-Side (manualSorting=true - default)
|
||||
</h5>
|
||||
<ul className="ml-4 list-disc space-y-1">
|
||||
<li>Large datasets (>1000 rows)</li>
|
||||
<li>Paginated data loading</li>
|
||||
<li>Database-level sorting performance</li>
|
||||
<li>Memory efficient</li>
|
||||
<li>Required for real-world applications</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
"format": "prettier --check --write \"**/*.{js,cjs,mjs,ts,tsx,md,json}\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@ai-sdk/openai": "^2.0.22",
|
||||
"@ai-sdk/openai": "^2.0.23",
|
||||
"@faker-js/faker": "^10.0.0",
|
||||
"@hookform/resolvers": "^5.2.1",
|
||||
"@tanstack/react-query": "5.85.5",
|
||||
"ai": "5.0.26",
|
||||
"ai": "5.0.28",
|
||||
"lucide-react": "^0.542.0",
|
||||
"next": "15.5.2",
|
||||
"nodemailer": "^7.0.5",
|
||||
@@ -30,9 +30,9 @@
|
||||
"@tailwindcss/postcss": "^4.1.12",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/nodemailer": "7.0.1",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react-dom": "19.1.8",
|
||||
"babel-plugin-react-compiler": "19.1.0-rc.2",
|
||||
"@types/react": "19.1.12",
|
||||
"@types/react-dom": "19.1.9",
|
||||
"babel-plugin-react-compiler": "19.1.0-rc.3",
|
||||
"pino-pretty": "13.0.0",
|
||||
"react-hook-form": "^7.62.0",
|
||||
"recharts": "2.15.3",
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"react": "19.1.1",
|
||||
"react-dom": "19.1.1",
|
||||
"react-hook-form": "^7.62.0",
|
||||
"react-i18next": "^15.7.2",
|
||||
"react-i18next": "^15.7.3",
|
||||
"recharts": "2.15.3",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"zod": "^3.25.74"
|
||||
@@ -79,9 +79,9 @@
|
||||
"@next/bundle-analyzer": "15.5.2",
|
||||
"@tailwindcss/postcss": "^4.1.12",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react-dom": "19.1.8",
|
||||
"babel-plugin-react-compiler": "19.1.0-rc.2",
|
||||
"@types/react": "19.1.12",
|
||||
"@types/react-dom": "19.1.9",
|
||||
"babel-plugin-react-compiler": "19.1.0-rc.3",
|
||||
"cssnano": "^7.1.1",
|
||||
"pino-pretty": "13.0.0",
|
||||
"prettier": "^3.6.2",
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@manypkg/cli": "^0.25.0",
|
||||
"@manypkg/cli": "^0.25.1",
|
||||
"@turbo/gen": "^2.5.6",
|
||||
"cross-env": "^10.0.0",
|
||||
"prettier": "^3.6.2",
|
||||
|
||||
@@ -27,13 +27,13 @@
|
||||
"@kit/tsconfig": "workspace:*",
|
||||
"@kit/ui": "workspace:*",
|
||||
"@supabase/supabase-js": "2.55.0",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"date-fns": "^4.1.0",
|
||||
"lucide-react": "^0.542.0",
|
||||
"next": "15.5.2",
|
||||
"react": "19.1.1",
|
||||
"react-hook-form": "^7.62.0",
|
||||
"react-i18next": "^15.7.2",
|
||||
"react-i18next": "^15.7.3",
|
||||
"zod": "^3.25.74"
|
||||
},
|
||||
"typesVersions": {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"@kit/supabase": "workspace:*",
|
||||
"@kit/tsconfig": "workspace:*",
|
||||
"@kit/ui": "workspace:*",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"next": "15.5.2",
|
||||
"react": "19.1.1",
|
||||
"zod": "^3.25.74"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"dependencies": {
|
||||
"@stripe/react-stripe-js": "^3.9.2",
|
||||
"@stripe/stripe-js": "^7.9.0",
|
||||
"stripe": "^18.4.0"
|
||||
"stripe": "^18.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@kit/billing": "workspace:*",
|
||||
@@ -27,7 +27,7 @@
|
||||
"@kit/supabase": "workspace:*",
|
||||
"@kit/tsconfig": "workspace:*",
|
||||
"@kit/ui": "workspace:*",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"date-fns": "^4.1.0",
|
||||
"next": "15.5.2",
|
||||
"react": "19.1.1",
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'server-only';
|
||||
|
||||
import { StripeServerEnvSchema } from '../schema/stripe-server-env.schema';
|
||||
|
||||
const STRIPE_API_VERSION = '2025-07-30.basil';
|
||||
const STRIPE_API_VERSION = '2025-08-27.basil';
|
||||
|
||||
/**
|
||||
* @description returns a Stripe instance
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"@kit/tsconfig": "workspace:*",
|
||||
"@kit/ui": "workspace:*",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"react": "19.1.1",
|
||||
"zod": "^3.25.74"
|
||||
},
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"@kit/tsconfig": "workspace:*",
|
||||
"@kit/ui": "workspace:*",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"wp-types": "^4.68.1"
|
||||
},
|
||||
"typesVersions": {
|
||||
|
||||
@@ -36,15 +36,15 @@
|
||||
"@radix-ui/react-icons": "^1.3.2",
|
||||
"@supabase/supabase-js": "2.55.0",
|
||||
"@tanstack/react-query": "5.85.5",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react-dom": "19.1.8",
|
||||
"@types/react": "19.1.12",
|
||||
"@types/react-dom": "19.1.9",
|
||||
"lucide-react": "^0.542.0",
|
||||
"next": "15.5.2",
|
||||
"next-themes": "0.4.6",
|
||||
"react": "19.1.1",
|
||||
"react-dom": "19.1.1",
|
||||
"react-hook-form": "^7.62.0",
|
||||
"react-i18next": "^15.7.2",
|
||||
"react-i18next": "^15.7.3",
|
||||
"zod": "^3.25.74"
|
||||
},
|
||||
"prettier": "@kit/prettier-config",
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"@supabase/supabase-js": "2.55.0",
|
||||
"@tanstack/react-query": "5.85.5",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"lucide-react": "^0.542.0",
|
||||
"next": "15.5.2",
|
||||
"react": "19.1.1",
|
||||
|
||||
@@ -31,11 +31,11 @@
|
||||
"@radix-ui/react-icons": "^1.3.2",
|
||||
"@supabase/supabase-js": "2.55.0",
|
||||
"@tanstack/react-query": "5.85.5",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"lucide-react": "^0.542.0",
|
||||
"next": "15.5.2",
|
||||
"react-hook-form": "^7.62.0",
|
||||
"react-i18next": "^15.7.2",
|
||||
"react-i18next": "^15.7.3",
|
||||
"sonner": "^2.0.7",
|
||||
"zod": "^3.25.74"
|
||||
},
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
"@kit/ui": "workspace:*",
|
||||
"@supabase/supabase-js": "2.55.0",
|
||||
"@tanstack/react-query": "5.85.5",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"lucide-react": "^0.542.0",
|
||||
"react": "19.1.1",
|
||||
"react-dom": "19.1.1",
|
||||
"react-i18next": "^15.7.2"
|
||||
"react-i18next": "^15.7.3"
|
||||
},
|
||||
"prettier": "@kit/prettier-config",
|
||||
"typesVersions": {
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
"@supabase/supabase-js": "2.55.0",
|
||||
"@tanstack/react-query": "5.85.5",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react-dom": "19.1.8",
|
||||
"@types/react": "19.1.12",
|
||||
"@types/react-dom": "19.1.9",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"lucide-react": "^0.542.0",
|
||||
@@ -44,7 +44,7 @@
|
||||
"react": "19.1.1",
|
||||
"react-dom": "19.1.1",
|
||||
"react-hook-form": "^7.62.0",
|
||||
"react-i18next": "^15.7.2",
|
||||
"react-i18next": "^15.7.3",
|
||||
"zod": "^3.25.74"
|
||||
},
|
||||
"prettier": "@kit/prettier-config",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"next": "15.5.2",
|
||||
"react": "19.1.1",
|
||||
"react-dom": "19.1.1",
|
||||
"react-i18next": "^15.7.2"
|
||||
"react-i18next": "^15.7.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"i18next": "25.4.2",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"@kit/sentry": "workspace:*",
|
||||
"@kit/shared": "workspace:*",
|
||||
"@kit/tsconfig": "workspace:*",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"react": "19.1.1",
|
||||
"zod": "^3.25.74"
|
||||
},
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"@kit/eslint-config": "workspace:*",
|
||||
"@kit/prettier-config": "workspace:*",
|
||||
"@kit/tsconfig": "workspace:*",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"react": "19.1.1",
|
||||
"zod": "^3.25.74"
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"@kit/eslint-config": "workspace:*",
|
||||
"@kit/prettier-config": "workspace:*",
|
||||
"@kit/tsconfig": "workspace:*",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"react": "19.1.1"
|
||||
},
|
||||
"typesVersions": {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"./config/server": "./src/sentry.client.server.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sentry/nextjs": "^10.6.0",
|
||||
"@sentry/nextjs": "^10.8.0",
|
||||
"import-in-the-middle": "1.14.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -24,7 +24,7 @@
|
||||
"@kit/monitoring-core": "workspace:*",
|
||||
"@kit/prettier-config": "workspace:*",
|
||||
"@kit/tsconfig": "workspace:*",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"react": "19.1.1"
|
||||
},
|
||||
"typesVersions": {
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
"@kit/ui": "workspace:*",
|
||||
"@radix-ui/react-icons": "^1.3.2",
|
||||
"@supabase/supabase-js": "2.55.0",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react-dom": "19.1.8",
|
||||
"@types/react": "19.1.12",
|
||||
"@types/react-dom": "19.1.9",
|
||||
"react": "19.1.1",
|
||||
"react-dom": "19.1.1",
|
||||
"react-hook-form": "^7.62.0",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"@kit/eslint-config": "workspace:*",
|
||||
"@kit/prettier-config": "workspace:*",
|
||||
"@kit/tsconfig": "workspace:*",
|
||||
"@types/react": "19.1.11"
|
||||
"@types/react": "19.1.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"pino": "^9.8.0"
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"@supabase/ssr": "^0.7.0",
|
||||
"@supabase/supabase-js": "2.55.0",
|
||||
"@tanstack/react-query": "5.85.5",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react": "19.1.12",
|
||||
"next": "15.5.2",
|
||||
"react": "19.1.1",
|
||||
"server-only": "^0.0.1",
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
"@supabase/supabase-js": "2.55.0",
|
||||
"@tanstack/react-query": "5.85.5",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"@types/react": "19.1.11",
|
||||
"@types/react-dom": "19.1.8",
|
||||
"@types/react": "19.1.12",
|
||||
"@types/react-dom": "19.1.9",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"eslint": "^9.34.0",
|
||||
@@ -38,7 +38,7 @@
|
||||
"prettier": "^3.6.2",
|
||||
"react-day-picker": "^9.9.0",
|
||||
"react-hook-form": "^7.62.0",
|
||||
"react-i18next": "^15.7.2",
|
||||
"react-i18next": "^15.7.3",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwindcss": "4.1.12",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
Cell,
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from '@tanstack/react-table';
|
||||
import type {
|
||||
@@ -21,8 +22,10 @@ import type {
|
||||
VisibilityState,
|
||||
} from '@tanstack/react-table';
|
||||
import {
|
||||
ChevronDown,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
ChevronUp,
|
||||
ChevronsLeft,
|
||||
ChevronsRight,
|
||||
} from 'lucide-react';
|
||||
@@ -87,6 +90,7 @@ interface ReactTableProps<T extends DataItem> {
|
||||
}) => (props: React.PropsWithChildren<object>) => React.ReactNode;
|
||||
noResultsMessage?: React.ReactNode;
|
||||
forcePagination?: boolean; // Force pagination to show even when pageCount <= 1
|
||||
manualSorting?: boolean; // Default true for server-side sorting, set false for client-side sorting
|
||||
}
|
||||
|
||||
export function DataTable<RecordData extends DataItem>({
|
||||
@@ -115,6 +119,7 @@ export function DataTable<RecordData extends DataItem>({
|
||||
rowSelection: controlledRowSelection,
|
||||
sticky = false,
|
||||
forcePagination = false,
|
||||
manualSorting = true,
|
||||
}: ReactTableProps<RecordData>) {
|
||||
// TODO: remove when https://github.com/TanStack/table/issues/5567 gets fixed
|
||||
'use no memo';
|
||||
@@ -149,10 +154,11 @@ export function DataTable<RecordData extends DataItem>({
|
||||
getRowId,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
enableColumnPinning: true,
|
||||
enableRowSelection: true,
|
||||
manualPagination: true,
|
||||
manualSorting: true,
|
||||
manualSorting,
|
||||
onColumnFiltersChange: setColumnFilters,
|
||||
onColumnVisibilityChange: (updater) => {
|
||||
if (typeof updater === 'function') {
|
||||
@@ -350,12 +356,42 @@ export function DataTable<RecordData extends DataItem>({
|
||||
}}
|
||||
key={header.id}
|
||||
>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
{header.isPlaceholder ? null : (
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center gap-2',
|
||||
header.column.getCanSort()
|
||||
? 'hover:bg-accent/50 -mx-3 cursor-pointer rounded px-3 py-1 select-none'
|
||||
: '',
|
||||
)}
|
||||
onClick={header.column.getToggleSortingHandler()}
|
||||
>
|
||||
{flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext(),
|
||||
)}
|
||||
{header.column.getCanSort() && (
|
||||
<div className="flex flex-col">
|
||||
<ChevronUp
|
||||
className={cn(
|
||||
'h-3 w-3',
|
||||
header.column.getIsSorted() === 'asc'
|
||||
? 'text-foreground'
|
||||
: 'text-muted-foreground/50',
|
||||
)}
|
||||
/>
|
||||
<ChevronDown
|
||||
className={cn(
|
||||
'-mt-1 h-3 w-3',
|
||||
header.column.getIsSorted() === 'desc'
|
||||
? 'text-foreground'
|
||||
: 'text-muted-foreground/50',
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
|
||||
1899
pnpm-lock.yaml
generated
1899
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user