@lp-labs/ui-components 0.0.0-stage → 1.0.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/CHANGELOG.md +41 -0
- package/LICENSE +21 -0
- package/README.md +256 -2
- package/dist/cjs/components/Accordion.d.ts +78 -0
- package/dist/cjs/components/Accordion.js +78 -0
- package/dist/cjs/components/AdvancedComponents.d.ts +353 -0
- package/dist/cjs/components/AdvancedComponents.js +353 -0
- package/dist/cjs/components/Alert.d.ts +102 -0
- package/dist/cjs/components/Alert.js +102 -0
- package/dist/cjs/components/Avatar.d.ts +89 -0
- package/dist/cjs/components/Avatar.js +89 -0
- package/dist/cjs/components/Badge.d.ts +57 -0
- package/dist/cjs/components/Badge.js +57 -0
- package/dist/cjs/components/Breadcrumb.d.ts +50 -0
- package/dist/cjs/components/Breadcrumb.js +50 -0
- package/dist/cjs/components/Button.d.ts +77 -0
- package/dist/cjs/components/Button.js +77 -0
- package/dist/cjs/components/ButtonVariants.d.ts +261 -0
- package/dist/cjs/components/ButtonVariants.js +261 -0
- package/dist/cjs/components/Card.d.ts +56 -0
- package/dist/cjs/components/Card.js +56 -0
- package/dist/cjs/components/CardVariants.d.ts +267 -0
- package/dist/cjs/components/CardVariants.js +267 -0
- package/dist/cjs/components/Checkbox.d.ts +50 -0
- package/dist/cjs/components/Checkbox.js +50 -0
- package/dist/cjs/components/Chip.d.ts +104 -0
- package/dist/cjs/components/Chip.js +104 -0
- package/dist/cjs/components/DataDisplayComponents.d.ts +275 -0
- package/dist/cjs/components/DataDisplayComponents.js +275 -0
- package/dist/cjs/components/Divider.d.ts +77 -0
- package/dist/cjs/components/Divider.js +77 -0
- package/dist/cjs/components/Drawer.d.ts +142 -0
- package/dist/cjs/components/Drawer.js +142 -0
- package/dist/cjs/components/Dropdown.d.ts +139 -0
- package/dist/cjs/components/Dropdown.js +139 -0
- package/dist/cjs/components/Form.d.ts +41 -0
- package/dist/cjs/components/Form.js +41 -0
- package/dist/cjs/components/FormGroup.d.ts +58 -0
- package/dist/cjs/components/FormGroup.js +58 -0
- package/dist/cjs/components/FormInputVariants.d.ts +298 -0
- package/dist/cjs/components/FormInputVariants.js +298 -0
- package/dist/cjs/components/Image.d.ts +106 -0
- package/dist/cjs/components/Image.js +106 -0
- package/dist/cjs/components/Input.d.ts +65 -0
- package/dist/cjs/components/Input.js +65 -0
- package/dist/cjs/components/LayoutComponents.d.ts +258 -0
- package/dist/cjs/components/LayoutComponents.js +258 -0
- package/dist/cjs/components/Link.d.ts +71 -0
- package/dist/cjs/components/Link.js +71 -0
- package/dist/cjs/components/LoadingFeedbackComponents.d.ts +230 -0
- package/dist/cjs/components/LoadingFeedbackComponents.js +230 -0
- package/dist/cjs/components/Menu.d.ts +167 -0
- package/dist/cjs/components/Menu.js +167 -0
- package/dist/cjs/components/Modal.d.ts +145 -0
- package/dist/cjs/components/Modal.js +145 -0
- package/dist/cjs/components/ModalTypes.d.ts +288 -0
- package/dist/cjs/components/ModalTypes.js +288 -0
- package/dist/cjs/components/Navbar.d.ts +181 -0
- package/dist/cjs/components/Navbar.js +181 -0
- package/dist/cjs/components/NavigationComponents.d.ts +276 -0
- package/dist/cjs/components/NavigationComponents.js +276 -0
- package/dist/cjs/components/Pagination.d.ts +94 -0
- package/dist/cjs/components/Pagination.js +94 -0
- package/dist/cjs/components/Popover.d.ts +108 -0
- package/dist/cjs/components/Popover.js +108 -0
- package/dist/cjs/components/Progress.d.ts +68 -0
- package/dist/cjs/components/Progress.js +68 -0
- package/dist/cjs/components/Radio.d.ts +93 -0
- package/dist/cjs/components/Radio.js +93 -0
- package/dist/cjs/components/Rating.d.ts +82 -0
- package/dist/cjs/components/Rating.js +82 -0
- package/dist/cjs/components/Select.d.ts +74 -0
- package/dist/cjs/components/Select.js +74 -0
- package/dist/cjs/components/Sidebar.d.ts +174 -0
- package/dist/cjs/components/Sidebar.js +174 -0
- package/dist/cjs/components/Skeleton.d.ts +57 -0
- package/dist/cjs/components/Skeleton.js +57 -0
- package/dist/cjs/components/Slider.d.ts +64 -0
- package/dist/cjs/components/Slider.js +64 -0
- package/dist/cjs/components/Spinner.d.ts +70 -0
- package/dist/cjs/components/Spinner.js +70 -0
- package/dist/cjs/components/Stack.d.ts +75 -0
- package/dist/cjs/components/Stack.js +75 -0
- package/dist/cjs/components/Stepper.d.ts +150 -0
- package/dist/cjs/components/Stepper.js +150 -0
- package/dist/cjs/components/Table.d.ts +173 -0
- package/dist/cjs/components/Table.js +173 -0
- package/dist/cjs/components/Tabs.d.ts +104 -0
- package/dist/cjs/components/Tabs.js +104 -0
- package/dist/cjs/components/Tag.d.ts +74 -0
- package/dist/cjs/components/Tag.js +74 -0
- package/dist/cjs/components/Textarea.d.ts +75 -0
- package/dist/cjs/components/Textarea.js +75 -0
- package/dist/cjs/components/Timeline.d.ts +124 -0
- package/dist/cjs/components/Timeline.js +124 -0
- package/dist/cjs/components/Toast.d.ts +155 -0
- package/dist/cjs/components/Toast.js +155 -0
- package/dist/cjs/components/Toggle.d.ts +75 -0
- package/dist/cjs/components/Toggle.js +75 -0
- package/dist/cjs/components/Tooltip.d.ts +80 -0
- package/dist/cjs/components/Tooltip.js +80 -0
- package/dist/cjs/components/TypographyComponents.d.ts +265 -0
- package/dist/cjs/components/TypographyComponents.js +265 -0
- package/dist/cjs/components/UtilityComponents.d.ts +345 -0
- package/dist/cjs/components/UtilityComponents.js +345 -0
- package/dist/cjs/components/Video.d.ts +82 -0
- package/dist/cjs/components/Video.js +82 -0
- package/dist/cjs/components/index.d.ts +311 -0
- package/dist/cjs/components/index.js +311 -0
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.js +5 -0
- package/dist/cjs/styles/main.css +493 -0
- package/dist/cjs/theme/ThemeProvider.d.ts +185 -0
- package/dist/cjs/theme/ThemeProvider.js +185 -0
- package/dist/cjs/theme/index.d.ts +2 -0
- package/dist/cjs/theme/index.js +2 -0
- package/dist/cjs/utilities/classNames.d.ts +200 -0
- package/dist/cjs/utilities/classNames.js +200 -0
- package/dist/cjs/utilities/index.d.ts +3 -0
- package/dist/cjs/utilities/index.js +3 -0
- package/dist/cjs/utilities/styles.d.ts +94 -0
- package/dist/cjs/utilities/styles.js +94 -0
- package/dist/esm/components/Accordion.d.ts +78 -0
- package/dist/esm/components/Accordion.js +78 -0
- package/dist/esm/components/AdvancedComponents.d.ts +353 -0
- package/dist/esm/components/AdvancedComponents.js +353 -0
- package/dist/esm/components/Alert.d.ts +102 -0
- package/dist/esm/components/Alert.js +102 -0
- package/dist/esm/components/Avatar.d.ts +89 -0
- package/dist/esm/components/Avatar.js +89 -0
- package/dist/esm/components/Badge.d.ts +57 -0
- package/dist/esm/components/Badge.js +57 -0
- package/dist/esm/components/Breadcrumb.d.ts +50 -0
- package/dist/esm/components/Breadcrumb.js +50 -0
- package/dist/esm/components/Button.d.ts +77 -0
- package/dist/esm/components/Button.js +77 -0
- package/dist/esm/components/ButtonVariants.d.ts +261 -0
- package/dist/esm/components/ButtonVariants.js +261 -0
- package/dist/esm/components/Card.d.ts +56 -0
- package/dist/esm/components/Card.js +56 -0
- package/dist/esm/components/CardVariants.d.ts +267 -0
- package/dist/esm/components/CardVariants.js +267 -0
- package/dist/esm/components/Checkbox.d.ts +50 -0
- package/dist/esm/components/Checkbox.js +50 -0
- package/dist/esm/components/Chip.d.ts +104 -0
- package/dist/esm/components/Chip.js +104 -0
- package/dist/esm/components/DataDisplayComponents.d.ts +275 -0
- package/dist/esm/components/DataDisplayComponents.js +275 -0
- package/dist/esm/components/Divider.d.ts +77 -0
- package/dist/esm/components/Divider.js +77 -0
- package/dist/esm/components/Drawer.d.ts +142 -0
- package/dist/esm/components/Drawer.js +142 -0
- package/dist/esm/components/Dropdown.d.ts +139 -0
- package/dist/esm/components/Dropdown.js +139 -0
- package/dist/esm/components/Form.d.ts +41 -0
- package/dist/esm/components/Form.js +41 -0
- package/dist/esm/components/FormGroup.d.ts +58 -0
- package/dist/esm/components/FormGroup.js +58 -0
- package/dist/esm/components/FormInputVariants.d.ts +298 -0
- package/dist/esm/components/FormInputVariants.js +298 -0
- package/dist/esm/components/Image.d.ts +106 -0
- package/dist/esm/components/Image.js +106 -0
- package/dist/esm/components/Input.d.ts +65 -0
- package/dist/esm/components/Input.js +65 -0
- package/dist/esm/components/LayoutComponents.d.ts +258 -0
- package/dist/esm/components/LayoutComponents.js +258 -0
- package/dist/esm/components/Link.d.ts +71 -0
- package/dist/esm/components/Link.js +71 -0
- package/dist/esm/components/LoadingFeedbackComponents.d.ts +230 -0
- package/dist/esm/components/LoadingFeedbackComponents.js +230 -0
- package/dist/esm/components/Menu.d.ts +167 -0
- package/dist/esm/components/Menu.js +167 -0
- package/dist/esm/components/Modal.d.ts +145 -0
- package/dist/esm/components/Modal.js +145 -0
- package/dist/esm/components/ModalTypes.d.ts +288 -0
- package/dist/esm/components/ModalTypes.js +288 -0
- package/dist/esm/components/Navbar.d.ts +181 -0
- package/dist/esm/components/Navbar.js +181 -0
- package/dist/esm/components/NavigationComponents.d.ts +276 -0
- package/dist/esm/components/NavigationComponents.js +276 -0
- package/dist/esm/components/Pagination.d.ts +94 -0
- package/dist/esm/components/Pagination.js +94 -0
- package/dist/esm/components/Popover.d.ts +108 -0
- package/dist/esm/components/Popover.js +108 -0
- package/dist/esm/components/Progress.d.ts +68 -0
- package/dist/esm/components/Progress.js +68 -0
- package/dist/esm/components/Radio.d.ts +93 -0
- package/dist/esm/components/Radio.js +93 -0
- package/dist/esm/components/Rating.d.ts +82 -0
- package/dist/esm/components/Rating.js +82 -0
- package/dist/esm/components/Select.d.ts +74 -0
- package/dist/esm/components/Select.js +74 -0
- package/dist/esm/components/Sidebar.d.ts +174 -0
- package/dist/esm/components/Sidebar.js +174 -0
- package/dist/esm/components/Skeleton.d.ts +57 -0
- package/dist/esm/components/Skeleton.js +57 -0
- package/dist/esm/components/Slider.d.ts +64 -0
- package/dist/esm/components/Slider.js +64 -0
- package/dist/esm/components/Spinner.d.ts +70 -0
- package/dist/esm/components/Spinner.js +70 -0
- package/dist/esm/components/Stack.d.ts +75 -0
- package/dist/esm/components/Stack.js +75 -0
- package/dist/esm/components/Stepper.d.ts +150 -0
- package/dist/esm/components/Stepper.js +150 -0
- package/dist/esm/components/Table.d.ts +173 -0
- package/dist/esm/components/Table.js +173 -0
- package/dist/esm/components/Tabs.d.ts +104 -0
- package/dist/esm/components/Tabs.js +104 -0
- package/dist/esm/components/Tag.d.ts +74 -0
- package/dist/esm/components/Tag.js +74 -0
- package/dist/esm/components/Textarea.d.ts +75 -0
- package/dist/esm/components/Textarea.js +75 -0
- package/dist/esm/components/Timeline.d.ts +124 -0
- package/dist/esm/components/Timeline.js +124 -0
- package/dist/esm/components/Toast.d.ts +155 -0
- package/dist/esm/components/Toast.js +155 -0
- package/dist/esm/components/Toggle.d.ts +75 -0
- package/dist/esm/components/Toggle.js +75 -0
- package/dist/esm/components/Tooltip.d.ts +80 -0
- package/dist/esm/components/Tooltip.js +80 -0
- package/dist/esm/components/TypographyComponents.d.ts +265 -0
- package/dist/esm/components/TypographyComponents.js +265 -0
- package/dist/esm/components/UtilityComponents.d.ts +345 -0
- package/dist/esm/components/UtilityComponents.js +345 -0
- package/dist/esm/components/Video.d.ts +82 -0
- package/dist/esm/components/Video.js +82 -0
- package/dist/esm/components/index.d.ts +311 -0
- package/dist/esm/components/index.js +311 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/styles/main.css +493 -0
- package/dist/esm/theme/ThemeProvider.d.ts +185 -0
- package/dist/esm/theme/ThemeProvider.js +185 -0
- package/dist/esm/theme/index.d.ts +2 -0
- package/dist/esm/theme/index.js +2 -0
- package/dist/esm/utilities/classNames.d.ts +200 -0
- package/dist/esm/utilities/classNames.js +200 -0
- package/dist/esm/utilities/index.d.ts +3 -0
- package/dist/esm/utilities/index.js +3 -0
- package/dist/esm/utilities/styles.d.ts +94 -0
- package/dist/esm/utilities/styles.js +94 -0
- package/dist/styles/main.css +493 -0
- package/package.json +124 -6
- package/src/styles/main.css +493 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { cn } from '../utilities/classNames';
|
|
3
|
+
|
|
4
|
+
export interface NavbarProps extends React.HTMLAttributes<HTMLNavElement> {
|
|
5
|
+
brand?: React.ReactNode;
|
|
6
|
+
fluid?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Navbar = React.forwardRef<HTMLNavElement, NavbarProps>(
|
|
10
|
+
(
|
|
11
|
+
{
|
|
12
|
+
brand,
|
|
13
|
+
fluid = false,
|
|
14
|
+
className,
|
|
15
|
+
children,
|
|
16
|
+
...props
|
|
17
|
+
},
|
|
18
|
+
ref,
|
|
19
|
+
) => {
|
|
20
|
+
return (
|
|
21
|
+
<nav
|
|
22
|
+
ref={ref}
|
|
23
|
+
className={cn(
|
|
24
|
+
'bg-white border-b border-gray-200 shadow-sm',
|
|
25
|
+
className,
|
|
26
|
+
)}
|
|
27
|
+
{...props}
|
|
28
|
+
>
|
|
29
|
+
<div className={cn('px-4 py-4', !fluid && 'max-w-7xl mx-auto')}>
|
|
30
|
+
<div className="flex items-center justify-between">
|
|
31
|
+
{brand && (
|
|
32
|
+
<div className="flex-shrink-0 font-bold text-xl">
|
|
33
|
+
{brand}
|
|
34
|
+
</div>
|
|
35
|
+
)}
|
|
36
|
+
<div className="flex items-center gap-4">
|
|
37
|
+
{children}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</nav>
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
Navbar.displayName = 'Navbar';
|
|
47
|
+
|
|
48
|
+
export interface NavbarBrandProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
49
|
+
href?: string;
|
|
50
|
+
children: React.ReactNode;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const NavbarBrand = React.forwardRef<HTMLDivElement, NavbarBrandProps>(
|
|
54
|
+
(
|
|
55
|
+
{
|
|
56
|
+
href,
|
|
57
|
+
className,
|
|
58
|
+
children,
|
|
59
|
+
...props
|
|
60
|
+
},
|
|
61
|
+
ref,
|
|
62
|
+
) => {
|
|
63
|
+
if (href) {
|
|
64
|
+
return (
|
|
65
|
+
<a
|
|
66
|
+
href={href}
|
|
67
|
+
className={cn(
|
|
68
|
+
'flex-shrink-0 font-bold text-xl hover:opacity-80 transition-opacity',
|
|
69
|
+
className,
|
|
70
|
+
)}
|
|
71
|
+
{...props as React.AnchorHTMLAttributes<HTMLAnchorElement>}
|
|
72
|
+
>
|
|
73
|
+
{children}
|
|
74
|
+
</a>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div
|
|
80
|
+
ref={ref}
|
|
81
|
+
className={cn('flex-shrink-0 font-bold text-xl', className)}
|
|
82
|
+
{...props}
|
|
83
|
+
>
|
|
84
|
+
{children}
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
NavbarBrand.displayName = 'NavbarBrand';
|
|
91
|
+
|
|
92
|
+
export interface NavbarNavProps extends React.HTMLAttributes<HTMLUListElement> {
|
|
93
|
+
children: React.ReactNode;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const NavbarNav = React.forwardRef<HTMLUListElement, NavbarNavProps>(
|
|
97
|
+
(
|
|
98
|
+
{
|
|
99
|
+
className,
|
|
100
|
+
children,
|
|
101
|
+
...props
|
|
102
|
+
},
|
|
103
|
+
ref,
|
|
104
|
+
) => (
|
|
105
|
+
<ul
|
|
106
|
+
ref={ref}
|
|
107
|
+
className={cn('flex items-center gap-6 list-none', className)}
|
|
108
|
+
{...props}
|
|
109
|
+
>
|
|
110
|
+
{children}
|
|
111
|
+
</ul>
|
|
112
|
+
),
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
NavbarNav.displayName = 'NavbarNav';
|
|
116
|
+
|
|
117
|
+
export interface NavbarItemProps extends React.LiHTMLAttributes<HTMLLIElement> {
|
|
118
|
+
active?: boolean;
|
|
119
|
+
children: React.ReactNode;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const NavbarItem = React.forwardRef<HTMLLIElement, NavbarItemProps>(
|
|
123
|
+
(
|
|
124
|
+
{
|
|
125
|
+
active = false,
|
|
126
|
+
className,
|
|
127
|
+
children,
|
|
128
|
+
...props
|
|
129
|
+
},
|
|
130
|
+
ref,
|
|
131
|
+
) => (
|
|
132
|
+
<li
|
|
133
|
+
ref={ref}
|
|
134
|
+
className={cn(
|
|
135
|
+
'text-gray-700 hover:text-gray-900 transition-colors',
|
|
136
|
+
active && 'font-semibold text-blue-600 border-b-2 border-blue-600 pb-1',
|
|
137
|
+
className,
|
|
138
|
+
)}
|
|
139
|
+
{...props}
|
|
140
|
+
>
|
|
141
|
+
{children}
|
|
142
|
+
</li>
|
|
143
|
+
),
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
NavbarItem.displayName = 'NavbarItem';
|
|
147
|
+
|
|
148
|
+
export interface NavbarToggleProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
149
|
+
open?: boolean;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export const NavbarToggle = React.forwardRef<HTMLButtonElement, NavbarToggleProps>(
|
|
153
|
+
(
|
|
154
|
+
{
|
|
155
|
+
open = false,
|
|
156
|
+
className,
|
|
157
|
+
...props
|
|
158
|
+
},
|
|
159
|
+
ref,
|
|
160
|
+
) => (
|
|
161
|
+
<button
|
|
162
|
+
ref={ref}
|
|
163
|
+
className={cn(
|
|
164
|
+
'md:hidden text-gray-700 hover:text-gray-900 transition-colors',
|
|
165
|
+
className,
|
|
166
|
+
)}
|
|
167
|
+
aria-label="Toggle navigation"
|
|
168
|
+
{...props}
|
|
169
|
+
>
|
|
170
|
+
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
171
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={
|
|
172
|
+
open
|
|
173
|
+
? "M6 18L18 6M6 6l12 12"
|
|
174
|
+
: "M4 6h16M4 12h16M4 18h16"
|
|
175
|
+
} />
|
|
176
|
+
</svg>
|
|
177
|
+
</button>
|
|
178
|
+
),
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
NavbarToggle.displayName = 'NavbarToggle';
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { cn } from '../utilities/classNames';
|
|
3
|
+
|
|
4
|
+
export interface NavbarProps extends React.HTMLAttributes<HTMLNavElement> {
|
|
5
|
+
brand?: React.ReactNode;
|
|
6
|
+
fluid?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Navbar = React.forwardRef<HTMLNavElement, NavbarProps>(
|
|
10
|
+
(
|
|
11
|
+
{
|
|
12
|
+
brand,
|
|
13
|
+
fluid = false,
|
|
14
|
+
className,
|
|
15
|
+
children,
|
|
16
|
+
...props
|
|
17
|
+
},
|
|
18
|
+
ref,
|
|
19
|
+
) => {
|
|
20
|
+
return (
|
|
21
|
+
<nav
|
|
22
|
+
ref={ref}
|
|
23
|
+
className={cn(
|
|
24
|
+
'bg-white border-b border-gray-200 shadow-sm',
|
|
25
|
+
className,
|
|
26
|
+
)}
|
|
27
|
+
{...props}
|
|
28
|
+
>
|
|
29
|
+
<div className={cn('px-4 py-4', !fluid && 'max-w-7xl mx-auto')}>
|
|
30
|
+
<div className="flex items-center justify-between">
|
|
31
|
+
{brand && (
|
|
32
|
+
<div className="flex-shrink-0 font-bold text-xl">
|
|
33
|
+
{brand}
|
|
34
|
+
</div>
|
|
35
|
+
)}
|
|
36
|
+
<div className="flex items-center gap-4">
|
|
37
|
+
{children}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</nav>
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
Navbar.displayName = 'Navbar';
|
|
47
|
+
|
|
48
|
+
export interface NavbarBrandProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
49
|
+
href?: string;
|
|
50
|
+
children: React.ReactNode;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const NavbarBrand = React.forwardRef<HTMLDivElement, NavbarBrandProps>(
|
|
54
|
+
(
|
|
55
|
+
{
|
|
56
|
+
href,
|
|
57
|
+
className,
|
|
58
|
+
children,
|
|
59
|
+
...props
|
|
60
|
+
},
|
|
61
|
+
ref,
|
|
62
|
+
) => {
|
|
63
|
+
if (href) {
|
|
64
|
+
return (
|
|
65
|
+
<a
|
|
66
|
+
href={href}
|
|
67
|
+
className={cn(
|
|
68
|
+
'flex-shrink-0 font-bold text-xl hover:opacity-80 transition-opacity',
|
|
69
|
+
className,
|
|
70
|
+
)}
|
|
71
|
+
{...props as React.AnchorHTMLAttributes<HTMLAnchorElement>}
|
|
72
|
+
>
|
|
73
|
+
{children}
|
|
74
|
+
</a>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div
|
|
80
|
+
ref={ref}
|
|
81
|
+
className={cn('flex-shrink-0 font-bold text-xl', className)}
|
|
82
|
+
{...props}
|
|
83
|
+
>
|
|
84
|
+
{children}
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
NavbarBrand.displayName = 'NavbarBrand';
|
|
91
|
+
|
|
92
|
+
export interface NavbarNavProps extends React.HTMLAttributes<HTMLUListElement> {
|
|
93
|
+
children: React.ReactNode;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const NavbarNav = React.forwardRef<HTMLUListElement, NavbarNavProps>(
|
|
97
|
+
(
|
|
98
|
+
{
|
|
99
|
+
className,
|
|
100
|
+
children,
|
|
101
|
+
...props
|
|
102
|
+
},
|
|
103
|
+
ref,
|
|
104
|
+
) => (
|
|
105
|
+
<ul
|
|
106
|
+
ref={ref}
|
|
107
|
+
className={cn('flex items-center gap-6 list-none', className)}
|
|
108
|
+
{...props}
|
|
109
|
+
>
|
|
110
|
+
{children}
|
|
111
|
+
</ul>
|
|
112
|
+
),
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
NavbarNav.displayName = 'NavbarNav';
|
|
116
|
+
|
|
117
|
+
export interface NavbarItemProps extends React.LiHTMLAttributes<HTMLLIElement> {
|
|
118
|
+
active?: boolean;
|
|
119
|
+
children: React.ReactNode;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const NavbarItem = React.forwardRef<HTMLLIElement, NavbarItemProps>(
|
|
123
|
+
(
|
|
124
|
+
{
|
|
125
|
+
active = false,
|
|
126
|
+
className,
|
|
127
|
+
children,
|
|
128
|
+
...props
|
|
129
|
+
},
|
|
130
|
+
ref,
|
|
131
|
+
) => (
|
|
132
|
+
<li
|
|
133
|
+
ref={ref}
|
|
134
|
+
className={cn(
|
|
135
|
+
'text-gray-700 hover:text-gray-900 transition-colors',
|
|
136
|
+
active && 'font-semibold text-blue-600 border-b-2 border-blue-600 pb-1',
|
|
137
|
+
className,
|
|
138
|
+
)}
|
|
139
|
+
{...props}
|
|
140
|
+
>
|
|
141
|
+
{children}
|
|
142
|
+
</li>
|
|
143
|
+
),
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
NavbarItem.displayName = 'NavbarItem';
|
|
147
|
+
|
|
148
|
+
export interface NavbarToggleProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
149
|
+
open?: boolean;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export const NavbarToggle = React.forwardRef<HTMLButtonElement, NavbarToggleProps>(
|
|
153
|
+
(
|
|
154
|
+
{
|
|
155
|
+
open = false,
|
|
156
|
+
className,
|
|
157
|
+
...props
|
|
158
|
+
},
|
|
159
|
+
ref,
|
|
160
|
+
) => (
|
|
161
|
+
<button
|
|
162
|
+
ref={ref}
|
|
163
|
+
className={cn(
|
|
164
|
+
'md:hidden text-gray-700 hover:text-gray-900 transition-colors',
|
|
165
|
+
className,
|
|
166
|
+
)}
|
|
167
|
+
aria-label="Toggle navigation"
|
|
168
|
+
{...props}
|
|
169
|
+
>
|
|
170
|
+
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
171
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={
|
|
172
|
+
open
|
|
173
|
+
? "M6 18L18 6M6 6l12 12"
|
|
174
|
+
: "M4 6h16M4 12h16M4 18h16"
|
|
175
|
+
} />
|
|
176
|
+
</svg>
|
|
177
|
+
</button>
|
|
178
|
+
),
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
NavbarToggle.displayName = 'NavbarToggle';
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
export interface NavItem {
|
|
4
|
+
label: string;
|
|
5
|
+
href?: string;
|
|
6
|
+
icon?: React.ReactNode;
|
|
7
|
+
active?: boolean;
|
|
8
|
+
badge?: string | number;
|
|
9
|
+
submenu?: NavItem[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface NavigationProps extends React.HTMLAttributes<HTMLElement> {
|
|
13
|
+
items: NavItem[];
|
|
14
|
+
orientation?: 'horizontal' | 'vertical';
|
|
15
|
+
size?: 'sm' | 'md' | 'lg';
|
|
16
|
+
variant?: 'default' | 'filled' | 'pills' | 'minimal';
|
|
17
|
+
onItemClick?: (item: NavItem) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const NavHorizontal: React.FC<NavigationProps> = ({
|
|
21
|
+
items,
|
|
22
|
+
size = 'md',
|
|
23
|
+
variant = 'default',
|
|
24
|
+
onItemClick,
|
|
25
|
+
className = '',
|
|
26
|
+
...props
|
|
27
|
+
}) => {
|
|
28
|
+
const sizeClass = { sm: 'px-2 py-1 text-sm', md: 'px-4 py-2 text-base', lg: 'px-6 py-3 text-lg' }[size];
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<nav className={`flex gap-4 ${className}`} {...props}>
|
|
32
|
+
{items.map((item, idx) => (
|
|
33
|
+
<button
|
|
34
|
+
key={idx}
|
|
35
|
+
onClick={() => onItemClick?.(item)}
|
|
36
|
+
className={`flex items-center gap-2 rounded ${sizeClass} transition-colors ${item.active ? 'bg-blue-600 text-white' : 'text-gray-700 hover:bg-gray-100'}`}
|
|
37
|
+
>
|
|
38
|
+
{item.icon}
|
|
39
|
+
{item.label}
|
|
40
|
+
{item.badge && <span className="ml-2 bg-red-500 text-white text-xs px-2 py-1 rounded-full">{item.badge}</span>}
|
|
41
|
+
</button>
|
|
42
|
+
))}
|
|
43
|
+
</nav>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const NavVertical: React.FC<NavigationProps> = ({
|
|
48
|
+
items,
|
|
49
|
+
size = 'md',
|
|
50
|
+
variant = 'default',
|
|
51
|
+
onItemClick,
|
|
52
|
+
className = '',
|
|
53
|
+
...props
|
|
54
|
+
}) => {
|
|
55
|
+
const sizeClass = { sm: 'px-3 py-2 text-sm', md: 'px-4 py-3 text-base', lg: 'px-6 py-4 text-lg' }[size];
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<nav className={`flex flex-col gap-1 ${className}`} {...props}>
|
|
59
|
+
{items.map((item, idx) => (
|
|
60
|
+
<button
|
|
61
|
+
key={idx}
|
|
62
|
+
onClick={() => onItemClick?.(item)}
|
|
63
|
+
className={`w-full text-left flex items-center gap-2 rounded ${sizeClass} transition-colors ${item.active ? 'bg-blue-600 text-white' : 'text-gray-700 hover:bg-gray-100'}`}
|
|
64
|
+
>
|
|
65
|
+
{item.icon}
|
|
66
|
+
{item.label}
|
|
67
|
+
{item.badge && <span className="ml-auto bg-red-500 text-white text-xs px-2 py-1 rounded-full">{item.badge}</span>}
|
|
68
|
+
</button>
|
|
69
|
+
))}
|
|
70
|
+
</nav>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const NavTabs: React.FC<NavigationProps> = ({
|
|
75
|
+
items,
|
|
76
|
+
onItemClick,
|
|
77
|
+
className = '',
|
|
78
|
+
...props
|
|
79
|
+
}) => {
|
|
80
|
+
return (
|
|
81
|
+
<nav className={`flex border-b border-gray-200 gap-1 ${className}`} {...props}>
|
|
82
|
+
{items.map((item, idx) => (
|
|
83
|
+
<button
|
|
84
|
+
key={idx}
|
|
85
|
+
onClick={() => onItemClick?.(item)}
|
|
86
|
+
className={`px-6 py-3 border-b-2 transition-colors font-medium ${item.active ? 'border-blue-600 text-blue-600' : 'border-transparent text-gray-600 hover:text-gray-900'}`}
|
|
87
|
+
>
|
|
88
|
+
{item.label}
|
|
89
|
+
</button>
|
|
90
|
+
))}
|
|
91
|
+
</nav>
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const NavPills: React.FC<NavigationProps> = ({
|
|
96
|
+
items,
|
|
97
|
+
onItemClick,
|
|
98
|
+
className = '',
|
|
99
|
+
...props
|
|
100
|
+
}) => {
|
|
101
|
+
return (
|
|
102
|
+
<nav className={`flex gap-2 flex-wrap ${className}`} {...props}>
|
|
103
|
+
{items.map((item, idx) => (
|
|
104
|
+
<button
|
|
105
|
+
key={idx}
|
|
106
|
+
onClick={() => onItemClick?.(item)}
|
|
107
|
+
className={`px-4 py-2 rounded-full font-medium transition-colors ${item.active ? 'bg-blue-600 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200'}`}
|
|
108
|
+
>
|
|
109
|
+
{item.label}
|
|
110
|
+
</button>
|
|
111
|
+
))}
|
|
112
|
+
</nav>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export const NavBreadcrumbs: React.FC<NavigationProps> = ({
|
|
117
|
+
items,
|
|
118
|
+
onItemClick,
|
|
119
|
+
className = '',
|
|
120
|
+
...props
|
|
121
|
+
}) => {
|
|
122
|
+
return (
|
|
123
|
+
<nav className={`flex items-center gap-2 ${className}`} {...props}>
|
|
124
|
+
{items.map((item, idx) => (
|
|
125
|
+
<React.Fragment key={idx}>
|
|
126
|
+
<button
|
|
127
|
+
onClick={() => onItemClick?.(item)}
|
|
128
|
+
className="text-blue-600 hover:text-blue-700 hover:underline"
|
|
129
|
+
>
|
|
130
|
+
{item.label}
|
|
131
|
+
</button>
|
|
132
|
+
{idx < items.length - 1 && <span className="text-gray-400">/</span>}
|
|
133
|
+
</React.Fragment>
|
|
134
|
+
))}
|
|
135
|
+
</nav>
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export const NavSteps: React.FC<
|
|
140
|
+
NavigationProps & {
|
|
141
|
+
currentStep?: number;
|
|
142
|
+
}
|
|
143
|
+
> = ({
|
|
144
|
+
items,
|
|
145
|
+
currentStep = 0,
|
|
146
|
+
onItemClick,
|
|
147
|
+
className = '',
|
|
148
|
+
...props
|
|
149
|
+
}) => {
|
|
150
|
+
return (
|
|
151
|
+
<div className={`flex items-center gap-4 ${className}`} {...props}>
|
|
152
|
+
{items.map((item, idx) => (
|
|
153
|
+
<React.Fragment key={idx}>
|
|
154
|
+
<div className="flex flex-col items-center gap-2">
|
|
155
|
+
<div
|
|
156
|
+
className={`w-10 h-10 rounded-full flex items-center justify-center font-bold ${idx <= currentStep ? 'bg-blue-600 text-white' : 'bg-gray-200 text-gray-600'}`}
|
|
157
|
+
>
|
|
158
|
+
{idx + 1}
|
|
159
|
+
</div>
|
|
160
|
+
<span className="text-sm text-gray-600">{item.label}</span>
|
|
161
|
+
</div>
|
|
162
|
+
{idx < items.length - 1 && (
|
|
163
|
+
<div
|
|
164
|
+
className={`flex-1 h-1 ${idx < currentStep ? 'bg-blue-600' : 'bg-gray-200'}`}
|
|
165
|
+
style={{ minWidth: '40px' }}
|
|
166
|
+
></div>
|
|
167
|
+
)}
|
|
168
|
+
</React.Fragment>
|
|
169
|
+
))}
|
|
170
|
+
</div>
|
|
171
|
+
);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export const NavTree: React.FC<NavigationProps & { expandable?: boolean }> = ({
|
|
175
|
+
items,
|
|
176
|
+
expandable = true,
|
|
177
|
+
onItemClick,
|
|
178
|
+
className = '',
|
|
179
|
+
...props
|
|
180
|
+
}) => {
|
|
181
|
+
const [expanded, setExpanded] = React.useState<Set<number>>(new Set());
|
|
182
|
+
|
|
183
|
+
const toggleExpanded = (idx: number) => {
|
|
184
|
+
const newExpanded = new Set(expanded);
|
|
185
|
+
if (newExpanded.has(idx)) {
|
|
186
|
+
newExpanded.delete(idx);
|
|
187
|
+
} else {
|
|
188
|
+
newExpanded.add(idx);
|
|
189
|
+
}
|
|
190
|
+
setExpanded(newExpanded);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
return (
|
|
194
|
+
<nav className={`space-y-1 ${className}`} {...props}>
|
|
195
|
+
{items.map((item, idx) => (
|
|
196
|
+
<div key={idx}>
|
|
197
|
+
<div className="flex items-center gap-2">
|
|
198
|
+
{item.submenu && expandable && (
|
|
199
|
+
<button
|
|
200
|
+
onClick={() => toggleExpanded(idx)}
|
|
201
|
+
className="w-4 h-4 flex items-center justify-center"
|
|
202
|
+
>
|
|
203
|
+
{expanded.has(idx) ? '▼' : '▶'}
|
|
204
|
+
</button>
|
|
205
|
+
)}
|
|
206
|
+
<button
|
|
207
|
+
onClick={() => onItemClick?.(item)}
|
|
208
|
+
className="flex-1 text-left px-3 py-2 rounded text-gray-700 hover:bg-gray-100"
|
|
209
|
+
>
|
|
210
|
+
{item.label}
|
|
211
|
+
</button>
|
|
212
|
+
</div>
|
|
213
|
+
{item.submenu && expanded.has(idx) && (
|
|
214
|
+
<div className="ml-4 border-l border-gray-200">
|
|
215
|
+
{item.submenu.map((subitem, sidx) => (
|
|
216
|
+
<button
|
|
217
|
+
key={sidx}
|
|
218
|
+
onClick={() => onItemClick?.(subitem)}
|
|
219
|
+
className="w-full text-left px-3 py-2 rounded text-gray-600 hover:bg-gray-100 text-sm"
|
|
220
|
+
>
|
|
221
|
+
{subitem.label}
|
|
222
|
+
</button>
|
|
223
|
+
))}
|
|
224
|
+
</div>
|
|
225
|
+
)}
|
|
226
|
+
</div>
|
|
227
|
+
))}
|
|
228
|
+
</nav>
|
|
229
|
+
);
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
export const NavMegamenu: React.FC<
|
|
233
|
+
NavigationProps & {
|
|
234
|
+
columns?: number;
|
|
235
|
+
}
|
|
236
|
+
> = ({
|
|
237
|
+
items,
|
|
238
|
+
columns = 3,
|
|
239
|
+
onItemClick,
|
|
240
|
+
className = '',
|
|
241
|
+
...props
|
|
242
|
+
}) => {
|
|
243
|
+
const [openMenu, setOpenMenu] = React.useState<number | null>(null);
|
|
244
|
+
|
|
245
|
+
return (
|
|
246
|
+
<nav className={`relative ${className}`} {...props}>
|
|
247
|
+
<div className="flex gap-6">
|
|
248
|
+
{items.map((item, idx) => (
|
|
249
|
+
<div key={idx} className="relative group">
|
|
250
|
+
<button
|
|
251
|
+
onClick={() => setOpenMenu(openMenu === idx ? null : idx)}
|
|
252
|
+
className="px-4 py-3 font-medium text-gray-700 hover:text-gray-900"
|
|
253
|
+
>
|
|
254
|
+
{item.label}
|
|
255
|
+
</button>
|
|
256
|
+
{item.submenu && (
|
|
257
|
+
<div className="absolute top-full left-0 hidden group-hover:block bg-white shadow-lg rounded-lg p-6 min-w-max">
|
|
258
|
+
<div className={`grid grid-cols-${columns} gap-6`}>
|
|
259
|
+
{item.submenu.map((subitem, sidx) => (
|
|
260
|
+
<button
|
|
261
|
+
key={sidx}
|
|
262
|
+
onClick={() => onItemClick?.(subitem)}
|
|
263
|
+
className="text-left text-gray-700 hover:text-blue-600"
|
|
264
|
+
>
|
|
265
|
+
<div className="font-medium">{subitem.label}</div>
|
|
266
|
+
</button>
|
|
267
|
+
))}
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
)}
|
|
271
|
+
</div>
|
|
272
|
+
))}
|
|
273
|
+
</div>
|
|
274
|
+
</nav>
|
|
275
|
+
);
|
|
276
|
+
};
|