@ponti-studios/ui 2.0.1 → 3.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/README.md +36 -3
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.js +3 -0
- package/dist/components/data-display/accordion.d.ts +10 -0
- package/dist/components/data-display/accordion.js +53 -0
- package/{src/components/data-display/index.ts → dist/components/data-display/index.d.ts} +1 -10
- package/dist/components/data-display/index.js +8 -0
- package/dist/components/data-display/metric-card.d.ts +9 -0
- package/dist/components/data-display/metric-card.js +25 -0
- package/dist/components/data-display/sort-controls.d.ts +13 -0
- package/dist/components/data-display/sort-controls.js +57 -0
- package/dist/components/data-display/sort-row.d.ts +10 -0
- package/dist/components/data-display/sort-row.js +52 -0
- package/dist/components/data-display/table.d.ts +10 -0
- package/dist/components/data-display/table.js +57 -0
- package/dist/components/feedback/alert.d.ts +9 -0
- package/dist/components/feedback/alert.js +38 -0
- package/dist/components/feedback/empty-state.d.ts +18 -0
- package/dist/components/feedback/empty-state.js +36 -0
- package/{src/components/feedback/index.ts → dist/components/feedback/index.d.ts} +2 -0
- package/dist/components/feedback/index.js +7 -0
- package/dist/components/feedback/progress.d.ts +6 -0
- package/dist/components/feedback/progress.js +25 -0
- package/dist/components/feedback/skeleton.d.ts +2 -0
- package/dist/components/feedback/skeleton.js +11 -0
- package/dist/components/feedback/spinner.d.ts +14 -0
- package/dist/components/feedback/spinner.js +27 -0
- package/dist/components/feedback/update-guard.d.ts +13 -0
- package/dist/components/feedback/update-guard.js +38 -0
- package/dist/components/filters/active-filters-bar.d.ts +14 -0
- package/dist/components/filters/active-filters-bar.js +44 -0
- package/dist/components/filters/filter-chip.d.ts +11 -0
- package/dist/components/filters/filter-chip.js +33 -0
- package/dist/components/filters/filter-select.d.ts +17 -0
- package/dist/components/filters/filter-select.js +46 -0
- package/dist/components/filters/index.js +4 -0
- package/dist/components/forms/checkbox.d.ts +4 -0
- package/dist/components/forms/checkbox.js +24 -0
- package/dist/components/forms/date-month-select.d.ts +11 -0
- package/dist/components/forms/date-month-select.js +47 -0
- package/dist/components/forms/date-picker.d.ts +60 -0
- package/dist/components/forms/date-picker.js +193 -0
- package/dist/components/forms/date-utils.d.ts +14 -0
- package/dist/components/forms/date-utils.js +18 -0
- package/dist/components/forms/drop-zone.d.ts +42 -0
- package/dist/components/forms/drop-zone.js +184 -0
- package/{src/components/forms/index.ts → dist/components/forms/index.d.ts} +3 -9
- package/dist/components/forms/index.js +17 -0
- package/dist/components/forms/input.d.ts +3 -0
- package/dist/components/forms/input.js +15 -0
- package/dist/components/forms/label.d.ts +3 -0
- package/dist/components/forms/label.js +14 -0
- package/dist/components/forms/passkey-management.d.ts +14 -0
- package/dist/components/forms/passkey-management.js +132 -0
- package/dist/components/forms/radio-group.d.ts +6 -0
- package/dist/components/forms/radio-group.js +28 -0
- package/dist/components/forms/select.d.ts +18 -0
- package/dist/components/forms/select.js +103 -0
- package/dist/components/forms/slider.d.ts +9 -0
- package/dist/components/forms/slider.js +25 -0
- package/dist/components/forms/stepper.d.ts +15 -0
- package/dist/components/forms/stepper.js +41 -0
- package/dist/components/forms/switch.d.ts +6 -0
- package/dist/components/forms/switch.js +21 -0
- package/dist/components/forms/text-field.d.ts +15 -0
- package/dist/components/forms/text-field.js +46 -0
- package/dist/components/forms/text-field.types.d.ts +8 -0
- package/dist/components/forms/textarea.d.ts +3 -0
- package/dist/components/forms/textarea.js +14 -0
- package/dist/components/layout/index.js +5 -0
- package/dist/components/layout/particle-background.d.ts +19 -0
- package/dist/components/layout/particle-background.js +171 -0
- package/dist/components/layout/scroll-area.d.ts +9 -0
- package/dist/components/layout/scroll-area.js +35 -0
- package/dist/components/layout/section-intro.d.ts +12 -0
- package/dist/components/layout/section-intro.js +28 -0
- package/dist/components/layout/surface-panel.d.ts +7 -0
- package/dist/components/layout/surface-panel.js +11 -0
- package/dist/components/navigation/app-navigation.d.ts +67 -0
- package/dist/components/navigation/app-navigation.js +106 -0
- package/{src/components/navigation/index.ts → dist/components/navigation/index.d.ts} +1 -7
- package/dist/components/navigation/index.js +4 -0
- package/dist/components/navigation/pagination-controls.d.ts +7 -0
- package/dist/components/navigation/pagination-controls.js +50 -0
- package/dist/components/navigation/tabs.d.ts +7 -0
- package/dist/components/navigation/tabs.js +35 -0
- package/dist/components/overlays/bottom-sheet.d.ts +20 -0
- package/dist/components/overlays/bottom-sheet.js +101 -0
- package/dist/components/overlays/command.d.ts +29 -0
- package/dist/components/overlays/command.js +123 -0
- package/dist/components/overlays/dialog.d.ts +30 -0
- package/dist/components/overlays/dialog.js +105 -0
- package/dist/components/overlays/dropdown-menu.d.ts +29 -0
- package/dist/components/overlays/dropdown-menu.js +128 -0
- package/dist/components/overlays/index.d.ts +7 -0
- package/dist/components/overlays/index.js +8 -0
- package/dist/components/overlays/popover.d.ts +14 -0
- package/dist/components/overlays/popover.js +56 -0
- package/dist/components/overlays/sheet.d.ts +27 -0
- package/dist/components/overlays/sheet.js +81 -0
- package/dist/components/overlays/tooltip.d.ts +10 -0
- package/dist/components/overlays/tooltip.js +23 -0
- package/dist/components/primitives/avatar.d.ts +14 -0
- package/dist/components/primitives/avatar.js +72 -0
- package/dist/components/primitives/badge.d.ts +7 -0
- package/dist/components/primitives/badge.js +27 -0
- package/dist/components/primitives/button.d.ts +13 -0
- package/dist/components/primitives/button.js +113 -0
- package/{src/components/primitives/button.types.ts → dist/components/primitives/button.types.d.ts} +4 -6
- package/dist/components/primitives/card.d.ts +9 -0
- package/dist/components/primitives/card.js +56 -0
- package/{src/components/primitives/index.ts → dist/components/primitives/index.d.ts} +1 -9
- package/dist/components/primitives/index.js +7 -0
- package/dist/components/primitives/segmented-control.d.ts +20 -0
- package/dist/components/primitives/segmented-control.js +27 -0
- package/dist/components/primitives/separator.d.ts +4 -0
- package/dist/components/primitives/separator.js +16 -0
- package/dist/constants/chart-colors.d.ts +33 -0
- package/dist/constants/chart-colors.js +31 -0
- package/dist/hooks/index.js +9 -0
- package/{src/hooks/sort.types.ts → dist/hooks/sort.types.d.ts} +2 -4
- package/dist/hooks/use-api-client.d.ts +30 -0
- package/dist/hooks/use-api-client.js +106 -0
- package/dist/hooks/use-debounced-value.d.ts +1 -0
- package/dist/hooks/use-debounced-value.js +12 -0
- package/dist/hooks/use-derived-filter-state.d.ts +20 -0
- package/dist/hooks/use-derived-filter-state.js +39 -0
- package/dist/hooks/use-filter-state.d.ts +12 -0
- package/dist/hooks/use-filter-state.js +37 -0
- package/dist/hooks/use-media-query.d.ts +6 -0
- package/dist/hooks/use-media-query.js +27 -0
- package/dist/hooks/use-mobile.d.ts +1 -0
- package/dist/hooks/use-mobile.js +14 -0
- package/dist/hooks/use-sort.d.ts +11 -0
- package/dist/hooks/use-sort.js +14 -0
- package/{src/index.ts → dist/index.d.ts} +4 -32
- package/dist/index.js +15 -0
- package/dist/integrations/service-worker.d.ts +2 -0
- package/dist/integrations/service-worker.js +2 -0
- package/dist/lib/auth.d.ts +2 -0
- package/dist/lib/auth.js +7 -0
- package/dist/lib/clipboard.d.ts +1 -0
- package/dist/lib/clipboard.js +10 -0
- package/dist/lib/index.js +4 -0
- package/{src/lib/slot.tsx → dist/lib/slot.d.ts} +2 -15
- package/dist/lib/slot.js +14 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +8 -0
- package/dist/native/components.d.ts +41 -0
- package/dist/native/components.js +135 -0
- package/dist/native/index.js +3 -0
- package/dist/native/theme.d.ts +19 -0
- package/dist/native/theme.js +58 -0
- package/dist/styles/tokens/css-vars.d.ts +7 -0
- package/dist/styles/tokens/css-vars.js +5 -0
- package/dist/styles/tokens/generated/dark.colors.generated.d.ts +40 -0
- package/dist/styles/tokens/generated/dark.colors.generated.js +39 -0
- package/dist/styles/tokens/generated/foundations.generated.d.ts +323 -0
- package/dist/styles/tokens/generated/foundations.generated.js +453 -0
- package/dist/styles/tokens/generated/light.colors.generated.d.ts +40 -0
- package/dist/styles/tokens/generated/light.colors.generated.js +39 -0
- package/dist/styles/tokens/index.d.ts +317 -0
- package/dist/styles/tokens/index.js +14 -0
- package/dist/styles.css +1 -1
- package/dist/translations/en.d.ts +34 -0
- package/dist/translations/index.d.ts +39 -0
- package/dist/translations/ui-provider.d.ts +9 -0
- package/dist/translations/ui-provider.js +16 -0
- package/dist/types/upload.d.ts +36 -0
- package/package.json +50 -33
- package/src/components/data-display/accordion.stories.tsx +0 -57
- package/src/components/data-display/accordion.tsx +0 -86
- package/src/components/data-display/metric-card.stories.tsx +0 -48
- package/src/components/data-display/metric-card.tsx +0 -20
- package/src/components/data-display/sort-controls.stories.tsx +0 -45
- package/src/components/data-display/sort-controls.tsx +0 -96
- package/src/components/data-display/sort-row.tsx +0 -88
- package/src/components/data-display/table.stories.tsx +0 -75
- package/src/components/data-display/table.tsx +0 -80
- package/src/components/feedback/alert.stories.tsx +0 -51
- package/src/components/feedback/alert.tsx +0 -64
- package/src/components/feedback/empty-state.tsx +0 -76
- package/src/components/feedback/progress.stories.tsx +0 -54
- package/src/components/feedback/progress.tsx +0 -41
- package/src/components/feedback/skeleton.stories.tsx +0 -36
- package/src/components/feedback/skeleton.tsx +0 -7
- package/src/components/feedback/spinner.stories.tsx +0 -52
- package/src/components/feedback/spinner.tsx +0 -47
- package/src/components/feedback/update-guard.stories.tsx +0 -28
- package/src/components/feedback/update-guard.tsx +0 -57
- package/src/components/filters/active-filters-bar.stories.tsx +0 -114
- package/src/components/filters/active-filters-bar.tsx +0 -61
- package/src/components/filters/filter-chip.tsx +0 -57
- package/src/components/filters/filter-select.stories.tsx +0 -71
- package/src/components/filters/filter-select.tsx +0 -68
- package/src/components/forms/checkbox.stories.tsx +0 -35
- package/src/components/forms/checkbox.tsx +0 -38
- package/src/components/forms/date-month-select.stories.tsx +0 -26
- package/src/components/forms/date-month-select.tsx +0 -79
- package/src/components/forms/date-picker.stories.tsx +0 -188
- package/src/components/forms/date-picker.tsx +0 -303
- package/src/components/forms/date-utils.ts +0 -37
- package/src/components/forms/drop-zone.stories.tsx +0 -140
- package/src/components/forms/drop-zone.tsx +0 -298
- package/src/components/forms/input.stories.tsx +0 -47
- package/src/components/forms/input.tsx +0 -24
- package/src/components/forms/label.stories.tsx +0 -16
- package/src/components/forms/label.tsx +0 -25
- package/src/components/forms/passkey-management.stories.tsx +0 -85
- package/src/components/forms/passkey-management.tsx +0 -168
- package/src/components/forms/radio-group.stories.tsx +0 -46
- package/src/components/forms/radio-group.tsx +0 -44
- package/src/components/forms/select.stories.tsx +0 -207
- package/src/components/forms/select.tsx +0 -182
- package/src/components/forms/slider.stories.tsx +0 -70
- package/src/components/forms/slider.tsx +0 -50
- package/src/components/forms/stepper.stories.tsx +0 -111
- package/src/components/forms/stepper.tsx +0 -66
- package/src/components/forms/switch.stories.tsx +0 -144
- package/src/components/forms/switch.tsx +0 -39
- package/src/components/forms/text-field.stories.tsx +0 -87
- package/src/components/forms/text-field.tsx +0 -75
- package/src/components/forms/text-field.types.ts +0 -9
- package/src/components/forms/textarea.stories.tsx +0 -150
- package/src/components/forms/textarea.tsx +0 -22
- package/src/components/layout/particle-background.stories.tsx +0 -38
- package/src/components/layout/particle-background.tsx +0 -378
- package/src/components/layout/scroll-area.stories.tsx +0 -91
- package/src/components/layout/scroll-area.tsx +0 -79
- package/src/components/layout/section-intro.stories.tsx +0 -29
- package/src/components/layout/section-intro.tsx +0 -31
- package/src/components/layout/surface-panel.stories.tsx +0 -32
- package/src/components/layout/surface-panel.tsx +0 -23
- package/src/components/navigation/app-navigation.stories.tsx +0 -217
- package/src/components/navigation/app-navigation.tsx +0 -234
- package/src/components/navigation/pagination-controls.stories.tsx +0 -41
- package/src/components/navigation/pagination-controls.tsx +0 -46
- package/src/components/navigation/tabs.stories.tsx +0 -48
- package/src/components/navigation/tabs.tsx +0 -52
- package/src/components/overlays/bottom-sheet.stories.tsx +0 -52
- package/src/components/overlays/bottom-sheet.tsx +0 -179
- package/src/components/overlays/command.stories.tsx +0 -65
- package/src/components/overlays/command.tsx +0 -227
- package/src/components/overlays/dialog.stories.tsx +0 -148
- package/src/components/overlays/dialog.tsx +0 -203
- package/src/components/overlays/dropdown-menu.stories.tsx +0 -74
- package/src/components/overlays/dropdown-menu.tsx +0 -236
- package/src/components/overlays/index.ts +0 -56
- package/src/components/overlays/popover.stories.tsx +0 -51
- package/src/components/overlays/popover.tsx +0 -78
- package/src/components/overlays/sheet.stories.tsx +0 -68
- package/src/components/overlays/sheet.tsx +0 -155
- package/src/components/overlays/tooltip.stories.tsx +0 -29
- package/src/components/overlays/tooltip.tsx +0 -41
- package/src/components/primitives/avatar-placeholder.svg +0 -13
- package/src/components/primitives/avatar.stories.tsx +0 -72
- package/src/components/primitives/avatar.tsx +0 -136
- package/src/components/primitives/badge.stories.tsx +0 -43
- package/src/components/primitives/badge.tsx +0 -43
- package/src/components/primitives/button.stories.tsx +0 -113
- package/src/components/primitives/button.tsx +0 -131
- package/src/components/primitives/card.stories.tsx +0 -59
- package/src/components/primitives/card.tsx +0 -66
- package/src/components/primitives/segmented-control.stories.tsx +0 -54
- package/src/components/primitives/segmented-control.tsx +0 -73
- package/src/components/primitives/separator.stories.tsx +0 -34
- package/src/components/primitives/separator.tsx +0 -27
- package/src/constants/chart-colors.ts +0 -39
- package/src/env.d.ts +0 -9
- package/src/hooks/use-api-client.ts +0 -122
- package/src/hooks/use-debounced-value.ts +0 -12
- package/src/hooks/use-derived-filter-state.ts +0 -70
- package/src/hooks/use-filter-state.ts +0 -66
- package/src/hooks/use-media-query.ts +0 -69
- package/src/hooks/use-mobile.tsx +0 -19
- package/src/hooks/use-sort.ts +0 -20
- package/src/lib/auth.ts +0 -5
- package/src/lib/clipboard.ts +0 -8
- package/src/lib/utils.ts +0 -6
- package/src/native/components.tsx +0 -198
- package/src/native/theme.tsx +0 -69
- package/src/storybook/controls.ts +0 -117
- package/src/storybook/options.ts +0 -52
- package/src/styles/build.ts +0 -1
- package/src/styles/index.css +0 -423
- package/src/styles/nokia.css +0 -36
- package/src/styles/package.css +0 -3
- package/src/styles/tokens/chart-colors.stories.tsx +0 -189
- package/src/styles/tokens/color-systems.stories.tsx +0 -190
- package/src/styles/tokens/css-vars.ts +0 -15
- package/src/styles/tokens/generated/dark-class.css +0 -39
- package/src/styles/tokens/generated/dark.colors.generated.ts +0 -39
- package/src/styles/tokens/generated/dark.css +0 -39
- package/src/styles/tokens/generated/foundations.css +0 -149
- package/src/styles/tokens/generated/foundations.generated.ts +0 -454
- package/src/styles/tokens/generated/light.colors.generated.ts +0 -39
- package/src/styles/tokens/generated/light.css +0 -39
- package/src/styles/tokens/index.ts +0 -70
- package/src/styles/tokens/layout.stories.tsx +0 -50
- package/src/styles/tokens/scripts/check-foundations.mjs +0 -126
- package/src/styles/tokens/scripts/check-source.mjs +0 -53
- package/src/styles/tokens/source/dark.tokens.json +0 -138
- package/src/styles/tokens/source/foundations.tokens.json +0 -344
- package/src/styles/tokens/source/light.tokens.json +0 -138
- package/src/styles/tokens/style-dictionary.dark-class.json +0 -16
- package/src/styles/tokens/style-dictionary.dark-storybook.json +0 -16
- package/src/styles/tokens/style-dictionary.dark.json +0 -21
- package/src/styles/tokens/style-dictionary.foundations.json +0 -21
- package/src/styles/tokens/style-dictionary.light-storybook.json +0 -16
- package/src/styles/tokens/style-dictionary.light.json +0 -21
- package/src/styles/tokens/typography.stories.tsx +0 -157
- package/src/translations/en.ts +0 -34
- package/src/translations/index.ts +0 -32
- package/src/types/upload.ts +0 -42
- /package/{src/components/filters/index.ts → dist/components/filters/index.d.ts} +0 -0
- /package/{src/components/layout/index.ts → dist/components/layout/index.d.ts} +0 -0
- /package/{src/hooks/index.ts → dist/hooks/index.d.ts} +0 -0
- /package/{src/lib/index.ts → dist/lib/index.d.ts} +0 -0
- /package/{src/native/index.ts → dist/native/index.d.ts} +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { Button as t } from "../primitives/button.js";
|
|
4
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
5
|
+
import { Minus as i, Plus as a } from "lucide-react";
|
|
6
|
+
//#region src/components/forms/stepper.tsx
|
|
7
|
+
function o({ value: o, min: s = 0, max: c = 100, step: l = 1, format: u, onChange: d, className: f, disabled: p, increaseLabel: m = "Increase", decreaseLabel: h = "Decrease" }) {
|
|
8
|
+
let g = o <= s, _ = o >= c;
|
|
9
|
+
return /* @__PURE__ */ r("div", {
|
|
10
|
+
className: e("border-input bg-muted flex items-center rounded-lg border", f),
|
|
11
|
+
children: [
|
|
12
|
+
/* @__PURE__ */ n(t, {
|
|
13
|
+
type: "button",
|
|
14
|
+
variant: "ghost",
|
|
15
|
+
onClick: () => d(Math.max(s, o - l)),
|
|
16
|
+
disabled: p || g,
|
|
17
|
+
className: "text-muted-foreground rounded-none rounded-l-lg border-r",
|
|
18
|
+
"aria-label": h,
|
|
19
|
+
children: /* @__PURE__ */ n(i, { className: "size-3.5" })
|
|
20
|
+
}),
|
|
21
|
+
/* @__PURE__ */ n("div", {
|
|
22
|
+
className: "flex min-w-[3ch] flex-1 items-center justify-center px-3",
|
|
23
|
+
children: /* @__PURE__ */ n("span", {
|
|
24
|
+
className: "text-foreground text-sm font-semibold tabular-nums",
|
|
25
|
+
children: u ? u(o) : o
|
|
26
|
+
})
|
|
27
|
+
}),
|
|
28
|
+
/* @__PURE__ */ n(t, {
|
|
29
|
+
type: "button",
|
|
30
|
+
variant: "ghost",
|
|
31
|
+
onClick: () => d(Math.min(c, o + l)),
|
|
32
|
+
disabled: p || _,
|
|
33
|
+
className: "text-muted-foreground rounded-none rounded-r-lg border-l",
|
|
34
|
+
"aria-label": m,
|
|
35
|
+
children: /* @__PURE__ */ n(a, { className: "size-3.5" })
|
|
36
|
+
})
|
|
37
|
+
]
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { o as Stepper };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Switch as SwitchPrimitive } from "@base-ui/react/switch";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
declare function Switch({ className, size, ...props }: React.ComponentProps<typeof SwitchPrimitive.Root> & {
|
|
4
|
+
size?: "sm" | "default";
|
|
5
|
+
}): React.JSX.Element;
|
|
6
|
+
export { Switch };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import "react";
|
|
4
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
5
|
+
import { Switch as n } from "@base-ui/react/switch";
|
|
6
|
+
//#region src/components/forms/switch.tsx
|
|
7
|
+
function r({ className: r, size: i = "default", ...a }) {
|
|
8
|
+
return /* @__PURE__ */ t(n.Root, {
|
|
9
|
+
"data-slot": "switch",
|
|
10
|
+
"data-size": i,
|
|
11
|
+
className: e("peer inline-flex shrink-0 items-center rounded-full border border-transparent p-px", "data-checked:bg-primary data-unchecked:bg-input data-checked:justify-end data-unchecked:justify-start", "focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none", "disabled:cursor-not-allowed disabled:opacity-50", i === "default" ? "h-[1.15rem] w-8" : "h-3.5 w-6", r),
|
|
12
|
+
...a,
|
|
13
|
+
children: /* @__PURE__ */ t(n.Thumb, {
|
|
14
|
+
"data-slot": "switch-thumb",
|
|
15
|
+
"data-size": i,
|
|
16
|
+
className: e("pointer-events-none block rounded-full bg-background shadow-sm ring-1 ring-border/5 transition-all", i === "default" ? "size-4" : "size-3")
|
|
17
|
+
})
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { r as Switch };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { TextFieldBaseProps, TextFieldType } from "./text-field.types";
|
|
3
|
+
interface TextFieldProps extends Omit<React.ComponentProps<"input">, "type">, TextFieldBaseProps {
|
|
4
|
+
type?: TextFieldType | undefined;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* TextField — composed input with label, helper text, and error state.
|
|
8
|
+
* Replaces raw `<input>` + `<label>` + error span patterns in feature code.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* <TextField label="Email" type="email" error={errors.email?.message} />
|
|
12
|
+
* <TextField label="Search" type="search" helpText="Press Enter to search" />
|
|
13
|
+
*/
|
|
14
|
+
declare function TextField({ id, label, helpText, error, className, disabled, type, ...inputProps }: TextFieldProps): React.JSX.Element;
|
|
15
|
+
export { TextField, type TextFieldProps };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { Input as t } from "./input.js";
|
|
4
|
+
import * as n from "react";
|
|
5
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/forms/text-field.tsx
|
|
7
|
+
function a({ id: a, label: o, helpText: s, error: c, className: l, disabled: u, type: d = "text", ...f }) {
|
|
8
|
+
let p = n.useId(), m = a ?? p, h = `${m}-description`, g = `${m}-error`;
|
|
9
|
+
return !o && !s && !c ? /* @__PURE__ */ r(t, {
|
|
10
|
+
id: m,
|
|
11
|
+
className: l,
|
|
12
|
+
disabled: u,
|
|
13
|
+
type: d,
|
|
14
|
+
...f
|
|
15
|
+
}) : /* @__PURE__ */ i("div", {
|
|
16
|
+
className: "flex flex-col gap-1.5",
|
|
17
|
+
children: [
|
|
18
|
+
o && /* @__PURE__ */ r("label", {
|
|
19
|
+
htmlFor: m,
|
|
20
|
+
className: e("text-foreground text-sm font-medium", f.required && "after:text-destructive-text after:ml-0.5 after:content-['*']"),
|
|
21
|
+
children: o
|
|
22
|
+
}),
|
|
23
|
+
/* @__PURE__ */ r(t, {
|
|
24
|
+
id: m,
|
|
25
|
+
className: l,
|
|
26
|
+
disabled: u,
|
|
27
|
+
type: d,
|
|
28
|
+
"aria-describedby": c ? g : s ? h : void 0,
|
|
29
|
+
"aria-invalid": c ? !0 : void 0,
|
|
30
|
+
...f
|
|
31
|
+
}),
|
|
32
|
+
c ? /* @__PURE__ */ r("p", {
|
|
33
|
+
id: g,
|
|
34
|
+
role: "alert",
|
|
35
|
+
className: "text-destructive-text text-sm",
|
|
36
|
+
children: c
|
|
37
|
+
}) : s ? /* @__PURE__ */ r("p", {
|
|
38
|
+
id: h,
|
|
39
|
+
className: "text-muted-foreground text-sm",
|
|
40
|
+
children: s
|
|
41
|
+
}) : null
|
|
42
|
+
]
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { a as TextField };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type TextFieldType = "text" | "email" | "password" | "search";
|
|
2
|
+
export interface TextFieldBaseProps {
|
|
3
|
+
disabled?: boolean | undefined;
|
|
4
|
+
error?: string | undefined;
|
|
5
|
+
helpText?: string | undefined;
|
|
6
|
+
label?: string | undefined;
|
|
7
|
+
id?: string | undefined;
|
|
8
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import "react";
|
|
4
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/forms/textarea.tsx
|
|
6
|
+
function n({ className: n, ...r }) {
|
|
7
|
+
return /* @__PURE__ */ t("textarea", {
|
|
8
|
+
"data-slot": "textarea",
|
|
9
|
+
className: e("border-input flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base transition-colors md:text-sm", "placeholder:text-muted-foreground", "focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none", "disabled:cursor-not-allowed disabled:opacity-50", "aria-invalid:ring-destructive/20 aria-invalid:border-destructive", n),
|
|
10
|
+
...r
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { n as Textarea };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ParticleBackground as e } from "./particle-background.js";
|
|
2
|
+
import { ScrollArea as t } from "./scroll-area.js";
|
|
3
|
+
import { SectionIntro as n } from "./section-intro.js";
|
|
4
|
+
import { SurfacePanel as r } from "./surface-panel.js";
|
|
5
|
+
export { e as ParticleBackground, t as ScrollArea, n as SectionIntro, r as SurfacePanel };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface ParticleBackgroundPalette {
|
|
3
|
+
particle: string;
|
|
4
|
+
link: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ParticleBackgroundProps extends React.ComponentProps<"div"> {
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
interactive?: boolean;
|
|
9
|
+
particleCount?: number;
|
|
10
|
+
particleDensity?: number;
|
|
11
|
+
maxLinkDistance?: number;
|
|
12
|
+
attractRadius?: number;
|
|
13
|
+
attractStrength?: number;
|
|
14
|
+
velocity?: number;
|
|
15
|
+
showGradient?: boolean;
|
|
16
|
+
palette?: ParticleBackgroundPalette;
|
|
17
|
+
}
|
|
18
|
+
/** Animated canvas background of drifting, linked particles. Skips rendering under `prefers-reduced-motion`. */
|
|
19
|
+
export declare function ParticleBackground({ className, enabled, interactive, particleCount, particleDensity, maxLinkDistance, attractRadius, attractStrength, velocity, showGradient: _showGradient, palette, ...props }: ParticleBackgroundProps): React.JSX.Element | null;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useMediaQuery as e } from "../../hooks/use-media-query.js";
|
|
3
|
+
import { cn as t } from "../../lib/utils.js";
|
|
4
|
+
import * as n from "react";
|
|
5
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/layout/particle-background.tsx
|
|
7
|
+
var i = 320, a = 2800, o = 90, s = .003, c = 150, l = .06, u = .015, d = 2e-4, f = 8e-4, p = .2, m = {
|
|
8
|
+
particle: "15,23,42",
|
|
9
|
+
link: "15,23,42"
|
|
10
|
+
};
|
|
11
|
+
function h(e, t) {
|
|
12
|
+
return typeof window > "u" ? t : getComputedStyle(document.documentElement).getPropertyValue(e).trim() || t;
|
|
13
|
+
}
|
|
14
|
+
function g(e) {
|
|
15
|
+
if (e.startsWith("#")) {
|
|
16
|
+
let t = e.slice(1);
|
|
17
|
+
t.length === 3 && (t = t.split("").map((e) => e + e).join(""));
|
|
18
|
+
let n = Number.parseInt(t, 16);
|
|
19
|
+
return `${n >> 16 & 255},${n >> 8 & 255},${n & 255}`;
|
|
20
|
+
}
|
|
21
|
+
let t = e.match(/rgba?\(([^)]+)\)/);
|
|
22
|
+
return t ? t[1].split(",").slice(0, 3).map((e) => e.trim()).join(",") : m.particle;
|
|
23
|
+
}
|
|
24
|
+
function _() {
|
|
25
|
+
let [e, t] = n.useState(m);
|
|
26
|
+
return n.useEffect(() => {
|
|
27
|
+
let e = () => {
|
|
28
|
+
let e = g(h("--color-primary", "#0969da")), n = g(h("--color-foreground", "#25292e"));
|
|
29
|
+
t({
|
|
30
|
+
particle: e,
|
|
31
|
+
link: n
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
e();
|
|
35
|
+
let n = window.matchMedia("(prefers-color-scheme: dark)");
|
|
36
|
+
return n.addEventListener("change", e), () => {
|
|
37
|
+
n.removeEventListener("change", e);
|
|
38
|
+
};
|
|
39
|
+
}, []), e;
|
|
40
|
+
}
|
|
41
|
+
function v() {
|
|
42
|
+
let [e, t] = n.useState("light");
|
|
43
|
+
return n.useEffect(() => {
|
|
44
|
+
let e = window.matchMedia("(prefers-color-scheme: dark)"), n = () => t(e.matches ? "dark" : "light");
|
|
45
|
+
return n(), e.addEventListener("change", n), () => {
|
|
46
|
+
e.removeEventListener("change", n);
|
|
47
|
+
};
|
|
48
|
+
}, []), e;
|
|
49
|
+
}
|
|
50
|
+
function y({ className: m, enabled: h = !0, interactive: g = !0, particleCount: y, particleDensity: b = a, maxLinkDistance: x = o, attractRadius: S = c, attractStrength: C = s, velocity: w = l, showGradient: T = !0, palette: E, ...D }) {
|
|
51
|
+
let O = e("(prefers-reduced-motion: reduce)"), k = n.useRef(null), A = n.useRef({
|
|
52
|
+
x: -9999,
|
|
53
|
+
y: -9999
|
|
54
|
+
}), j = n.useRef([]), M = n.useRef(0), N = n.useRef(typeof window > "u" ? 0 : window.scrollY), P = v(), F = _(), I = E ?? F;
|
|
55
|
+
return n.useEffect(() => {
|
|
56
|
+
if (O || !h) return;
|
|
57
|
+
let e = k.current;
|
|
58
|
+
if (!e) return;
|
|
59
|
+
let t = e.getContext("2d");
|
|
60
|
+
if (!t) return;
|
|
61
|
+
let n = e, r = t;
|
|
62
|
+
function a() {
|
|
63
|
+
let e = n.getBoundingClientRect(), t = window.devicePixelRatio || 1;
|
|
64
|
+
n.width = Math.max(1, Math.round(e.width * t)), n.height = Math.max(1, Math.round(e.height * t)), r.setTransform(t, 0, 0, t, 0, 0);
|
|
65
|
+
let a = y ?? Math.max(80, Math.min(i, Math.round(e.width * e.height / b)));
|
|
66
|
+
j.current = Array.from({ length: a }, () => {
|
|
67
|
+
let t = Math.random();
|
|
68
|
+
return {
|
|
69
|
+
x: Math.random() * e.width,
|
|
70
|
+
y: Math.random() * e.height,
|
|
71
|
+
vx: (Math.random() - .5) * w * (.4 + t * .8),
|
|
72
|
+
vy: (Math.random() - .5) * w * (.4 + t * .8),
|
|
73
|
+
opacity: p * (.5 + t * .5),
|
|
74
|
+
depth: t,
|
|
75
|
+
twinklePhase: Math.random() * Math.PI * 2,
|
|
76
|
+
twinkleSpeed: d + Math.random() * (f - d)
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
let o = !1, s = !0, c = !document.hidden, l = [];
|
|
81
|
+
function m(e) {
|
|
82
|
+
let t = n.clientWidth, i = n.clientHeight;
|
|
83
|
+
r.clearRect(0, 0, t, i), r.lineCap = "round";
|
|
84
|
+
let a = j.current, s = N.current * u;
|
|
85
|
+
for (let n = 0; n < a.length; n++) {
|
|
86
|
+
let o = a[n], c = A.current.x - o.x, u = A.current.y - o.y, d = Math.sqrt(c * c + u * u);
|
|
87
|
+
if (g && d < S) {
|
|
88
|
+
let e = (1 - d / S) * C;
|
|
89
|
+
o.vx += c * e, o.vy += u * e;
|
|
90
|
+
}
|
|
91
|
+
o.vx *= .98, o.vy *= .98, o.x += o.vx, o.y += o.vy, o.x < 0 && (o.x = t), o.x > t && (o.x = 0), o.y < 0 && (o.y = i), o.y > i && (o.y = 0);
|
|
92
|
+
let f = ((o.y + s * o.depth) % i + i) % i;
|
|
93
|
+
l[n] = {
|
|
94
|
+
x: o.x,
|
|
95
|
+
y: f
|
|
96
|
+
};
|
|
97
|
+
let p = .6 + .4 * Math.sin(e * o.twinkleSpeed + o.twinklePhase), m = .6 + o.depth * 1.4;
|
|
98
|
+
r.beginPath(), r.arc(o.x, f, m, 0, Math.PI * 2), r.fillStyle = `rgba(${I.particle},${o.opacity * p})`, r.fill();
|
|
99
|
+
for (let e = n + 1; e < a.length; e++) {
|
|
100
|
+
let t = a[e], n = l[e] ?? {
|
|
101
|
+
x: t.x,
|
|
102
|
+
y: t.y
|
|
103
|
+
}, i = o.x - t.x, s = f - n.y, c = Math.sqrt(i * i + s * s);
|
|
104
|
+
if (c < x) {
|
|
105
|
+
let e = (o.depth + t.depth) / 2, i = (1 - c / x) * (P === "dark" ? .015 : .01) * e;
|
|
106
|
+
r.beginPath(), r.moveTo(o.x, f), r.lineTo(n.x, n.y), r.strokeStyle = `rgba(${I.link},${i})`, r.lineWidth = .5, r.stroke();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
o && (M.current = requestAnimationFrame(m));
|
|
111
|
+
}
|
|
112
|
+
function _() {
|
|
113
|
+
let e = s && c;
|
|
114
|
+
e && !o ? (o = !0, M.current = requestAnimationFrame(m)) : !e && o && (o = !1, cancelAnimationFrame(M.current));
|
|
115
|
+
}
|
|
116
|
+
function v() {
|
|
117
|
+
a(), o || m(performance.now());
|
|
118
|
+
}
|
|
119
|
+
let T = new ResizeObserver(v);
|
|
120
|
+
T.observe(n), a(), m(performance.now()), _();
|
|
121
|
+
let E = (e) => {
|
|
122
|
+
let t = n.getBoundingClientRect();
|
|
123
|
+
A.current = {
|
|
124
|
+
x: e.clientX - t.left,
|
|
125
|
+
y: e.clientY - t.top
|
|
126
|
+
};
|
|
127
|
+
}, D = () => {
|
|
128
|
+
A.current = {
|
|
129
|
+
x: -9999,
|
|
130
|
+
y: -9999
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
g && (n.addEventListener("mousemove", E), n.addEventListener("mouseleave", D), document.addEventListener("mousemove", E));
|
|
134
|
+
let F = () => {
|
|
135
|
+
N.current = window.scrollY;
|
|
136
|
+
};
|
|
137
|
+
window.addEventListener("scroll", F, { passive: !0 });
|
|
138
|
+
let L = new IntersectionObserver(([e]) => {
|
|
139
|
+
s = e?.isIntersecting ?? !0, _();
|
|
140
|
+
}, { threshold: 0 });
|
|
141
|
+
L.observe(n);
|
|
142
|
+
let R = () => {
|
|
143
|
+
c = !document.hidden, _();
|
|
144
|
+
};
|
|
145
|
+
return document.addEventListener("visibilitychange", R), () => {
|
|
146
|
+
o = !1, cancelAnimationFrame(M.current), T.disconnect(), L.disconnect(), document.removeEventListener("mousemove", E), document.removeEventListener("visibilitychange", R), n.removeEventListener("mousemove", E), n.removeEventListener("mouseleave", D), window.removeEventListener("scroll", F);
|
|
147
|
+
};
|
|
148
|
+
}, [
|
|
149
|
+
S,
|
|
150
|
+
C,
|
|
151
|
+
h,
|
|
152
|
+
g,
|
|
153
|
+
x,
|
|
154
|
+
I,
|
|
155
|
+
y,
|
|
156
|
+
b,
|
|
157
|
+
O,
|
|
158
|
+
P,
|
|
159
|
+
w
|
|
160
|
+
]), !h || O ? null : /* @__PURE__ */ r("div", {
|
|
161
|
+
className: t("pointer-events-none absolute inset-0 overflow-hidden", m),
|
|
162
|
+
"aria-hidden": "true",
|
|
163
|
+
...D,
|
|
164
|
+
children: /* @__PURE__ */ r("canvas", {
|
|
165
|
+
ref: k,
|
|
166
|
+
className: "absolute inset-0 h-full w-full"
|
|
167
|
+
})
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
//#endregion
|
|
171
|
+
export { y as ParticleBackground };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ScrollArea as ScrollAreaPrimitive } from "@base-ui/react/scroll-area";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
interface ScrollAreaProps extends React.ComponentProps<typeof ScrollAreaPrimitive.Root> {
|
|
4
|
+
orientation?: "horizontal" | "vertical";
|
|
5
|
+
snap?: "start" | "center" | "none";
|
|
6
|
+
}
|
|
7
|
+
declare const ScrollArea: React.ForwardRefExoticComponent<Omit<ScrollAreaProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
8
|
+
export { ScrollArea };
|
|
9
|
+
export type { ScrollAreaProps };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import * as t from "react";
|
|
4
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
5
|
+
import { ScrollArea as i } from "@base-ui/react/scroll-area";
|
|
6
|
+
//#region src/components/layout/scroll-area.tsx
|
|
7
|
+
var a = {
|
|
8
|
+
start: "snap-start",
|
|
9
|
+
center: "snap-center",
|
|
10
|
+
none: void 0
|
|
11
|
+
}, o = e("flex touch-none p-0.5 opacity-0 transition-opacity duration-150 ease-out", "data-[hovering]:opacity-100 data-[scrolling]:opacity-100", "data-[orientation=vertical]:w-2.5", "data-[orientation=horizontal]:h-2.5 data-[orientation=horizontal]:flex-col"), s = t.forwardRef(({ className: s, children: c, orientation: l = "horizontal", snap: u = "none", ...d }, f) => /* @__PURE__ */ r(i.Root, {
|
|
12
|
+
ref: f,
|
|
13
|
+
className: e("relative flex overflow-hidden", l === "horizontal" ? "flex-row" : "flex-col", s),
|
|
14
|
+
...d,
|
|
15
|
+
children: [
|
|
16
|
+
/* @__PURE__ */ n(i.Viewport, {
|
|
17
|
+
className: e("scrollbar-hide flex overflow-auto", l === "horizontal" ? "min-w-0 flex-1 flex-row" : "min-h-0 flex-1 flex-col", u !== "none" && (l === "horizontal" ? "snap-x" : "snap-y"), u !== "none" && "snap-mandatory"),
|
|
18
|
+
children: t.Children.map(c, (n) => t.isValidElement(n) ? t.cloneElement(n, { className: e(a[u], n.props.className) }) : n)
|
|
19
|
+
}),
|
|
20
|
+
/* @__PURE__ */ n(i.Scrollbar, {
|
|
21
|
+
orientation: "horizontal",
|
|
22
|
+
className: o,
|
|
23
|
+
children: /* @__PURE__ */ n(i.Thumb, { className: "bg-foreground/40 hover:bg-foreground/60 relative flex-1 rounded-full transition-colors duration-150 ease" })
|
|
24
|
+
}),
|
|
25
|
+
/* @__PURE__ */ n(i.Scrollbar, {
|
|
26
|
+
orientation: "vertical",
|
|
27
|
+
className: o,
|
|
28
|
+
children: /* @__PURE__ */ n(i.Thumb, { className: "bg-foreground/40 hover:bg-foreground/60 relative flex-1 rounded-full transition-colors duration-150 ease" })
|
|
29
|
+
}),
|
|
30
|
+
/* @__PURE__ */ n(i.Corner, {})
|
|
31
|
+
]
|
|
32
|
+
}));
|
|
33
|
+
s.displayName = "ScrollArea";
|
|
34
|
+
//#endregion
|
|
35
|
+
export { s as ScrollArea };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export interface SectionIntroProps {
|
|
3
|
+
eyebrow?: ReactNode;
|
|
4
|
+
title: ReactNode;
|
|
5
|
+
description?: ReactNode;
|
|
6
|
+
actions?: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Page-level heading composition: eyebrow label, title, description, and an
|
|
10
|
+
* optional trailing actions slot.
|
|
11
|
+
*/
|
|
12
|
+
export declare function SectionIntro({ eyebrow, title, description, actions }: SectionIntroProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as e, jsxs as t } from "react/jsx-runtime";
|
|
2
|
+
//#region src/components/layout/section-intro.tsx
|
|
3
|
+
function n({ eyebrow: n, title: r, description: i, actions: a }) {
|
|
4
|
+
return /* @__PURE__ */ t("div", {
|
|
5
|
+
className: "flex items-start justify-between gap-6",
|
|
6
|
+
children: [/* @__PURE__ */ t("div", {
|
|
7
|
+
className: "min-w-0 flex-1",
|
|
8
|
+
children: [n ? /* @__PURE__ */ e("div", {
|
|
9
|
+
className: "text-muted-foreground mb-3 text-[11px] font-medium tracking-[0.18em] uppercase",
|
|
10
|
+
children: n
|
|
11
|
+
}) : null, /* @__PURE__ */ t("div", {
|
|
12
|
+
className: "space-y-3",
|
|
13
|
+
children: [/* @__PURE__ */ e("h1", {
|
|
14
|
+
className: "text-2xl text-foreground font-semibold tracking-tight",
|
|
15
|
+
children: r
|
|
16
|
+
}), i ? /* @__PURE__ */ e("p", {
|
|
17
|
+
className: "text-muted-foreground text-sm",
|
|
18
|
+
children: i
|
|
19
|
+
}) : null]
|
|
20
|
+
})]
|
|
21
|
+
}), a ? /* @__PURE__ */ e("div", {
|
|
22
|
+
className: "shrink-0",
|
|
23
|
+
children: a
|
|
24
|
+
}) : null]
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { n as SectionIntro };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ElementType } from "react";
|
|
2
|
+
type SurfacePanelProps<T extends ElementType = "div"> = {
|
|
3
|
+
as?: T;
|
|
4
|
+
} & Omit<ComponentPropsWithoutRef<T>, "as">;
|
|
5
|
+
/** Rounded, bordered surface panel — a generic content container. */
|
|
6
|
+
export declare function SurfacePanel<T extends ElementType = "div">({ as, className, ...props }: SurfacePanelProps<T>): import("react").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { cn as e } from "../../lib/utils.js";
|
|
2
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
3
|
+
//#region src/components/layout/surface-panel.tsx
|
|
4
|
+
function n({ as: n, className: r, ...i }) {
|
|
5
|
+
return /* @__PURE__ */ t(n ?? "div", {
|
|
6
|
+
className: e("border-border bg-card rounded-3xl border p-5", r),
|
|
7
|
+
...i
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { n as SurfacePanel };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
/** @internal Undocumented — not part of the public API surface. */
|
|
4
|
+
type NavigationVariant = "nokia";
|
|
5
|
+
export interface NavigationRootProps {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
ariaLabel?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
/**
|
|
10
|
+
* @internal Undocumented mobile-Sheet skin, not part of the public API
|
|
11
|
+
* (no README/Storybook entry). Opt in at your own risk.
|
|
12
|
+
*/
|
|
13
|
+
variant?: NavigationVariant;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Sticky nav shell. Compose it with `Navigation.Brand`, `Navigation.List`
|
|
17
|
+
* (containing `Navigation.Item`s), and any other content — a CTA `Button`,
|
|
18
|
+
* a search input, a notification bell — as plain children. `Navigation`
|
|
19
|
+
* only owns the responsive chrome: `Navigation.Brand` stays visible at
|
|
20
|
+
* every width, everything else collapses into a Sheet-based mobile menu
|
|
21
|
+
* below `sm`, reusing the exact elements you composed (not a parallel data
|
|
22
|
+
* shape) so `Navigation.Item`'s active state and `asChild` composition
|
|
23
|
+
* behave identically in both places.
|
|
24
|
+
*/
|
|
25
|
+
declare function NavigationRoot({ children, ariaLabel, className, variant, }: NavigationRootProps): React.JSX.Element;
|
|
26
|
+
export interface NavigationBrandProps {
|
|
27
|
+
children: ReactNode;
|
|
28
|
+
className?: string;
|
|
29
|
+
}
|
|
30
|
+
/** Always visible, at every viewport width — compose your own link/logo markup directly. */
|
|
31
|
+
declare function NavigationBrand({ children, className }: NavigationBrandProps): React.JSX.Element;
|
|
32
|
+
export interface NavigationListProps {
|
|
33
|
+
children: ReactNode;
|
|
34
|
+
className?: string;
|
|
35
|
+
}
|
|
36
|
+
/** Semantic `<ul>` of `Navigation.Item`s. Lays out horizontally on desktop, stacks inside the mobile Sheet. */
|
|
37
|
+
declare function NavigationList({ children, className }: NavigationListProps): React.JSX.Element;
|
|
38
|
+
interface NavigationItemOwnProps {
|
|
39
|
+
active?: boolean;
|
|
40
|
+
/** Apply the item styling to a single child (e.g. your router's `Link`) instead of rendering an `<a>`. */
|
|
41
|
+
asChild?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export type NavigationItemProps = NavigationItemOwnProps & Omit<ComponentPropsWithoutRef<"a">, keyof NavigationItemOwnProps>;
|
|
44
|
+
/** A single nav link, wrapped in `<li>`. Auto-closes the mobile Sheet on click when rendered there. */
|
|
45
|
+
declare function NavigationItem({ active, asChild, className, children, ...props }: NavigationItemProps): React.JSX.Element;
|
|
46
|
+
export interface NavigationActionProps {
|
|
47
|
+
children: ReactNode;
|
|
48
|
+
className?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Layout wrapper for a CTA, avatar menu, theme toggle, etc. — bring your
|
|
52
|
+
* own `Button`, no dedicated CTA component needed. Content here does not
|
|
53
|
+
* auto-close the mobile Sheet on click (it may hold more than one
|
|
54
|
+
* element, or non-navigational controls) — use `Navigation.Item` instead
|
|
55
|
+
* for a link that should close the menu when tapped.
|
|
56
|
+
*/
|
|
57
|
+
declare function NavigationAction({ children, className }: NavigationActionProps): React.JSX.Element;
|
|
58
|
+
type NavigationComponent = typeof NavigationRoot & {
|
|
59
|
+
Brand: typeof NavigationBrand;
|
|
60
|
+
List: typeof NavigationList;
|
|
61
|
+
Item: typeof NavigationItem;
|
|
62
|
+
Action: typeof NavigationAction;
|
|
63
|
+
};
|
|
64
|
+
export declare const Navigation: NavigationComponent;
|
|
65
|
+
/** @deprecated Use `Navigation` instead. */
|
|
66
|
+
export declare const AppNavigation: NavigationComponent;
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { Button as t } from "../primitives/button.js";
|
|
4
|
+
import { Sheet as n, SheetClose as r, SheetContent as i, SheetTitle as a, SheetTrigger as o } from "../overlays/sheet.js";
|
|
5
|
+
import { Slot as s } from "../../lib/slot.js";
|
|
6
|
+
import * as c from "react";
|
|
7
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
8
|
+
import { Menu as d } from "lucide-react";
|
|
9
|
+
//#region src/components/navigation/app-navigation.tsx
|
|
10
|
+
var f = c.createContext({ isMobile: !1 }), p = "nokia-screen rounded-none border-[6px] border-nokia-bezel bg-nokia-screen p-4 font-nokia text-nokia-ink shadow-[0_0_0_3px_var(--color-nokia-screen-deep),0_10px_30px_-6px_rgba(0,0,0,0.65)]", m = "text-nokia-ink hover:bg-nokia-ink hover:text-nokia-screen rounded-none border-2 border-nokia-ink", h = "!grid grid-cols-3 gap-3", g = "!h-auto !max-h-none w-full flex-col justify-center gap-1 rounded-none border-2 border-nokia-ink/40 px-2 py-3 text-center font-nokia text-base tracking-widest uppercase hover:bg-transparent active:bg-nokia-ink active:text-nokia-screen data-[active]:border-nokia-ink data-[active]:bg-nokia-ink data-[active]:text-nokia-screen";
|
|
11
|
+
function _({ children: r, ariaLabel: s = "Primary navigation", className: h, variant: g }) {
|
|
12
|
+
let [_, y] = c.useState(!1), b = g === "nokia", x = c.Children.toArray(r), S = x.find((e) => c.isValidElement(e) && e.type === v), C = x.filter((e) => e !== S);
|
|
13
|
+
return /* @__PURE__ */ l("header", {
|
|
14
|
+
className: "bg-background/95 supports-backdrop-filter:bg-background/60 sticky top-0 z-50 flex w-full justify-center border-b px-4 backdrop-blur",
|
|
15
|
+
children: /* @__PURE__ */ u("nav", {
|
|
16
|
+
className: e("flex min-h-14 w-full max-w-7xl items-center justify-between gap-6", h),
|
|
17
|
+
"aria-label": s,
|
|
18
|
+
children: [
|
|
19
|
+
/* @__PURE__ */ l("div", {
|
|
20
|
+
className: "flex min-w-0 items-center",
|
|
21
|
+
children: S
|
|
22
|
+
}),
|
|
23
|
+
/* @__PURE__ */ l("div", {
|
|
24
|
+
className: "ml-auto hidden min-w-0 items-center gap-6 sm:flex",
|
|
25
|
+
children: C
|
|
26
|
+
}),
|
|
27
|
+
/* @__PURE__ */ l("div", {
|
|
28
|
+
className: "ml-auto flex items-center sm:hidden",
|
|
29
|
+
children: /* @__PURE__ */ u(n, {
|
|
30
|
+
open: _,
|
|
31
|
+
onOpenChange: y,
|
|
32
|
+
children: [/* @__PURE__ */ l(o, {
|
|
33
|
+
asChild: !0,
|
|
34
|
+
children: /* @__PURE__ */ l(t, {
|
|
35
|
+
variant: "outline",
|
|
36
|
+
size: "icon",
|
|
37
|
+
"aria-label": _ ? "Close menu" : "Open menu",
|
|
38
|
+
children: /* @__PURE__ */ l(d, {
|
|
39
|
+
className: "size-4",
|
|
40
|
+
"aria-hidden": "true"
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
}), /* @__PURE__ */ u(i, {
|
|
44
|
+
className: b ? p : void 0,
|
|
45
|
+
closeClassName: b ? m : void 0,
|
|
46
|
+
children: [/* @__PURE__ */ l(a, {
|
|
47
|
+
className: "sr-only",
|
|
48
|
+
children: "Navigation menu"
|
|
49
|
+
}), /* @__PURE__ */ l("div", {
|
|
50
|
+
className: "mt-8 flex flex-1 flex-col gap-4",
|
|
51
|
+
children: /* @__PURE__ */ l(f.Provider, {
|
|
52
|
+
value: {
|
|
53
|
+
isMobile: !0,
|
|
54
|
+
variant: g
|
|
55
|
+
},
|
|
56
|
+
children: C
|
|
57
|
+
})
|
|
58
|
+
})]
|
|
59
|
+
})]
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
]
|
|
63
|
+
})
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function v({ children: t, className: n }) {
|
|
67
|
+
return /* @__PURE__ */ l("div", {
|
|
68
|
+
className: e("flex items-center font-semibold", n),
|
|
69
|
+
children: t
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function y({ children: t, className: n }) {
|
|
73
|
+
let { isMobile: r, variant: i } = c.useContext(f);
|
|
74
|
+
return /* @__PURE__ */ l("ul", {
|
|
75
|
+
className: e("flex items-center gap-1", r && "flex-col items-stretch gap-1", r && i === "nokia" && h, n),
|
|
76
|
+
children: t
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function b({ active: t = !1, asChild: n = !1, className: i, children: a, ...o }) {
|
|
80
|
+
let { isMobile: u, variant: d } = c.useContext(f), p = e("inline-flex h-9 max-h-9 shrink-0 items-center px-3 py-2 text-sm font-medium hover:bg-muted hover:text-muted-foreground data-[active]:font-semibold data-[active]:text-foreground", u && d === "nokia" && g, i), m = l(n ? s : "a", {
|
|
81
|
+
...o,
|
|
82
|
+
"data-active": t || void 0,
|
|
83
|
+
"aria-current": t ? "page" : void 0,
|
|
84
|
+
className: p,
|
|
85
|
+
children: a
|
|
86
|
+
});
|
|
87
|
+
return /* @__PURE__ */ l("li", { children: u ? /* @__PURE__ */ l(r, {
|
|
88
|
+
asChild: !0,
|
|
89
|
+
children: m
|
|
90
|
+
}) : m });
|
|
91
|
+
}
|
|
92
|
+
function x({ children: t, className: n }) {
|
|
93
|
+
let { isMobile: r, variant: i } = c.useContext(f);
|
|
94
|
+
return /* @__PURE__ */ l("div", {
|
|
95
|
+
className: e("flex items-center gap-3", r && "mt-2 flex-col items-stretch gap-3 border-t pt-4", r && i === "nokia" && "border-nokia-ink/40", n),
|
|
96
|
+
children: t
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
var S = Object.assign(_, {
|
|
100
|
+
Brand: v,
|
|
101
|
+
List: y,
|
|
102
|
+
Item: b,
|
|
103
|
+
Action: x
|
|
104
|
+
}), C = S;
|
|
105
|
+
//#endregion
|
|
106
|
+
export { C as AppNavigation, S as Navigation };
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
export { AppNavigation, Navigation } from "./app-navigation";
|
|
2
|
-
export type {
|
|
3
|
-
NavigationActionProps,
|
|
4
|
-
NavigationBrandProps,
|
|
5
|
-
NavigationItemProps,
|
|
6
|
-
NavigationListProps,
|
|
7
|
-
NavigationRootProps,
|
|
8
|
-
} from "./app-navigation";
|
|
2
|
+
export type { NavigationActionProps, NavigationBrandProps, NavigationItemProps, NavigationListProps, NavigationRootProps, } from "./app-navigation";
|
|
9
3
|
export { PaginationControls } from "./pagination-controls";
|
|
10
4
|
export type { PaginationControlsProps } from "./pagination-controls";
|
|
11
5
|
export { Tabs, TabsContent, TabsList, TabsTrigger } from "./tabs";
|