@capy-vn/ui 0.1.0 → 0.1.2
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 +51 -61
- package/dist/index.browser.js +83 -61
- package/dist/index.cjs +83 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +83 -61
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @capy/ui
|
|
1
|
+
# @capy-vn/ui
|
|
2
2
|
|
|
3
3
|
Thư viện component dùng chung cho các project frontend, xây dựng trên shadcn/ui + Radix UI + Tailwind CSS.
|
|
4
4
|
|
|
@@ -6,23 +6,15 @@ Thư viện component dùng chung cho các project frontend, xây dựng trên s
|
|
|
6
6
|
|
|
7
7
|
## Cài đặt
|
|
8
8
|
|
|
9
|
-
Thêm package vào project qua git dependency:
|
|
10
|
-
|
|
11
9
|
```bash
|
|
12
10
|
# npm
|
|
13
|
-
npm install
|
|
11
|
+
npm install @capy-vn/ui
|
|
14
12
|
|
|
15
13
|
# yarn
|
|
16
|
-
yarn add
|
|
14
|
+
yarn add @capy-vn/ui
|
|
17
15
|
|
|
18
16
|
# pnpm
|
|
19
|
-
pnpm add
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Để pin vào một commit cụ thể (khuyến nghị cho production):
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
npm install "git+https://gitlab.com/capy-agents/capy-frontend-components.git#<commit-hash>"
|
|
17
|
+
pnpm add @capy-vn/ui
|
|
26
18
|
```
|
|
27
19
|
|
|
28
20
|
---
|
|
@@ -35,7 +27,7 @@ Trong `app/globals.css` hoặc `app/layout.tsx`:
|
|
|
35
27
|
|
|
36
28
|
```css
|
|
37
29
|
/* globals.css */
|
|
38
|
-
@import "@capy/ui/styles";
|
|
30
|
+
@import "@capy-vn/ui/styles";
|
|
39
31
|
@tailwind base;
|
|
40
32
|
@tailwind components;
|
|
41
33
|
@tailwind utilities;
|
|
@@ -44,7 +36,7 @@ Trong `app/globals.css` hoặc `app/layout.tsx`:
|
|
|
44
36
|
Hoặc trong `layout.tsx`:
|
|
45
37
|
|
|
46
38
|
```tsx
|
|
47
|
-
import "@capy/ui/styles";
|
|
39
|
+
import "@capy-vn/ui/styles";
|
|
48
40
|
```
|
|
49
41
|
|
|
50
42
|
### 2. Cấu hình Tailwind
|
|
@@ -57,7 +49,7 @@ module.exports = {
|
|
|
57
49
|
content: [
|
|
58
50
|
"./app/**/*.{ts,tsx}",
|
|
59
51
|
"./components/**/*.{ts,tsx}",
|
|
60
|
-
"./node_modules/@capy/ui/dist/**/*.{js,mjs}", // <-- thêm dòng này
|
|
52
|
+
"./node_modules/@capy-vn/ui/dist/**/*.{js,mjs}", // <-- thêm dòng này
|
|
61
53
|
],
|
|
62
54
|
theme: {
|
|
63
55
|
extend: {},
|
|
@@ -71,7 +63,7 @@ module.exports = {
|
|
|
71
63
|
Trong root layout:
|
|
72
64
|
|
|
73
65
|
```tsx
|
|
74
|
-
import { Toaster } from "@capy/ui";
|
|
66
|
+
import { Toaster } from "@capy-vn/ui";
|
|
75
67
|
|
|
76
68
|
export default function RootLayout({ children }) {
|
|
77
69
|
return (
|
|
@@ -90,7 +82,7 @@ export default function RootLayout({ children }) {
|
|
|
90
82
|
## Sử dụng
|
|
91
83
|
|
|
92
84
|
```tsx
|
|
93
|
-
import { Button, Input, Card, CardContent } from "@capy/ui";
|
|
85
|
+
import { Button, Input, Card, CardContent } from "@capy-vn/ui";
|
|
94
86
|
|
|
95
87
|
export function LoginCard() {
|
|
96
88
|
return (
|
|
@@ -110,7 +102,7 @@ Các component `Form*` đã tích hợp sẵn `react-hook-form`:
|
|
|
110
102
|
|
|
111
103
|
```tsx
|
|
112
104
|
import { useForm } from "react-hook-form";
|
|
113
|
-
import { Form, FormInput, FormSelect, Button } from "@capy/ui";
|
|
105
|
+
import { Form, FormInput, FormSelect, Button } from "@capy-vn/ui";
|
|
114
106
|
|
|
115
107
|
export function CreateUserForm() {
|
|
116
108
|
const form = useForm({ defaultValues: { name: "", role: "" } });
|
|
@@ -142,44 +134,44 @@ export function CreateUserForm() {
|
|
|
142
134
|
|
|
143
135
|
| Component | Import |
|
|
144
136
|
|-----------|--------|
|
|
145
|
-
| `Button` | `@capy/ui` |
|
|
146
|
-
| `Input` | `@capy/ui` |
|
|
147
|
-
| `Textarea` | `@capy/ui` |
|
|
148
|
-
| `Label` | `@capy/ui` |
|
|
149
|
-
| `Checkbox` | `@capy/ui` |
|
|
150
|
-
| `Switch` | `@capy/ui` |
|
|
151
|
-
| `RadioGroup`, `RadioGroupItem` | `@capy/ui` |
|
|
152
|
-
| `Select`, `SelectTrigger`, `SelectContent`, `SelectItem` | `@capy/ui` |
|
|
153
|
-
| `SearchSelect` | `@capy/ui` |
|
|
154
|
-
| `MultiSelect` | `@capy/ui` |
|
|
155
|
-
| `NumberInput` | `@capy/ui` |
|
|
156
|
-
| `Slider` | `@capy/ui` |
|
|
157
|
-
| `OtpInput` | `@capy/ui` |
|
|
158
|
-
| `FileUpload` | `@capy/ui` |
|
|
159
|
-
| `Badge` | `@capy/ui` |
|
|
160
|
-
| `Avatar`, `AvatarImage`, `AvatarFallback` | `@capy/ui` |
|
|
161
|
-
| `Card`, `CardHeader`, `CardContent`, `CardFooter`, `CardTitle`, `CardDescription` | `@capy/ui` |
|
|
162
|
-
| `Alert`, `AlertTitle`, `AlertDescription` | `@capy/ui` |
|
|
163
|
-
| `Separator` | `@capy/ui` |
|
|
164
|
-
| `Progress` | `@capy/ui` |
|
|
165
|
-
| `Skeleton` | `@capy/ui` |
|
|
166
|
-
| `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` | `@capy/ui` |
|
|
167
|
-
| `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogFooter` | `@capy/ui` |
|
|
168
|
-
| `AlertDialog`, `AlertDialogTrigger`, `AlertDialogContent`, ... | `@capy/ui` |
|
|
169
|
-
| `Sheet`, `SheetTrigger`, `SheetContent` | `@capy/ui` |
|
|
170
|
-
| `Popover`, `PopoverTrigger`, `PopoverContent` | `@capy/ui` |
|
|
171
|
-
| `DropdownMenu`, `DropdownMenuTrigger`, `DropdownMenuContent`, `DropdownMenuItem` | `@capy/ui` |
|
|
172
|
-
| `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` | `@capy/ui` |
|
|
173
|
-
| `Tooltip`, `TooltipTrigger`, `TooltipContent`, `TooltipProvider` | `@capy/ui` |
|
|
174
|
-
| `ScrollArea` | `@capy/ui` |
|
|
175
|
-
| `Breadcrumb`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbSeparator` | `@capy/ui` |
|
|
176
|
-
| `Calendar` | `@capy/ui` |
|
|
177
|
-
| `DatePicker` | `@capy/ui` |
|
|
178
|
-
| `DateRangePicker` | `@capy/ui` |
|
|
179
|
-
| `TimePicker` | `@capy/ui` |
|
|
180
|
-
| `DatetimePicker` | `@capy/ui` |
|
|
181
|
-
| `DatetimeRangePicker` | `@capy/ui` |
|
|
182
|
-
| `Toaster` | `@capy/ui` |
|
|
137
|
+
| `Button` | `@capy-vn/ui` |
|
|
138
|
+
| `Input` | `@capy-vn/ui` |
|
|
139
|
+
| `Textarea` | `@capy-vn/ui` |
|
|
140
|
+
| `Label` | `@capy-vn/ui` |
|
|
141
|
+
| `Checkbox` | `@capy-vn/ui` |
|
|
142
|
+
| `Switch` | `@capy-vn/ui` |
|
|
143
|
+
| `RadioGroup`, `RadioGroupItem` | `@capy-vn/ui` |
|
|
144
|
+
| `Select`, `SelectTrigger`, `SelectContent`, `SelectItem` | `@capy-vn/ui` |
|
|
145
|
+
| `SearchSelect` | `@capy-vn/ui` |
|
|
146
|
+
| `MultiSelect` | `@capy-vn/ui` |
|
|
147
|
+
| `NumberInput` | `@capy-vn/ui` |
|
|
148
|
+
| `Slider` | `@capy-vn/ui` |
|
|
149
|
+
| `OtpInput` | `@capy-vn/ui` |
|
|
150
|
+
| `FileUpload` | `@capy-vn/ui` |
|
|
151
|
+
| `Badge` | `@capy-vn/ui` |
|
|
152
|
+
| `Avatar`, `AvatarImage`, `AvatarFallback` | `@capy-vn/ui` |
|
|
153
|
+
| `Card`, `CardHeader`, `CardContent`, `CardFooter`, `CardTitle`, `CardDescription` | `@capy-vn/ui` |
|
|
154
|
+
| `Alert`, `AlertTitle`, `AlertDescription` | `@capy-vn/ui` |
|
|
155
|
+
| `Separator` | `@capy-vn/ui` |
|
|
156
|
+
| `Progress` | `@capy-vn/ui` |
|
|
157
|
+
| `Skeleton` | `@capy-vn/ui` |
|
|
158
|
+
| `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` | `@capy-vn/ui` |
|
|
159
|
+
| `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogFooter` | `@capy-vn/ui` |
|
|
160
|
+
| `AlertDialog`, `AlertDialogTrigger`, `AlertDialogContent`, ... | `@capy-vn/ui` |
|
|
161
|
+
| `Sheet`, `SheetTrigger`, `SheetContent` | `@capy-vn/ui` |
|
|
162
|
+
| `Popover`, `PopoverTrigger`, `PopoverContent` | `@capy-vn/ui` |
|
|
163
|
+
| `DropdownMenu`, `DropdownMenuTrigger`, `DropdownMenuContent`, `DropdownMenuItem` | `@capy-vn/ui` |
|
|
164
|
+
| `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` | `@capy-vn/ui` |
|
|
165
|
+
| `Tooltip`, `TooltipTrigger`, `TooltipContent`, `TooltipProvider` | `@capy-vn/ui` |
|
|
166
|
+
| `ScrollArea` | `@capy-vn/ui` |
|
|
167
|
+
| `Breadcrumb`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbSeparator` | `@capy-vn/ui` |
|
|
168
|
+
| `Calendar` | `@capy-vn/ui` |
|
|
169
|
+
| `DatePicker` | `@capy-vn/ui` |
|
|
170
|
+
| `DateRangePicker` | `@capy-vn/ui` |
|
|
171
|
+
| `TimePicker` | `@capy-vn/ui` |
|
|
172
|
+
| `DatetimePicker` | `@capy-vn/ui` |
|
|
173
|
+
| `DatetimeRangePicker` | `@capy-vn/ui` |
|
|
174
|
+
| `Toaster` | `@capy-vn/ui` |
|
|
183
175
|
|
|
184
176
|
### Forms (tích hợp react-hook-form)
|
|
185
177
|
|
|
@@ -245,7 +237,7 @@ Tất cả Form components nhận prop `name`, `label`, và `description` (optio
|
|
|
245
237
|
## Hooks
|
|
246
238
|
|
|
247
239
|
```tsx
|
|
248
|
-
import { useDisclosure, useDebounce, usePagination, useLocalStorage } from "@capy/ui";
|
|
240
|
+
import { useDisclosure, useDebounce, usePagination, useLocalStorage } from "@capy-vn/ui";
|
|
249
241
|
```
|
|
250
242
|
|
|
251
243
|
| Hook | Mô tả |
|
|
@@ -260,7 +252,7 @@ import { useDisclosure, useDebounce, usePagination, useLocalStorage } from "@cap
|
|
|
260
252
|
## Utilities
|
|
261
253
|
|
|
262
254
|
```tsx
|
|
263
|
-
import { cn } from "@capy/ui";
|
|
255
|
+
import { cn } from "@capy-vn/ui";
|
|
264
256
|
|
|
265
257
|
// Kết hợp Tailwind class
|
|
266
258
|
<div className={cn("base-class", condition && "conditional-class")} />
|
|
@@ -286,10 +278,8 @@ Next.js là optional — library hoạt động với bất kỳ React 18+ proje
|
|
|
286
278
|
|
|
287
279
|
## Cập nhật
|
|
288
280
|
|
|
289
|
-
Để lấy version mới nhất từ `main`:
|
|
290
|
-
|
|
291
281
|
```bash
|
|
292
|
-
npm
|
|
282
|
+
npm update @capy-vn/ui
|
|
293
283
|
```
|
|
294
284
|
|
|
295
285
|
---
|
package/dist/index.browser.js
CHANGED
|
@@ -45883,16 +45883,16 @@ Defaulting to \`null\`.`;
|
|
|
45883
45883
|
variant: "ghost",
|
|
45884
45884
|
size: "sm",
|
|
45885
45885
|
className: cn(
|
|
45886
|
-
"gap-1",
|
|
45887
|
-
link.active && "text-foreground"
|
|
45886
|
+
"gap-1.5 text-muted-foreground hover:bg-transparent hover:text-foreground",
|
|
45887
|
+
link.active && "text-foreground font-medium"
|
|
45888
45888
|
),
|
|
45889
45889
|
children: [
|
|
45890
45890
|
link.label,
|
|
45891
|
-
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ChevronDown, { className: "h-3.5 w-3.5 opacity-
|
|
45891
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ChevronDown, { className: "h-3.5 w-3.5 opacity-50", "aria-hidden": "true" })
|
|
45892
45892
|
]
|
|
45893
45893
|
}
|
|
45894
45894
|
) }),
|
|
45895
|
-
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(DropdownMenuContent2, { align: "
|
|
45895
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(DropdownMenuContent2, { align: "center", children: link.children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(DropdownMenuItem2, { asChild: !!child.href, children: child.href ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
45896
45896
|
"a",
|
|
45897
45897
|
{
|
|
45898
45898
|
href: child.href,
|
|
@@ -45911,7 +45911,10 @@ Defaulting to \`null\`.`;
|
|
|
45911
45911
|
variant: "ghost",
|
|
45912
45912
|
size: "sm",
|
|
45913
45913
|
asChild: !!link.href,
|
|
45914
|
-
className: cn(
|
|
45914
|
+
className: cn(
|
|
45915
|
+
"text-muted-foreground hover:bg-transparent hover:text-foreground",
|
|
45916
|
+
link.active && "text-foreground font-medium"
|
|
45917
|
+
),
|
|
45915
45918
|
onClick: !link.href ? link.onClick : void 0,
|
|
45916
45919
|
children: link.href ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
45917
45920
|
"a",
|
|
@@ -45943,9 +45946,9 @@ Defaulting to \`null\`.`;
|
|
|
45943
45946
|
onClose();
|
|
45944
45947
|
};
|
|
45945
45948
|
const baseClass = cn(
|
|
45946
|
-
"flex w-full items-center justify-between rounded-md px-3 py-2 text-sm font-medium transition-colors",
|
|
45949
|
+
"flex w-full items-center justify-between rounded-md px-3 py-2.5 text-sm font-medium transition-colors",
|
|
45947
45950
|
"hover:bg-accent hover:text-accent-foreground",
|
|
45948
|
-
link.active
|
|
45951
|
+
link.active ? "text-foreground bg-accent/60" : "text-muted-foreground",
|
|
45949
45952
|
depth > 0 && "pl-6 font-normal"
|
|
45950
45953
|
);
|
|
45951
45954
|
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("li", { children: [
|
|
@@ -45969,7 +45972,7 @@ Defaulting to \`null\`.`;
|
|
|
45969
45972
|
ChevronDown,
|
|
45970
45973
|
{
|
|
45971
45974
|
className: cn(
|
|
45972
|
-
"h-4 w-4 opacity-
|
|
45975
|
+
"h-4 w-4 opacity-50 transition-transform",
|
|
45973
45976
|
open && "rotate-180"
|
|
45974
45977
|
),
|
|
45975
45978
|
"aria-hidden": "true"
|
|
@@ -45996,8 +45999,7 @@ Defaulting to \`null\`.`;
|
|
|
45996
45999
|
const [scrolled, setScrolled] = React97.useState(false);
|
|
45997
46000
|
const [sheetOpen, setSheetOpen] = React97.useState(false);
|
|
45998
46001
|
React97.useEffect(() => {
|
|
45999
|
-
|
|
46000
|
-
const handler = () => setScrolled(window.scrollY > transparentThreshold);
|
|
46002
|
+
const handler = () => setScrolled(window.scrollY > (transparent ? transparentThreshold : 10));
|
|
46001
46003
|
window.addEventListener("scroll", handler, { passive: true });
|
|
46002
46004
|
handler();
|
|
46003
46005
|
return () => window.removeEventListener("scroll", handler);
|
|
@@ -46012,41 +46014,52 @@ Defaulting to \`null\`.`;
|
|
|
46012
46014
|
{
|
|
46013
46015
|
ref,
|
|
46014
46016
|
className: cn(
|
|
46015
|
-
"z-50 w-full transition-all duration-
|
|
46017
|
+
"z-50 w-full transition-all duration-300",
|
|
46016
46018
|
sticky && "sticky top-0",
|
|
46017
|
-
isTransparent ? "bg-transparent" :
|
|
46019
|
+
isTransparent ? "bg-transparent" : cn(
|
|
46020
|
+
"border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60",
|
|
46021
|
+
scrolled && "shadow-sm"
|
|
46022
|
+
),
|
|
46018
46023
|
className
|
|
46019
46024
|
),
|
|
46020
46025
|
...props,
|
|
46021
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Container, { size: containerSize, children: /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "
|
|
46022
|
-
|
|
46023
|
-
|
|
46024
|
-
|
|
46025
|
-
|
|
46026
|
-
|
|
46027
|
-
|
|
46028
|
-
|
|
46029
|
-
|
|
46030
|
-
|
|
46031
|
-
|
|
46032
|
-
|
|
46033
|
-
|
|
46034
|
-
|
|
46035
|
-
|
|
46036
|
-
) }),
|
|
46037
|
-
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(SheetContent, { side: "left", className: "flex flex-col", children: [
|
|
46038
|
-
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(SheetHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(SheetTitle, { children: mobileMenuTitle }) }),
|
|
46039
|
-
links && links.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("nav", { className: "mt-4 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("ul", { className: "space-y-1", children: links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
46040
|
-
NavMobileLink,
|
|
46026
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Container, { size: containerSize, children: /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "grid h-16 grid-cols-[auto_1fr_auto] items-center gap-4", children: [
|
|
46027
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "shrink-0", children: logo }),
|
|
46028
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
46029
|
+
"nav",
|
|
46030
|
+
{
|
|
46031
|
+
className: "hidden items-center justify-center gap-0.5 md:flex",
|
|
46032
|
+
"aria-label": "Main navigation",
|
|
46033
|
+
children: (links ?? []).map((link) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(NavDesktopLink, { link }, link.label))
|
|
46034
|
+
}
|
|
46035
|
+
),
|
|
46036
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
46037
|
+
cta && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "hidden items-center gap-3 md:flex", children: cta }),
|
|
46038
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "md:hidden", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(Sheet, { open: sheetOpen, onOpenChange: handleSheetOpen, children: [
|
|
46039
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(SheetTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
46040
|
+
Button,
|
|
46041
46041
|
{
|
|
46042
|
-
|
|
46043
|
-
|
|
46044
|
-
|
|
46045
|
-
|
|
46046
|
-
|
|
46047
|
-
|
|
46048
|
-
|
|
46049
|
-
|
|
46042
|
+
variant: "ghost",
|
|
46043
|
+
size: "icon",
|
|
46044
|
+
"aria-label": "M\u1EDF menu",
|
|
46045
|
+
className: "h-9 w-9",
|
|
46046
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Menu, { className: "h-5 w-5", "aria-hidden": "true" })
|
|
46047
|
+
}
|
|
46048
|
+
) }),
|
|
46049
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(SheetContent, { side: "right", className: "flex flex-col w-72", children: [
|
|
46050
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(SheetHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(SheetTitle, { children: mobileMenuTitle }) }),
|
|
46051
|
+
links && links.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("nav", { className: "mt-4 flex-1", "aria-label": "Mobile navigation", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("ul", { className: "space-y-0.5", children: links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
46052
|
+
NavMobileLink,
|
|
46053
|
+
{
|
|
46054
|
+
link,
|
|
46055
|
+
onClose: () => handleSheetOpen(false)
|
|
46056
|
+
},
|
|
46057
|
+
link.label
|
|
46058
|
+
)) }) }),
|
|
46059
|
+
cta && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "mt-auto border-t pt-4", children: cta })
|
|
46060
|
+
] })
|
|
46061
|
+
] }) })
|
|
46062
|
+
] })
|
|
46050
46063
|
] }) })
|
|
46051
46064
|
}
|
|
46052
46065
|
);
|
|
@@ -46084,31 +46097,40 @@ Defaulting to \`null\`.`;
|
|
|
46084
46097
|
ref,
|
|
46085
46098
|
className: cn("border-t bg-background", className),
|
|
46086
46099
|
...props,
|
|
46087
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(Container, { size: containerSize, className: "py-
|
|
46088
|
-
/* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "
|
|
46089
|
-
(logo || tagline) && /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex
|
|
46100
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(Container, { size: containerSize, className: "py-14", children: [
|
|
46101
|
+
(logo || tagline || linkGroups && linkGroups.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "grid grid-cols-1 gap-10 md:grid-cols-[2fr_3fr] md:gap-16", children: [
|
|
46102
|
+
(logo || tagline) && /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex flex-col gap-4", children: [
|
|
46090
46103
|
logo,
|
|
46091
|
-
tagline && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("p", { className: "text-sm text-muted-foreground", children: tagline })
|
|
46104
|
+
tagline && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("p", { className: "max-w-xs text-sm leading-relaxed text-muted-foreground", children: tagline })
|
|
46092
46105
|
] }),
|
|
46093
|
-
linkGroups && linkGroups.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
46094
|
-
|
|
46095
|
-
|
|
46096
|
-
|
|
46097
|
-
|
|
46098
|
-
|
|
46099
|
-
|
|
46100
|
-
|
|
46101
|
-
className: "text-sm
|
|
46102
|
-
children: link.
|
|
46103
|
-
|
|
46104
|
-
|
|
46105
|
-
|
|
46106
|
+
linkGroups && linkGroups.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
46107
|
+
"div",
|
|
46108
|
+
{
|
|
46109
|
+
className: cn(
|
|
46110
|
+
"grid gap-8",
|
|
46111
|
+
linkGroups.length === 1 ? "grid-cols-1" : linkGroups.length === 2 ? "grid-cols-2" : "grid-cols-2 sm:grid-cols-3"
|
|
46112
|
+
),
|
|
46113
|
+
children: linkGroups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex flex-col gap-3", children: [
|
|
46114
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("p", { className: "text-sm font-semibold tracking-wide", children: group.heading }),
|
|
46115
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("ul", { className: "flex flex-col gap-2", children: group.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
46116
|
+
"a",
|
|
46117
|
+
{
|
|
46118
|
+
href: link.href,
|
|
46119
|
+
target: link.external ? "_blank" : void 0,
|
|
46120
|
+
rel: link.external ? "noopener noreferrer" : void 0,
|
|
46121
|
+
className: "text-sm text-muted-foreground transition-colors hover:text-foreground",
|
|
46122
|
+
children: link.label
|
|
46123
|
+
}
|
|
46124
|
+
) }, link.href)) })
|
|
46125
|
+
] }, group.heading))
|
|
46126
|
+
}
|
|
46127
|
+
)
|
|
46106
46128
|
] }),
|
|
46107
|
-
newsletter && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "mt-10", children: newsletter }),
|
|
46129
|
+
newsletter && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: cn((logo || tagline || linkGroups?.length) && "mt-10"), children: newsletter }),
|
|
46108
46130
|
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(Separator2, { className: "my-8" }),
|
|
46109
|
-
/* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex flex-
|
|
46131
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex flex-col-reverse gap-4 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
46110
46132
|
copyright && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("p", { className: "text-sm text-muted-foreground", children: copyright }),
|
|
46111
|
-
socialLinks && socialLinks.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "flex items-center gap-
|
|
46133
|
+
socialLinks && socialLinks.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "flex items-center gap-1", children: socialLinks.map((social) => {
|
|
46112
46134
|
const Icon2 = socialIconMap[social.platform];
|
|
46113
46135
|
return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
46114
46136
|
"a",
|
|
@@ -46117,7 +46139,7 @@ Defaulting to \`null\`.`;
|
|
|
46117
46139
|
target: "_blank",
|
|
46118
46140
|
rel: "noopener noreferrer",
|
|
46119
46141
|
"aria-label": social.label ?? social.platform,
|
|
46120
|
-
className: "flex h-
|
|
46142
|
+
className: "flex h-9 w-9 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
|
|
46121
46143
|
children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(Icon2, { className: "h-4 w-4", "aria-hidden": "true" })
|
|
46122
46144
|
},
|
|
46123
46145
|
social.platform
|