@fayz-ai/ui 0.8.4 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ChartWidgetInner-GDE5PBTR.js +46 -0
- package/dist/ChartWidgetInner-GDE5PBTR.js.map +1 -0
- package/dist/{chunk-VVQ45ZDZ.js → chunk-KV3MHB6N.js} +85 -179
- package/dist/chunk-KV3MHB6N.js.map +1 -0
- package/dist/{chunk-M34ACV5E.js → chunk-OUPJDGKE.js} +6 -41
- package/dist/chunk-OUPJDGKE.js.map +1 -0
- package/dist/chunk-PVIB724L.js +161 -0
- package/dist/chunk-PVIB724L.js.map +1 -0
- package/dist/{chunk-DYMBFHD7.js → chunk-VDAYIQX4.js} +202 -3
- package/dist/chunk-VDAYIQX4.js.map +1 -0
- package/dist/{chunk-R4LPSXTT.js → chunk-YLQGUJAQ.js} +18 -6
- package/dist/chunk-YLQGUJAQ.js.map +1 -0
- package/dist/dashboard/ChartWidget.d.ts.map +1 -1
- package/dist/dashboard/ChartWidgetInner.d.ts +11 -0
- package/dist/dashboard/ChartWidgetInner.d.ts.map +1 -0
- package/dist/dashboard/index.js +2 -1
- package/dist/icons.d.ts +8 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/icons.js +3 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/layout/Sidebar.d.ts +1 -2
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/index.js +2 -1
- package/dist/preset.cjs +201 -11
- package/dist/preset.cjs.map +1 -1
- package/dist/preset.js +201 -1
- package/dist/preset.js.map +1 -1
- package/dist/primitives/date-picker.d.ts +7 -1
- package/dist/primitives/date-picker.d.ts.map +1 -1
- package/dist/primitives/index.js +1 -1
- package/dist/tailwind.cjs +199 -2
- package/dist/tailwind.cjs.map +1 -1
- package/dist/tailwind.js +198 -1
- package/dist/tailwind.js.map +1 -1
- package/dist/theme/index.js +1 -2
- package/package.json +24 -22
- package/src/dashboard/ChartWidget.tsx +8 -65
- package/src/dashboard/ChartWidgetInner.tsx +83 -0
- package/src/dashboard/icon.ts +2 -2
- package/src/icons.ts +66 -0
- package/src/index.ts +4 -0
- package/src/layout/Sidebar.tsx +4 -110
- package/src/primitives/date-picker.tsx +30 -4
- package/dist/chunk-2P7T6QQK.cjs +0 -206
- package/dist/chunk-2P7T6QQK.cjs.map +0 -1
- package/dist/chunk-7ZQQZD4Q.cjs +0 -1823
- package/dist/chunk-7ZQQZD4Q.cjs.map +0 -1
- package/dist/chunk-B3BTZDTA.cjs +0 -1701
- package/dist/chunk-B3BTZDTA.cjs.map +0 -1
- package/dist/chunk-DYMBFHD7.js.map +0 -1
- package/dist/chunk-H6OULCHF.cjs +0 -81
- package/dist/chunk-H6OULCHF.cjs.map +0 -1
- package/dist/chunk-IWBXYV4U.js +0 -203
- package/dist/chunk-IWBXYV4U.js.map +0 -1
- package/dist/chunk-M34ACV5E.js.map +0 -1
- package/dist/chunk-MUGRP5DD.cjs +0 -701
- package/dist/chunk-MUGRP5DD.cjs.map +0 -1
- package/dist/chunk-NZV47HWO.cjs +0 -380
- package/dist/chunk-NZV47HWO.cjs.map +0 -1
- package/dist/chunk-OW73RZOU.cjs +0 -313
- package/dist/chunk-OW73RZOU.cjs.map +0 -1
- package/dist/chunk-R4LPSXTT.js.map +0 -1
- package/dist/chunk-R4SQ2GVD.cjs +0 -475
- package/dist/chunk-R4SQ2GVD.cjs.map +0 -1
- package/dist/chunk-VVQ45ZDZ.js.map +0 -1
- package/dist/dashboard/index.cjs +0 -106
- package/dist/dashboard/index.cjs.map +0 -1
- package/dist/index.cjs +0 -650
- package/dist/index.cjs.map +0 -1
- package/dist/layout/index.cjs +0 -98
- package/dist/layout/index.cjs.map +0 -1
- package/dist/primitives/index.cjs +0 -363
- package/dist/primitives/index.cjs.map +0 -1
- package/dist/theme/index.cjs +0 -41
- package/dist/theme/index.cjs.map +0 -1
|
@@ -1,27 +1,8 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
|
-
import {
|
|
3
|
-
ResponsiveContainer,
|
|
4
|
-
LineChart, Line,
|
|
5
|
-
BarChart, Bar,
|
|
6
|
-
AreaChart, Area,
|
|
7
|
-
PieChart, Pie, Cell,
|
|
8
|
-
XAxis, YAxis, CartesianGrid, Tooltip, Legend,
|
|
9
|
-
} from 'recharts'
|
|
10
2
|
import { Card, CardContent, CardHeader, CardTitle } from '../primitives/card'
|
|
11
3
|
import { renderIcon } from './icon'
|
|
12
4
|
import type { ChartSeries, ChartType, IconRef } from './types'
|
|
13
5
|
|
|
14
|
-
/** Theme-driven palette (HSL triplet CSS vars defined in styles.css). */
|
|
15
|
-
const PALETTE = [
|
|
16
|
-
'hsl(var(--info))',
|
|
17
|
-
'hsl(var(--magic))',
|
|
18
|
-
'hsl(var(--success))',
|
|
19
|
-
'hsl(var(--warning))',
|
|
20
|
-
'hsl(var(--destructive))',
|
|
21
|
-
]
|
|
22
|
-
const AXIS = 'hsl(var(--muted-foreground))'
|
|
23
|
-
const GRID = 'hsl(var(--border))'
|
|
24
|
-
|
|
25
6
|
export interface ChartWidgetProps {
|
|
26
7
|
type: ChartType
|
|
27
8
|
/** Rows of data; each key referenced by a series.dataKey. */
|
|
@@ -37,12 +18,15 @@ export interface ChartWidgetProps {
|
|
|
37
18
|
className?: string
|
|
38
19
|
}
|
|
39
20
|
|
|
21
|
+
// The recharts body is lazy so recharts ships as an async chunk instead of in
|
|
22
|
+
// every consumer's entry bundle; the Card shell renders immediately and the
|
|
23
|
+
// fallback reserves the chart's height to avoid layout shift.
|
|
24
|
+
const ChartWidgetInner = React.lazy(() => import('./ChartWidgetInner'))
|
|
25
|
+
|
|
40
26
|
/** recharts-backed chart in a Card. Replaces the hand-rolled CSS bar charts. */
|
|
41
27
|
export function ChartWidget({
|
|
42
28
|
type, data, series, categoryKey = 'name', title, icon, headerAction, height = 240, className,
|
|
43
29
|
}: ChartWidgetProps) {
|
|
44
|
-
const color = (i: number, explicit?: string) => explicit ?? PALETTE[i % PALETTE.length]
|
|
45
|
-
|
|
46
30
|
return (
|
|
47
31
|
<Card className={className}>
|
|
48
32
|
{(title || headerAction) && (
|
|
@@ -57,50 +41,9 @@ export function ChartWidget({
|
|
|
57
41
|
</CardHeader>
|
|
58
42
|
)}
|
|
59
43
|
<CardContent className="p-4 pt-2">
|
|
60
|
-
<
|
|
61
|
-
{type
|
|
62
|
-
|
|
63
|
-
<Tooltip />
|
|
64
|
-
<Pie data={data} dataKey={series[0]?.dataKey ?? 'value'} nameKey={categoryKey} innerRadius={50} outerRadius={80} paddingAngle={2}>
|
|
65
|
-
{data.map((_, i) => <Cell key={i} fill={color(i, series[0]?.color)} />)}
|
|
66
|
-
</Pie>
|
|
67
|
-
<Legend />
|
|
68
|
-
</PieChart>
|
|
69
|
-
) : type === 'bar' ? (
|
|
70
|
-
<BarChart data={data}>
|
|
71
|
-
<CartesianGrid strokeDasharray="3 3" stroke={GRID} vertical={false} />
|
|
72
|
-
<XAxis dataKey={categoryKey} stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} />
|
|
73
|
-
<YAxis stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} width={36} />
|
|
74
|
-
<Tooltip cursor={{ fill: GRID, opacity: 0.3 }} />
|
|
75
|
-
{series.length > 1 && <Legend />}
|
|
76
|
-
{series.map((s, i) => (
|
|
77
|
-
<Bar key={s.dataKey} dataKey={s.dataKey} name={s.label ?? s.dataKey} fill={color(i, s.color)} radius={[4, 4, 0, 0]} />
|
|
78
|
-
))}
|
|
79
|
-
</BarChart>
|
|
80
|
-
) : type === 'area' ? (
|
|
81
|
-
<AreaChart data={data}>
|
|
82
|
-
<CartesianGrid strokeDasharray="3 3" stroke={GRID} vertical={false} />
|
|
83
|
-
<XAxis dataKey={categoryKey} stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} />
|
|
84
|
-
<YAxis stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} width={36} />
|
|
85
|
-
<Tooltip />
|
|
86
|
-
{series.length > 1 && <Legend />}
|
|
87
|
-
{series.map((s, i) => (
|
|
88
|
-
<Area key={s.dataKey} dataKey={s.dataKey} name={s.label ?? s.dataKey} stroke={color(i, s.color)} fill={color(i, s.color)} fillOpacity={0.15} />
|
|
89
|
-
))}
|
|
90
|
-
</AreaChart>
|
|
91
|
-
) : (
|
|
92
|
-
<LineChart data={data}>
|
|
93
|
-
<CartesianGrid strokeDasharray="3 3" stroke={GRID} vertical={false} />
|
|
94
|
-
<XAxis dataKey={categoryKey} stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} />
|
|
95
|
-
<YAxis stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} width={36} />
|
|
96
|
-
<Tooltip />
|
|
97
|
-
{series.length > 1 && <Legend />}
|
|
98
|
-
{series.map((s, i) => (
|
|
99
|
-
<Line key={s.dataKey} dataKey={s.dataKey} name={s.label ?? s.dataKey} stroke={color(i, s.color)} strokeWidth={2} dot={false} />
|
|
100
|
-
))}
|
|
101
|
-
</LineChart>
|
|
102
|
-
)}
|
|
103
|
-
</ResponsiveContainer>
|
|
44
|
+
<React.Suspense fallback={<div style={{ height }} />}>
|
|
45
|
+
<ChartWidgetInner type={type} data={data} series={series} categoryKey={categoryKey} height={height} />
|
|
46
|
+
</React.Suspense>
|
|
104
47
|
</CardContent>
|
|
105
48
|
</Card>
|
|
106
49
|
)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import {
|
|
3
|
+
ResponsiveContainer,
|
|
4
|
+
LineChart, Line,
|
|
5
|
+
BarChart, Bar,
|
|
6
|
+
AreaChart, Area,
|
|
7
|
+
PieChart, Pie, Cell,
|
|
8
|
+
XAxis, YAxis, CartesianGrid, Tooltip, Legend,
|
|
9
|
+
} from 'recharts'
|
|
10
|
+
import type { ChartSeries, ChartType } from './types'
|
|
11
|
+
|
|
12
|
+
/** Theme-driven palette (HSL triplet CSS vars defined in styles.css). */
|
|
13
|
+
const PALETTE = [
|
|
14
|
+
'hsl(var(--info))',
|
|
15
|
+
'hsl(var(--magic))',
|
|
16
|
+
'hsl(var(--success))',
|
|
17
|
+
'hsl(var(--warning))',
|
|
18
|
+
'hsl(var(--destructive))',
|
|
19
|
+
]
|
|
20
|
+
const AXIS = 'hsl(var(--muted-foreground))'
|
|
21
|
+
const GRID = 'hsl(var(--border))'
|
|
22
|
+
|
|
23
|
+
export interface ChartWidgetInnerProps {
|
|
24
|
+
type: ChartType
|
|
25
|
+
data: Array<Record<string, string | number>>
|
|
26
|
+
series: ChartSeries[]
|
|
27
|
+
categoryKey: string
|
|
28
|
+
height: number
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// recharts-backed chart body. Default export + own module so ChartWidget can
|
|
32
|
+
// React.lazy it — recharts (~400 KB min) then lives in an async chunk instead
|
|
33
|
+
// of every consumer's entry bundle.
|
|
34
|
+
export default function ChartWidgetInner({ type, data, series, categoryKey, height }: ChartWidgetInnerProps) {
|
|
35
|
+
const color = (i: number, explicit?: string) => explicit ?? PALETTE[i % PALETTE.length]
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<ResponsiveContainer width="100%" height={height}>
|
|
39
|
+
{type === 'pie' ? (
|
|
40
|
+
<PieChart>
|
|
41
|
+
<Tooltip />
|
|
42
|
+
<Pie data={data} dataKey={series[0]?.dataKey ?? 'value'} nameKey={categoryKey} innerRadius={50} outerRadius={80} paddingAngle={2}>
|
|
43
|
+
{data.map((_, i) => <Cell key={i} fill={color(i, series[0]?.color)} />)}
|
|
44
|
+
</Pie>
|
|
45
|
+
<Legend />
|
|
46
|
+
</PieChart>
|
|
47
|
+
) : type === 'bar' ? (
|
|
48
|
+
<BarChart data={data}>
|
|
49
|
+
<CartesianGrid strokeDasharray="3 3" stroke={GRID} vertical={false} />
|
|
50
|
+
<XAxis dataKey={categoryKey} stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} />
|
|
51
|
+
<YAxis stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} width={36} />
|
|
52
|
+
<Tooltip cursor={{ fill: GRID, opacity: 0.3 }} />
|
|
53
|
+
{series.length > 1 && <Legend />}
|
|
54
|
+
{series.map((s, i) => (
|
|
55
|
+
<Bar key={s.dataKey} dataKey={s.dataKey} name={s.label ?? s.dataKey} fill={color(i, s.color)} radius={[4, 4, 0, 0]} />
|
|
56
|
+
))}
|
|
57
|
+
</BarChart>
|
|
58
|
+
) : type === 'area' ? (
|
|
59
|
+
<AreaChart data={data}>
|
|
60
|
+
<CartesianGrid strokeDasharray="3 3" stroke={GRID} vertical={false} />
|
|
61
|
+
<XAxis dataKey={categoryKey} stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} />
|
|
62
|
+
<YAxis stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} width={36} />
|
|
63
|
+
<Tooltip />
|
|
64
|
+
{series.length > 1 && <Legend />}
|
|
65
|
+
{series.map((s, i) => (
|
|
66
|
+
<Area key={s.dataKey} dataKey={s.dataKey} name={s.label ?? s.dataKey} stroke={color(i, s.color)} fill={color(i, s.color)} fillOpacity={0.15} />
|
|
67
|
+
))}
|
|
68
|
+
</AreaChart>
|
|
69
|
+
) : (
|
|
70
|
+
<LineChart data={data}>
|
|
71
|
+
<CartesianGrid strokeDasharray="3 3" stroke={GRID} vertical={false} />
|
|
72
|
+
<XAxis dataKey={categoryKey} stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} />
|
|
73
|
+
<YAxis stroke={AXIS} fontSize={12} tickLine={false} axisLine={false} width={36} />
|
|
74
|
+
<Tooltip />
|
|
75
|
+
{series.length > 1 && <Legend />}
|
|
76
|
+
{series.map((s, i) => (
|
|
77
|
+
<Line key={s.dataKey} dataKey={s.dataKey} name={s.label ?? s.dataKey} stroke={color(i, s.color)} strokeWidth={2} dot={false} />
|
|
78
|
+
))}
|
|
79
|
+
</LineChart>
|
|
80
|
+
)}
|
|
81
|
+
</ResponsiveContainer>
|
|
82
|
+
)
|
|
83
|
+
}
|
package/src/dashboard/icon.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
|
-
import
|
|
2
|
+
import { getLucideIcon } from '../icons'
|
|
3
3
|
import type { IconRef } from './types'
|
|
4
4
|
|
|
5
5
|
/** Resolve an IconRef (lucide name or component) to a renderable element. */
|
|
6
6
|
export function renderIcon(icon: IconRef | undefined, className = 'h-4 w-4'): React.ReactNode {
|
|
7
7
|
if (!icon) return null
|
|
8
8
|
if (typeof icon === 'string') {
|
|
9
|
-
const Comp = (
|
|
9
|
+
const Comp = getLucideIcon(icon)
|
|
10
10
|
return Comp ? React.createElement(Comp, { className }) : null
|
|
11
11
|
}
|
|
12
12
|
return React.createElement(icon, { className })
|
package/src/icons.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { LucideIcon } from 'lucide-react'
|
|
2
|
+
import {
|
|
3
|
+
Activity, AlertTriangle, Apple, ArrowDownCircle, ArrowDownRight, ArrowLeftRight, ArrowUpCircle, ArrowUpRight,
|
|
4
|
+
Award, BadgeDollarSign, Ban, Banknote, BarChart3, Bell, Bike, BookOpen,
|
|
5
|
+
BookOpenCheck, Box, Boxes, Briefcase, Building2, Calendar, CalendarCheck, CalendarCheck2,
|
|
6
|
+
CalendarClock, CalendarDays, CalendarPlus, CalendarX, Camera, Cat, Check, CheckCircle,
|
|
7
|
+
CheckSquare, ChefHat, ChevronsUpDown, Circle, CircleCheck, CircleDollarSign, Clapperboard, ClipboardList,
|
|
8
|
+
Clock, Clock3, Command, Compass, Contact, CreditCard, Disc3, Dog,
|
|
9
|
+
DollarSign, DoorOpen, Egg, ExternalLink, Eye, FileCheck2, FileDown,
|
|
10
|
+
FileText, Filter, Flame, FolderOpen, Globe, GraduationCap, Handshake, Heart,
|
|
11
|
+
Home, Image, Inbox, Instagram, Landmark, Layers, LayoutDashboard, LayoutTemplate,
|
|
12
|
+
Leaf, LeafyGreen, Link, List, ListChecks, ListMusic, ListPlus, Lock,
|
|
13
|
+
Mail, Map, MapPin, Megaphone, MessageCircle, MessageSquare, Mic, MoreHorizontal,
|
|
14
|
+
MousePointerClick, Music, Newspaper, Package, PackageCheck, Palette, PartyPopper, PawPrint,
|
|
15
|
+
Pencil, Percent, Phone, PieChart, Plug, Plus, PlusCircle, Puzzle, Radio,
|
|
16
|
+
Receipt, Repeat, RotateCcw, Ruler, Search, Send, Settings, Shield,
|
|
17
|
+
ShieldCheck, ShoppingBag, ShoppingCart, Sigma, SlidersHorizontal, Sparkles, Star, Tag,
|
|
18
|
+
Tags, Target, ToggleLeft, TreePalm, TrendingDown, TrendingUp, Trophy, Truck,
|
|
19
|
+
User, UserCheck, UserCog, UserPlus, UserX, Users, UsersRound, Utensils,
|
|
20
|
+
UtensilsCrossed, Wallet, Warehouse, Wheat, Workflow, Wrench, X, XCircle,
|
|
21
|
+
Zap,
|
|
22
|
+
} from 'lucide-react'
|
|
23
|
+
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Central lucide icon registry. The SDK's manifest-driven surfaces resolve
|
|
26
|
+
// icons by string name; a namespace import (`import * as LucideIcons`) defeats
|
|
27
|
+
// tree-shaking and drags all ~1,500 icons (~500 KB min) into every bundle, so
|
|
28
|
+
// the SDK ships this curated set instead — the union of every icon name the
|
|
29
|
+
// SDK, plugins, and app templates reference. Apps using names outside the set
|
|
30
|
+
// call registerIcons({ Name: Component }) with their own named imports.
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
const registry: Record<string, LucideIcon> = {
|
|
34
|
+
Activity, AlertTriangle, Apple, ArrowDownCircle, ArrowDownRight, ArrowLeftRight, ArrowUpCircle, ArrowUpRight,
|
|
35
|
+
Award, BadgeDollarSign, Ban, Banknote, BarChart3, Bell, Bike, BookOpen,
|
|
36
|
+
BookOpenCheck, Box, Boxes, Briefcase, Building2, Calendar, CalendarCheck, CalendarCheck2,
|
|
37
|
+
CalendarClock, CalendarDays, CalendarPlus, CalendarX, Camera, Cat, Check, CheckCircle,
|
|
38
|
+
CheckSquare, ChefHat, ChevronsUpDown, Circle, CircleCheck, CircleDollarSign, Clapperboard, ClipboardList,
|
|
39
|
+
Clock, Clock3, Command, Compass, Contact, CreditCard, Disc3, Dog,
|
|
40
|
+
DollarSign, DoorOpen, Egg, ExternalLink, Eye, FileCheck2, FileDown,
|
|
41
|
+
FileText, Filter, Flame, FolderOpen, Globe, GraduationCap, Handshake, Heart,
|
|
42
|
+
Home, Image, Inbox, Instagram, Landmark, Layers, LayoutDashboard, LayoutTemplate,
|
|
43
|
+
Leaf, LeafyGreen, Link, List, ListChecks, ListMusic, ListPlus, Lock,
|
|
44
|
+
Mail, Map, MapPin, Megaphone, MessageCircle, MessageSquare, Mic, MoreHorizontal,
|
|
45
|
+
MousePointerClick, Music, Newspaper, Package, PackageCheck, Palette, PartyPopper, PawPrint,
|
|
46
|
+
Pencil, Percent, Phone, PieChart, Plug, Plus, PlusCircle, Puzzle, Radio,
|
|
47
|
+
Receipt, Repeat, RotateCcw, Ruler, Search, Send, Settings, Shield,
|
|
48
|
+
ShieldCheck, ShoppingBag, ShoppingCart, Sigma, SlidersHorizontal, Sparkles, Star, Tag,
|
|
49
|
+
Tags, Target, ToggleLeft, TreePalm, TrendingDown, TrendingUp, Trophy, Truck,
|
|
50
|
+
User, UserCheck, UserCog, UserPlus, UserX, Users, UsersRound, Utensils,
|
|
51
|
+
UtensilsCrossed, Wallet, Warehouse, Wheat, Workflow, Wrench, X, XCircle,
|
|
52
|
+
Zap,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Add or override icons resolvable by string name (e.g. from app manifests). */
|
|
56
|
+
export function registerIcons(icons: Record<string, LucideIcon>): void {
|
|
57
|
+
Object.assign(registry, icons)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Resolve a lucide icon by name; undefined when not registered. */
|
|
61
|
+
export function getLucideIcon(name: string): LucideIcon | undefined {
|
|
62
|
+
return registry[name]
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** The registered icon map (live reference — do not mutate directly). */
|
|
66
|
+
export const ICON_MAP = registry
|
package/src/index.ts
CHANGED
|
@@ -228,3 +228,7 @@ export {
|
|
|
228
228
|
type ChartType,
|
|
229
229
|
type ChartSeries,
|
|
230
230
|
} from './dashboard'
|
|
231
|
+
|
|
232
|
+
// Central lucide icon registry — curated tree-shakable set + escape hatch for
|
|
233
|
+
// apps that need icon names outside it (registerIcons({ Name: Component })).
|
|
234
|
+
export { registerIcons, getLucideIcon } from './icons'
|
package/src/layout/Sidebar.tsx
CHANGED
|
@@ -1,106 +1,10 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
2
|
import * as Tooltip from '@radix-ui/react-tooltip'
|
|
3
3
|
import {
|
|
4
|
-
Crown,
|
|
5
|
-
ExternalLink,
|
|
6
|
-
Home,
|
|
7
|
-
Users,
|
|
8
|
-
Settings,
|
|
9
|
-
CreditCard,
|
|
10
|
-
Bell,
|
|
11
|
-
Calendar,
|
|
12
|
-
CalendarClock,
|
|
13
|
-
Package,
|
|
14
|
-
Activity,
|
|
15
|
-
BarChart3,
|
|
16
|
-
FileText,
|
|
17
|
-
Mail,
|
|
18
|
-
PanelLeftClose,
|
|
19
|
-
PanelLeft,
|
|
20
|
-
Search,
|
|
21
|
-
Shield,
|
|
22
|
-
DollarSign,
|
|
23
|
-
Megaphone,
|
|
24
|
-
Receipt,
|
|
25
|
-
ShoppingCart,
|
|
26
|
-
ShoppingBag,
|
|
27
|
-
Target,
|
|
28
|
-
Wrench,
|
|
29
|
-
Truck,
|
|
30
|
-
ClipboardList,
|
|
31
|
-
ListChecks,
|
|
32
|
-
Briefcase,
|
|
33
|
-
UserCog,
|
|
34
|
-
BookOpen,
|
|
35
|
-
BookOpenCheck,
|
|
36
|
-
MessageCircle,
|
|
37
|
-
Globe,
|
|
38
|
-
Percent,
|
|
39
|
-
Tag,
|
|
40
|
-
Tags,
|
|
41
|
-
Camera,
|
|
42
|
-
UtensilsCrossed,
|
|
43
|
-
MapPin,
|
|
44
|
-
Map,
|
|
45
|
-
Handshake,
|
|
46
|
-
Contact,
|
|
47
|
-
Building2,
|
|
48
|
-
Filter,
|
|
49
|
-
Plus,
|
|
50
|
-
List,
|
|
51
|
-
ListPlus,
|
|
52
|
-
ChevronDown,
|
|
53
|
-
Ban,
|
|
54
|
-
Clock,
|
|
55
|
-
Dog,
|
|
56
|
-
Cat,
|
|
57
|
-
PawPrint,
|
|
58
|
-
Heart,
|
|
59
|
-
FolderOpen,
|
|
60
|
-
LayoutTemplate,
|
|
61
|
-
LeafyGreen,
|
|
62
|
-
Apple,
|
|
63
|
-
Egg,
|
|
64
|
-
Wheat,
|
|
65
|
-
PartyPopper,
|
|
66
|
-
Radio,
|
|
67
|
-
CalendarDays,
|
|
68
|
-
CalendarCheck2,
|
|
69
|
-
CalendarX,
|
|
70
|
-
BadgeDollarSign,
|
|
71
|
-
Banknote,
|
|
72
|
-
Landmark,
|
|
73
|
-
CircleDollarSign,
|
|
74
|
-
Layers,
|
|
75
|
-
Music,
|
|
76
|
-
Eye,
|
|
77
|
-
ListMusic,
|
|
78
|
-
Disc3,
|
|
79
|
-
UsersRound,
|
|
80
|
-
Mic,
|
|
81
|
-
Zap,
|
|
82
|
-
Award,
|
|
83
|
-
LayoutDashboard,
|
|
84
|
-
MessageSquare,
|
|
85
|
-
Inbox,
|
|
86
|
-
Star,
|
|
87
|
-
TrendingUp,
|
|
88
|
-
GraduationCap,
|
|
89
|
-
Repeat,
|
|
90
|
-
UserCheck,
|
|
91
|
-
UserPlus,
|
|
92
|
-
UserX,
|
|
93
|
-
Workflow,
|
|
94
|
-
Boxes,
|
|
95
|
-
Clock3,
|
|
96
|
-
FileCheck2,
|
|
97
|
-
User,
|
|
98
|
-
Palette,
|
|
99
|
-
ShieldCheck,
|
|
100
|
-
SlidersHorizontal,
|
|
101
|
-
Puzzle,
|
|
4
|
+
Bell, ChevronDown, Crown, ExternalLink, Home, PanelLeft, PanelLeftClose, Search, Settings, User,
|
|
102
5
|
type LucideIcon,
|
|
103
6
|
} from 'lucide-react'
|
|
7
|
+
import { ICON_MAP } from '../icons'
|
|
104
8
|
import { cn } from '../utils/cn'
|
|
105
9
|
import { useLayoutStore } from '../stores/layout.store'
|
|
106
10
|
|
|
@@ -166,18 +70,8 @@ export interface SidebarProps {
|
|
|
166
70
|
navDirection?: 'forward' | 'back'
|
|
167
71
|
}
|
|
168
72
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
FileText, Mail, DollarSign, Megaphone, ShoppingCart, Target, Wrench, Truck,
|
|
172
|
-
Receipt, ShoppingBag, ClipboardList, ListChecks, Briefcase, UserCog, BookOpen, BookOpenCheck, MessageCircle, Globe,
|
|
173
|
-
Percent, Tag, Tags, Camera, UtensilsCrossed, MapPin, Map, Handshake, Contact,
|
|
174
|
-
Building2, Filter, Plus, List, ListPlus, Search, Shield, Ban, Clock, Dog, Cat, PawPrint, Heart, FolderOpen, LayoutTemplate, LeafyGreen, Apple, Egg, Wheat,
|
|
175
|
-
PartyPopper, Radio, CalendarDays, CalendarCheck2, CalendarX, BadgeDollarSign, Banknote, Landmark, CircleDollarSign, Layers, Music, Eye, ListMusic, Disc3, UsersRound, Mic,
|
|
176
|
-
Zap, Award, LayoutDashboard, MessageSquare, Inbox, Star, TrendingUp, UserCheck, UserPlus, UserX, Workflow, Boxes, Clock3, FileCheck2,
|
|
177
|
-
GraduationCap, Repeat,
|
|
178
|
-
User, Palette, ShieldCheck, SlidersHorizontal, Puzzle,
|
|
179
|
-
}
|
|
180
|
-
|
|
73
|
+
// ICON_MAP now lives in ../icons (central curated registry, shared by every
|
|
74
|
+
// string-name icon lookup in the SDK); re-exported here for compat.
|
|
181
75
|
export { ICON_MAP }
|
|
182
76
|
|
|
183
77
|
/** Kept in sync with --saas-rail-duration in styles.css. */
|
|
@@ -28,6 +28,17 @@ function formatDate(date: Date, locale: string) {
|
|
|
28
28
|
return date.toLocaleDateString(toDateLocale(locale), { month: 'short', day: 'numeric', year: 'numeric' })
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/** Toolbar label: the year is noise while you're inside it, and two of these sit
|
|
32
|
+
* side by side in a range — it only earns its space on another year. */
|
|
33
|
+
function formatDateCompact(date: Date, locale: string) {
|
|
34
|
+
const sameYear = date.getFullYear() === new Date().getFullYear()
|
|
35
|
+
return date.toLocaleDateString(toDateLocale(locale), {
|
|
36
|
+
month: 'short',
|
|
37
|
+
day: 'numeric',
|
|
38
|
+
...(sameYear ? {} : { year: 'numeric' }),
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
31
42
|
function toDateStr(d: Date) {
|
|
32
43
|
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
|
|
33
44
|
}
|
|
@@ -42,13 +53,24 @@ interface DatePickerProps {
|
|
|
42
53
|
value: string
|
|
43
54
|
onChange: (value: string) => void
|
|
44
55
|
className?: string
|
|
56
|
+
/**
|
|
57
|
+
* `input` (default) is the form-field trigger. `toolbar` is the 26px pill that
|
|
58
|
+
* matches SegmentedControl/Button `sm`, for filter bars where a full-height
|
|
59
|
+
* form field towers over everything beside it.
|
|
60
|
+
*/
|
|
61
|
+
variant?: 'input' | 'toolbar'
|
|
45
62
|
/** Open the dropdown immediately on mount */
|
|
46
63
|
defaultOpen?: boolean
|
|
47
64
|
/** Called when the dropdown opens or closes */
|
|
48
65
|
onOpenChange?: (open: boolean) => void
|
|
49
66
|
}
|
|
50
67
|
|
|
51
|
-
|
|
68
|
+
const TRIGGER_VARIANT: Record<'input' | 'toolbar', string> = {
|
|
69
|
+
input: 'rounded-input border border-input bg-card shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] px-3 py-2 text-sm w-full',
|
|
70
|
+
toolbar: 'h-[26px] rounded-button border border-border bg-card shadow-button px-2.5 text-xs font-medium',
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function DatePicker({ value, onChange, className, variant = 'input', defaultOpen, onOpenChange }: DatePickerProps) {
|
|
52
74
|
const t = useTranslation()
|
|
53
75
|
const locale = getCurrentLocale()
|
|
54
76
|
const [open, setOpen] = useState(defaultOpen ?? false)
|
|
@@ -129,9 +151,13 @@ export function DatePicker({ value, onChange, className, defaultOpen, onOpenChan
|
|
|
129
151
|
<div ref={ref} className={`relative ${className ?? ''}`}>
|
|
130
152
|
{/* Trigger */}
|
|
131
153
|
<button ref={triggerRef} type="button" onClick={() => setOpen((p) => !p)}
|
|
132
|
-
className=
|
|
133
|
-
<Calendar className=
|
|
134
|
-
<span
|
|
154
|
+
className={`flex items-center gap-2 text-left transition-colors hover:bg-muted/30 ${TRIGGER_VARIANT[variant]}`}>
|
|
155
|
+
<Calendar className={`shrink-0 text-muted-foreground ${variant === 'toolbar' ? 'h-3 w-3' : 'h-3.5 w-3.5'}`} />
|
|
156
|
+
<span className="whitespace-nowrap">
|
|
157
|
+
{value
|
|
158
|
+
? (variant === 'toolbar' ? formatDateCompact : formatDate)(selectedDate, locale)
|
|
159
|
+
: t('common.selectDate')}
|
|
160
|
+
</span>
|
|
135
161
|
</button>
|
|
136
162
|
|
|
137
163
|
{/* Dropdown — portal to escape overflow containers */}
|
package/dist/chunk-2P7T6QQK.cjs
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// src/theme/preset.ts
|
|
4
|
-
var fayzUiPreset = {
|
|
5
|
-
darkMode: "class",
|
|
6
|
-
theme: {
|
|
7
|
-
extend: {
|
|
8
|
-
colors: {
|
|
9
|
-
border: "hsl(var(--border))",
|
|
10
|
-
input: "hsl(var(--input))",
|
|
11
|
-
ring: "hsl(var(--ring))",
|
|
12
|
-
background: "hsl(var(--background))",
|
|
13
|
-
foreground: "hsl(var(--foreground))",
|
|
14
|
-
primary: {
|
|
15
|
-
DEFAULT: "hsl(var(--primary))",
|
|
16
|
-
foreground: "hsl(var(--primary-foreground))"
|
|
17
|
-
},
|
|
18
|
-
secondary: {
|
|
19
|
-
DEFAULT: "hsl(var(--secondary))",
|
|
20
|
-
foreground: "hsl(var(--secondary-foreground))"
|
|
21
|
-
},
|
|
22
|
-
destructive: {
|
|
23
|
-
DEFAULT: "hsl(var(--destructive))",
|
|
24
|
-
foreground: "hsl(var(--destructive-foreground))"
|
|
25
|
-
},
|
|
26
|
-
success: {
|
|
27
|
-
DEFAULT: "hsl(var(--success))",
|
|
28
|
-
foreground: "hsl(var(--success-foreground))"
|
|
29
|
-
},
|
|
30
|
-
warning: {
|
|
31
|
-
DEFAULT: "hsl(var(--warning))",
|
|
32
|
-
foreground: "hsl(var(--warning-foreground))"
|
|
33
|
-
},
|
|
34
|
-
info: {
|
|
35
|
-
DEFAULT: "hsl(var(--info))",
|
|
36
|
-
foreground: "hsl(var(--info-foreground))"
|
|
37
|
-
},
|
|
38
|
-
magic: {
|
|
39
|
-
DEFAULT: "hsl(var(--magic))",
|
|
40
|
-
foreground: "hsl(var(--magic-foreground))"
|
|
41
|
-
},
|
|
42
|
-
"info-soft": {
|
|
43
|
-
DEFAULT: "hsl(var(--info-soft))",
|
|
44
|
-
foreground: "hsl(var(--info-soft-foreground))"
|
|
45
|
-
},
|
|
46
|
-
"success-soft": {
|
|
47
|
-
DEFAULT: "hsl(var(--success-soft))",
|
|
48
|
-
foreground: "hsl(var(--success-soft-foreground))"
|
|
49
|
-
},
|
|
50
|
-
"warning-soft": {
|
|
51
|
-
DEFAULT: "hsl(var(--warning-soft))",
|
|
52
|
-
foreground: "hsl(var(--warning-soft-foreground))"
|
|
53
|
-
},
|
|
54
|
-
"destructive-soft": {
|
|
55
|
-
DEFAULT: "hsl(var(--destructive-soft))",
|
|
56
|
-
foreground: "hsl(var(--destructive-soft-foreground))"
|
|
57
|
-
},
|
|
58
|
-
"magic-soft": {
|
|
59
|
-
DEFAULT: "hsl(var(--magic-soft))",
|
|
60
|
-
foreground: "hsl(var(--magic-soft-foreground))"
|
|
61
|
-
},
|
|
62
|
-
muted: {
|
|
63
|
-
DEFAULT: "hsl(var(--muted))",
|
|
64
|
-
foreground: "hsl(var(--muted-foreground))"
|
|
65
|
-
},
|
|
66
|
-
accent: {
|
|
67
|
-
DEFAULT: "hsl(var(--accent))",
|
|
68
|
-
foreground: "hsl(var(--accent-foreground))"
|
|
69
|
-
},
|
|
70
|
-
card: {
|
|
71
|
-
DEFAULT: "hsl(var(--card))",
|
|
72
|
-
foreground: "hsl(var(--card-foreground))"
|
|
73
|
-
},
|
|
74
|
-
popover: {
|
|
75
|
-
DEFAULT: "hsl(var(--popover))",
|
|
76
|
-
foreground: "hsl(var(--popover-foreground))"
|
|
77
|
-
},
|
|
78
|
-
// Layout surface tokens
|
|
79
|
-
sidebar: {
|
|
80
|
-
DEFAULT: "hsl(var(--sidebar))",
|
|
81
|
-
foreground: "hsl(var(--sidebar-foreground))",
|
|
82
|
-
border: "hsl(var(--sidebar-border))",
|
|
83
|
-
accent: "hsl(var(--sidebar-accent))",
|
|
84
|
-
"accent-foreground": "hsl(var(--sidebar-accent-foreground))",
|
|
85
|
-
muted: "hsl(var(--sidebar-muted))"
|
|
86
|
-
},
|
|
87
|
-
content: "hsl(var(--content))"
|
|
88
|
-
},
|
|
89
|
-
borderRadius: {
|
|
90
|
-
button: "var(--button-radius)",
|
|
91
|
-
card: "var(--card-radius)",
|
|
92
|
-
input: "var(--input-radius)",
|
|
93
|
-
modal: "var(--modal-radius)"
|
|
94
|
-
},
|
|
95
|
-
fontFamily: {
|
|
96
|
-
sans: ["var(--font-family)"],
|
|
97
|
-
mono: ["var(--font-family-mono)"]
|
|
98
|
-
},
|
|
99
|
-
boxShadow: {
|
|
100
|
-
sm: "var(--shadow-sm)",
|
|
101
|
-
md: "var(--shadow-md)",
|
|
102
|
-
lg: "var(--shadow-lg)",
|
|
103
|
-
button: "var(--shadow-button)",
|
|
104
|
-
"button-primary": "var(--shadow-button-primary)",
|
|
105
|
-
"button-inset": "var(--shadow-button-inset)"
|
|
106
|
-
},
|
|
107
|
-
keyframes: {
|
|
108
|
-
"fade-in": {
|
|
109
|
-
from: { opacity: "0" },
|
|
110
|
-
to: { opacity: "1" }
|
|
111
|
-
},
|
|
112
|
-
"fade-out": {
|
|
113
|
-
from: { opacity: "1" },
|
|
114
|
-
to: { opacity: "0" }
|
|
115
|
-
},
|
|
116
|
-
"zoom-in": {
|
|
117
|
-
from: { transform: "scale(0.95)", opacity: "0" },
|
|
118
|
-
to: { transform: "scale(1)", opacity: "1" }
|
|
119
|
-
},
|
|
120
|
-
"zoom-out": {
|
|
121
|
-
from: { transform: "scale(1)", opacity: "1" },
|
|
122
|
-
to: { transform: "scale(0.95)", opacity: "0" }
|
|
123
|
-
},
|
|
124
|
-
"slide-in-from-top": {
|
|
125
|
-
from: { transform: "translateY(-4px)", opacity: "0" },
|
|
126
|
-
to: { transform: "translateY(0)", opacity: "1" }
|
|
127
|
-
},
|
|
128
|
-
"slide-in-from-bottom": {
|
|
129
|
-
from: { transform: "translateY(4px)", opacity: "0" },
|
|
130
|
-
to: { transform: "translateY(0)", opacity: "1" }
|
|
131
|
-
},
|
|
132
|
-
"slide-out-to-top": {
|
|
133
|
-
from: { transform: "translateY(0)", opacity: "1" },
|
|
134
|
-
to: { transform: "translateY(-4px)", opacity: "0" }
|
|
135
|
-
},
|
|
136
|
-
"page-in": {
|
|
137
|
-
from: { opacity: "0", transform: "translateY(6px)" },
|
|
138
|
-
to: { opacity: "1", transform: "translateY(0)" }
|
|
139
|
-
},
|
|
140
|
-
"slide-in-from-right": {
|
|
141
|
-
from: { transform: "translateX(100%)" },
|
|
142
|
-
to: { transform: "translateX(0)" }
|
|
143
|
-
},
|
|
144
|
-
"slide-out-to-right": {
|
|
145
|
-
from: { transform: "translateX(0)" },
|
|
146
|
-
to: { transform: "translateX(100%)" }
|
|
147
|
-
},
|
|
148
|
-
"fade-up": {
|
|
149
|
-
from: { opacity: "0", transform: "translateY(18px)" },
|
|
150
|
-
to: { opacity: "1", transform: "translateY(0)" }
|
|
151
|
-
},
|
|
152
|
-
kenburns: {
|
|
153
|
-
from: { transform: "scale(1)" },
|
|
154
|
-
to: { transform: "scale(1.07)" }
|
|
155
|
-
},
|
|
156
|
-
"badge-pop": {
|
|
157
|
-
"0%": { transform: "scale(0.6)" },
|
|
158
|
-
"60%": { transform: "scale(1.25)" },
|
|
159
|
-
"100%": { transform: "scale(1)" }
|
|
160
|
-
},
|
|
161
|
-
"draw-check": {
|
|
162
|
-
from: { "stroke-dashoffset": "48" },
|
|
163
|
-
to: { "stroke-dashoffset": "0" }
|
|
164
|
-
},
|
|
165
|
-
"pop-in": {
|
|
166
|
-
"0%": { transform: "scale(0)", opacity: "0" },
|
|
167
|
-
"70%": { transform: "scale(1.15)", opacity: "1" },
|
|
168
|
-
"100%": { transform: "scale(1)", opacity: "1" }
|
|
169
|
-
},
|
|
170
|
-
"confetti-fall": {
|
|
171
|
-
"0%": { transform: "translateY(-10px) rotate(0deg)", opacity: "1" },
|
|
172
|
-
"100%": { transform: "translateY(140px) rotate(540deg)", opacity: "0" }
|
|
173
|
-
},
|
|
174
|
-
"pulse-soft": {
|
|
175
|
-
"0%, 100%": { opacity: "1" },
|
|
176
|
-
"50%": { opacity: "0.55" }
|
|
177
|
-
}
|
|
178
|
-
},
|
|
179
|
-
animation: {
|
|
180
|
-
"fade-in": "fade-in 200ms ease-out",
|
|
181
|
-
"fade-out": "fade-out 150ms ease-in",
|
|
182
|
-
"zoom-in": "zoom-in 200ms ease-out",
|
|
183
|
-
"zoom-out": "zoom-out 150ms ease-in",
|
|
184
|
-
"slide-in-from-top": "slide-in-from-top 200ms ease-out",
|
|
185
|
-
"slide-in-from-bottom": "slide-in-from-bottom 200ms ease-out",
|
|
186
|
-
"slide-out-to-top": "slide-out-to-top 150ms ease-in",
|
|
187
|
-
"slide-in-from-right": "slide-in-from-right 250ms cubic-bezier(0.16, 1, 0.3, 1)",
|
|
188
|
-
"slide-out-to-right": "slide-out-to-right 200ms ease-in",
|
|
189
|
-
"page-in": "page-in 250ms ease-out",
|
|
190
|
-
"fade-up": "fade-up 600ms cubic-bezier(0.16, 1, 0.3, 1) both",
|
|
191
|
-
kenburns: "kenburns 9s ease-out both",
|
|
192
|
-
"badge-pop": "badge-pop 350ms cubic-bezier(0.34, 1.56, 0.64, 1)",
|
|
193
|
-
"draw-check": "draw-check 600ms ease-out 250ms both",
|
|
194
|
-
"pop-in": "pop-in 450ms cubic-bezier(0.34, 1.56, 0.64, 1) both",
|
|
195
|
-
"confetti-fall": "confetti-fall 1100ms ease-in both",
|
|
196
|
-
"pulse-soft": "pulse-soft 1.6s ease-in-out infinite"
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
var preset_default = fayzUiPreset;
|
|
202
|
-
|
|
203
|
-
exports.fayzUiPreset = fayzUiPreset;
|
|
204
|
-
exports.preset_default = preset_default;
|
|
205
|
-
//# sourceMappingURL=chunk-2P7T6QQK.cjs.map
|
|
206
|
-
//# sourceMappingURL=chunk-2P7T6QQK.cjs.map
|