@craftzbay/ui 0.5.0 → 0.6.0
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-lib/components/patterns/AppShell.d.ts +142 -4
- package/dist-lib/components/ui/EmptyState.d.ts +22 -7
- package/dist-lib/components/ui/ErrorState.d.ts +15 -4
- package/dist-lib/index.cjs +2 -2
- package/dist-lib/index.cjs.map +1 -1
- package/dist-lib/index.js +1075 -985
- package/dist-lib/index.js.map +1 -1
- package/dist-lib/showcase/guides/DarkMode.d.ts +1 -0
- package/dist-lib/showcase/guides/Forms.d.ts +1 -0
- package/dist-lib/showcase/guides/Responsive.d.ts +1 -0
- package/dist-lib/showcase/guides/Theming.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,12 +1,150 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Legacy nav keys retained for back-compat. The `active` prop now accepts
|
|
4
|
+
* any string — these are kept as a typed alias for consumers that hard-code
|
|
5
|
+
* one of the original demo values.
|
|
6
|
+
*/
|
|
2
7
|
export type AppShellNavKey = 'home' | 'projects' | 'inbox' | 'members' | 'insights' | 'bookmarks' | 'apps' | 'settings' | 'integrations' | 'help';
|
|
8
|
+
export interface AppShellNavItem {
|
|
9
|
+
/** Active-state identifier — matches AppShell's `active` prop. */
|
|
10
|
+
key: string;
|
|
11
|
+
label: ReactNode;
|
|
12
|
+
/** Leading icon. */
|
|
13
|
+
icon?: ReactNode;
|
|
14
|
+
/** Destination. Renders as <a href>; for SPAs intercept onClick. */
|
|
15
|
+
href?: string;
|
|
16
|
+
/** Right-aligned content (Badge, count). */
|
|
17
|
+
trailing?: ReactNode;
|
|
18
|
+
/** Optional click handler. */
|
|
19
|
+
onClick?: () => void;
|
|
20
|
+
}
|
|
21
|
+
export interface AppShellNavSection {
|
|
22
|
+
/** Section heading shown above the items. */
|
|
23
|
+
label?: ReactNode;
|
|
24
|
+
items: AppShellNavItem[];
|
|
25
|
+
}
|
|
26
|
+
export interface AppShellUser {
|
|
27
|
+
name: ReactNode;
|
|
28
|
+
email?: ReactNode;
|
|
29
|
+
/** 1–2 char initials for the Avatar fallback. */
|
|
30
|
+
initials: string;
|
|
31
|
+
/** Online status — drives the Avatar status dot. */
|
|
32
|
+
status?: 'online' | 'busy' | 'away' | 'offline';
|
|
33
|
+
}
|
|
34
|
+
export interface AppShellNotification {
|
|
35
|
+
id: string;
|
|
36
|
+
who: {
|
|
37
|
+
name: string;
|
|
38
|
+
initials: string;
|
|
39
|
+
};
|
|
40
|
+
action: ReactNode;
|
|
41
|
+
target: ReactNode;
|
|
42
|
+
when: ReactNode;
|
|
43
|
+
unread?: boolean;
|
|
44
|
+
onClick?: () => void;
|
|
45
|
+
}
|
|
46
|
+
export interface AppShellProfileMenuItem {
|
|
47
|
+
label: ReactNode;
|
|
48
|
+
icon?: ReactNode;
|
|
49
|
+
trailing?: ReactNode;
|
|
50
|
+
onSelect?: () => void;
|
|
51
|
+
/** Renders a separator before this item. */
|
|
52
|
+
separatorAbove?: boolean;
|
|
53
|
+
}
|
|
3
54
|
export interface AppShellProps {
|
|
4
55
|
/** Page content. */
|
|
5
56
|
children: ReactNode;
|
|
6
57
|
/** Logo / wordmark rendered at the top of the sidebar. */
|
|
7
58
|
brand: ReactNode;
|
|
8
|
-
/** Which sidebar item is active. Defaults to `home`. */
|
|
9
|
-
active?:
|
|
59
|
+
/** Which sidebar item is active. Matches `AppShellNavItem.key`. Defaults to `'home'`. */
|
|
60
|
+
active?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Sidebar nav sections. Defaults to the built-in demo nav. Pass an empty
|
|
63
|
+
* array to hide the nav entirely, or use `sidebar` for a fully custom rail.
|
|
64
|
+
*/
|
|
65
|
+
navSections?: AppShellNavSection[];
|
|
66
|
+
/**
|
|
67
|
+
* Escape hatch: replace the entire Sidebar contents. Takes precedence over
|
|
68
|
+
* `navSections`. Use when you need custom section components, groups, etc.
|
|
69
|
+
*/
|
|
70
|
+
sidebar?: ReactNode;
|
|
71
|
+
/** Slot for additional topbar actions (left of notifications). */
|
|
72
|
+
topbarActions?: ReactNode;
|
|
73
|
+
/** Topbar search input — pass `false` to hide. */
|
|
74
|
+
search?: ReactNode | false;
|
|
75
|
+
/** Currently signed-in user, shown in the sidebar footer + profile menu. */
|
|
76
|
+
user?: AppShellUser;
|
|
77
|
+
/** Profile dropdown items. Defaults to the demo Profile / Settings / Sign out menu. */
|
|
78
|
+
profileMenu?: AppShellProfileMenuItem[];
|
|
79
|
+
/** Notification feed. Set to an empty array to hide the bell entirely. */
|
|
80
|
+
notifications?: AppShellNotification[];
|
|
81
|
+
/** Fires when the user clicks "Mark all read". */
|
|
82
|
+
onMarkAllNotificationsRead?: () => void;
|
|
83
|
+
/** Fires when the user clicks "View all" in the notifications menu. */
|
|
84
|
+
onViewAllNotifications?: () => void;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* AppShell — sticky sidebar + topbar shell for SaaS dashboards.
|
|
88
|
+
*
|
|
89
|
+
* @example Default — uses the built-in demo nav, user, notifications
|
|
90
|
+
* <AppShell brand={<Logo />} active="home">
|
|
91
|
+
* <Dashboard />
|
|
92
|
+
* </AppShell>
|
|
93
|
+
*
|
|
94
|
+
* @example Custom nav + user
|
|
95
|
+
* <AppShell
|
|
96
|
+
* brand={<Logo />}
|
|
97
|
+
* active="projects"
|
|
98
|
+
* user={{ name: 'Avery Long', email: 'avery@acme.com', initials: 'AL', status: 'online' }}
|
|
99
|
+
* navSections={[
|
|
100
|
+
* { label: 'Workspace', items: [
|
|
101
|
+
* { key: 'home', label: 'Home', icon: <Home />, href: '/' },
|
|
102
|
+
* { key: 'projects', label: 'Projects', icon: <Folder />, href: '/projects',
|
|
103
|
+
* trailing: <Badge tone="neutral">{count}</Badge> },
|
|
104
|
+
* ]},
|
|
105
|
+
* ]}
|
|
106
|
+
* notifications={data?.notifications ?? []}
|
|
107
|
+
* >
|
|
108
|
+
* <ProjectsPage />
|
|
109
|
+
* </AppShell>
|
|
110
|
+
*/
|
|
111
|
+
export declare function AppShell({ children, brand, active, navSections, sidebar, topbarActions, search, user, profileMenu, notifications, onMarkAllNotificationsRead, onViewAllNotifications, }: AppShellProps): import("react/jsx-runtime").JSX.Element;
|
|
112
|
+
export interface DashboardStat {
|
|
113
|
+
label: ReactNode;
|
|
114
|
+
value: ReactNode;
|
|
115
|
+
delta?: {
|
|
116
|
+
value: string;
|
|
117
|
+
positive?: boolean;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export interface DashboardActivityRow {
|
|
121
|
+
id: string;
|
|
122
|
+
who: {
|
|
123
|
+
name: string;
|
|
124
|
+
initials: string;
|
|
125
|
+
};
|
|
126
|
+
action: ReactNode;
|
|
127
|
+
target: ReactNode;
|
|
128
|
+
when: ReactNode;
|
|
129
|
+
}
|
|
130
|
+
export interface DashboardProps {
|
|
131
|
+
/** Top heading. */
|
|
132
|
+
title?: ReactNode;
|
|
133
|
+
/** Subtitle below the heading. */
|
|
134
|
+
subtitle?: ReactNode;
|
|
135
|
+
/** Top-right slot (date-range picker, segmented control, …). */
|
|
136
|
+
headerActions?: ReactNode;
|
|
137
|
+
/** Stat cards rendered in a responsive grid. */
|
|
138
|
+
stats?: DashboardStat[];
|
|
139
|
+
/** Chart card — any ReactNode (Chart component, SVG, image, placeholder). */
|
|
140
|
+
chart?: ReactNode;
|
|
141
|
+
/** Title above the chart. */
|
|
142
|
+
chartTitle?: ReactNode;
|
|
143
|
+
/** Subtitle under the chart title. */
|
|
144
|
+
chartDescription?: ReactNode;
|
|
145
|
+
/** Activity table rows. */
|
|
146
|
+
activity?: DashboardActivityRow[];
|
|
147
|
+
/** Title for the activity table. */
|
|
148
|
+
activityTitle?: ReactNode;
|
|
10
149
|
}
|
|
11
|
-
export declare function
|
|
12
|
-
export declare function Dashboard(): import("react/jsx-runtime").JSX.Element;
|
|
150
|
+
export declare function Dashboard({ title, subtitle, headerActions, stats, chart, chartTitle, chartDescription, activity, activityTitle, }?: DashboardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
2
|
export interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Small Lucide-sized icon rendered inside a 48px circular container.
|
|
5
|
+
* Use for compact empty states (table cells, sidebar panes, cards).
|
|
6
|
+
*/
|
|
4
7
|
icon?: ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Full-size illustration rendered without the icon container. Takes
|
|
10
|
+
* precedence over `icon`. If neither is set, the default `InboxEmpty`
|
|
11
|
+
* line illustration is used.
|
|
12
|
+
*/
|
|
13
|
+
illustration?: ReactNode;
|
|
5
14
|
/** Heading. One short sentence. */
|
|
6
15
|
title: ReactNode;
|
|
7
16
|
/** Description. One or two sentences max. */
|
|
@@ -15,17 +24,23 @@ export interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 't
|
|
|
15
24
|
* Shown when a list / dataset / surface has no content yet. Tone is helpful,
|
|
16
25
|
* never apologetic.
|
|
17
26
|
*
|
|
18
|
-
* @example
|
|
27
|
+
* @example Default — uses the built-in InboxEmpty illustration
|
|
19
28
|
* <EmptyState
|
|
20
|
-
* icon={<Folder className="size-6" />}
|
|
21
29
|
* title="No projects yet"
|
|
22
30
|
* description="Create a project to start tracking work."
|
|
23
31
|
* action={<Button>New project</Button>}
|
|
24
32
|
* />
|
|
25
33
|
*
|
|
26
|
-
* @
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
34
|
+
* @example Compact — small Lucide icon for dense layouts
|
|
35
|
+
* <EmptyState
|
|
36
|
+
* icon={<Folder className="size-6" />}
|
|
37
|
+
* title="No items"
|
|
38
|
+
* />
|
|
39
|
+
*
|
|
40
|
+
* @example Custom illustration
|
|
41
|
+
* <EmptyState
|
|
42
|
+
* illustration={<Illustrations.NoSearchResults className="size-32" />}
|
|
43
|
+
* title="No results"
|
|
44
|
+
* />
|
|
30
45
|
*/
|
|
31
46
|
export declare const EmptyState: import('react').ForwardRefExoticComponent<EmptyStateProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -6,6 +6,11 @@ export interface ErrorStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 't
|
|
|
6
6
|
title?: ReactNode;
|
|
7
7
|
/** Override the default description. */
|
|
8
8
|
description?: ReactNode;
|
|
9
|
+
/**
|
|
10
|
+
* Override the variant's default illustration. Pass any ReactNode (e.g.
|
|
11
|
+
* `<Illustrations.Construction className="size-32" />`).
|
|
12
|
+
*/
|
|
13
|
+
illustration?: ReactNode;
|
|
9
14
|
/** Custom action node. Replaces the default retry button. */
|
|
10
15
|
action?: ReactNode;
|
|
11
16
|
/** When provided, renders a default "Try again" button calling this handler. */
|
|
@@ -14,13 +19,19 @@ export interface ErrorStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 't
|
|
|
14
19
|
/**
|
|
15
20
|
* Page-level error placeholder. Pair with `onRetry` for transient failures.
|
|
16
21
|
*
|
|
17
|
-
* @example
|
|
22
|
+
* @example 404 (uses built-in line illustration)
|
|
23
|
+
* <ErrorState variant="404" />
|
|
24
|
+
*
|
|
25
|
+
* @example 500 with retry
|
|
18
26
|
* <ErrorState variant="500" onRetry={refetch} />
|
|
19
27
|
*
|
|
20
28
|
* @example Custom
|
|
21
|
-
* <ErrorState
|
|
22
|
-
*
|
|
23
|
-
*
|
|
29
|
+
* <ErrorState
|
|
30
|
+
* title="Quota exceeded"
|
|
31
|
+
* description="Your plan allows 1,000 events/day."
|
|
32
|
+
* illustration={<Illustrations.Construction className="size-32" />}
|
|
33
|
+
* action={<Button>Upgrade plan</Button>}
|
|
34
|
+
* />
|
|
24
35
|
*
|
|
25
36
|
* @do Match the tone to the cause — server errors apologise, user errors
|
|
26
37
|
* explain. Always offer a next step.
|