@classytic/fluid 0.1.1
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/README.md +62 -0
- package/dist/dashboard.d.ts +349 -0
- package/dist/dashboard.js +992 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/index.d.ts +2046 -0
- package/dist/index.js +6968 -0
- package/dist/index.js.map +1 -0
- package/dist/layout.d.ts +25 -0
- package/dist/layout.js +62 -0
- package/dist/layout.js.map +1 -0
- package/dist/utils-Cbsgs0XP.d.ts +5 -0
- package/package.json +111 -0
- package/styles.css +12 -0
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# @classytic/fluid
|
|
2
|
+
|
|
3
|
+
Reusable UI components built on shadcn/ui for Next.js projects.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @classytic/fluid
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { DialogWrapper, FormInput, DataTable } from "@classytic/fluid";
|
|
15
|
+
import { PageHeader, InsetSidebar } from "@classytic/fluid/dashboard";
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Components
|
|
19
|
+
|
|
20
|
+
| Category | Components |
|
|
21
|
+
|----------|-----------|
|
|
22
|
+
| **Dialogs/Sheets** | DialogWrapper, FormDialog, SheetWrapper, FormSheet, ConfirmDialog |
|
|
23
|
+
| **Forms** | FormInput, FormTextarea, SelectInput, CheckboxInput, RadioInput, SwitchInput, DateInput, TagInput, ComboboxInput, SlugField, FormErrorSummary, DateRangeFilter |
|
|
24
|
+
| **Tables** | DataTable, TableWrapper, SimpleTable |
|
|
25
|
+
| **Layout** | CardWrapper, CollapsibleWrapper, ResponsiveSplitLayout, TabsWrapper |
|
|
26
|
+
| **Display** | Pill, InfoRow, CopyButton, Thumbnail, DisplayHeading |
|
|
27
|
+
| **Navigation** | ApiPagination, CustomPagination |
|
|
28
|
+
| **Dashboard** | PageHeader, HeaderSection, InsetSidebar, DualSidebar, ProjectSwitcher, SidebarNav, SidebarUserMenu |
|
|
29
|
+
| **Other** | ModeToggle, TooltipWrapper, DropdownWrapper, AccordionWrapper |
|
|
30
|
+
|
|
31
|
+
## Exports
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
// Main components
|
|
35
|
+
import { ... } from "@classytic/fluid";
|
|
36
|
+
|
|
37
|
+
// Dashboard components (sidebar, header)
|
|
38
|
+
import { ... } from "@classytic/fluid/dashboard";
|
|
39
|
+
|
|
40
|
+
// Layout utilities
|
|
41
|
+
import { ... } from "@classytic/fluid/layout";
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Requirements
|
|
45
|
+
|
|
46
|
+
- Next.js with `@/` path alias
|
|
47
|
+
- shadcn/ui components at `@/components/ui/*`
|
|
48
|
+
|
|
49
|
+
## Dev
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm run build # Build package
|
|
53
|
+
npm run dev # Watch mode
|
|
54
|
+
```
|
|
55
|
+
## License
|
|
56
|
+
|
|
57
|
+
**UNLICENSED**
|
|
58
|
+
|
|
59
|
+
Copyright © 2026 Classytic. All rights reserved.
|
|
60
|
+
|
|
61
|
+
This software is the confidential and proprietary information of Classytic.
|
|
62
|
+
Unauthorized copying of this software, via any medium is strictly prohibited.
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import React__default, { ReactNode } from 'react';
|
|
5
|
+
export { c as cn } from './utils-Cbsgs0XP.js';
|
|
6
|
+
import 'clsx';
|
|
7
|
+
|
|
8
|
+
interface HeaderAction {
|
|
9
|
+
text: string;
|
|
10
|
+
onClick?: () => void;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link";
|
|
13
|
+
size?: "default" | "sm" | "lg" | "icon";
|
|
14
|
+
className?: string;
|
|
15
|
+
icon?: LucideIcon;
|
|
16
|
+
iconPosition?: "left" | "right";
|
|
17
|
+
loadingText?: string;
|
|
18
|
+
loading?: boolean;
|
|
19
|
+
}
|
|
20
|
+
interface HeaderBadge {
|
|
21
|
+
text: string;
|
|
22
|
+
variant?: "default" | "secondary" | "destructive" | "outline";
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
interface HeaderMetadata {
|
|
26
|
+
text: string;
|
|
27
|
+
icon?: LucideIcon;
|
|
28
|
+
}
|
|
29
|
+
interface HeaderSectionProps {
|
|
30
|
+
title?: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
actions?: HeaderAction[] | null;
|
|
33
|
+
icon?: LucideIcon | null;
|
|
34
|
+
iconClassName?: string;
|
|
35
|
+
loading?: boolean;
|
|
36
|
+
variant?: "default" | "compact" | "hero" | "minimal";
|
|
37
|
+
className?: string;
|
|
38
|
+
badge?: HeaderBadge | ReactNode;
|
|
39
|
+
breadcrumbs?: ReactNode;
|
|
40
|
+
metadata?: HeaderMetadata[];
|
|
41
|
+
children?: ReactNode;
|
|
42
|
+
}
|
|
43
|
+
declare function HeaderSection({ title, description, actions, icon: Icon, iconClassName, loading, variant, className, badge, breadcrumbs, metadata, children, }: HeaderSectionProps): react_jsx_runtime.JSX.Element;
|
|
44
|
+
|
|
45
|
+
interface BreadcrumbItemData {
|
|
46
|
+
label: string;
|
|
47
|
+
href?: string;
|
|
48
|
+
current?: boolean;
|
|
49
|
+
}
|
|
50
|
+
interface PageHeaderProps {
|
|
51
|
+
items: BreadcrumbItemData[];
|
|
52
|
+
className?: string;
|
|
53
|
+
actions?: React__default.ReactNode;
|
|
54
|
+
}
|
|
55
|
+
declare function PageHeader({ items, className, actions }: PageHeaderProps): react_jsx_runtime.JSX.Element;
|
|
56
|
+
|
|
57
|
+
interface SidebarBrandProps {
|
|
58
|
+
/** Brand title text */
|
|
59
|
+
title: string;
|
|
60
|
+
/** Brand icon/logo element */
|
|
61
|
+
icon: React.ReactNode;
|
|
62
|
+
/** Link href (defaults to "/") */
|
|
63
|
+
href?: string;
|
|
64
|
+
/** Additional className */
|
|
65
|
+
className?: string;
|
|
66
|
+
/** Tooltip text when collapsed (defaults to title) */
|
|
67
|
+
tooltip?: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* SidebarBrand - Logo and title section for dashboard sidebar.
|
|
71
|
+
* Automatically handles collapsed state styling.
|
|
72
|
+
*/
|
|
73
|
+
declare function SidebarBrand({ title, icon, href, className, tooltip, }: SidebarBrandProps): react_jsx_runtime.JSX.Element;
|
|
74
|
+
|
|
75
|
+
interface NavSubItem {
|
|
76
|
+
title: string;
|
|
77
|
+
url: string;
|
|
78
|
+
badge?: string | number;
|
|
79
|
+
}
|
|
80
|
+
interface NavItem {
|
|
81
|
+
title: string;
|
|
82
|
+
url: string;
|
|
83
|
+
icon?: LucideIcon;
|
|
84
|
+
isActive?: boolean;
|
|
85
|
+
badge?: string | number;
|
|
86
|
+
items?: NavSubItem[];
|
|
87
|
+
}
|
|
88
|
+
interface NavGroup {
|
|
89
|
+
title?: string;
|
|
90
|
+
items: NavItem[];
|
|
91
|
+
}
|
|
92
|
+
interface SidebarNavProps {
|
|
93
|
+
/** Navigation groups to render */
|
|
94
|
+
groups: NavGroup[];
|
|
95
|
+
/** Additional className */
|
|
96
|
+
className?: string;
|
|
97
|
+
/** Callback when a nav item is clicked */
|
|
98
|
+
onItemClick?: (item: NavItem) => void;
|
|
99
|
+
}
|
|
100
|
+
interface SidebarNavGroupProps {
|
|
101
|
+
/** Group title (optional) */
|
|
102
|
+
title?: string;
|
|
103
|
+
/** Navigation items in this group */
|
|
104
|
+
items: NavItem[];
|
|
105
|
+
/** Additional className */
|
|
106
|
+
className?: string;
|
|
107
|
+
/** Callback when an item is clicked */
|
|
108
|
+
onItemClick?: (item: NavItem) => void;
|
|
109
|
+
}
|
|
110
|
+
interface SidebarNavItemProps {
|
|
111
|
+
/** The navigation item data */
|
|
112
|
+
item: NavItem;
|
|
113
|
+
/** Callback when clicked */
|
|
114
|
+
onClick?: () => void;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* SidebarNavItem - Single navigation item with optional sub-items.
|
|
118
|
+
*/
|
|
119
|
+
declare function SidebarNavItem({ item, onClick }: SidebarNavItemProps): react_jsx_runtime.JSX.Element;
|
|
120
|
+
/**
|
|
121
|
+
* SidebarNavGroup - A group of navigation items with optional title.
|
|
122
|
+
*/
|
|
123
|
+
declare function SidebarNavGroup({ title, items, className, onItemClick, }: SidebarNavGroupProps): react_jsx_runtime.JSX.Element;
|
|
124
|
+
/**
|
|
125
|
+
* SidebarNav - Complete navigation section with multiple groups.
|
|
126
|
+
*/
|
|
127
|
+
declare function SidebarNav({ groups, className, onItemClick }: SidebarNavProps): react_jsx_runtime.JSX.Element;
|
|
128
|
+
|
|
129
|
+
interface UserData {
|
|
130
|
+
name: string;
|
|
131
|
+
email: string;
|
|
132
|
+
avatar?: string;
|
|
133
|
+
}
|
|
134
|
+
interface UserMenuItem {
|
|
135
|
+
label: string;
|
|
136
|
+
icon?: LucideIcon;
|
|
137
|
+
href?: string;
|
|
138
|
+
onClick?: () => void;
|
|
139
|
+
separator?: boolean;
|
|
140
|
+
}
|
|
141
|
+
interface SidebarUserMenuProps {
|
|
142
|
+
/** User data to display */
|
|
143
|
+
user: UserData;
|
|
144
|
+
/** Menu items (account, settings, etc.) */
|
|
145
|
+
menuItems?: UserMenuItem[];
|
|
146
|
+
/** Logout handler */
|
|
147
|
+
onLogout?: () => void;
|
|
148
|
+
/** Additional className */
|
|
149
|
+
className?: string;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* SidebarUserMenu - User avatar and dropdown menu for sidebar footer.
|
|
153
|
+
* Accepts handlers for logout and custom menu items.
|
|
154
|
+
*/
|
|
155
|
+
declare function SidebarUserMenu({ user, menuItems, onLogout, className, }: SidebarUserMenuProps): react_jsx_runtime.JSX.Element;
|
|
156
|
+
|
|
157
|
+
interface ProjectItem {
|
|
158
|
+
/** Unique identifier */
|
|
159
|
+
id: string;
|
|
160
|
+
/** Display name */
|
|
161
|
+
name: string;
|
|
162
|
+
/** Short code or identifier */
|
|
163
|
+
code?: string;
|
|
164
|
+
/** Optional type badge */
|
|
165
|
+
type?: string;
|
|
166
|
+
/** Is this the default project */
|
|
167
|
+
isDefault?: boolean;
|
|
168
|
+
/** Is this project active */
|
|
169
|
+
isActive?: boolean;
|
|
170
|
+
/** Optional subtitle/description */
|
|
171
|
+
subtitle?: string;
|
|
172
|
+
}
|
|
173
|
+
interface ProjectSwitcherProps {
|
|
174
|
+
/** List of available projects */
|
|
175
|
+
items: ProjectItem[];
|
|
176
|
+
/** Currently selected project */
|
|
177
|
+
selected?: ProjectItem;
|
|
178
|
+
/** Callback when a project is selected */
|
|
179
|
+
onSelect: (project: ProjectItem) => void;
|
|
180
|
+
/** Whether the data is loading */
|
|
181
|
+
isLoading?: boolean;
|
|
182
|
+
/** Label shown in dropdown header */
|
|
183
|
+
label?: string;
|
|
184
|
+
/** Icon to display (defaults to Building2) */
|
|
185
|
+
icon?: LucideIcon;
|
|
186
|
+
/** Additional className */
|
|
187
|
+
className?: string;
|
|
188
|
+
/** Whether to show as disabled (single item) */
|
|
189
|
+
disabled?: boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Render variant:
|
|
192
|
+
* - "sidebar": Uses SidebarMenu components, requires SidebarProvider context
|
|
193
|
+
* - "standalone": Uses Button, works anywhere (headers, toolbars, etc.)
|
|
194
|
+
*/
|
|
195
|
+
variant?: "sidebar" | "standalone";
|
|
196
|
+
/** Size for standalone variant (ignored in sidebar variant) */
|
|
197
|
+
size?: "sm" | "default";
|
|
198
|
+
/** Render custom item content */
|
|
199
|
+
renderItem?: (item: ProjectItem, isSelected: boolean) => React.ReactNode;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* ProjectSwitcher - Generic project/workspace/branch switcher.
|
|
203
|
+
* Works for any entity that needs switching functionality.
|
|
204
|
+
*
|
|
205
|
+
* @example Sidebar usage (inside SidebarProvider)
|
|
206
|
+
* ```tsx
|
|
207
|
+
* <ProjectSwitcher
|
|
208
|
+
* items={projects}
|
|
209
|
+
* selected={selectedProject}
|
|
210
|
+
* onSelect={setSelectedProject}
|
|
211
|
+
* />
|
|
212
|
+
* ```
|
|
213
|
+
*
|
|
214
|
+
* @example Header/Standalone usage (no SidebarProvider needed)
|
|
215
|
+
* ```tsx
|
|
216
|
+
* <ProjectSwitcher
|
|
217
|
+
* variant="standalone"
|
|
218
|
+
* items={projects}
|
|
219
|
+
* selected={selectedProject}
|
|
220
|
+
* onSelect={setSelectedProject}
|
|
221
|
+
* size="sm"
|
|
222
|
+
* />
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
declare function ProjectSwitcher({ items, selected, onSelect, isLoading, label, icon: Icon, className, disabled, variant, size, renderItem, }: ProjectSwitcherProps): react_jsx_runtime.JSX.Element | null;
|
|
226
|
+
|
|
227
|
+
interface BreadcrumbItem {
|
|
228
|
+
label: string;
|
|
229
|
+
href?: string;
|
|
230
|
+
current?: boolean;
|
|
231
|
+
}
|
|
232
|
+
interface DashboardHeaderProps {
|
|
233
|
+
/** Breadcrumb items */
|
|
234
|
+
breadcrumbs?: BreadcrumbItem[];
|
|
235
|
+
/** Content to show on the left (after breadcrumbs) */
|
|
236
|
+
leftContent?: React.ReactNode;
|
|
237
|
+
/** Content to show on the right (actions, mode toggle, etc.) */
|
|
238
|
+
rightContent?: React.ReactNode;
|
|
239
|
+
/** Whether to show sidebar trigger */
|
|
240
|
+
showSidebarTrigger?: boolean;
|
|
241
|
+
/** Additional className */
|
|
242
|
+
className?: string;
|
|
243
|
+
/** Custom content (replaces default breadcrumb) */
|
|
244
|
+
children?: React.ReactNode;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* DashboardHeader - Top header bar for dashboard pages.
|
|
248
|
+
* Includes sidebar trigger, breadcrumbs, and action slots.
|
|
249
|
+
*/
|
|
250
|
+
declare function DashboardHeader({ breadcrumbs, leftContent, rightContent, showSidebarTrigger, className, children, }: DashboardHeaderProps): react_jsx_runtime.JSX.Element;
|
|
251
|
+
|
|
252
|
+
interface InsetSidebarBrand {
|
|
253
|
+
title: string;
|
|
254
|
+
icon: React.ReactNode;
|
|
255
|
+
href?: string;
|
|
256
|
+
}
|
|
257
|
+
interface InsetSidebarProject {
|
|
258
|
+
items: ProjectItem[];
|
|
259
|
+
selected?: ProjectItem;
|
|
260
|
+
onSelect: (project: ProjectItem) => void;
|
|
261
|
+
isLoading?: boolean;
|
|
262
|
+
label?: string;
|
|
263
|
+
icon?: LucideIcon;
|
|
264
|
+
}
|
|
265
|
+
interface InsetSidebarUser {
|
|
266
|
+
data: UserData;
|
|
267
|
+
menuItems?: UserMenuItem[];
|
|
268
|
+
onLogout?: () => void;
|
|
269
|
+
}
|
|
270
|
+
interface InsetSidebarProps {
|
|
271
|
+
/** Brand configuration */
|
|
272
|
+
brand: InsetSidebarBrand;
|
|
273
|
+
/** Navigation groups */
|
|
274
|
+
navigation: NavGroup[];
|
|
275
|
+
/** Secondary navigation (shown at bottom above user) */
|
|
276
|
+
secondaryNavigation?: NavGroup[];
|
|
277
|
+
/** Project/workspace switcher configuration */
|
|
278
|
+
project?: InsetSidebarProject;
|
|
279
|
+
/** User menu configuration */
|
|
280
|
+
user?: InsetSidebarUser;
|
|
281
|
+
/** Custom content to render in header (after brand/project switcher) */
|
|
282
|
+
headerContent?: React.ReactNode;
|
|
283
|
+
/** Accessibility label for the sidebar */
|
|
284
|
+
ariaLabel?: string;
|
|
285
|
+
/** Additional className */
|
|
286
|
+
className?: string;
|
|
287
|
+
/** Children to render in content area */
|
|
288
|
+
children?: React.ReactNode;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* InsetSidebar - Complete sidebar preset with inset variant.
|
|
292
|
+
* The standard dashboard sidebar with collapsible to icons.
|
|
293
|
+
*/
|
|
294
|
+
declare function InsetSidebar({ brand, navigation, secondaryNavigation, project, user, headerContent, ariaLabel, className, children, }: InsetSidebarProps): react_jsx_runtime.JSX.Element;
|
|
295
|
+
|
|
296
|
+
interface DualSidebarCategory {
|
|
297
|
+
/** Unique identifier */
|
|
298
|
+
id: string;
|
|
299
|
+
/** Display name */
|
|
300
|
+
name: string;
|
|
301
|
+
/** Category icon */
|
|
302
|
+
icon: LucideIcon;
|
|
303
|
+
/** Sub-items in this category */
|
|
304
|
+
items: DualSidebarItem[];
|
|
305
|
+
}
|
|
306
|
+
interface DualSidebarItem {
|
|
307
|
+
title: string;
|
|
308
|
+
url: string;
|
|
309
|
+
icon?: LucideIcon;
|
|
310
|
+
badge?: string | number;
|
|
311
|
+
isActive?: boolean;
|
|
312
|
+
}
|
|
313
|
+
interface DualSidebarBrand {
|
|
314
|
+
title: string;
|
|
315
|
+
icon: React.ReactNode;
|
|
316
|
+
href?: string;
|
|
317
|
+
}
|
|
318
|
+
interface DualSidebarUser {
|
|
319
|
+
data: UserData;
|
|
320
|
+
menuItems?: UserMenuItem[];
|
|
321
|
+
onLogout?: () => void;
|
|
322
|
+
}
|
|
323
|
+
interface DualSidebarProps {
|
|
324
|
+
/** Brand configuration */
|
|
325
|
+
brand: DualSidebarBrand;
|
|
326
|
+
/** Main categories with their items */
|
|
327
|
+
categories: DualSidebarCategory[];
|
|
328
|
+
/** User menu configuration */
|
|
329
|
+
user?: DualSidebarUser;
|
|
330
|
+
/** Initially active category ID */
|
|
331
|
+
defaultCategoryId?: string;
|
|
332
|
+
/** Callback when category changes */
|
|
333
|
+
onCategoryChange?: (categoryId: string) => void;
|
|
334
|
+
/** Whether the expanded panel starts collapsed */
|
|
335
|
+
defaultCollapsed?: boolean;
|
|
336
|
+
/** Rail color variant */
|
|
337
|
+
railVariant?: "default" | "dark" | "primary" | "muted";
|
|
338
|
+
/** Accessibility label */
|
|
339
|
+
ariaLabel?: string;
|
|
340
|
+
/** Additional className for outer container */
|
|
341
|
+
className?: string;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* DualSidebar - A sidebar with icon rail and collapsible expanded panel.
|
|
345
|
+
* Mimics the inset sidebar variant structure for consistent styling.
|
|
346
|
+
*/
|
|
347
|
+
declare function DualSidebar({ brand, categories, user, defaultCategoryId, onCategoryChange, defaultCollapsed, railVariant, ariaLabel, className, }: DualSidebarProps): react_jsx_runtime.JSX.Element;
|
|
348
|
+
|
|
349
|
+
export { type BreadcrumbItem, type BreadcrumbItemData, DashboardHeader, type DashboardHeaderProps, DualSidebar, type DualSidebarBrand, type DualSidebarCategory, type DualSidebarItem, type DualSidebarProps, type DualSidebarUser, type HeaderAction, type HeaderBadge, type HeaderMetadata, HeaderSection, type HeaderSectionProps, InsetSidebar, type InsetSidebarBrand, type InsetSidebarProject, type InsetSidebarProps, type InsetSidebarUser, type NavGroup, type NavItem, type NavSubItem, PageHeader, type PageHeaderProps, type ProjectItem, ProjectSwitcher, type ProjectSwitcherProps, SidebarBrand, type SidebarBrandProps, SidebarNav, SidebarNavGroup, type SidebarNavGroupProps, SidebarNavItem, type SidebarNavItemProps, type SidebarNavProps, SidebarUserMenu, type SidebarUserMenuProps, type UserData, type UserMenuItem };
|