@krizaka/ui 2.9.0 → 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 +44 -6
- package/dist/audio-player.js +1 -1
- package/dist/blocks.css +247 -0
- package/dist/catalogue-page.d.ts +34 -0
- package/dist/catalogue-page.js +26 -0
- package/dist/catalogue-page.js.map +1 -0
- package/dist/changelog-page.d.ts +50 -0
- package/dist/changelog-page.js +27 -0
- package/dist/changelog-page.js.map +1 -0
- package/dist/{chunk-EUPTXKH7.js → chunk-BRKMQ6JV.js} +2 -1
- package/dist/chunk-FDCMBWUU.js +168 -0
- package/dist/chunk-FDCMBWUU.js.map +1 -0
- package/dist/chunk-HCNOOPZE.js +210 -0
- package/dist/chunk-HCNOOPZE.js.map +1 -0
- package/dist/{chunk-NOVUREEC.js → chunk-JZPVUJIX.js} +25 -3
- package/dist/chunk-JZPVUJIX.js.map +1 -0
- package/dist/chunk-KNBYZGSQ.js +11 -0
- package/dist/chunk-KNBYZGSQ.js.map +1 -0
- package/dist/{chunk-X6TW3X6Y.js → chunk-LCZXS6AK.js} +2 -2
- package/dist/chunk-OGJI5X4W.js +157 -0
- package/dist/chunk-OGJI5X4W.js.map +1 -0
- package/dist/combobox.js +2 -2
- package/dist/component-page.d.ts +41 -0
- package/dist/component-page.js +17 -0
- package/dist/component-page.js.map +1 -0
- package/dist/contact-page.d.ts +31 -0
- package/dist/contact-page.js +26 -0
- package/dist/contact-page.js.map +1 -0
- package/dist/data-table.d.ts +284 -24
- package/dist/data-table.js +914 -121
- package/dist/data-table.js.map +1 -1
- package/dist/date-picker.js +1 -1
- package/dist/docs-article-page.d.ts +54 -0
- package/dist/docs-article-page.js +29 -0
- package/dist/docs-article-page.js.map +1 -0
- package/dist/docs-hub-page.d.ts +72 -0
- package/dist/docs-hub-page.js +45 -0
- package/dist/docs-hub-page.js.map +1 -0
- package/dist/error-page.d.ts +22 -0
- package/dist/error-page.js +23 -0
- package/dist/error-page.js.map +1 -0
- package/dist/filter-bar.d.ts +12 -12
- package/dist/filter-bar.js +9 -145
- package/dist/filter-bar.js.map +1 -1
- package/dist/gallery-page.d.ts +50 -0
- package/dist/gallery-page.js +30 -0
- package/dist/gallery-page.js.map +1 -0
- package/dist/{geometry-CXrAW34x.d.ts → geometry-CbOU4rtL.d.ts} +4 -4
- package/dist/how-it-works-page.d.ts +48 -0
- package/dist/how-it-works-page.js +28 -0
- package/dist/how-it-works-page.js.map +1 -0
- package/dist/image-cropper.js +1 -1
- package/dist/index.d.ts +11 -2
- package/dist/index.js +93 -5
- package/dist/index.js.map +1 -1
- package/dist/landing-page.d.ts +58 -0
- package/dist/landing-page.js +42 -0
- package/dist/landing-page.js.map +1 -0
- package/dist/legal-page.d.ts +34 -0
- package/dist/legal-page.js +18 -0
- package/dist/legal-page.js.map +1 -0
- package/dist/longform-page.d.ts +42 -0
- package/dist/longform-page.js +29 -0
- package/dist/longform-page.js.map +1 -0
- package/dist/mascot-quote.d.ts +4 -4
- package/dist/mascot-quote.js +23 -1
- package/dist/mascot-quote.js.map +1 -1
- package/dist/mascot-state.d.ts +2 -2
- package/dist/mascot-state.js +1 -1
- package/dist/mascot-state.js.map +1 -1
- package/dist/mascots.d.ts +4 -4
- package/dist/mascots.js +1 -1
- package/dist/media-capture.js +1 -1
- package/dist/native/list.d.ts +95 -0
- package/dist/native/list.js +135 -0
- package/dist/native/list.js.map +1 -0
- package/dist/native.d.ts +16 -9
- package/dist/native.js +183 -74
- package/dist/native.js.map +1 -1
- package/dist/pricing-page.d.ts +62 -0
- package/dist/pricing-page.js +71 -0
- package/dist/pricing-page.js.map +1 -0
- package/dist/product-page.d.ts +83 -0
- package/dist/product-page.js +60 -0
- package/dist/product-page.js.map +1 -0
- package/dist/search-field.js +6 -160
- package/dist/search-field.js.map +1 -1
- package/dist/status-page.d.ts +42 -0
- package/dist/status-page.js +28 -0
- package/dist/status-page.js.map +1 -0
- package/dist/tag-input.js +2 -2
- package/dist/video-player.js +1 -1
- package/dist/video-trimmer.js +1 -1
- package/dist/virtual.d.ts +140 -0
- package/dist/virtual.js +19 -0
- package/dist/virtual.js.map +1 -0
- package/package.json +296 -10
- package/registry/achievement.json +1 -1
- package/registry/action-bar.json +1 -1
- package/registry/alert.json +1 -1
- package/registry/app-shell.json +1 -1
- package/registry/argument-card.json +1 -1
- package/registry/audio-player.json +1 -1
- package/registry/auth-layout.json +1 -1
- package/registry/avatar.json +1 -1
- package/registry/badge.json +1 -1
- package/registry/button.json +1 -1
- package/registry/card-grid.json +1 -1
- package/registry/card.json +1 -1
- package/registry/catalogue-page.json +240 -0
- package/registry/changelog-page.json +226 -0
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +1 -1
- package/registry/chip.json +1 -1
- package/registry/choice-grid.json +1 -1
- package/registry/code-block.json +1 -1
- package/registry/combobox.json +1 -1
- package/registry/command.json +1 -1
- package/registry/component-page.json +227 -0
- package/registry/confirm-button.json +1 -1
- package/registry/contact-page.json +212 -0
- package/registry/continue-prompt.json +1 -1
- package/registry/countdown.json +1 -1
- package/registry/cta-panel.json +1 -1
- package/registry/dashboard-layout.json +1 -1
- package/registry/data-table.json +643 -49
- package/registry/date-picker.json +1 -1
- package/registry/decision-list.json +1 -1
- package/registry/detail-layout.json +1 -1
- package/registry/dialog.json +1 -1
- package/registry/docs-article-page.json +242 -0
- package/registry/docs-hub-page.json +270 -0
- package/registry/docs-layout.json +1 -1
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/error-page.json +183 -0
- package/registry/examples/catalogue-page/components.d.ts +4 -0
- package/registry/examples/catalogue-page/components.js +33 -0
- package/registry/examples/catalogue-page/components.tsx +36 -0
- package/registry/examples/changelog-page/releases.d.ts +4 -0
- package/registry/examples/changelog-page/releases.js +44 -0
- package/registry/examples/changelog-page/releases.tsx +39 -0
- package/registry/examples/component-page/button.d.ts +4 -0
- package/registry/examples/component-page/button.js +33 -0
- package/registry/examples/component-page/button.tsx +30 -0
- package/registry/examples/contact-page/team.d.ts +4 -0
- package/registry/examples/contact-page/team.js +39 -0
- package/registry/examples/contact-page/team.tsx +38 -0
- package/registry/examples/data-table/details.d.ts +4 -0
- package/registry/examples/data-table/details.js +33 -0
- package/registry/examples/data-table/details.tsx +31 -0
- package/registry/examples/data-table/filters.d.ts +4 -0
- package/registry/examples/data-table/filters.js +40 -0
- package/registry/examples/data-table/filters.tsx +40 -0
- package/registry/examples/data-table/grouped.d.ts +4 -0
- package/registry/examples/data-table/grouped.js +24 -0
- package/registry/examples/data-table/grouped.tsx +23 -0
- package/registry/examples/data-table/paginated.d.ts +4 -0
- package/registry/examples/data-table/paginated.js +23 -0
- package/registry/examples/data-table/paginated.tsx +22 -0
- package/registry/examples/data-table/pinned.d.ts +4 -0
- package/registry/examples/data-table/pinned.js +26 -0
- package/registry/examples/data-table/pinned.tsx +25 -0
- package/registry/examples/data-table/server.d.ts +4 -0
- package/registry/examples/data-table/server.js +40 -0
- package/registry/examples/data-table/server.tsx +40 -0
- package/registry/examples/data-table/virtualized.js +2 -2
- package/registry/examples/data-table/virtualized.tsx +3 -3
- package/registry/examples/docs-article-page/cli.d.ts +4 -0
- package/registry/examples/docs-article-page/cli.js +33 -0
- package/registry/examples/docs-article-page/cli.tsx +38 -0
- package/registry/examples/docs-hub-page/krizaka.d.ts +4 -0
- package/registry/examples/docs-hub-page/krizaka.js +46 -0
- package/registry/examples/docs-hub-page/krizaka.tsx +37 -0
- package/registry/examples/error-page/not-found.d.ts +4 -0
- package/registry/examples/error-page/not-found.js +24 -0
- package/registry/examples/error-page/not-found.tsx +19 -0
- package/registry/examples/gallery-page/made-here.d.ts +4 -0
- package/registry/examples/gallery-page/made-here.js +34 -0
- package/registry/examples/gallery-page/made-here.tsx +32 -0
- package/registry/examples/how-it-works-page/orazaka.d.ts +4 -0
- package/registry/examples/how-it-works-page/orazaka.js +30 -0
- package/registry/examples/how-it-works-page/orazaka.tsx +26 -0
- package/registry/examples/landing-page/krizaka.d.ts +4 -0
- package/registry/examples/landing-page/krizaka.js +44 -0
- package/registry/examples/landing-page/krizaka.tsx +44 -0
- package/registry/examples/legal-page/privacy.d.ts +4 -0
- package/registry/examples/legal-page/privacy.js +24 -0
- package/registry/examples/legal-page/privacy.tsx +19 -0
- package/registry/examples/list/native/default.d.ts +4 -0
- package/registry/examples/list/native/default.dark.png +0 -0
- package/registry/examples/list/native/default.js +33 -0
- package/registry/examples/list/native/default.light.png +0 -0
- package/registry/examples/list/native/default.tsx +31 -0
- package/registry/examples/list/native/infinite.d.ts +4 -0
- package/registry/examples/list/native/infinite.dark.png +0 -0
- package/registry/examples/list/native/infinite.js +30 -0
- package/registry/examples/list/native/infinite.light.png +0 -0
- package/registry/examples/list/native/infinite.tsx +35 -0
- package/registry/examples/list/native/states.d.ts +4 -0
- package/registry/examples/list/native/states.dark.png +0 -0
- package/registry/examples/list/native/states.js +26 -0
- package/registry/examples/list/native/states.light.png +0 -0
- package/registry/examples/list/native/states.tsx +21 -0
- package/registry/examples/longform-page/story.d.ts +4 -0
- package/registry/examples/longform-page/story.js +38 -0
- package/registry/examples/longform-page/story.tsx +35 -0
- package/registry/examples/mascots/crane.d.ts +4 -0
- package/registry/examples/mascots/crane.js +19 -0
- package/registry/examples/mascots/crane.tsx +18 -0
- package/registry/examples/mascots/flock.tsx +2 -1
- package/registry/examples/mascots/native/crane.d.ts +4 -0
- package/registry/examples/mascots/native/crane.dark.png +0 -0
- package/registry/examples/mascots/native/crane.js +21 -0
- package/registry/examples/mascots/native/crane.light.png +0 -0
- package/registry/examples/mascots/native/crane.tsx +18 -0
- package/registry/examples/pricing-page/credits.d.ts +4 -0
- package/registry/examples/pricing-page/credits.js +41 -0
- package/registry/examples/pricing-page/credits.tsx +33 -0
- package/registry/examples/product-page/orazaka.d.ts +4 -0
- package/registry/examples/product-page/orazaka.js +44 -0
- package/registry/examples/product-page/orazaka.tsx +36 -0
- package/registry/examples/status-page/building.d.ts +4 -0
- package/registry/examples/status-page/building.js +29 -0
- package/registry/examples/status-page/building.tsx +25 -0
- package/registry/examples/status-page/operational.d.ts +4 -0
- package/registry/examples/status-page/operational.js +26 -0
- package/registry/examples/status-page/operational.tsx +20 -0
- package/registry/examples/virtual/feed.d.ts +4 -0
- package/registry/examples/virtual/feed.js +26 -0
- package/registry/examples/virtual/feed.tsx +24 -0
- package/registry/examples/virtual/gallery.d.ts +4 -0
- package/registry/examples/virtual/gallery.js +31 -0
- package/registry/examples/virtual/gallery.tsx +28 -0
- package/registry/examples/virtual/messages.d.ts +4 -0
- package/registry/examples/virtual/messages.js +28 -0
- package/registry/examples/virtual/messages.tsx +28 -0
- package/registry/field.json +1 -1
- package/registry/file-upload.json +1 -1
- package/registry/filter-bar.json +1 -1
- package/registry/gallery-page.json +256 -0
- package/registry/glow-card.json +1 -1
- package/registry/goal-gauge.json +1 -1
- package/registry/how-it-works-page.json +242 -0
- package/registry/image-cropper.json +1 -1
- package/registry/index.json +356 -9
- package/registry/iso.json +1 -1
- package/registry/kbd.json +1 -1
- package/registry/landing-page.json +242 -0
- package/registry/landscape.json +1 -1
- package/registry/legal-page.json +199 -0
- package/registry/link-card.json +1 -1
- package/registry/list.json +249 -0
- package/registry/loader.json +1 -1
- package/registry/longform-page.json +213 -0
- package/registry/marketing-layout.json +1 -1
- package/registry/marquee.json +1 -1
- package/registry/mascot-quote.json +6 -6
- package/registry/mascot-state.json +34 -34
- package/registry/mascots.json +41 -21
- package/registry/media-capture.json +1 -1
- package/registry/meter.json +1 -1
- package/registry/nav-bar.json +1 -1
- package/registry/number-ticker.json +1 -1
- package/registry/page-header.json +1 -1
- package/registry/page-hero.json +1 -1
- package/registry/page.json +1 -1
- package/registry/pagination.json +1 -1
- package/registry/pointer-light.json +1 -1
- package/registry/popover.json +1 -1
- package/registry/pricing-page.json +245 -0
- package/registry/product-page.json +319 -0
- package/registry/profile-card.json +1 -1
- package/registry/progress.json +1 -1
- package/registry/promise-card.json +1 -1
- package/registry/radio-group.json +1 -1
- package/registry/scroll-stage.json +1 -1
- package/registry/search-field.json +1 -1
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/settings-layout.json +1 -1
- package/registry/skeleton.json +1 -1
- package/registry/slider.json +1 -1
- package/registry/slot.json +1 -1
- package/registry/spinner.json +1 -1
- package/registry/split-view.json +1 -1
- package/registry/stage-banner.json +1 -1
- package/registry/stat.json +1 -1
- package/registry/status-page.json +263 -0
- package/registry/stepper.json +1 -1
- package/registry/switch.json +1 -1
- package/registry/tabs.json +1 -1
- package/registry/tag-input.json +1 -1
- package/registry/terminal-replay.json +1 -1
- package/registry/theme.json +1 -1
- package/registry/toast.json +1 -1
- package/registry/toc.json +1 -1
- package/registry/tooltip.json +1 -1
- package/registry/video-player.json +1 -1
- package/registry/video-trimmer.json +1 -1
- package/registry/virtual.json +569 -0
- package/skills/data-table/SKILL.md +56 -0
- package/skills/native-list/SKILL.md +39 -0
- package/skills/virtual/SKILL.md +35 -0
- package/dist/chunk-NOVUREEC.js.map +0 -1
- /package/dist/{chunk-EUPTXKH7.js.map → chunk-BRKMQ6JV.js.map} +0 -0
- /package/dist/{chunk-X6TW3X6Y.js.map → chunk-LCZXS6AK.js.map} +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
Chip
|
|
4
|
+
} from "./chunk-YH4LMWRU.js";
|
|
5
|
+
import {
|
|
6
|
+
cn,
|
|
7
|
+
floating
|
|
8
|
+
} from "./chunk-2USC2YT6.js";
|
|
9
|
+
import {
|
|
10
|
+
ChevronGlyph
|
|
11
|
+
} from "./chunk-CPA5CF35.js";
|
|
12
|
+
|
|
13
|
+
// src/filter-bar/filter-bar.tsx
|
|
14
|
+
import { DropdownMenu as MenuPrimitive2 } from "radix-ui";
|
|
15
|
+
import { tv as tv2 } from "tailwind-variants";
|
|
16
|
+
|
|
17
|
+
// src/dropdown-menu/dropdown-menu.tsx
|
|
18
|
+
import { DropdownMenu as MenuPrimitive } from "radix-ui";
|
|
19
|
+
import { tv } from "tailwind-variants";
|
|
20
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
21
|
+
var menu = tv({
|
|
22
|
+
slots: {
|
|
23
|
+
content: cn(floating, "min-w-48 max-h-(--radix-dropdown-menu-content-available-height) overflow-y-auto p-1 origin-(--radix-dropdown-menu-content-transform-origin)"),
|
|
24
|
+
item: "relative flex cursor-pointer select-none items-center gap-2 rounded-md px-2.5 py-2 text-sm text-fg outline-hidden transition-colors data-highlighted:bg-surface-3 data-disabled:pointer-events-none data-disabled:opacity-40 [&>svg]:h-4 [&>svg]:w-4 [&>svg]:shrink-0 [&>svg]:text-fg-secondary",
|
|
25
|
+
indicator: "ml-auto flex h-4 w-4 items-center justify-center text-fg-accent",
|
|
26
|
+
label: "px-2.5 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wider text-fg-secondary",
|
|
27
|
+
separator: "-mx-1 my-1 h-px bg-border-subtle"
|
|
28
|
+
},
|
|
29
|
+
variants: {
|
|
30
|
+
// The label reads in the danger text role (≥ 4.5:1 on the menu surface, both themes); the icon and the highlight
|
|
31
|
+
// carry the danger fill.
|
|
32
|
+
tone: { default: {}, danger: { item: "text-fg-danger data-highlighted:bg-danger/15 [&>svg]:text-danger" } }
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: { tone: "default" }
|
|
35
|
+
});
|
|
36
|
+
var s = menu();
|
|
37
|
+
function DropdownMenuContent({ sideOffset = 6, align = "end", collisionPadding = 8, container, className, ...props }) {
|
|
38
|
+
return /* @__PURE__ */ jsx(MenuPrimitive.Portal, { container, children: /* @__PURE__ */ jsx(MenuPrimitive.Content, { sideOffset, align, collisionPadding, className: s.content({ className }), ...props }) });
|
|
39
|
+
}
|
|
40
|
+
function DropdownMenuItem({ tone, className, ...props }) {
|
|
41
|
+
return /* @__PURE__ */ jsx(MenuPrimitive.Item, { "data-tone": tone ?? "default", className: menu({ tone }).item({ className }), ...props });
|
|
42
|
+
}
|
|
43
|
+
function DropdownMenuCheckboxItem({ className, children, ...props }) {
|
|
44
|
+
return /* @__PURE__ */ jsxs(MenuPrimitive.CheckboxItem, { className: s.item({ className }), ...props, children: [
|
|
45
|
+
children,
|
|
46
|
+
/* @__PURE__ */ jsx(MenuPrimitive.ItemIndicator, { className: s.indicator(), children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) }) })
|
|
47
|
+
] });
|
|
48
|
+
}
|
|
49
|
+
function DropdownMenuLabel({ className, ...props }) {
|
|
50
|
+
return /* @__PURE__ */ jsx(MenuPrimitive.Label, { className: s.label({ className }), ...props });
|
|
51
|
+
}
|
|
52
|
+
function DropdownMenuSeparator({ className, ...props }) {
|
|
53
|
+
return /* @__PURE__ */ jsx(MenuPrimitive.Separator, { className: s.separator({ className }), ...props });
|
|
54
|
+
}
|
|
55
|
+
var DropdownMenu = {
|
|
56
|
+
Root: MenuPrimitive.Root,
|
|
57
|
+
Trigger: MenuPrimitive.Trigger,
|
|
58
|
+
Content: DropdownMenuContent,
|
|
59
|
+
Item: DropdownMenuItem,
|
|
60
|
+
CheckboxItem: DropdownMenuCheckboxItem,
|
|
61
|
+
Label: DropdownMenuLabel,
|
|
62
|
+
Separator: DropdownMenuSeparator,
|
|
63
|
+
Group: MenuPrimitive.Group
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/filter-bar/filter-bar.tsx
|
|
67
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
68
|
+
var filterBar = tv2({
|
|
69
|
+
slots: {
|
|
70
|
+
root: "flex w-full flex-col gap-3",
|
|
71
|
+
controls: "flex w-full flex-wrap items-center gap-2 [&>*]:min-w-0",
|
|
72
|
+
active: "flex flex-wrap items-center gap-2",
|
|
73
|
+
clear: "rounded-md px-2 py-1 text-xs font-semibold text-fg-accent hover:bg-surface-2 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
|
|
74
|
+
results: "ml-auto text-xs text-fg-secondary tabular-nums",
|
|
75
|
+
trigger: "inline-flex h-11 shrink-0 items-center gap-2 rounded-lg border border-border-default bg-surface-1 px-3.5 text-sm font-semibold text-fg-secondary transition-colors hover:border-border-strong hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-[active]:border-accent data-[active]:bg-accent-soft data-[active]:text-fg data-[state=open]:border-border-strong",
|
|
76
|
+
count: "inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-accent px-1.5 text-[11px] font-bold tabular-nums text-on-accent",
|
|
77
|
+
optionCount: "ml-auto pl-4 text-xs tabular-nums text-fg-secondary"
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
function FilterBar({
|
|
81
|
+
label,
|
|
82
|
+
children,
|
|
83
|
+
active = [],
|
|
84
|
+
onClearAll,
|
|
85
|
+
clearLabel = "Clear filters",
|
|
86
|
+
removeLabel = (text) => `Remove ${text}`,
|
|
87
|
+
results,
|
|
88
|
+
className,
|
|
89
|
+
...props
|
|
90
|
+
}) {
|
|
91
|
+
const s2 = filterBar();
|
|
92
|
+
return /* @__PURE__ */ jsxs2("div", { role: "group", "aria-label": label, className: s2.root({ className }), ...props, children: [
|
|
93
|
+
children ? /* @__PURE__ */ jsx2("div", { className: s2.controls(), children }) : null,
|
|
94
|
+
active.length > 0 || results !== void 0 ? /* @__PURE__ */ jsxs2("div", { className: s2.active(), children: [
|
|
95
|
+
active.map((filter) => /* @__PURE__ */ jsx2(Chip, { size: "sm", removable: true, removeLabel: removeLabel(filter.label), onRemove: filter.onRemove, children: filter.label }, filter.id)),
|
|
96
|
+
active.length > 0 && onClearAll ? /* @__PURE__ */ jsx2("button", { type: "button", className: s2.clear(), onClick: onClearAll, children: clearLabel }) : null,
|
|
97
|
+
/* @__PURE__ */ jsx2("p", { className: s2.results(), "aria-live": "polite", "aria-atomic": true, children: results })
|
|
98
|
+
] }) : null
|
|
99
|
+
] });
|
|
100
|
+
}
|
|
101
|
+
function FilterMenu(props) {
|
|
102
|
+
const { label, options, defaultOpen, className } = props;
|
|
103
|
+
const s2 = filterBar();
|
|
104
|
+
const m = menu();
|
|
105
|
+
const chosen = props.multiple === false ? props.value ? [props.value] : [] : props.value;
|
|
106
|
+
const single = props.multiple === false ? options.find((o) => o.value === props.value) : void 0;
|
|
107
|
+
const content = (option) => /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
108
|
+
option.label,
|
|
109
|
+
option.count !== void 0 ? /* @__PURE__ */ jsx2("span", { className: s2.optionCount(), children: option.count }) : null
|
|
110
|
+
] });
|
|
111
|
+
return /* @__PURE__ */ jsxs2(DropdownMenu.Root, { defaultOpen, modal: false, children: [
|
|
112
|
+
/* @__PURE__ */ jsxs2(DropdownMenu.Trigger, { className: s2.trigger({ className }), "data-active": chosen.length > 0 ? "" : void 0, children: [
|
|
113
|
+
single ? `${label}: ${single.label}` : label,
|
|
114
|
+
props.multiple !== false && chosen.length > 0 ? /* @__PURE__ */ jsx2("span", { className: s2.count(), children: chosen.length }) : null,
|
|
115
|
+
/* @__PURE__ */ jsx2(ChevronGlyph, { className: "h-4 w-4" })
|
|
116
|
+
] }),
|
|
117
|
+
/* @__PURE__ */ jsx2(DropdownMenu.Content, { align: "start", "aria-label": label, children: props.multiple === false ? /* @__PURE__ */ jsx2(MenuPrimitive2.RadioGroup, { value: props.value, onValueChange: props.onValueChange, children: options.map((option) => /* @__PURE__ */ jsxs2(MenuPrimitive2.RadioItem, { value: option.value, disabled: option.disabled, className: m.item(), children: [
|
|
118
|
+
/* @__PURE__ */ jsx2("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center rounded-full border border-border-strong", children: /* @__PURE__ */ jsx2(MenuPrimitive2.ItemIndicator, { className: "h-2 w-2 rounded-full bg-accent" }) }),
|
|
119
|
+
content(option)
|
|
120
|
+
] }, option.value)) }) : options.map((option) => /* @__PURE__ */ jsx2(
|
|
121
|
+
DropdownMenu.CheckboxItem,
|
|
122
|
+
{
|
|
123
|
+
disabled: option.disabled,
|
|
124
|
+
checked: props.value.includes(option.value),
|
|
125
|
+
onSelect: (event) => event.preventDefault(),
|
|
126
|
+
onCheckedChange: (checked) => props.onValueChange(checked ? [...props.value, option.value] : props.value.filter((v) => v !== option.value)),
|
|
127
|
+
children: content(option)
|
|
128
|
+
},
|
|
129
|
+
option.value
|
|
130
|
+
)) })
|
|
131
|
+
] });
|
|
132
|
+
}
|
|
133
|
+
function readFilterParams(params, keys) {
|
|
134
|
+
return Object.fromEntries(
|
|
135
|
+
keys.map((key) => [key, params.getAll(key).flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean)])
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
function writeFilterParams(base, filters, resetKey = "page") {
|
|
139
|
+
const next = new URLSearchParams(base);
|
|
140
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
141
|
+
const list = value == null ? [] : typeof value === "string" ? [value] : [...value];
|
|
142
|
+
if (list.filter(Boolean).length === 0) next.delete(key);
|
|
143
|
+
else next.set(key, list.filter(Boolean).join(","));
|
|
144
|
+
}
|
|
145
|
+
if (resetKey) next.delete(resetKey);
|
|
146
|
+
return next;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export {
|
|
150
|
+
DropdownMenu,
|
|
151
|
+
filterBar,
|
|
152
|
+
FilterBar,
|
|
153
|
+
FilterMenu,
|
|
154
|
+
readFilterParams,
|
|
155
|
+
writeFilterParams
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=chunk-OGJI5X4W.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/filter-bar/filter-bar.tsx","../src/dropdown-menu/dropdown-menu.tsx"],"sourcesContent":["// Client (menus in a portal). The bar above a list: the controls that narrow it (a SearchField, FilterMenus, a\n// DateRangePicker — any child), the filters in force as removable chips, \"Clear all\", and the count of results in a\n// polite live region. It holds no state: the app keeps the filters — in the address, ideally — and the\n// `readFilterParams` / `writeFilterParams` helpers move them between a `URLSearchParams` and an object.\nimport { DropdownMenu as MenuPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { Chip } from \"../chip\";\nimport { DropdownMenu, menu } from \"../dropdown-menu\";\nimport { ChevronGlyph } from \"../glyphs\";\n\nexport const filterBar = tv({\n slots: {\n root: \"flex w-full flex-col gap-3\",\n controls: \"flex w-full flex-wrap items-center gap-2 [&>*]:min-w-0\",\n active: \"flex flex-wrap items-center gap-2\",\n clear:\n \"rounded-md px-2 py-1 text-xs font-semibold text-fg-accent hover:bg-surface-2 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n results: \"ml-auto text-xs text-fg-secondary tabular-nums\",\n trigger:\n \"inline-flex h-11 shrink-0 items-center gap-2 rounded-lg border border-border-default bg-surface-1 px-3.5 text-sm font-semibold text-fg-secondary \" +\n \"transition-colors hover:border-border-strong hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring \" +\n \"data-[active]:border-accent data-[active]:bg-accent-soft data-[active]:text-fg data-[state=open]:border-border-strong\",\n count: \"inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-accent px-1.5 text-[11px] font-bold tabular-nums text-on-accent\",\n optionCount: \"ml-auto pl-4 text-xs tabular-nums text-fg-secondary\",\n },\n});\n\nexport type ActiveFilter = {\n /** A stable key (`\"status:failed\"`). */\n id: string;\n /** What the chip says, passed translated (\"Status: Failed\"). */\n label: string;\n /** Removes this filter. */\n onRemove: () => void;\n};\n\nexport type FilterBarProps = Omit<React.ComponentProps<\"div\">, \"children\" | \"results\"> & {\n /** The accessible name of the bar (\"Filter jobs\"), passed translated. */\n label: string;\n /** The controls: `SearchField`, `FilterMenu`, `DateRangePicker`, a `Chip.Group`… */\n children?: React.ReactNode;\n /** The filters in force, each a removable chip. */\n active?: readonly ActiveFilter[];\n /** Clears every filter; the \"Clear all\" button shows when there is at least one. */\n onClearAll?: () => void;\n /** The \"Clear all\" button (\"Clear filters\"), passed translated. */\n clearLabel?: string;\n /** A chip's remove button: `(label) => \"Remove \" + label`, passed translated. */\n removeLabel?: (label: string) => string;\n /** The count of results (\"42 jobs\"), announced politely when it changes. */\n results?: string;\n};\n\n/** The bar of filters above a list: controls, active filters as chips, clear all, the count of results. */\nexport function FilterBar({\n label,\n children,\n active = [],\n onClearAll,\n clearLabel = \"Clear filters\",\n removeLabel = (text) => `Remove ${text}`,\n results,\n className,\n ...props\n}: FilterBarProps) {\n const s = filterBar();\n return (\n <div role=\"group\" aria-label={label} className={s.root({ className })} {...props}>\n {children ? <div className={s.controls()}>{children}</div> : null}\n {active.length > 0 || results !== undefined ? (\n <div className={s.active()}>\n {active.map((filter) => (\n <Chip key={filter.id} size=\"sm\" removable removeLabel={removeLabel(filter.label)} onRemove={filter.onRemove}>\n {filter.label}\n </Chip>\n ))}\n {active.length > 0 && onClearAll ? (\n <button type=\"button\" className={s.clear()} onClick={onClearAll}>\n {clearLabel}\n </button>\n ) : null}\n <p className={s.results()} aria-live=\"polite\" aria-atomic>\n {results}\n </p>\n </div>\n ) : null}\n </div>\n );\n}\n\nexport type FilterOption = {\n /** What the app stores (and puts in the address). */\n value: string;\n /** What the person reads, passed translated. */\n label: string;\n /** How many results it would give: shown on the right. */\n count?: number;\n /** Shown but not choosable. */\n disabled?: boolean;\n};\n\ntype FilterMenuBase = {\n /** The name of the filter on its button (\"Status\"), passed translated. */\n label: string;\n /** The choices. */\n options: readonly FilterOption[];\n /** Opens the menu at first (a story, a test). */\n defaultOpen?: boolean;\n /** Classes merged on the button. */\n className?: string;\n};\n\nexport type FilterMenuProps =\n | (FilterMenuBase & {\n /** Several values (checkboxes, default) or one (radios). */\n multiple?: true;\n /** The values chosen. */\n value: readonly string[];\n /** Called with the values chosen. */\n onValueChange: (value: string[]) => void;\n })\n | (FilterMenuBase & {\n /** One value: the options are radios. */\n multiple: false;\n /** The value chosen, `\"\"` for none. */\n value: string;\n /** Called with the value chosen. */\n onValueChange: (value: string) => void;\n });\n\n/** A filter's button and its menu of options — checkboxes (several values) or radios (one) — with a count of chosen ones. */\nexport function FilterMenu(props: FilterMenuProps) {\n const { label, options, defaultOpen, className } = props;\n const s = filterBar();\n const m = menu();\n const chosen = props.multiple === false ? (props.value ? [props.value] : []) : props.value;\n const single = props.multiple === false ? options.find((o) => o.value === props.value) : undefined;\n const content = (option: FilterOption) => (\n <>\n {option.label}\n {option.count !== undefined ? <span className={s.optionCount()}>{option.count}</span> : null}\n </>\n );\n return (\n <DropdownMenu.Root defaultOpen={defaultOpen} modal={false}>\n <DropdownMenu.Trigger className={s.trigger({ className })} data-active={chosen.length > 0 ? \"\" : undefined}>\n {single ? `${label}: ${single.label}` : label}\n {props.multiple !== false && chosen.length > 0 ? <span className={s.count()}>{chosen.length}</span> : null}\n <ChevronGlyph className=\"h-4 w-4\" />\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"start\" aria-label={label}>\n {props.multiple === false ? (\n <MenuPrimitive.RadioGroup value={props.value} onValueChange={props.onValueChange}>\n {options.map((option) => (\n <MenuPrimitive.RadioItem key={option.value} value={option.value} disabled={option.disabled} className={m.item()}>\n <span className=\"flex h-4 w-4 shrink-0 items-center justify-center rounded-full border border-border-strong\">\n <MenuPrimitive.ItemIndicator className=\"h-2 w-2 rounded-full bg-accent\" />\n </span>\n {content(option)}\n </MenuPrimitive.RadioItem>\n ))}\n </MenuPrimitive.RadioGroup>\n ) : (\n options.map((option) => (\n <DropdownMenu.CheckboxItem\n key={option.value}\n disabled={option.disabled}\n checked={props.value.includes(option.value)}\n onSelect={(event) => event.preventDefault()}\n onCheckedChange={(checked) =>\n props.onValueChange(checked ? [...props.value, option.value] : props.value.filter((v) => v !== option.value))\n }\n >\n {content(option)}\n </DropdownMenu.CheckboxItem>\n ))\n )}\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n );\n}\n\n/** Filters read from an address: `{ status: [\"failed\", \"running\"], q: [\"cat\"] }` for the keys asked (repeated or comma-separated values). */\nexport function readFilterParams(params: URLSearchParams, keys: readonly string[]): Record<string, string[]> {\n return Object.fromEntries(\n keys.map((key) => [key, params.getAll(key).flatMap((v) => v.split(\",\")).map((v) => v.trim()).filter(Boolean)]),\n );\n}\n\n/** Filters written into an address (a copy of `base`): empty filters removed, several values comma-separated, the page reset. */\nexport function writeFilterParams(base: URLSearchParams, filters: Record<string, string | readonly string[] | null | undefined>, resetKey = \"page\") {\n const next = new URLSearchParams(base);\n for (const [key, value] of Object.entries(filters)) {\n const list = value == null ? [] : typeof value === \"string\" ? [value] : [...value];\n if (list.filter(Boolean).length === 0) next.delete(key);\n else next.set(key, list.filter(Boolean).join(\",\"));\n }\n if (resetKey) next.delete(resetKey);\n return next;\n}\n","// Client (a portal). Radix does the roving focus, the arrows, Home/End, typeahead, Escape and the focus return.\nimport { DropdownMenu as MenuPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { floating } from \"../floating\";\n\nexport const menu = tv({\n slots: {\n content: cn(floating, \"min-w-48 max-h-(--radix-dropdown-menu-content-available-height) overflow-y-auto p-1 origin-(--radix-dropdown-menu-content-transform-origin)\"),\n item:\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-md px-2.5 py-2 text-sm text-fg outline-hidden transition-colors \" +\n \"data-highlighted:bg-surface-3 data-disabled:pointer-events-none data-disabled:opacity-40 [&>svg]:h-4 [&>svg]:w-4 [&>svg]:shrink-0 \" +\n \"[&>svg]:text-fg-secondary\",\n indicator: \"ml-auto flex h-4 w-4 items-center justify-center text-fg-accent\",\n label: \"px-2.5 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wider text-fg-secondary\",\n separator: \"-mx-1 my-1 h-px bg-border-subtle\",\n },\n variants: {\n // The label reads in the danger text role (≥ 4.5:1 on the menu surface, both themes); the icon and the highlight\n // carry the danger fill.\n tone: { default: {}, danger: { item: \"text-fg-danger data-highlighted:bg-danger/15 [&>svg]:text-danger\" } },\n },\n defaultVariants: { tone: \"default\" },\n});\nconst s = menu();\n\nexport type DropdownMenuContentProps = React.ComponentProps<typeof MenuPrimitive.Content> & {\n /** The element the portal renders into (default: document.body). */\n container?: HTMLElement | null;\n};\n\nexport function DropdownMenuContent({ sideOffset = 6, align = \"end\", collisionPadding = 8, container, className, ...props }: DropdownMenuContentProps) {\n return (\n <MenuPrimitive.Portal container={container}>\n <MenuPrimitive.Content sideOffset={sideOffset} align={align} collisionPadding={collisionPadding} className={s.content({ className })} {...props} />\n </MenuPrimitive.Portal>\n );\n}\n\nexport type DropdownMenuItemProps = React.ComponentProps<typeof MenuPrimitive.Item> & {\n /** `danger` for a destructive action: the icon and the highlight carry the danger, the label stays legible. */\n tone?: \"default\" | \"danger\";\n};\n\n/** An action. `tone=\"danger\"` for a destructive one; `onSelect` runs it (the menu closes). */\nexport function DropdownMenuItem({ tone, className, ...props }: DropdownMenuItemProps) {\n return <MenuPrimitive.Item data-tone={tone ?? \"default\"} className={menu({ tone }).item({ className })} {...props} />;\n}\n\n/** A toggled option: `checked` + `onCheckedChange`. */\nexport function DropdownMenuCheckboxItem({ className, children, ...props }: React.ComponentProps<typeof MenuPrimitive.CheckboxItem>) {\n return (\n <MenuPrimitive.CheckboxItem className={s.item({ className })} {...props}>\n {children}\n <MenuPrimitive.ItemIndicator className={s.indicator()}>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n </MenuPrimitive.ItemIndicator>\n </MenuPrimitive.CheckboxItem>\n );\n}\n\nexport function DropdownMenuLabel({ className, ...props }: React.ComponentProps<typeof MenuPrimitive.Label>) {\n return <MenuPrimitive.Label className={s.label({ className })} {...props} />;\n}\n\nexport function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof MenuPrimitive.Separator>) {\n return <MenuPrimitive.Separator className={s.separator({ className })} {...props} />;\n}\n\n/** `DropdownMenu.Root/Trigger/Content/Item/CheckboxItem/Label/Separator/Group`. `open`/`defaultOpen` + `onOpenChange`. */\nexport const DropdownMenu = {\n Root: MenuPrimitive.Root,\n Trigger: MenuPrimitive.Trigger,\n Content: DropdownMenuContent,\n Item: DropdownMenuItem,\n CheckboxItem: DropdownMenuCheckboxItem,\n Label: DropdownMenuLabel,\n Separator: DropdownMenuSeparator,\n Group: MenuPrimitive.Group,\n};\n"],"mappings":"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","names":["MenuPrimitive","tv","jsx","jsxs","tv","s","MenuPrimitive"]}
|
package/dist/combobox.js
CHANGED
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
Combobox,
|
|
4
4
|
combobox,
|
|
5
5
|
comboboxLabels
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-LCZXS6AK.js";
|
|
7
7
|
import "./chunk-YH4LMWRU.js";
|
|
8
8
|
import "./chunk-ZIXB33X7.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-BRKMQ6JV.js";
|
|
10
10
|
import "./chunk-CPA5CF35.js";
|
|
11
11
|
export {
|
|
12
12
|
Combobox,
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Fact } from '@krizaka/ui/page';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
interface ComponentPageSection {
|
|
5
|
+
/** The section's anchor. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** Its title (`When to use`, `Props`). */
|
|
8
|
+
title: React.ReactNode;
|
|
9
|
+
/** Its content (lists, a props table, examples). */
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
type ComponentPageProps = Omit<React.HTMLAttributes<HTMLElement>, "title"> & {
|
|
13
|
+
/** The way back to the catalogue (your router's link). */
|
|
14
|
+
back?: React.ReactNode;
|
|
15
|
+
/** The category (`Blocks`, `Forms`). */
|
|
16
|
+
eyebrow?: React.ReactNode;
|
|
17
|
+
/** The component's name: the `h1`. */
|
|
18
|
+
title: React.ReactNode;
|
|
19
|
+
/** Its summary, in one sentence. */
|
|
20
|
+
summary: React.ReactNode;
|
|
21
|
+
/** Its status and platforms. */
|
|
22
|
+
facts?: readonly Fact[];
|
|
23
|
+
/** The live preview of its first example (a framed stage with its code). */
|
|
24
|
+
preview: React.ReactNode;
|
|
25
|
+
/** The line to install or import it, and the copy words. */
|
|
26
|
+
install?: {
|
|
27
|
+
code: string;
|
|
28
|
+
language?: string;
|
|
29
|
+
copyLabel: string;
|
|
30
|
+
copiedLabel: string;
|
|
31
|
+
file?: React.ReactNode;
|
|
32
|
+
};
|
|
33
|
+
/** The sections, in reading order: when to use / not, examples, props, accessibility. */
|
|
34
|
+
sections: readonly ComponentPageSection[];
|
|
35
|
+
/** The side column: related components, source, the version. */
|
|
36
|
+
aside?: React.ReactNode;
|
|
37
|
+
};
|
|
38
|
+
/** A component's page: name, summary, facts, live preview, install, then its sections; facts and related aside. */
|
|
39
|
+
declare function ComponentPage({ back, eyebrow, title, summary, facts, preview, install, sections, aside, ...props }: ComponentPageProps): React.JSX.Element;
|
|
40
|
+
|
|
41
|
+
export { ComponentPage, type ComponentPageProps, type ComponentPageSection };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/component-page/component-page.tsx
|
|
2
|
+
import { CodeBlock } from "@krizaka/ui/code-block";
|
|
3
|
+
import { DetailLayout } from "@krizaka/ui/detail-layout";
|
|
4
|
+
import { Facts, Section } from "@krizaka/ui/page";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
function ComponentPage({ back, eyebrow, title, summary, facts, preview, install, sections, aside, ...props }) {
|
|
7
|
+
return /* @__PURE__ */ jsxs(DetailLayout, { back, eyebrow, title, meta: /* @__PURE__ */ jsx("span", { children: summary }), aside, ...props, children: [
|
|
8
|
+
facts && facts.length > 0 && /* @__PURE__ */ jsx(Facts, { items: facts }),
|
|
9
|
+
/* @__PURE__ */ jsx("div", { className: "kz-tpl-stage", children: preview }),
|
|
10
|
+
install && /* @__PURE__ */ jsx(CodeBlock, { code: install.code, language: install.language ?? "bash", file: install.file, copyLabel: install.copyLabel, copiedLabel: install.copiedLabel }),
|
|
11
|
+
/* @__PURE__ */ jsx("div", { className: "kz-tpl-flush", children: sections.map((s) => /* @__PURE__ */ jsx(Section, { id: s.id, title: s.title, headingSize: "sm", spacing: "sm", size: "full", divider: true, children: s.children }, s.id)) })
|
|
12
|
+
] });
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
ComponentPage
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=component-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/component-page/component-page.tsx"],"sourcesContent":["// Server-safe. The page of one component of a design system (what krizaka.com/docs/ui draws from the registry): its\n// name, summary, status and platforms; the live preview with its code; installation; when to use it and when not; its\n// examples; its props; its accessibility — the facts in a side column that goes under the content on a phone.\nimport { CodeBlock } from \"@krizaka/ui/code-block\";\nimport { DetailLayout } from \"@krizaka/ui/detail-layout\";\nimport { type Fact, Facts, Section } from \"@krizaka/ui/page\";\nimport type * as React from \"react\";\n\nexport interface ComponentPageSection {\n /** The section's anchor. */\n id: string;\n /** Its title (`When to use`, `Props`). */\n title: React.ReactNode;\n /** Its content (lists, a props table, examples). */\n children: React.ReactNode;\n}\n\nexport type ComponentPageProps = Omit<React.HTMLAttributes<HTMLElement>, \"title\"> & {\n /** The way back to the catalogue (your router's link). */\n back?: React.ReactNode;\n /** The category (`Blocks`, `Forms`). */\n eyebrow?: React.ReactNode;\n /** The component's name: the `h1`. */\n title: React.ReactNode;\n /** Its summary, in one sentence. */\n summary: React.ReactNode;\n /** Its status and platforms. */\n facts?: readonly Fact[];\n /** The live preview of its first example (a framed stage with its code). */\n preview: React.ReactNode;\n /** The line to install or import it, and the copy words. */\n install?: { code: string; language?: string; copyLabel: string; copiedLabel: string; file?: React.ReactNode };\n /** The sections, in reading order: when to use / not, examples, props, accessibility. */\n sections: readonly ComponentPageSection[];\n /** The side column: related components, source, the version. */\n aside?: React.ReactNode;\n};\n\n/** A component's page: name, summary, facts, live preview, install, then its sections; facts and related aside. */\nexport function ComponentPage({ back, eyebrow, title, summary, facts, preview, install, sections, aside, ...props }: ComponentPageProps) {\n return (\n <DetailLayout back={back} eyebrow={eyebrow} title={title} meta={<span>{summary}</span>} aside={aside} {...props}>\n {facts && facts.length > 0 && <Facts items={facts} />}\n <div className=\"kz-tpl-stage\">{preview}</div>\n {install && <CodeBlock code={install.code} language={install.language ?? \"bash\"} file={install.file} copyLabel={install.copyLabel} copiedLabel={install.copiedLabel} />}\n <div className=\"kz-tpl-flush\">\n {sections.map((s) => (\n <Section key={s.id} id={s.id} title={s.title} headingSize=\"sm\" spacing=\"sm\" size=\"full\" divider>\n {s.children}\n </Section>\n ))}\n </div>\n </DetailLayout>\n );\n}\n"],"mappings":";AAGA,SAAS,iBAAiB;AAC1B,SAAS,oBAAoB;AAC7B,SAAoB,OAAO,eAAe;AAoCtC,SAAgE,KAAhE;AAFG,SAAS,cAAc,EAAE,MAAM,SAAS,OAAO,SAAS,OAAO,SAAS,SAAS,UAAU,OAAO,GAAG,MAAM,GAAuB;AACvI,SACE,qBAAC,gBAAa,MAAY,SAAkB,OAAc,MAAM,oBAAC,UAAM,mBAAQ,GAAS,OAAe,GAAG,OACvG;AAAA,aAAS,MAAM,SAAS,KAAK,oBAAC,SAAM,OAAO,OAAO;AAAA,IACnD,oBAAC,SAAI,WAAU,gBAAgB,mBAAQ;AAAA,IACtC,WAAW,oBAAC,aAAU,MAAM,QAAQ,MAAM,UAAU,QAAQ,YAAY,QAAQ,MAAM,QAAQ,MAAM,WAAW,QAAQ,WAAW,aAAa,QAAQ,aAAa;AAAA,IACrK,oBAAC,SAAI,WAAU,gBACZ,mBAAS,IAAI,CAAC,MACb,oBAAC,WAAmB,IAAI,EAAE,IAAI,OAAO,EAAE,OAAO,aAAY,MAAK,SAAQ,MAAK,MAAK,QAAO,SAAO,MAC5F,YAAE,YADS,EAAE,EAEhB,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { LinkComponent } from '@krizaka/ui/page-hero';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
type ContactPageProps = Omit<React.HTMLAttributes<HTMLElement>, "title"> & {
|
|
5
|
+
/** A mono line above the title. */
|
|
6
|
+
eyebrow?: React.ReactNode;
|
|
7
|
+
/** The page's `h1`. */
|
|
8
|
+
title: React.ReactNode;
|
|
9
|
+
/** One or two sentences: who answers, how fast. */
|
|
10
|
+
lead?: React.ReactNode;
|
|
11
|
+
/** Beside the hero: the bird that answers (the flamingo). */
|
|
12
|
+
aside?: React.ReactNode;
|
|
13
|
+
/** The ways to reach us: LinkCards (discussions, issues, email). */
|
|
14
|
+
channels: React.ReactNode;
|
|
15
|
+
/** The form (fields, the cut primary action). */
|
|
16
|
+
form: React.ReactNode;
|
|
17
|
+
/** What happens after sending: steps with a title and a sentence. */
|
|
18
|
+
next?: {
|
|
19
|
+
title: React.ReactNode;
|
|
20
|
+
steps: readonly {
|
|
21
|
+
title: React.ReactNode;
|
|
22
|
+
text: React.ReactNode;
|
|
23
|
+
}[];
|
|
24
|
+
};
|
|
25
|
+
/** The app's link component (Next's `Link`). */
|
|
26
|
+
linkAs?: LinkComponent;
|
|
27
|
+
};
|
|
28
|
+
/** A contact page: hero, the channels beside the form, then what happens next. */
|
|
29
|
+
declare function ContactPage({ eyebrow, title, lead, aside, channels, form, next, linkAs, ...props }: ContactPageProps): React.JSX.Element;
|
|
30
|
+
|
|
31
|
+
export { ContactPage, type ContactPageProps };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/contact-page/contact-page.tsx
|
|
2
|
+
import { Page } from "@krizaka/ui/page";
|
|
3
|
+
import { PageHero } from "@krizaka/ui/page-hero";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
function ContactPage({ eyebrow, title, lead, aside, channels, form, next, linkAs, ...props }) {
|
|
6
|
+
return /* @__PURE__ */ jsxs("div", { ...props, children: [
|
|
7
|
+
/* @__PURE__ */ jsx(PageHero, { eyebrow, title, lead, aside, linkAs }),
|
|
8
|
+
/* @__PURE__ */ jsx(Page, { className: "kz-tpl-longform", children: /* @__PURE__ */ jsxs("div", { className: "kz-tpl-contact", children: [
|
|
9
|
+
/* @__PURE__ */ jsxs("div", { className: "kz-tpl-stack", children: [
|
|
10
|
+
channels,
|
|
11
|
+
next && /* @__PURE__ */ jsxs("div", { className: "kz-tpl-stack", children: [
|
|
12
|
+
/* @__PURE__ */ jsx("h2", { className: "kz-heading-title kz-tpl-h2", children: next.title }),
|
|
13
|
+
/* @__PURE__ */ jsx("ol", { className: "kz-tpl-next", children: next.steps.map((s, i) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("span", { children: [
|
|
14
|
+
/* @__PURE__ */ jsx("strong", { children: s.title }),
|
|
15
|
+
s.text
|
|
16
|
+
] }) }, i)) })
|
|
17
|
+
] })
|
|
18
|
+
] }),
|
|
19
|
+
/* @__PURE__ */ jsx("div", { className: "kz-tpl-form", children: form })
|
|
20
|
+
] }) })
|
|
21
|
+
] });
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
ContactPage
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=contact-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/contact-page/contact-page.tsx"],"sourcesContent":["// Server-safe. Reaching the team (blocks.css `.kz-tpl-contact`): the hero, then the ways to reach us as cards beside\n// the form — the form in its own panel — and what happens after sending, as numbered steps. The form is yours.\nimport { Page } from \"@krizaka/ui/page\";\nimport type { LinkComponent } from \"@krizaka/ui/page-hero\";\nimport { PageHero } from \"@krizaka/ui/page-hero\";\nimport type * as React from \"react\";\n\nexport type ContactPageProps = Omit<React.HTMLAttributes<HTMLElement>, \"title\"> & {\n /** A mono line above the title. */\n eyebrow?: React.ReactNode;\n /** The page's `h1`. */\n title: React.ReactNode;\n /** One or two sentences: who answers, how fast. */\n lead?: React.ReactNode;\n /** Beside the hero: the bird that answers (the flamingo). */\n aside?: React.ReactNode;\n /** The ways to reach us: LinkCards (discussions, issues, email). */\n channels: React.ReactNode;\n /** The form (fields, the cut primary action). */\n form: React.ReactNode;\n /** What happens after sending: steps with a title and a sentence. */\n next?: { title: React.ReactNode; steps: readonly { title: React.ReactNode; text: React.ReactNode }[] };\n /** The app's link component (Next's `Link`). */\n linkAs?: LinkComponent;\n};\n\n/** A contact page: hero, the channels beside the form, then what happens next. */\nexport function ContactPage({ eyebrow, title, lead, aside, channels, form, next, linkAs, ...props }: ContactPageProps) {\n return (\n <div {...props}>\n <PageHero eyebrow={eyebrow} title={title} lead={lead} aside={aside} linkAs={linkAs} />\n <Page className=\"kz-tpl-longform\">\n <div className=\"kz-tpl-contact\">\n <div className=\"kz-tpl-stack\">\n {channels}\n {next && (\n <div className=\"kz-tpl-stack\">\n <h2 className=\"kz-heading-title kz-tpl-h2\">{next.title}</h2>\n <ol className=\"kz-tpl-next\">\n {next.steps.map((s, i) => (\n <li key={i}>\n <span>\n <strong>{s.title}</strong>\n {s.text}\n </span>\n </li>\n ))}\n </ol>\n </div>\n )}\n </div>\n <div className=\"kz-tpl-form\">{form}</div>\n </div>\n </Page>\n </div>\n );\n}\n"],"mappings":";AAEA,SAAS,YAAY;AAErB,SAAS,gBAAgB;AA0BnB,cAWgB,YAXhB;AAHC,SAAS,YAAY,EAAE,SAAS,OAAO,MAAM,OAAO,UAAU,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAqB;AACrH,SACE,qBAAC,SAAK,GAAG,OACP;AAAA,wBAAC,YAAS,SAAkB,OAAc,MAAY,OAAc,QAAgB;AAAA,IACpF,oBAAC,QAAK,WAAU,mBACd,+BAAC,SAAI,WAAU,kBACb;AAAA,2BAAC,SAAI,WAAU,gBACZ;AAAA;AAAA,QACA,QACC,qBAAC,SAAI,WAAU,gBACb;AAAA,8BAAC,QAAG,WAAU,8BAA8B,eAAK,OAAM;AAAA,UACvD,oBAAC,QAAG,WAAU,eACX,eAAK,MAAM,IAAI,CAAC,GAAG,MAClB,oBAAC,QACC,+BAAC,UACC;AAAA,gCAAC,YAAQ,YAAE,OAAM;AAAA,YAChB,EAAE;AAAA,aACL,KAJO,CAKT,CACD,GACH;AAAA,WACF;AAAA,SAEJ;AAAA,MACA,oBAAC,SAAI,WAAU,eAAe,gBAAK;AAAA,OACrC,GACF;AAAA,KACF;AAEJ;","names":[]}
|