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;
|
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() {
|
export function DataTableStory() {
|
||||||
const { controls, updateControl } = useStoryControls<DataTableControls>({
|
const { controls, updateControl } = useStoryControls<DataTableControls>({
|
||||||
dataCount: 50,
|
dataCount: 50,
|
||||||
@@ -291,6 +386,7 @@ export function DataTableStory() {
|
|||||||
pageCount={Math.ceil(data.length / controls.pageSize)}
|
pageCount={Math.ceil(data.length / controls.pageSize)}
|
||||||
sticky={controls.stickyHeader}
|
sticky={controls.stickyHeader}
|
||||||
forcePagination={true}
|
forcePagination={true}
|
||||||
|
manualSorting={false} // Enable client-side sorting for demo
|
||||||
columnVisibility={
|
columnVisibility={
|
||||||
controls.enableColumnVisibility
|
controls.enableColumnVisibility
|
||||||
? columnManagement.columnVisibility
|
? columnManagement.columnVisibility
|
||||||
@@ -1397,6 +1493,154 @@ export function DataTableStory() {
|
|||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</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>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
"format": "prettier --check --write \"**/*.{js,cjs,mjs,ts,tsx,md,json}\""
|
"format": "prettier --check --write \"**/*.{js,cjs,mjs,ts,tsx,md,json}\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ai-sdk/openai": "^2.0.22",
|
"@ai-sdk/openai": "^2.0.23",
|
||||||
"@faker-js/faker": "^10.0.0",
|
"@faker-js/faker": "^10.0.0",
|
||||||
"@hookform/resolvers": "^5.2.1",
|
"@hookform/resolvers": "^5.2.1",
|
||||||
"@tanstack/react-query": "5.85.5",
|
"@tanstack/react-query": "5.85.5",
|
||||||
"ai": "5.0.26",
|
"ai": "5.0.28",
|
||||||
"lucide-react": "^0.542.0",
|
"lucide-react": "^0.542.0",
|
||||||
"next": "15.5.2",
|
"next": "15.5.2",
|
||||||
"nodemailer": "^7.0.5",
|
"nodemailer": "^7.0.5",
|
||||||
@@ -30,9 +30,9 @@
|
|||||||
"@tailwindcss/postcss": "^4.1.12",
|
"@tailwindcss/postcss": "^4.1.12",
|
||||||
"@types/node": "^24.3.0",
|
"@types/node": "^24.3.0",
|
||||||
"@types/nodemailer": "7.0.1",
|
"@types/nodemailer": "7.0.1",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"@types/react-dom": "19.1.8",
|
"@types/react-dom": "19.1.9",
|
||||||
"babel-plugin-react-compiler": "19.1.0-rc.2",
|
"babel-plugin-react-compiler": "19.1.0-rc.3",
|
||||||
"pino-pretty": "13.0.0",
|
"pino-pretty": "13.0.0",
|
||||||
"react-hook-form": "^7.62.0",
|
"react-hook-form": "^7.62.0",
|
||||||
"recharts": "2.15.3",
|
"recharts": "2.15.3",
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"react-dom": "19.1.1",
|
"react-dom": "19.1.1",
|
||||||
"react-hook-form": "^7.62.0",
|
"react-hook-form": "^7.62.0",
|
||||||
"react-i18next": "^15.7.2",
|
"react-i18next": "^15.7.3",
|
||||||
"recharts": "2.15.3",
|
"recharts": "2.15.3",
|
||||||
"tailwind-merge": "^3.3.1",
|
"tailwind-merge": "^3.3.1",
|
||||||
"zod": "^3.25.74"
|
"zod": "^3.25.74"
|
||||||
@@ -79,9 +79,9 @@
|
|||||||
"@next/bundle-analyzer": "15.5.2",
|
"@next/bundle-analyzer": "15.5.2",
|
||||||
"@tailwindcss/postcss": "^4.1.12",
|
"@tailwindcss/postcss": "^4.1.12",
|
||||||
"@types/node": "^24.3.0",
|
"@types/node": "^24.3.0",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"@types/react-dom": "19.1.8",
|
"@types/react-dom": "19.1.9",
|
||||||
"babel-plugin-react-compiler": "19.1.0-rc.2",
|
"babel-plugin-react-compiler": "19.1.0-rc.3",
|
||||||
"cssnano": "^7.1.1",
|
"cssnano": "^7.1.1",
|
||||||
"pino-pretty": "13.0.0",
|
"pino-pretty": "13.0.0",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@manypkg/cli": "^0.25.0",
|
"@manypkg/cli": "^0.25.1",
|
||||||
"@turbo/gen": "^2.5.6",
|
"@turbo/gen": "^2.5.6",
|
||||||
"cross-env": "^10.0.0",
|
"cross-env": "^10.0.0",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
|
|||||||
@@ -27,13 +27,13 @@
|
|||||||
"@kit/tsconfig": "workspace:*",
|
"@kit/tsconfig": "workspace:*",
|
||||||
"@kit/ui": "workspace:*",
|
"@kit/ui": "workspace:*",
|
||||||
"@supabase/supabase-js": "2.55.0",
|
"@supabase/supabase-js": "2.55.0",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"lucide-react": "^0.542.0",
|
"lucide-react": "^0.542.0",
|
||||||
"next": "15.5.2",
|
"next": "15.5.2",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"react-hook-form": "^7.62.0",
|
"react-hook-form": "^7.62.0",
|
||||||
"react-i18next": "^15.7.2",
|
"react-i18next": "^15.7.3",
|
||||||
"zod": "^3.25.74"
|
"zod": "^3.25.74"
|
||||||
},
|
},
|
||||||
"typesVersions": {
|
"typesVersions": {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"@kit/supabase": "workspace:*",
|
"@kit/supabase": "workspace:*",
|
||||||
"@kit/tsconfig": "workspace:*",
|
"@kit/tsconfig": "workspace:*",
|
||||||
"@kit/ui": "workspace:*",
|
"@kit/ui": "workspace:*",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"next": "15.5.2",
|
"next": "15.5.2",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"zod": "^3.25.74"
|
"zod": "^3.25.74"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@stripe/react-stripe-js": "^3.9.2",
|
"@stripe/react-stripe-js": "^3.9.2",
|
||||||
"@stripe/stripe-js": "^7.9.0",
|
"@stripe/stripe-js": "^7.9.0",
|
||||||
"stripe": "^18.4.0"
|
"stripe": "^18.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@kit/billing": "workspace:*",
|
"@kit/billing": "workspace:*",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"@kit/supabase": "workspace:*",
|
"@kit/supabase": "workspace:*",
|
||||||
"@kit/tsconfig": "workspace:*",
|
"@kit/tsconfig": "workspace:*",
|
||||||
"@kit/ui": "workspace:*",
|
"@kit/ui": "workspace:*",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"next": "15.5.2",
|
"next": "15.5.2",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'server-only';
|
|||||||
|
|
||||||
import { StripeServerEnvSchema } from '../schema/stripe-server-env.schema';
|
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
|
* @description returns a Stripe instance
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
"@kit/tsconfig": "workspace:*",
|
"@kit/tsconfig": "workspace:*",
|
||||||
"@kit/ui": "workspace:*",
|
"@kit/ui": "workspace:*",
|
||||||
"@types/node": "^24.3.0",
|
"@types/node": "^24.3.0",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"zod": "^3.25.74"
|
"zod": "^3.25.74"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"@kit/tsconfig": "workspace:*",
|
"@kit/tsconfig": "workspace:*",
|
||||||
"@kit/ui": "workspace:*",
|
"@kit/ui": "workspace:*",
|
||||||
"@types/node": "^24.3.0",
|
"@types/node": "^24.3.0",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"wp-types": "^4.68.1"
|
"wp-types": "^4.68.1"
|
||||||
},
|
},
|
||||||
"typesVersions": {
|
"typesVersions": {
|
||||||
|
|||||||
@@ -36,15 +36,15 @@
|
|||||||
"@radix-ui/react-icons": "^1.3.2",
|
"@radix-ui/react-icons": "^1.3.2",
|
||||||
"@supabase/supabase-js": "2.55.0",
|
"@supabase/supabase-js": "2.55.0",
|
||||||
"@tanstack/react-query": "5.85.5",
|
"@tanstack/react-query": "5.85.5",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"@types/react-dom": "19.1.8",
|
"@types/react-dom": "19.1.9",
|
||||||
"lucide-react": "^0.542.0",
|
"lucide-react": "^0.542.0",
|
||||||
"next": "15.5.2",
|
"next": "15.5.2",
|
||||||
"next-themes": "0.4.6",
|
"next-themes": "0.4.6",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"react-dom": "19.1.1",
|
"react-dom": "19.1.1",
|
||||||
"react-hook-form": "^7.62.0",
|
"react-hook-form": "^7.62.0",
|
||||||
"react-i18next": "^15.7.2",
|
"react-i18next": "^15.7.3",
|
||||||
"zod": "^3.25.74"
|
"zod": "^3.25.74"
|
||||||
},
|
},
|
||||||
"prettier": "@kit/prettier-config",
|
"prettier": "@kit/prettier-config",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"@supabase/supabase-js": "2.55.0",
|
"@supabase/supabase-js": "2.55.0",
|
||||||
"@tanstack/react-query": "5.85.5",
|
"@tanstack/react-query": "5.85.5",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"lucide-react": "^0.542.0",
|
"lucide-react": "^0.542.0",
|
||||||
"next": "15.5.2",
|
"next": "15.5.2",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
|
|||||||
@@ -31,11 +31,11 @@
|
|||||||
"@radix-ui/react-icons": "^1.3.2",
|
"@radix-ui/react-icons": "^1.3.2",
|
||||||
"@supabase/supabase-js": "2.55.0",
|
"@supabase/supabase-js": "2.55.0",
|
||||||
"@tanstack/react-query": "5.85.5",
|
"@tanstack/react-query": "5.85.5",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"lucide-react": "^0.542.0",
|
"lucide-react": "^0.542.0",
|
||||||
"next": "15.5.2",
|
"next": "15.5.2",
|
||||||
"react-hook-form": "^7.62.0",
|
"react-hook-form": "^7.62.0",
|
||||||
"react-i18next": "^15.7.2",
|
"react-i18next": "^15.7.3",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
"zod": "^3.25.74"
|
"zod": "^3.25.74"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,11 +21,11 @@
|
|||||||
"@kit/ui": "workspace:*",
|
"@kit/ui": "workspace:*",
|
||||||
"@supabase/supabase-js": "2.55.0",
|
"@supabase/supabase-js": "2.55.0",
|
||||||
"@tanstack/react-query": "5.85.5",
|
"@tanstack/react-query": "5.85.5",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"lucide-react": "^0.542.0",
|
"lucide-react": "^0.542.0",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"react-dom": "19.1.1",
|
"react-dom": "19.1.1",
|
||||||
"react-i18next": "^15.7.2"
|
"react-i18next": "^15.7.3"
|
||||||
},
|
},
|
||||||
"prettier": "@kit/prettier-config",
|
"prettier": "@kit/prettier-config",
|
||||||
"typesVersions": {
|
"typesVersions": {
|
||||||
|
|||||||
@@ -35,8 +35,8 @@
|
|||||||
"@supabase/supabase-js": "2.55.0",
|
"@supabase/supabase-js": "2.55.0",
|
||||||
"@tanstack/react-query": "5.85.5",
|
"@tanstack/react-query": "5.85.5",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"@types/react-dom": "19.1.8",
|
"@types/react-dom": "19.1.9",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"lucide-react": "^0.542.0",
|
"lucide-react": "^0.542.0",
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"react-dom": "19.1.1",
|
"react-dom": "19.1.1",
|
||||||
"react-hook-form": "^7.62.0",
|
"react-hook-form": "^7.62.0",
|
||||||
"react-i18next": "^15.7.2",
|
"react-i18next": "^15.7.3",
|
||||||
"zod": "^3.25.74"
|
"zod": "^3.25.74"
|
||||||
},
|
},
|
||||||
"prettier": "@kit/prettier-config",
|
"prettier": "@kit/prettier-config",
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"next": "15.5.2",
|
"next": "15.5.2",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"react-dom": "19.1.1",
|
"react-dom": "19.1.1",
|
||||||
"react-i18next": "^15.7.2"
|
"react-i18next": "^15.7.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"i18next": "25.4.2",
|
"i18next": "25.4.2",
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"@kit/sentry": "workspace:*",
|
"@kit/sentry": "workspace:*",
|
||||||
"@kit/shared": "workspace:*",
|
"@kit/shared": "workspace:*",
|
||||||
"@kit/tsconfig": "workspace:*",
|
"@kit/tsconfig": "workspace:*",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"zod": "^3.25.74"
|
"zod": "^3.25.74"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"@kit/eslint-config": "workspace:*",
|
"@kit/eslint-config": "workspace:*",
|
||||||
"@kit/prettier-config": "workspace:*",
|
"@kit/prettier-config": "workspace:*",
|
||||||
"@kit/tsconfig": "workspace:*",
|
"@kit/tsconfig": "workspace:*",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"zod": "^3.25.74"
|
"zod": "^3.25.74"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
"@kit/eslint-config": "workspace:*",
|
"@kit/eslint-config": "workspace:*",
|
||||||
"@kit/prettier-config": "workspace:*",
|
"@kit/prettier-config": "workspace:*",
|
||||||
"@kit/tsconfig": "workspace:*",
|
"@kit/tsconfig": "workspace:*",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"react": "19.1.1"
|
"react": "19.1.1"
|
||||||
},
|
},
|
||||||
"typesVersions": {
|
"typesVersions": {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
"./config/server": "./src/sentry.client.server.ts"
|
"./config/server": "./src/sentry.client.server.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/nextjs": "^10.6.0",
|
"@sentry/nextjs": "^10.8.0",
|
||||||
"import-in-the-middle": "1.14.2"
|
"import-in-the-middle": "1.14.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
"@kit/monitoring-core": "workspace:*",
|
"@kit/monitoring-core": "workspace:*",
|
||||||
"@kit/prettier-config": "workspace:*",
|
"@kit/prettier-config": "workspace:*",
|
||||||
"@kit/tsconfig": "workspace:*",
|
"@kit/tsconfig": "workspace:*",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"react": "19.1.1"
|
"react": "19.1.1"
|
||||||
},
|
},
|
||||||
"typesVersions": {
|
"typesVersions": {
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
"@kit/ui": "workspace:*",
|
"@kit/ui": "workspace:*",
|
||||||
"@radix-ui/react-icons": "^1.3.2",
|
"@radix-ui/react-icons": "^1.3.2",
|
||||||
"@supabase/supabase-js": "2.55.0",
|
"@supabase/supabase-js": "2.55.0",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"@types/react-dom": "19.1.8",
|
"@types/react-dom": "19.1.9",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"react-dom": "19.1.1",
|
"react-dom": "19.1.1",
|
||||||
"react-hook-form": "^7.62.0",
|
"react-hook-form": "^7.62.0",
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
"@kit/eslint-config": "workspace:*",
|
"@kit/eslint-config": "workspace:*",
|
||||||
"@kit/prettier-config": "workspace:*",
|
"@kit/prettier-config": "workspace:*",
|
||||||
"@kit/tsconfig": "workspace:*",
|
"@kit/tsconfig": "workspace:*",
|
||||||
"@types/react": "19.1.11"
|
"@types/react": "19.1.12"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pino": "^9.8.0"
|
"pino": "^9.8.0"
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
"@supabase/ssr": "^0.7.0",
|
"@supabase/ssr": "^0.7.0",
|
||||||
"@supabase/supabase-js": "2.55.0",
|
"@supabase/supabase-js": "2.55.0",
|
||||||
"@tanstack/react-query": "5.85.5",
|
"@tanstack/react-query": "5.85.5",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"next": "15.5.2",
|
"next": "15.5.2",
|
||||||
"react": "19.1.1",
|
"react": "19.1.1",
|
||||||
"server-only": "^0.0.1",
|
"server-only": "^0.0.1",
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
"@supabase/supabase-js": "2.55.0",
|
"@supabase/supabase-js": "2.55.0",
|
||||||
"@tanstack/react-query": "5.85.5",
|
"@tanstack/react-query": "5.85.5",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
"@types/react": "19.1.11",
|
"@types/react": "19.1.12",
|
||||||
"@types/react-dom": "19.1.8",
|
"@types/react-dom": "19.1.9",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"eslint": "^9.34.0",
|
"eslint": "^9.34.0",
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"react-day-picker": "^9.9.0",
|
"react-day-picker": "^9.9.0",
|
||||||
"react-hook-form": "^7.62.0",
|
"react-hook-form": "^7.62.0",
|
||||||
"react-i18next": "^15.7.2",
|
"react-i18next": "^15.7.3",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
"tailwindcss": "4.1.12",
|
"tailwindcss": "4.1.12",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
Cell,
|
Cell,
|
||||||
flexRender,
|
flexRender,
|
||||||
getCoreRowModel,
|
getCoreRowModel,
|
||||||
|
getSortedRowModel,
|
||||||
useReactTable,
|
useReactTable,
|
||||||
} from '@tanstack/react-table';
|
} from '@tanstack/react-table';
|
||||||
import type {
|
import type {
|
||||||
@@ -21,8 +22,10 @@ import type {
|
|||||||
VisibilityState,
|
VisibilityState,
|
||||||
} from '@tanstack/react-table';
|
} from '@tanstack/react-table';
|
||||||
import {
|
import {
|
||||||
|
ChevronDown,
|
||||||
ChevronLeft,
|
ChevronLeft,
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
|
ChevronUp,
|
||||||
ChevronsLeft,
|
ChevronsLeft,
|
||||||
ChevronsRight,
|
ChevronsRight,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
@@ -87,6 +90,7 @@ interface ReactTableProps<T extends DataItem> {
|
|||||||
}) => (props: React.PropsWithChildren<object>) => React.ReactNode;
|
}) => (props: React.PropsWithChildren<object>) => React.ReactNode;
|
||||||
noResultsMessage?: React.ReactNode;
|
noResultsMessage?: React.ReactNode;
|
||||||
forcePagination?: boolean; // Force pagination to show even when pageCount <= 1
|
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>({
|
export function DataTable<RecordData extends DataItem>({
|
||||||
@@ -115,6 +119,7 @@ export function DataTable<RecordData extends DataItem>({
|
|||||||
rowSelection: controlledRowSelection,
|
rowSelection: controlledRowSelection,
|
||||||
sticky = false,
|
sticky = false,
|
||||||
forcePagination = false,
|
forcePagination = false,
|
||||||
|
manualSorting = true,
|
||||||
}: ReactTableProps<RecordData>) {
|
}: ReactTableProps<RecordData>) {
|
||||||
// TODO: remove when https://github.com/TanStack/table/issues/5567 gets fixed
|
// TODO: remove when https://github.com/TanStack/table/issues/5567 gets fixed
|
||||||
'use no memo';
|
'use no memo';
|
||||||
@@ -149,10 +154,11 @@ export function DataTable<RecordData extends DataItem>({
|
|||||||
getRowId,
|
getRowId,
|
||||||
columns,
|
columns,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
getSortedRowModel: getSortedRowModel(),
|
||||||
enableColumnPinning: true,
|
enableColumnPinning: true,
|
||||||
enableRowSelection: true,
|
enableRowSelection: true,
|
||||||
manualPagination: true,
|
manualPagination: true,
|
||||||
manualSorting: true,
|
manualSorting,
|
||||||
onColumnFiltersChange: setColumnFilters,
|
onColumnFiltersChange: setColumnFilters,
|
||||||
onColumnVisibilityChange: (updater) => {
|
onColumnVisibilityChange: (updater) => {
|
||||||
if (typeof updater === 'function') {
|
if (typeof updater === 'function') {
|
||||||
@@ -350,12 +356,42 @@ export function DataTable<RecordData extends DataItem>({
|
|||||||
}}
|
}}
|
||||||
key={header.id}
|
key={header.id}
|
||||||
>
|
>
|
||||||
{header.isPlaceholder
|
{header.isPlaceholder ? null : (
|
||||||
? null
|
<div
|
||||||
: flexRender(
|
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.column.columnDef.header,
|
||||||
header.getContext(),
|
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>
|
</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