@pihanga2/shadcn 0.2.1 → 0.2.3
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/AGENT.building-cards.md +208 -3
- package/AGENT.md +58 -3
- package/AGENT.using-cards.md +142 -4
- package/README.md +4 -12
- package/cards/badge/badge.component.js +1 -0
- package/cards/badge/badge.component.js.map +1 -1
- package/cards/box/box.component.js +2 -2
- package/cards/box/box.component.js.map +1 -1
- package/cards/box/box.types.d.ts +0 -8
- package/cards/box/box.types.js.map +1 -1
- package/cards/button/button.component.js +13 -13
- package/cards/button/button.types.d.ts +1 -0
- package/cards/button/button.types.js.map +1 -1
- package/cards/{chartGraph/chartGraph.component.d.ts → chart/chart.component.d.ts} +1 -1
- package/cards/chart/chart.types.d.ts +223 -0
- package/cards/chart/index.d.ts +1 -0
- package/cards/checkbox/checkbox.component.js +1 -0
- package/cards/checkbox/checkbox.component.js.map +1 -1
- package/cards/checkbox/checkbox.types.d.ts +4 -0
- package/cards/checkbox/checkbox.types.js +2 -2
- package/cards/checkbox/checkbox.types.js.map +1 -1
- package/cards/checkbox/index.js +5 -5
- package/cards/conditional/conditional.component.js +5 -5
- package/cards/conditional/conditional.types.d.ts +20 -5
- package/cards/conditional/conditional.types.js.map +1 -1
- package/cards/core-index.d.ts +3 -0
- package/cards/dataTable/dataTable.component.js +8 -8
- package/cards/dataTable/dataTable.types.js.map +1 -1
- package/cards/dataTable/dataTableRowDetail.component.js +1 -0
- package/cards/dataTable/dataTableRowDetail.component.js.map +1 -1
- package/cards/dialog/dialog.component.js +7 -7
- package/cards/dropDownMenu/drop-down.component.js +7 -7
- package/cards/field/field.component.js +4 -4
- package/cards/field/field.types.js.map +1 -1
- package/cards/fileDrop/fileDrop.component.js +90 -0
- package/cards/fileDrop/fileDrop.component.js.map +1 -0
- package/cards/fileDrop/fileDrop.types.js +11 -0
- package/cards/fileDrop/fileDrop.types.js.map +1 -0
- package/cards/fileDrop/index.js +13 -0
- package/cards/fileDrop/index.js.map +1 -0
- package/cards/flexGrid/flexGrid.component.js +1 -1
- package/cards/flexGrid/flexGrid.types.js.map +1 -1
- package/cards/form/form.component.js +6 -6
- package/cards/form/form.types.d.ts +4 -0
- package/cards/form/form.types.js +2 -2
- package/cards/form/form.types.js.map +1 -1
- package/cards/form/index.js +5 -5
- package/cards/framework/framework.component.js +4 -4
- package/cards/graphin/graphin.types.d.ts +37 -4
- package/cards/input/index.js +5 -5
- package/cards/input/input.component.js +1 -0
- package/cards/input/input.component.js.map +1 -1
- package/cards/input/input.types.d.ts +10 -2
- package/cards/input/input.types.js +2 -2
- package/cards/input/input.types.js.map +1 -1
- package/cards/list/list.component.js +32 -32
- package/cards/list/list.types.js +1 -0
- package/cards/list/list.types.js.map +1 -1
- package/cards/loadingOverlay/loadingOverlay.component.js +1 -1
- package/cards/loadingSkeleton/loading-skeleton.component.js +1 -1
- package/cards/pageWithNavbar/pageWithNavbar.component.d.ts +5 -7
- package/cards/pageWithNavbar/pageWithNavbar.component.js +43 -43
- package/cards/pageWithNavbar/pageWithNavbar.component.js.map +1 -1
- package/cards/pasteTarget/pasteTarget.component.js.map +1 -1
- package/cards/select/index.js +5 -5
- package/cards/select/select.component.js +1 -0
- package/cards/select/select.component.js.map +1 -1
- package/cards/select/select.types.d.ts +12 -0
- package/cards/select/select.types.js +2 -2
- package/cards/select/select.types.js.map +1 -1
- package/cards/slider/index.js +13 -0
- package/cards/slider/index.js.map +1 -0
- package/cards/slider/slider.component.js +64 -0
- package/cards/slider/slider.component.js.map +1 -0
- package/cards/slider/slider.types.d.ts +12 -4
- package/cards/slider/slider.types.js +7 -0
- package/cards/slider/slider.types.js.map +1 -0
- package/cards/sliderValue/index.js +12 -0
- package/cards/sliderValue/index.js.map +1 -0
- package/cards/sliderValue/sliderValue.component.js +33 -0
- package/cards/sliderValue/sliderValue.component.js.map +1 -0
- package/cards/sliderValue/sliderValue.types.js +7 -0
- package/cards/sliderValue/sliderValue.types.js.map +1 -0
- package/cards/stack/stack.component.js +5 -5
- package/cards/stack/stack.component.js.map +1 -1
- package/cards/stack/stack.types.js.map +1 -1
- package/cards/stepper/stepper.component.js +7 -7
- package/cards/switch/index.js +5 -5
- package/cards/switch/switch.component.js +1 -0
- package/cards/switch/switch.component.js.map +1 -1
- package/cards/switch/switch.types.d.ts +4 -0
- package/cards/switch/switch.types.js +2 -2
- package/cards/switch/switch.types.js.map +1 -1
- package/cards/tabs/tabs.component.js +6 -6
- package/cards/textField/index.js +5 -5
- package/cards/textField/textField.component.js +1 -0
- package/cards/textField/textField.component.js.map +1 -1
- package/cards/textField/textField.types.d.ts +4 -0
- package/cards/textField/textField.types.js +2 -2
- package/cards/textField/textField.types.js.map +1 -1
- package/cards/toast/index.js +7 -7
- package/cards/toast/toast.component.js +12 -12
- package/cards/toast/toast.component.js.map +1 -1
- package/cards/toast/toast.types.d.ts +4 -0
- package/cards/toast/toast.types.js +2 -2
- package/cards/toast/toast.types.js.map +1 -1
- package/cards/toggleGroup/index.js +5 -5
- package/cards/toggleGroup/toggleGroup.component.js +1 -0
- package/cards/toggleGroup/toggleGroup.component.js.map +1 -1
- package/cards/toggleGroup/toggleGroup.types.d.ts +4 -0
- package/cards/toggleGroup/toggleGroup.types.js +2 -2
- package/cards/toggleGroup/toggleGroup.types.js.map +1 -1
- package/cards/typography/typography.component.js +4 -4
- package/cards/typography/typography.types.js +1 -0
- package/cards/typography/typography.types.js.map +1 -1
- package/components/ui/slider.js +36 -0
- package/components/ui/slider.js.map +1 -0
- package/components/ui/toggle-group.js +1 -0
- package/components/ui/toggle-group.js.map +1 -1
- package/package.json +19 -8
- package/pihanga-shadcn.css +1 -1
- package/cards/chartGraph/chartGraph.types.d.ts +0 -102
- package/cards/chartGraph/index.d.ts +0 -1
- package/cards/core-index.js +0 -61
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { getIcon as e } from "../icons.js";
|
|
2
|
+
import { Badge as t } from "../../components/ui/badge.js";
|
|
3
|
+
import { cn as n } from "../../lib/utils.js";
|
|
4
4
|
import { Avatar as r, AvatarFallback as i, AvatarImage as a } from "../../components/ui/avatar.js";
|
|
5
|
-
import
|
|
6
|
-
import
|
|
5
|
+
import * as o from "react";
|
|
6
|
+
import { Card as s } from "@pihanga2/core";
|
|
7
7
|
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
8
8
|
import { ChevronDown as u } from "lucide-react";
|
|
9
9
|
//#region src/cards/list/list.component.tsx
|
|
@@ -20,75 +20,75 @@ var d = {
|
|
|
20
20
|
md: "size-6",
|
|
21
21
|
lg: "size-7"
|
|
22
22
|
};
|
|
23
|
-
function m(
|
|
24
|
-
if (!
|
|
25
|
-
switch (
|
|
23
|
+
function m(o, u, d) {
|
|
24
|
+
if (!o) return null;
|
|
25
|
+
switch (o.type) {
|
|
26
26
|
case "icon": return /* @__PURE__ */ c("span", {
|
|
27
|
-
className:
|
|
28
|
-
children:
|
|
27
|
+
className: n("flex shrink-0 items-center [&>svg]:size-4", o.className),
|
|
28
|
+
children: e(o.name)
|
|
29
29
|
});
|
|
30
30
|
case "avatar": return /* @__PURE__ */ l(r, {
|
|
31
|
-
className:
|
|
32
|
-
children: [/* @__PURE__ */ c(a, { src:
|
|
31
|
+
className: n(p[u], o.className),
|
|
32
|
+
children: [/* @__PURE__ */ c(a, { src: o.src }), /* @__PURE__ */ c(i, { children: o.fallback ?? "" })]
|
|
33
33
|
});
|
|
34
|
-
case "chip": return /* @__PURE__ */ c(
|
|
34
|
+
case "chip": return /* @__PURE__ */ c(t, {
|
|
35
35
|
variant: "secondary",
|
|
36
|
-
className:
|
|
37
|
-
children:
|
|
36
|
+
className: o.className,
|
|
37
|
+
children: o.text
|
|
38
38
|
});
|
|
39
|
-
case "card": return /* @__PURE__ */ c(
|
|
40
|
-
cardName:
|
|
39
|
+
case "card": return /* @__PURE__ */ c(s, {
|
|
40
|
+
cardName: o.cardName,
|
|
41
41
|
parentCard: d
|
|
42
42
|
});
|
|
43
43
|
default: return null;
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
function h({ item: e, size:
|
|
47
|
-
let [a,
|
|
46
|
+
function h({ item: e, size: t, onItemClicked: r, cardName: i }) {
|
|
47
|
+
let [a, s] = o.useState(!1), p = !!e.nested?.length;
|
|
48
48
|
function g() {
|
|
49
|
-
p ?
|
|
49
|
+
p ? s((e) => !e) : r({ itemID: e.id });
|
|
50
50
|
}
|
|
51
51
|
return /* @__PURE__ */ l("li", { children: [/* @__PURE__ */ l("button", {
|
|
52
52
|
type: "button",
|
|
53
|
-
className:
|
|
53
|
+
className: n("flex w-full items-center rounded-sm outline-none transition-colors", "hover:bg-accent hover:text-accent-foreground", "focus-visible:ring-1 focus-visible:ring-ring", e.isSelected && "bg-accent text-accent-foreground font-medium", d[t], e.className),
|
|
54
54
|
onClick: g,
|
|
55
55
|
"aria-expanded": p ? a : void 0,
|
|
56
56
|
"data-selected": e.isSelected || void 0,
|
|
57
57
|
children: [
|
|
58
|
-
m(e.startDecorator,
|
|
58
|
+
m(e.startDecorator, t, i),
|
|
59
59
|
/* @__PURE__ */ l("span", {
|
|
60
60
|
className: "flex min-w-0 flex-1 flex-col items-start",
|
|
61
61
|
children: [/* @__PURE__ */ c("span", {
|
|
62
62
|
className: "truncate leading-none",
|
|
63
63
|
children: e.title
|
|
64
64
|
}), e.subTitle && /* @__PURE__ */ c("span", {
|
|
65
|
-
className:
|
|
65
|
+
className: n("mt-0.5 truncate text-muted-foreground", f[t]),
|
|
66
66
|
children: e.subTitle
|
|
67
67
|
})]
|
|
68
68
|
}),
|
|
69
|
-
!p && m(e.endDecorator,
|
|
70
|
-
p && /* @__PURE__ */ c(u, { className:
|
|
69
|
+
!p && m(e.endDecorator, t, i),
|
|
70
|
+
p && /* @__PURE__ */ c(u, { className: n("ml-auto size-4 shrink-0 text-muted-foreground transition-transform duration-200", a && "rotate-180") })
|
|
71
71
|
]
|
|
72
72
|
}), p && a && /* @__PURE__ */ c("ul", {
|
|
73
|
-
className:
|
|
74
|
-
children: e.nested.map((e,
|
|
73
|
+
className: n("ml-3 mt-0.5 flex flex-col gap-0.5 border-l border-border pl-2", "list-none p-0", t === "lg" ? "ml-4 pl-3" : "ml-3 pl-2"),
|
|
74
|
+
children: e.nested.map((e, n) => /* @__PURE__ */ c(h, {
|
|
75
75
|
item: e,
|
|
76
|
-
size:
|
|
76
|
+
size: t,
|
|
77
77
|
onItemClicked: r,
|
|
78
78
|
cardName: i
|
|
79
|
-
}, e.id ??
|
|
79
|
+
}, e.id ?? n))
|
|
80
80
|
})] });
|
|
81
81
|
}
|
|
82
82
|
var g = (e) => {
|
|
83
|
-
let { items:
|
|
83
|
+
let { items: t, size: r = "md", marker: i, className: a, style: o, onItemClicked: s, cardName: l } = e, u = {
|
|
84
84
|
...o,
|
|
85
85
|
...i && i !== "none" ? { listStyleType: i } : void 0
|
|
86
86
|
};
|
|
87
87
|
return /* @__PURE__ */ c("ul", {
|
|
88
|
-
className:
|
|
88
|
+
className: n("flex flex-col gap-0.5 p-0", i && i !== "none" ? "list-inside" : "list-none", a),
|
|
89
89
|
style: u,
|
|
90
90
|
"data-pihanga": l,
|
|
91
|
-
children:
|
|
91
|
+
children: t.map((e, t) => /* @__PURE__ */ c(h, {
|
|
92
92
|
item: e,
|
|
93
93
|
size: r,
|
|
94
94
|
onItemClicked: s,
|
package/cards/list/list.types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.types.js","names":[],"sources":["../../../src/cards/list/list.types.ts"],"sourcesContent":["import * as React from \"react\";\nimport {\n PiCardRef,\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\n\nexport const LIST_CARD = \"shad/list\";\n\nexport const List = createCardDeclaration<ListProps, ListEvents>(LIST_CARD);\n\nexport const LIST_ACTION = registerActions(LIST_CARD, [\"item_clicked\"]);\n\nexport const onListItemClicked = createOnAction<ItemClickedEvent>(\n LIST_ACTION.ITEM_CLICKED,\n);\n\n// Decorator shown before or after an item's title/subtitle block.\nexport type IconDecorator = {\n type: \"icon\";\n /** Name registered via registerIcon() in src/cards/icons.ts */\n name: string;\n className?: string;\n};\n\nexport type AvatarDecorator = {\n type: \"avatar\";\n src: string;\n fallback?: string;\n className?: string;\n};\n\nexport type ChipDecorator = {\n type: \"chip\";\n text: string;\n className?: string;\n};\n\nexport type CardDecorator = {\n type: \"card\";\n cardName: PiCardRef;\n};\n\nexport type DecoratorT =\n | IconDecorator\n | AvatarDecorator\n | ChipDecorator\n | CardDecorator;\n\nexport type ListItem = {\n /** React key — must be unique within the list. */\n id: string | number;\n isSelected?: boolean;\n title: string;\n subTitle?: string;\n /** When present the item becomes a collapsible parent. */\n nested?: ListItem[];\n startDecorator?: DecoratorT;\n endDecorator?: DecoratorT;\n /** Extra CSS classes on this item's button. */\n className?: string;\n};\n\nexport type ListProps = {\n items: ListItem[];\n /** Visual density — defaults to \"md\". */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * CSS `list-style-type` value (e.g. \"disc\", \"decimal\", \"none\").\n * Defaults to \"none\" (plain list without markers).\n */\n marker?: string;\n /** CSS classes applied directly to the root `<ul>`. */\n className?: string;\n /** Inline styles applied directly to the root `<ul>`. */\n style?: React.CSSProperties;\n};\n\nexport type ItemClickedEvent = {\n itemID: string | number;\n};\n\nexport type ListEvents = {\n onItemClicked: ItemClickedEvent;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"list.types.js","names":[],"sources":["../../../src/cards/list/list.types.ts"],"sourcesContent":["import * as React from \"react\";\nimport {\n type PiCardRef,\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\n\nexport const LIST_CARD = \"shad/list\";\n\nexport const List = createCardDeclaration<ListProps, ListEvents>(LIST_CARD);\n\nexport const LIST_ACTION = registerActions(LIST_CARD, [\"item_clicked\"]);\n\nexport const onListItemClicked = createOnAction<ItemClickedEvent>(\n LIST_ACTION.ITEM_CLICKED,\n);\n\n// Decorator shown before or after an item's title/subtitle block.\nexport type IconDecorator = {\n type: \"icon\";\n /** Name registered via registerIcon() in src/cards/icons.ts */\n name: string;\n className?: string;\n};\n\nexport type AvatarDecorator = {\n type: \"avatar\";\n src: string;\n fallback?: string;\n className?: string;\n};\n\nexport type ChipDecorator = {\n type: \"chip\";\n text: string;\n className?: string;\n};\n\nexport type CardDecorator = {\n type: \"card\";\n cardName: PiCardRef;\n};\n\nexport type DecoratorT =\n | IconDecorator\n | AvatarDecorator\n | ChipDecorator\n | CardDecorator;\n\nexport type ListItem = {\n /** React key — must be unique within the list. */\n id: string | number;\n isSelected?: boolean;\n title: string;\n subTitle?: string;\n /** When present the item becomes a collapsible parent. */\n nested?: ListItem[];\n startDecorator?: DecoratorT;\n endDecorator?: DecoratorT;\n /** Extra CSS classes on this item's button. */\n className?: string;\n};\n\nexport type ListProps = {\n items: ListItem[];\n /** Visual density — defaults to \"md\". */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * CSS `list-style-type` value (e.g. \"disc\", \"decimal\", \"none\").\n * Defaults to \"none\" (plain list without markers).\n */\n marker?: string;\n /** CSS classes applied directly to the root `<ul>`. */\n className?: string;\n /** Inline styles applied directly to the root `<ul>`. */\n style?: React.CSSProperties;\n};\n\nexport type ItemClickedEvent = {\n itemID: string | number;\n};\n\nexport type ListEvents = {\n onItemClicked: ItemClickedEvent;\n};\n"],"mappings":";;;AAQA,IAAa,IAAY,aAEZ,IAAO,EAA6C,CAAS,GAE7D,IAAc,EAAgB,GAAW,CAAC,cAAc,CAAC,GAEzD,IAAoB,EAC/B,EAAY,YACd"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Spinner as e } from "../../components/ui/spinner.js";
|
|
2
2
|
/* empty css */
|
|
3
|
-
import { Card as t } from "@pihanga2/core";
|
|
4
3
|
import "react";
|
|
4
|
+
import { Card as t } from "@pihanga2/core";
|
|
5
5
|
import n from "clsx";
|
|
6
6
|
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
7
7
|
//#region src/cards/loadingOverlay/loadingOverlay.component.tsx
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { PiCardProps } from '@pihanga2/core';
|
|
2
2
|
import { PageWithNavbarEvents, PageWithNavbarProps } from './pageWithNavbar.type';
|
|
3
3
|
export type ShadStyle = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
footer?: string;
|
|
10
|
-
};
|
|
4
|
+
window?: string;
|
|
5
|
+
page?: string;
|
|
6
|
+
header?: string;
|
|
7
|
+
main?: string;
|
|
8
|
+
footer?: string;
|
|
11
9
|
};
|
|
12
10
|
export declare const Component: (props: PiCardProps<PageWithNavbarProps<ShadStyle>, PageWithNavbarEvents>) => React.ReactNode;
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getIconElement as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { SCREEN_SIZE_ORDER as e, SCREEN_SIZE_WIDTHS as t, ScreenSize as n } from "../types.js";
|
|
2
|
+
import { getIconElement as r } from "../icons.js";
|
|
3
|
+
import { Button as i } from "../../components/ui/button.js";
|
|
4
|
+
import { Sheet as a, SheetContent as o, SheetTrigger as s } from "../../components/ui/sheet.js";
|
|
5
5
|
/* empty css */
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { useEffect as c, useRef as l, useState as u } from "react";
|
|
7
|
+
import { Card as d } from "@pihanga2/core";
|
|
8
8
|
import f from "clsx";
|
|
9
9
|
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
10
10
|
import { Menu as h } from "lucide-react";
|
|
11
11
|
//#region src/cards/pageWithNavbar/pageWithNavbar.component.tsx
|
|
12
12
|
function g() {
|
|
13
|
-
let
|
|
14
|
-
for (let
|
|
15
|
-
let
|
|
16
|
-
if (
|
|
13
|
+
let r = typeof window < "u" ? window.innerWidth : 0;
|
|
14
|
+
for (let n = e.length - 1; n >= 0; n--) {
|
|
15
|
+
let i = e[n];
|
|
16
|
+
if (r >= t[i]) return i;
|
|
17
17
|
}
|
|
18
|
-
return
|
|
18
|
+
return n.XS;
|
|
19
19
|
}
|
|
20
20
|
function _() {
|
|
21
|
-
let [e, t] =
|
|
22
|
-
return
|
|
21
|
+
let [e, t] = u(g);
|
|
22
|
+
return c(() => {
|
|
23
23
|
let e = () => t(g());
|
|
24
24
|
return window.addEventListener("resize", e), () => window.removeEventListener("resize", e);
|
|
25
25
|
}, []), e;
|
|
@@ -27,19 +27,19 @@ function _() {
|
|
|
27
27
|
function v(e) {
|
|
28
28
|
return typeof e == "object" && !!e;
|
|
29
29
|
}
|
|
30
|
-
function y(
|
|
31
|
-
if (!
|
|
32
|
-
if (!v(
|
|
33
|
-
let
|
|
34
|
-
for (let
|
|
35
|
-
let
|
|
36
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
30
|
+
function y(t, n) {
|
|
31
|
+
if (!t) return;
|
|
32
|
+
if (!v(t)) return t;
|
|
33
|
+
let r = e.indexOf(n);
|
|
34
|
+
for (let n = r; n >= 0; n--) {
|
|
35
|
+
let r = e[n];
|
|
36
|
+
if (Object.prototype.hasOwnProperty.call(t, r)) return t[r] ?? void 0;
|
|
37
37
|
}
|
|
38
|
-
return
|
|
38
|
+
return t.default ?? void 0;
|
|
39
39
|
}
|
|
40
|
-
var b = (
|
|
41
|
-
let { title:
|
|
42
|
-
|
|
40
|
+
var b = (e) => {
|
|
41
|
+
let { title: t, iconName: n, main: u, footer: g, navLinks: v = [], scrollResetKey: b, headerLeftCard: S, headerRightCard: C, style: w, onNavigateTo: T, cardName: E } = e, D = _(), O = w ?? {}, k = l(null);
|
|
42
|
+
c(() => {
|
|
43
43
|
k.current?.scrollTo({
|
|
44
44
|
top: 0,
|
|
45
45
|
behavior: "auto"
|
|
@@ -47,15 +47,15 @@ var b = (a) => {
|
|
|
47
47
|
}, [b]);
|
|
48
48
|
let A = y(S, D), j = y(C, D), M = v.length > 0;
|
|
49
49
|
function N({ className: e }) {
|
|
50
|
-
let
|
|
50
|
+
let i = n ? r(n) : void 0;
|
|
51
51
|
return /* @__PURE__ */ m("div", {
|
|
52
52
|
className: f("title-section", e),
|
|
53
|
-
children: [
|
|
53
|
+
children: [i && /* @__PURE__ */ p(i, {
|
|
54
54
|
className: "title-icon",
|
|
55
55
|
"aria-hidden": !0
|
|
56
56
|
}), /* @__PURE__ */ p("span", {
|
|
57
57
|
className: "title-text",
|
|
58
|
-
children:
|
|
58
|
+
children: t
|
|
59
59
|
})]
|
|
60
60
|
});
|
|
61
61
|
}
|
|
@@ -63,18 +63,18 @@ var b = (a) => {
|
|
|
63
63
|
return /* @__PURE__ */ m("nav", {
|
|
64
64
|
className: "nav-md",
|
|
65
65
|
"aria-label": "Main navigation",
|
|
66
|
-
children: [/* @__PURE__ */ p(N, {}), v.map((
|
|
67
|
-
onClick: () => T({ id:
|
|
66
|
+
children: [/* @__PURE__ */ p(N, {}), v.map((e) => /* @__PURE__ */ p(i, {
|
|
67
|
+
onClick: () => T({ id: e.id }),
|
|
68
68
|
variant: "link",
|
|
69
69
|
className: "nav-link",
|
|
70
|
-
children:
|
|
71
|
-
},
|
|
70
|
+
children: e.title ?? x(e.id)
|
|
71
|
+
}, e.id))]
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
74
|
function F() {
|
|
75
|
-
return /* @__PURE__ */ m(
|
|
75
|
+
return /* @__PURE__ */ m(a, { children: [/* @__PURE__ */ p(s, {
|
|
76
76
|
asChild: !0,
|
|
77
|
-
children: /* @__PURE__ */ p(
|
|
77
|
+
children: /* @__PURE__ */ p(i, {
|
|
78
78
|
variant: "outline",
|
|
79
79
|
size: "icon",
|
|
80
80
|
className: "shrink-0 md:hidden",
|
|
@@ -84,17 +84,17 @@ var b = (a) => {
|
|
|
84
84
|
"aria-hidden": !0
|
|
85
85
|
})
|
|
86
86
|
})
|
|
87
|
-
}), /* @__PURE__ */ p(
|
|
87
|
+
}), /* @__PURE__ */ p(o, {
|
|
88
88
|
side: "left",
|
|
89
89
|
children: /* @__PURE__ */ m("nav", {
|
|
90
90
|
className: "nav-sm",
|
|
91
91
|
"aria-label": "Mobile navigation",
|
|
92
|
-
children: [/* @__PURE__ */ p(N, {}), v.map((
|
|
93
|
-
onClick: () => T({ id:
|
|
92
|
+
children: [/* @__PURE__ */ p(N, {}), v.map((e) => /* @__PURE__ */ p(i, {
|
|
93
|
+
onClick: () => T({ id: e.id }),
|
|
94
94
|
variant: "link",
|
|
95
95
|
className: "nav-link",
|
|
96
|
-
children:
|
|
97
|
-
},
|
|
96
|
+
children: e.title ?? x(e.id)
|
|
97
|
+
}, e.id))]
|
|
98
98
|
})
|
|
99
99
|
})] });
|
|
100
100
|
}
|
|
@@ -115,10 +115,10 @@ var b = (a) => {
|
|
|
115
115
|
}),
|
|
116
116
|
/* @__PURE__ */ m("div", {
|
|
117
117
|
className: "header-actions",
|
|
118
|
-
children: [A && /* @__PURE__ */ p(
|
|
118
|
+
children: [A && /* @__PURE__ */ p(d, {
|
|
119
119
|
cardName: A,
|
|
120
120
|
parentCard: E
|
|
121
|
-
}), j && /* @__PURE__ */ p(
|
|
121
|
+
}), j && /* @__PURE__ */ p(d, {
|
|
122
122
|
cardName: j,
|
|
123
123
|
parentCard: E
|
|
124
124
|
})]
|
|
@@ -128,14 +128,14 @@ var b = (a) => {
|
|
|
128
128
|
/* @__PURE__ */ p("main", {
|
|
129
129
|
className: f("main", O.main),
|
|
130
130
|
ref: k,
|
|
131
|
-
children: /* @__PURE__ */ p(
|
|
132
|
-
cardName:
|
|
131
|
+
children: /* @__PURE__ */ p(d, {
|
|
132
|
+
cardName: u,
|
|
133
133
|
parentCard: E
|
|
134
134
|
})
|
|
135
135
|
}),
|
|
136
136
|
g && /* @__PURE__ */ p("footer", {
|
|
137
137
|
className: f("footer", O.footer),
|
|
138
|
-
children: /* @__PURE__ */ p(
|
|
138
|
+
children: /* @__PURE__ */ p(d, {
|
|
139
139
|
cardName: g,
|
|
140
140
|
parentCard: E
|
|
141
141
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageWithNavbar.component.js","names":[],"sources":["../../../src/cards/pageWithNavbar/pageWithNavbar.component.tsx"],"sourcesContent":["import {Menu} from \"lucide-react\";\nimport clsx from \"clsx\";\nimport {useEffect, useRef, useState} from \"react\";\n\nimport {Button} from \"@/components/ui/button\";\nimport {Sheet, SheetContent, SheetTrigger} from \"@/components/ui/sheet\";\nimport {Card, type PiCardProps} from \"@pihanga2/core\";\nimport {getIconElement} from \"@/cards/icons\";\nimport {ScreenSize, SCREEN_SIZE_ORDER, SCREEN_SIZE_WIDTHS} from \"@/cards/types\";\nimport type {\n PageWithNavbarEvents,\n PageWithNavbarProps,\n ResponsiveCardRef,\n} from \"./pageWithNavbar.type\";\nimport type {SizeMap} from \"@/cards/types\";\nimport type {PiCardRef} from \"@pihanga2/core\";\n\nimport \"./pageWithNavbar.css\";\n\n// ---------------------------------------------------------------------------\n// Style override type — consumers can extend this to add Tailwind class names\n// to any structural section of the layout.\n// ---------------------------------------------------------------------------\n\nexport type ShadStyle = {\n shad?: {\n window?: string;\n page?: string;\n header?: string;\n main?: string;\n footer?: string;\n };\n};\n\n// ---------------------------------------------------------------------------\n// Screen-size hook\n// ---------------------------------------------------------------------------\n\nfunction getCurrentScreenSize(): ScreenSize {\n const w = typeof window !== \"undefined\" ? window.innerWidth : 0;\n // Walk breakpoints from largest to smallest\n for (let i = SCREEN_SIZE_ORDER.length - 1; i >= 0; i--) {\n const size = SCREEN_SIZE_ORDER[i];\n if (w >= SCREEN_SIZE_WIDTHS[size]) return size;\n }\n return ScreenSize.XS;\n}\n\nfunction useScreenSize(): ScreenSize {\n const [size, setSize] = useState<ScreenSize>(getCurrentScreenSize);\n\n useEffect(() => {\n const handleResize = () => setSize(getCurrentScreenSize());\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n return size;\n}\n\n// ---------------------------------------------------------------------------\n// Responsive card-ref resolution\n// ---------------------------------------------------------------------------\n\nfunction isSizeMap(ref: ResponsiveCardRef): ref is SizeMap<PiCardRef> {\n return typeof ref === \"object\" && ref !== null;\n}\n\n/**\n * Resolve a {@link ResponsiveCardRef} to a concrete `PiCardRef` (or\n * `undefined`) for the given screen size.\n *\n * Uses a **mobile-first cascade**: the entry with the largest breakpoint\n * that is still ≤ `currentSize` wins; falls back to `default` otherwise.\n */\nfunction resolveCardRef(\n ref: ResponsiveCardRef | undefined,\n currentSize: ScreenSize,\n): PiCardRef | undefined {\n if (!ref) return undefined;\n if (!isSizeMap(ref)) return ref; // plain PiCardRef (string or PiCardDef)\n\n // Cascade: find the highest breakpoint that is ≤ current size\n const currentIdx = SCREEN_SIZE_ORDER.indexOf(currentSize);\n for (let i = currentIdx; i >= 0; i--) {\n const size = SCREEN_SIZE_ORDER[i];\n if (Object.prototype.hasOwnProperty.call(ref, size)) {\n const val = ref[size];\n // null means \"explicitly hidden at this breakpoint\"\n return val ?? undefined;\n }\n }\n // Fall back to the default entry\n return ref.default ?? undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport const Component = (\n props: PiCardProps<PageWithNavbarProps<ShadStyle>, PageWithNavbarEvents>,\n): React.ReactNode => {\n const {\n title,\n iconName,\n main,\n footer,\n navLinks = [],\n scrollResetKey,\n headerLeftCard,\n headerRightCard,\n style,\n onNavigateTo,\n cardName,\n } = props;\n\n const screenSize = useScreenSize();\n const cl = style?.shad ?? {};\n const mainRef = useRef<HTMLElement | null>(null);\n\n // Scroll main back to top when the logical \"page\" changes\n useEffect(() => {\n mainRef.current?.scrollTo({top: 0, behavior: \"auto\"});\n }, [scrollResetKey]);\n\n const resolvedLeftCard = resolveCardRef(headerLeftCard, screenSize);\n const resolvedRightCard = resolveCardRef(headerRightCard, screenSize);\n const hasNavLinks = navLinks.length > 0;\n\n // ------------------------------------------------------------------\n // Sub-components\n // ------------------------------------------------------------------\n\n /** Title section: optional icon + text */\n function TitleSection({className}: {className?: string}) {\n const IconEl = iconName ? getIconElement(iconName) : undefined;\n return (\n <div className={clsx(\"title-section\", className)}>\n {IconEl && <IconEl className=\"title-icon\" aria-hidden />}\n <span className=\"title-text\">{title}</span>\n </div>\n );\n }\n\n /** Nav bar rendered on medium screens and above */\n function NavMd() {\n return (\n <nav className=\"nav-md\" aria-label=\"Main navigation\">\n <TitleSection />\n {navLinks.map((el) => (\n <Button\n key={el.id}\n onClick={() => onNavigateTo({id: el.id})}\n variant=\"link\"\n className=\"nav-link\"\n >\n {el.title ?? capitalize(el.id)}\n </Button>\n ))}\n </nav>\n );\n }\n\n /** Hamburger trigger that opens a slide-out sheet on small screens */\n function NavSm() {\n return (\n <Sheet>\n <SheetTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"shrink-0 md:hidden\"\n aria-label=\"Toggle navigation menu\"\n >\n <Menu className=\"h-5 w-5\" aria-hidden />\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\">\n <nav className=\"nav-sm\" aria-label=\"Mobile navigation\">\n <TitleSection />\n {navLinks.map((el) => (\n <Button\n key={el.id}\n onClick={() => onNavigateTo({id: el.id})}\n variant=\"link\"\n className=\"nav-link\"\n >\n {el.title ?? capitalize(el.id)}\n </Button>\n ))}\n </nav>\n </SheetContent>\n </Sheet>\n );\n }\n\n // ------------------------------------------------------------------\n // Layout\n // ------------------------------------------------------------------\n\n return (\n <div className={clsx(\"window\", cl.window)} data-pihanga={cardName}>\n <div className={clsx(\"page\", cl.page)}>\n {/* ── Header ─────────────────────────────────────────────── */}\n <header className={clsx(\"header\", cl.header)}>\n {/* Medium+ nav (title + links) */}\n <NavMd />\n\n {/* Small-screen hamburger (only when there are nav links) */}\n {hasNavLinks && <NavSm />}\n\n {/* On small screens with no nav links, show the title inline.\n Wrap in a plain div so md:hidden isn't overridden by the\n .title-section CSS class that sets display:inline-flex. */}\n {!hasNavLinks && (\n <div className=\"md:hidden\">\n <TitleSection />\n </div>\n )}\n\n {/* Push action cards to the right */}\n <div className=\"header-actions\">\n {resolvedLeftCard && (\n <Card cardName={resolvedLeftCard} parentCard={cardName} />\n )}\n {resolvedRightCard && (\n <Card cardName={resolvedRightCard} parentCard={cardName} />\n )}\n </div>\n </header>\n\n {/* ── Main ───────────────────────────────────────────────── */}\n <main className={clsx(\"main\", cl.main)} ref={mainRef}>\n <Card cardName={main} parentCard={cardName} />\n </main>\n\n {/* ── Footer (optional) ──────────────────────────────────── */}\n {footer && (\n <footer className={clsx(\"footer\", cl.footer)}>\n <Card cardName={footer} parentCard={cardName} />\n </footer>\n )}\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction capitalize(str: string): string {\n if (!str) return \"\";\n return str.charAt(0).toLocaleUpperCase() + str.slice(1);\n}\n"],"mappings":";;;;;;;;;;;AAsCA,SAAS,IAAmC;CAC1C,IAAM,IAAI,OAAO,SAAW,MAAc,OAAO,aAAa;CAE9D,KAAK,IAAI,IAAI,EAAkB,SAAS,GAAG,KAAK,GAAG,KAAK;EACtD,IAAM,IAAO,EAAkB;EAC/B,IAAI,KAAK,EAAmB,IAAO,OAAO;CAC5C;CACA,OAAO,EAAW;AACpB;AAEA,SAAS,IAA4B;CACnC,IAAM,CAAC,GAAM,KAAW,EAAqB,CAAoB;CAQjE,OANA,QAAgB;EACd,IAAM,UAAqB,EAAQ,EAAqB,CAAC;EAEzD,OADA,OAAO,iBAAiB,UAAU,CAAY,SACjC,OAAO,oBAAoB,UAAU,CAAY;CAChE,GAAG,CAAC,CAAC,GAEE;AACT;AAMA,SAAS,EAAU,GAAmD;CACpE,OAAO,OAAO,KAAQ,cAAY;AACpC;AASA,SAAS,EACP,GACA,GACuB;CACvB,IAAI,CAAC,GAAK;CACV,IAAI,CAAC,EAAU,CAAG,GAAG,OAAO;CAG5B,IAAM,IAAa,EAAkB,QAAQ,CAAW;CACxD,KAAK,IAAI,IAAI,GAAY,KAAK,GAAG,KAAK;EACpC,IAAM,IAAO,EAAkB;EAC/B,IAAI,OAAO,UAAU,eAAe,KAAK,GAAK,CAAI,GAGhD,OAFY,EAAI,MAEF,KAAA;CAElB;CAEA,OAAO,EAAI,WAAW,KAAA;AACxB;AAMA,IAAa,KACX,MACoB;CACpB,IAAM,EACJ,UACA,aACA,SACA,WACA,cAAW,CAAC,GACZ,mBACA,mBACA,oBACA,UACA,iBACA,gBACE,GAEE,IAAa,EAAc,GAC3B,IAAK,GAAO,QAAQ,CAAC,GACrB,IAAU,EAA2B,IAAI;CAG/C,QAAgB;EACd,EAAQ,SAAS,SAAS;GAAC,KAAK;GAAG,UAAU;EAAM,CAAC;CACtD,GAAG,CAAC,CAAc,CAAC;CAEnB,IAAM,IAAmB,EAAe,GAAgB,CAAU,GAC5D,IAAoB,EAAe,GAAiB,CAAU,GAC9D,IAAc,EAAS,SAAS;CAOtC,SAAS,EAAa,EAAC,gBAAkC;EACvD,IAAM,IAAS,IAAW,EAAe,CAAQ,IAAI,KAAA;EACrD,OACE,kBAAC,OAAD;GAAK,WAAW,EAAK,iBAAiB,CAAS;aAA/C,CACG,KAAU,kBAAC,GAAD;IAAQ,WAAU;IAAa,eAAA;GAAa,CAAA,GACvD,kBAAC,QAAD;IAAM,WAAU;cAAc;GAAY,CAAA,CACvC;;CAET;CAGA,SAAS,IAAQ;EACf,OACE,kBAAC,OAAD;GAAK,WAAU;GAAS,cAAW;aAAnC,CACE,kBAAC,GAAD,CAAe,CAAA,GACd,EAAS,KAAK,MACb,kBAAC,GAAD;IAEE,eAAe,EAAa,EAAC,IAAI,EAAG,GAAE,CAAC;IACvC,SAAQ;IACR,WAAU;cAET,EAAG,SAAS,EAAW,EAAG,EAAE;GACvB,GAND,EAAG,EAMF,CACT,CACE;;CAET;CAGA,SAAS,IAAQ;EACf,OACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;GAAc,SAAA;aACZ,kBAAC,GAAD;IACE,SAAQ;IACR,MAAK;IACL,WAAU;IACV,cAAW;cAEX,kBAAC,GAAD;KAAM,WAAU;KAAU,eAAA;IAAa,CAAA;GACjC,CAAA;EACI,CAAA,GACd,kBAAC,GAAD;GAAc,MAAK;aACjB,kBAAC,OAAD;IAAK,WAAU;IAAS,cAAW;cAAnC,CACE,kBAAC,GAAD,CAAe,CAAA,GACd,EAAS,KAAK,MACb,kBAAC,GAAD;KAEE,eAAe,EAAa,EAAC,IAAI,EAAG,GAAE,CAAC;KACvC,SAAQ;KACR,WAAU;eAET,EAAG,SAAS,EAAW,EAAG,EAAE;IACvB,GAND,EAAG,EAMF,CACT,CACE;;EACO,CAAA,CACT,EAAA,CAAA;CAEX;CAMA,OACE,kBAAC,OAAD;EAAK,WAAW,EAAK,UAAU,EAAG,MAAM;EAAG,gBAAc;YACvD,kBAAC,OAAD;GAAK,WAAW,EAAK,QAAQ,EAAG,IAAI;aAApC;IAEE,kBAAC,UAAD;KAAQ,WAAW,EAAK,UAAU,EAAG,MAAM;eAA3C;MAEE,kBAAC,GAAD,CAAQ,CAAA;MAGP,KAAe,kBAAC,GAAD,CAAQ,CAAA;MAKvB,CAAC,KACA,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,CAAe,CAAA;MACZ,CAAA;MAIP,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACG,KACC,kBAAC,GAAD;QAAM,UAAU;QAAkB,YAAY;OAAW,CAAA,GAE1D,KACC,kBAAC,GAAD;QAAM,UAAU;QAAmB,YAAY;OAAW,CAAA,CAEzD;;KACC;;IAGR,kBAAC,QAAD;KAAM,WAAW,EAAK,QAAQ,EAAG,IAAI;KAAG,KAAK;eAC3C,kBAAC,GAAD;MAAM,UAAU;MAAM,YAAY;KAAW,CAAA;IACzC,CAAA;IAGL,KACC,kBAAC,UAAD;KAAQ,WAAW,EAAK,UAAU,EAAG,MAAM;eACzC,kBAAC,GAAD;MAAM,UAAU;MAAQ,YAAY;KAAW,CAAA;IACzC,CAAA;GAEP;;CACF,CAAA;AAET;AAMA,SAAS,EAAW,GAAqB;CAEvC,OADK,IACE,EAAI,OAAO,CAAC,EAAE,kBAAkB,IAAI,EAAI,MAAM,CAAC,IADrC;AAEnB"}
|
|
1
|
+
{"version":3,"file":"pageWithNavbar.component.js","names":[],"sources":["../../../src/cards/pageWithNavbar/pageWithNavbar.component.tsx"],"sourcesContent":["import {Menu} from \"lucide-react\";\nimport clsx from \"clsx\";\nimport {useEffect, useRef, useState} from \"react\";\n\nimport {Button} from \"@/components/ui/button\";\nimport {Sheet, SheetContent, SheetTrigger} from \"@/components/ui/sheet\";\nimport {Card, type PiCardProps} from \"@pihanga2/core\";\nimport {getIconElement} from \"@/cards/icons\";\nimport {ScreenSize, SCREEN_SIZE_ORDER, SCREEN_SIZE_WIDTHS} from \"@/cards/types\";\nimport type {\n PageWithNavbarEvents,\n PageWithNavbarProps,\n ResponsiveCardRef,\n} from \"./pageWithNavbar.type\";\nimport type {SizeMap} from \"@/cards/types\";\nimport type {PiCardRef} from \"@pihanga2/core\";\n\nimport \"./pageWithNavbar.css\";\n\n// ---------------------------------------------------------------------------\n// Style override type — consumers can extend this to add Tailwind class names\n// to any structural section of the layout.\n// ---------------------------------------------------------------------------\n\nexport type ShadStyle = {\n window?: string;\n page?: string;\n header?: string;\n main?: string;\n footer?: string;\n};\n\n// ---------------------------------------------------------------------------\n// Screen-size hook\n// ---------------------------------------------------------------------------\n\nfunction getCurrentScreenSize(): ScreenSize {\n const w = typeof window !== \"undefined\" ? window.innerWidth : 0;\n // Walk breakpoints from largest to smallest\n for (let i = SCREEN_SIZE_ORDER.length - 1; i >= 0; i--) {\n const size = SCREEN_SIZE_ORDER[i];\n if (w >= SCREEN_SIZE_WIDTHS[size]) return size;\n }\n return ScreenSize.XS;\n}\n\nfunction useScreenSize(): ScreenSize {\n const [size, setSize] = useState<ScreenSize>(getCurrentScreenSize);\n\n useEffect(() => {\n const handleResize = () => setSize(getCurrentScreenSize());\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n return size;\n}\n\n// ---------------------------------------------------------------------------\n// Responsive card-ref resolution\n// ---------------------------------------------------------------------------\n\nfunction isSizeMap(ref: ResponsiveCardRef): ref is SizeMap<PiCardRef> {\n return typeof ref === \"object\" && ref !== null;\n}\n\n/**\n * Resolve a {@link ResponsiveCardRef} to a concrete `PiCardRef` (or\n * `undefined`) for the given screen size.\n *\n * Uses a **mobile-first cascade**: the entry with the largest breakpoint\n * that is still ≤ `currentSize` wins; falls back to `default` otherwise.\n */\nfunction resolveCardRef(\n ref: ResponsiveCardRef | undefined,\n currentSize: ScreenSize,\n): PiCardRef | undefined {\n if (!ref) return undefined;\n if (!isSizeMap(ref)) return ref; // plain PiCardRef (string or PiCardDef)\n\n // Cascade: find the highest breakpoint that is ≤ current size\n const currentIdx = SCREEN_SIZE_ORDER.indexOf(currentSize);\n for (let i = currentIdx; i >= 0; i--) {\n const size = SCREEN_SIZE_ORDER[i];\n if (Object.prototype.hasOwnProperty.call(ref, size)) {\n const val = ref[size];\n // null means \"explicitly hidden at this breakpoint\"\n return val ?? undefined;\n }\n }\n // Fall back to the default entry\n return ref.default ?? undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport const Component = (\n props: PiCardProps<PageWithNavbarProps<ShadStyle>, PageWithNavbarEvents>,\n): React.ReactNode => {\n const {\n title,\n iconName,\n main,\n footer,\n navLinks = [],\n scrollResetKey,\n headerLeftCard,\n headerRightCard,\n style,\n onNavigateTo,\n cardName,\n } = props;\n\n const screenSize = useScreenSize();\n const cl = style ?? {};\n const mainRef = useRef<HTMLElement | null>(null);\n\n // Scroll main back to top when the logical \"page\" changes\n useEffect(() => {\n mainRef.current?.scrollTo({top: 0, behavior: \"auto\"});\n }, [scrollResetKey]);\n\n const resolvedLeftCard = resolveCardRef(headerLeftCard, screenSize);\n const resolvedRightCard = resolveCardRef(headerRightCard, screenSize);\n const hasNavLinks = navLinks.length > 0;\n\n // ------------------------------------------------------------------\n // Sub-components\n // ------------------------------------------------------------------\n\n /** Title section: optional icon + text */\n function TitleSection({className}: {className?: string}) {\n const IconEl = iconName ? getIconElement(iconName) : undefined;\n return (\n <div className={clsx(\"title-section\", className)}>\n {IconEl && <IconEl className=\"title-icon\" aria-hidden />}\n <span className=\"title-text\">{title}</span>\n </div>\n );\n }\n\n /** Nav bar rendered on medium screens and above */\n function NavMd() {\n return (\n <nav className=\"nav-md\" aria-label=\"Main navigation\">\n <TitleSection />\n {navLinks.map((el) => (\n <Button\n key={el.id}\n onClick={() => onNavigateTo({id: el.id})}\n variant=\"link\"\n className=\"nav-link\"\n >\n {el.title ?? capitalize(el.id)}\n </Button>\n ))}\n </nav>\n );\n }\n\n /** Hamburger trigger that opens a slide-out sheet on small screens */\n function NavSm() {\n return (\n <Sheet>\n <SheetTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"shrink-0 md:hidden\"\n aria-label=\"Toggle navigation menu\"\n >\n <Menu className=\"h-5 w-5\" aria-hidden />\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\">\n <nav className=\"nav-sm\" aria-label=\"Mobile navigation\">\n <TitleSection />\n {navLinks.map((el) => (\n <Button\n key={el.id}\n onClick={() => onNavigateTo({id: el.id})}\n variant=\"link\"\n className=\"nav-link\"\n >\n {el.title ?? capitalize(el.id)}\n </Button>\n ))}\n </nav>\n </SheetContent>\n </Sheet>\n );\n }\n\n // ------------------------------------------------------------------\n // Layout\n // ------------------------------------------------------------------\n\n return (\n <div className={clsx(\"window\", cl.window)} data-pihanga={cardName}>\n <div className={clsx(\"page\", cl.page)}>\n {/* ── Header ─────────────────────────────────────────────── */}\n <header className={clsx(\"header\", cl.header)}>\n {/* Medium+ nav (title + links) */}\n <NavMd />\n\n {/* Small-screen hamburger (only when there are nav links) */}\n {hasNavLinks && <NavSm />}\n\n {/* On small screens with no nav links, show the title inline.\n Wrap in a plain div so md:hidden isn't overridden by the\n .title-section CSS class that sets display:inline-flex. */}\n {!hasNavLinks && (\n <div className=\"md:hidden\">\n <TitleSection />\n </div>\n )}\n\n {/* Push action cards to the right */}\n <div className=\"header-actions\">\n {resolvedLeftCard && (\n <Card cardName={resolvedLeftCard} parentCard={cardName} />\n )}\n {resolvedRightCard && (\n <Card cardName={resolvedRightCard} parentCard={cardName} />\n )}\n </div>\n </header>\n\n {/* ── Main ───────────────────────────────────────────────── */}\n <main className={clsx(\"main\", cl.main)} ref={mainRef}>\n <Card cardName={main} parentCard={cardName} />\n </main>\n\n {/* ── Footer (optional) ──────────────────────────────────── */}\n {footer && (\n <footer className={clsx(\"footer\", cl.footer)}>\n <Card cardName={footer} parentCard={cardName} />\n </footer>\n )}\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction capitalize(str: string): string {\n if (!str) return \"\";\n return str.charAt(0).toLocaleUpperCase() + str.slice(1);\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pasteTarget.component.js","names":[],"sources":["../../../src/cards/pasteTarget/pasteTarget.component.tsx"],"sourcesContent":["import {\n DEF_ERROR_COLOR,\n DEF_EVENT_DURATION_SECONDS,\n DEF_HEIGHT,\n DEF_OVERLAY_OPACITY,\n DEF_PASTE_FIRST_REMINDER,\n DEF_SUCCESS_COLOR,\n PasteItem,\n PasteTargetEvents,\n PasteTargetProps,\n} from \"@/cards/pasteTarget/pasteTarget.types\";\nimport {PiCardProps} from \"@pihanga2/core\";\nimport React, {useRef, useState} from \"react\";\n\nimport \"./pasteTarget.css\";\nimport clsx from \"clsx\";\nimport {Button} from \"@/registry/ui/button\";\n\n// /* 3. Stretch the child to cover the parent entirely */\n// top: 0,\n// left: 0,\n// right: 0,\n// bottom: 0,\n\n// /* 4. Ensure the child is visually stacked above the parent's content */\n// z-index: 10,\n\n// /* Optional: Make the overlay visible (e.g., semi-transparent black) */\n// overlayOpacity: \"rgba(0, 0, 0, 0.5)\";\n// }\n\nexport const PasteTargetComponent = (\n props: PiCardProps<PasteTargetProps, PasteTargetEvents>,\n): React.ReactNode => {\n const {\n title, // = \"Paste content right here\",\n description,\n pasteFirstReminder = DEF_PASTE_FIRST_REMINDER,\n withUpload,\n fileTypes,\n\n height = DEF_HEIGHT,\n\n onPastedContent,\n\n successColor = DEF_SUCCESS_COLOR,\n errorColor = DEF_ERROR_COLOR,\n eventDurationSeconds = DEF_EVENT_DURATION_SECONDS,\n eventOpacity = DEF_OVERLAY_OPACITY,\n cardName,\n className,\n _cls,\n } = props;\n const [overlayOpacity, setOverlayOpacity] = useState<number>(0);\n const [overlayBackground, setOverlayBackground] = useState<string>(\"gray\");\n const timerRef = React.useRef<number | null>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [isFocused, setIsFocused] = useState<boolean>(false);\n\n const overlayStyle: React.CSSProperties = {\n backgroundColor: overlayBackground,\n opacity: overlayOpacity,\n };\n\n const handlePaste = (event: React.ClipboardEvent<HTMLTextAreaElement>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n }\n\n event.preventDefault();\n const clipboardData =\n event.clipboardData ||\n (window as Window & {clipboardData?: DataTransfer}).clipboardData;\n\n if (clipboardData) {\n const pItems = clipboardData.items;\n const items: PasteItem[] = [];\n for (let i = 0; i < pItems.length; i++) {\n const pi = pItems[i];\n const mimeType = pi.type;\n const content = clipboardData.getData(pi.type);\n if (!(content == \"\" || content == \"\\n\")) {\n items.push({mimeType, content});\n }\n }\n onPastedContent({items});\n setOverlayBackground(successColor);\n } else {\n setOverlayBackground(errorColor);\n }\n setOverlayOpacity(eventOpacity);\n if (textareaRef.current) textareaRef.current.blur();\n\n // Set a timeout to switch the color back after 'n' seconds\n const newTimerId = setTimeout(() => {\n setOverlayOpacity(0);\n timerRef.current = null; // Clear the ref after the timeout executes\n }, eventDurationSeconds * 1000); // Convert seconds to milliseconds\n\n // Save the new timer ID to the ref (unknown necessary type casting)\n timerRef.current = newTimerId as unknown as number;\n };\n\n // Cleanup function to clear the timer when the component unmounts\n React.useEffect(() => {\n return () => {\n const ref = timerRef.current;\n if (ref) {\n clearTimeout(ref);\n }\n };\n }, []); // runs only on mount/unmount\n\n function renderPasteHandler() {\n return (\n <textarea\n onPaste={handlePaste}\n onFocus={() => {\n setIsFocused(true);\n }}\n onBlur={() => setIsFocused(false)}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n resize: \"none\",\n background: \"transparent\",\n cursor: isFocused ? \"copy\" : \"pointer\",\n ...overlayStyle,\n }}\n // 🔑 CRUCIAL: Focus the element before pasting so it receives the paste event.\n // autoFocus\n readOnly\n ref={textareaRef}\n />\n );\n }\n\n /** Map friendly file-type labels to accept= strings for the hidden input. */\n function buildAccept(): string | undefined {\n if (!fileTypes?.length) return undefined;\n return fileTypes\n .map((t) => {\n const ext = t.toLowerCase();\n if (ext === \"jpg\" || ext === \"jpeg\") return \".jpg,.jpeg\";\n return `.${ext}`;\n })\n .join(\",\");\n }\n\n function flashOverlay(color: string) {\n if (timerRef.current) clearTimeout(timerRef.current);\n setOverlayBackground(color);\n setOverlayOpacity(eventOpacity);\n const id = setTimeout(() => {\n setOverlayOpacity(0);\n timerRef.current = null;\n }, eventDurationSeconds * 1000);\n timerRef.current = id as unknown as number;\n }\n\n function handleFileChange(ev: React.ChangeEvent<HTMLInputElement>) {\n const file = ev.target.files?.[0];\n // Reset input so the same file can be re-selected later.\n ev.target.value = \"\";\n if (!file) return;\n\n const reader = new FileReader();\n reader.onload = (e) => {\n const content = (e.target?.result as string) ?? \"\";\n onPastedContent({items: [{mimeType: file.type, content}]});\n flashOverlay(successColor);\n };\n reader.onerror = () => {\n flashOverlay(errorColor);\n };\n reader.readAsDataURL(file);\n }\n\n function onUpload(ev: React.MouseEvent<HTMLButtonElement>) {\n ev.stopPropagation();\n ev.preventDefault();\n fileInputRef.current?.click();\n }\n\n function renderTitle() {\n const uploadBtn = !isFocused && withUpload && (\n <Button\n onClick={onUpload}\n style={{position: \"relative\", zIndex: 30, pointerEvents: \"auto\"}}\n >\n Upload\n </Button>\n );\n\n if (title) {\n return (\n <div className=\"paste-target-msg-title\">\n <h2>{title}</h2>\n {uploadBtn}\n </div>\n );\n } else {\n return (\n <div className=\"paste-target-msg-title\">\n Paste\n {uploadBtn && (\n <>\n or \n {uploadBtn}\n </>\n )}\n here\n </div>\n );\n }\n }\n\n const cn = _cls(\"root\", className || \"pihanga-paste-target\");\n\n return (\n <div\n className={clsx(cn, isFocused && \"pihanga-paste-target-focused\")}\n data-pihanga={cardName}\n style={{position: \"relative\", height, width: \"100%\"}}\n >\n <div\n className=\"paste-target-label\"\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n textAlign: \"center\",\n // zIndex must be above textarea (10) so the Upload button is clickable.\n // pointer-events: none lets click/focus pass through to the textarea,\n // EXCEPT on children that override with pointer-events: auto (the button).\n pointerEvents: \"none\",\n zIndex: 20,\n }}\n >\n {renderTitle()}\n {description && (\n <span className=\"paste-target-msg-desc\">{description}</span>\n )}\n <div className=\"paste-target-focus-reminder\">{pasteFirstReminder}</div>\n </div>\n {renderPasteHandler()}\n {/* Hidden file input — triggered programmatically by the Upload button */}\n {withUpload && (\n <input\n type=\"file\"\n ref={fileInputRef}\n accept={buildAccept()}\n onChange={handleFileChange}\n style={{display: \"none\"}}\n />\n )}\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pasteTarget.component.js","names":[],"sources":["../../../src/cards/pasteTarget/pasteTarget.component.tsx"],"sourcesContent":["import {\n DEF_ERROR_COLOR,\n DEF_EVENT_DURATION_SECONDS,\n DEF_HEIGHT,\n DEF_OVERLAY_OPACITY,\n DEF_PASTE_FIRST_REMINDER,\n DEF_SUCCESS_COLOR,\n type PasteItem,\n type PasteTargetEvents,\n type PasteTargetProps,\n} from \"@/cards/pasteTarget/pasteTarget.types\";\nimport type {PiCardProps} from \"@pihanga2/core\";\nimport React, {useRef, useState} from \"react\";\n\nimport \"./pasteTarget.css\";\nimport clsx from \"clsx\";\nimport {Button} from \"@/registry/ui/button\";\n\n// /* 3. Stretch the child to cover the parent entirely */\n// top: 0,\n// left: 0,\n// right: 0,\n// bottom: 0,\n\n// /* 4. Ensure the child is visually stacked above the parent's content */\n// z-index: 10,\n\n// /* Optional: Make the overlay visible (e.g., semi-transparent black) */\n// overlayOpacity: \"rgba(0, 0, 0, 0.5)\";\n// }\n\nexport const PasteTargetComponent = (\n props: PiCardProps<PasteTargetProps, PasteTargetEvents>,\n): React.ReactNode => {\n const {\n title, // = \"Paste content right here\",\n description,\n pasteFirstReminder = DEF_PASTE_FIRST_REMINDER,\n withUpload,\n fileTypes,\n\n height = DEF_HEIGHT,\n\n onPastedContent,\n\n successColor = DEF_SUCCESS_COLOR,\n errorColor = DEF_ERROR_COLOR,\n eventDurationSeconds = DEF_EVENT_DURATION_SECONDS,\n eventOpacity = DEF_OVERLAY_OPACITY,\n cardName,\n className,\n _cls,\n } = props;\n const [overlayOpacity, setOverlayOpacity] = useState<number>(0);\n const [overlayBackground, setOverlayBackground] = useState<string>(\"gray\");\n const timerRef = React.useRef<number | null>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [isFocused, setIsFocused] = useState<boolean>(false);\n\n const overlayStyle: React.CSSProperties = {\n backgroundColor: overlayBackground,\n opacity: overlayOpacity,\n };\n\n const handlePaste = (event: React.ClipboardEvent<HTMLTextAreaElement>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n }\n\n event.preventDefault();\n const clipboardData =\n event.clipboardData ||\n (window as Window & {clipboardData?: DataTransfer}).clipboardData;\n\n if (clipboardData) {\n const pItems = clipboardData.items;\n const items: PasteItem[] = [];\n for (let i = 0; i < pItems.length; i++) {\n const pi = pItems[i];\n const mimeType = pi.type;\n const content = clipboardData.getData(pi.type);\n if (!(content == \"\" || content == \"\\n\")) {\n items.push({mimeType, content});\n }\n }\n onPastedContent({items});\n setOverlayBackground(successColor);\n } else {\n setOverlayBackground(errorColor);\n }\n setOverlayOpacity(eventOpacity);\n if (textareaRef.current) textareaRef.current.blur();\n\n // Set a timeout to switch the color back after 'n' seconds\n const newTimerId = setTimeout(() => {\n setOverlayOpacity(0);\n timerRef.current = null; // Clear the ref after the timeout executes\n }, eventDurationSeconds * 1000); // Convert seconds to milliseconds\n\n // Save the new timer ID to the ref (unknown necessary type casting)\n timerRef.current = newTimerId as unknown as number;\n };\n\n // Cleanup function to clear the timer when the component unmounts\n React.useEffect(() => {\n return () => {\n const ref = timerRef.current;\n if (ref) {\n clearTimeout(ref);\n }\n };\n }, []); // runs only on mount/unmount\n\n function renderPasteHandler() {\n return (\n <textarea\n onPaste={handlePaste}\n onFocus={() => {\n setIsFocused(true);\n }}\n onBlur={() => setIsFocused(false)}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n resize: \"none\",\n background: \"transparent\",\n cursor: isFocused ? \"copy\" : \"pointer\",\n ...overlayStyle,\n }}\n // 🔑 CRUCIAL: Focus the element before pasting so it receives the paste event.\n // autoFocus\n readOnly\n ref={textareaRef}\n />\n );\n }\n\n /** Map friendly file-type labels to accept= strings for the hidden input. */\n function buildAccept(): string | undefined {\n if (!fileTypes?.length) return undefined;\n return fileTypes\n .map((t) => {\n const ext = t.toLowerCase();\n if (ext === \"jpg\" || ext === \"jpeg\") return \".jpg,.jpeg\";\n return `.${ext}`;\n })\n .join(\",\");\n }\n\n function flashOverlay(color: string) {\n if (timerRef.current) clearTimeout(timerRef.current);\n setOverlayBackground(color);\n setOverlayOpacity(eventOpacity);\n const id = setTimeout(() => {\n setOverlayOpacity(0);\n timerRef.current = null;\n }, eventDurationSeconds * 1000);\n timerRef.current = id as unknown as number;\n }\n\n function handleFileChange(ev: React.ChangeEvent<HTMLInputElement>) {\n const file = ev.target.files?.[0];\n // Reset input so the same file can be re-selected later.\n ev.target.value = \"\";\n if (!file) return;\n\n const reader = new FileReader();\n reader.onload = (e) => {\n const content = (e.target?.result as string) ?? \"\";\n onPastedContent({items: [{mimeType: file.type, content}]});\n flashOverlay(successColor);\n };\n reader.onerror = () => {\n flashOverlay(errorColor);\n };\n reader.readAsDataURL(file);\n }\n\n function onUpload(ev: React.MouseEvent<HTMLButtonElement>) {\n ev.stopPropagation();\n ev.preventDefault();\n fileInputRef.current?.click();\n }\n\n function renderTitle() {\n const uploadBtn = !isFocused && withUpload && (\n <Button\n onClick={onUpload}\n style={{position: \"relative\", zIndex: 30, pointerEvents: \"auto\"}}\n >\n Upload\n </Button>\n );\n\n if (title) {\n return (\n <div className=\"paste-target-msg-title\">\n <h2>{title}</h2>\n {uploadBtn}\n </div>\n );\n } else {\n return (\n <div className=\"paste-target-msg-title\">\n Paste\n {uploadBtn && (\n <>\n or \n {uploadBtn}\n </>\n )}\n here\n </div>\n );\n }\n }\n\n const cn = _cls(\"root\", className || \"pihanga-paste-target\");\n\n return (\n <div\n className={clsx(cn, isFocused && \"pihanga-paste-target-focused\")}\n data-pihanga={cardName}\n style={{position: \"relative\", height, width: \"100%\"}}\n >\n <div\n className=\"paste-target-label\"\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n textAlign: \"center\",\n // zIndex must be above textarea (10) so the Upload button is clickable.\n // pointer-events: none lets click/focus pass through to the textarea,\n // EXCEPT on children that override with pointer-events: auto (the button).\n pointerEvents: \"none\",\n zIndex: 20,\n }}\n >\n {renderTitle()}\n {description && (\n <span className=\"paste-target-msg-desc\">{description}</span>\n )}\n <div className=\"paste-target-focus-reminder\">{pasteFirstReminder}</div>\n </div>\n {renderPasteHandler()}\n {/* Hidden file input — triggered programmatically by the Upload button */}\n {withUpload && (\n <input\n type=\"file\"\n ref={fileInputRef}\n accept={buildAccept()}\n onChange={handleFileChange}\n style={{display: \"none\"}}\n />\n )}\n </div>\n );\n};\n"],"mappings":"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"}
|
package/cards/select/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { SelectComponent as e } from "./select.component.js";
|
|
2
|
-
import { PI_SELECT_ACTION as t, PI_SELECT_CARD as n, Select as r, onPiSelectChanged as i, onPiSelectClosed as a, onPiSelectOpened as o } from "./select.types.js";
|
|
3
|
-
import { actionTypesToEvents as
|
|
2
|
+
import { PI_SELECT_ACTION as t, PI_SELECT_CARD as n, Select as r, onPiSelectChanged as i, onPiSelectClosed as a, onPiSelectOpened as o, onSelectChanged as s, onSelectClosed as c, onSelectOpened as l } from "./select.types.js";
|
|
3
|
+
import { actionTypesToEvents as u, registerCardComponent as d } from "@pihanga2/core";
|
|
4
4
|
//#region src/cards/select/index.ts
|
|
5
|
-
|
|
5
|
+
d({
|
|
6
6
|
name: n,
|
|
7
7
|
component: e,
|
|
8
|
-
events:
|
|
8
|
+
events: u(t)
|
|
9
9
|
});
|
|
10
10
|
//#endregion
|
|
11
|
-
export { t as PI_SELECT_ACTION, n as PI_SELECT_CARD, r as Select, i as onPiSelectChanged, a as onPiSelectClosed, o as onPiSelectOpened };
|
|
11
|
+
export { t as PI_SELECT_ACTION, n as PI_SELECT_CARD, r as Select, i as onPiSelectChanged, a as onPiSelectClosed, o as onPiSelectOpened, s as onSelectChanged, c as onSelectClosed, l as onSelectOpened };
|
|
12
12
|
|
|
13
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useFormContext as e } from "../form/form.context.js";
|
|
2
2
|
import { Select as t, SelectContent as n, SelectGroup as r, SelectItem as i, SelectTrigger as a, SelectValue as o } from "../../components/ui/select.js";
|
|
3
3
|
import { useState as s } from "react";
|
|
4
|
+
import "@pihanga2/core";
|
|
4
5
|
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
5
6
|
//#region src/cards/select/select.component.tsx
|
|
6
7
|
var u = (u) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.component.js","names":[],"sources":["../../../src/cards/select/select.component.tsx"],"sourcesContent":["import React, {useState} from \"react\";\nimport {type PiCardProps} from \"@pihanga2/core\";\nimport {\n Select as RadixSelect,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport {useFormContext} from \"@/cards/form/form.context\";\nimport type {PiSelectEvents, PiSelectProps} from \"./select.types\";\n\nexport const SelectComponent = (\n props: PiCardProps<PiSelectProps, PiSelectEvents>,\n): React.ReactNode => {\n const {\n name,\n value: propValue = \"\",\n defaultValue,\n selfManaged = false,\n options,\n placeholder,\n required,\n disabled,\n ariaLabel,\n cardName,\n onChanged,\n onOpened,\n onClosed,\n } = props;\n\n // `id` and `invalid` may be injected by a parent pi/field card via\n // Pihanga's extra-prop forwarding. They are not in the official type so\n // we read them through an escape hatch.\n const injectedId = (props as {id?: string}).id;\n const invalid = Boolean((props as {invalid?: boolean}).invalid);\n\n // Detect if we are inside a pi/form card via React context.\n const form = useFormContext();\n const useFormData = form.isInForm && Boolean(name);\n\n // Internal state used only when selfManaged=true and not bound to a form.\n const [managedValue, setManagedValue] = useState<string>(\n defaultValue ?? propValue,\n );\n\n const value = useFormData\n ? ((form.formData[name!] as string | undefined) ?? \"\")\n : selfManaged\n ? managedValue\n : propValue;\n\n function handleChange(newValue: string) {\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n if (selfManaged) {\n setManagedValue(newValue);\n }\n onChanged({name, value: newValue});\n }\n }\n\n function handleOpenChange(open: boolean) {\n if (open) {\n onOpened({});\n } else {\n onClosed({});\n }\n }\n\n // Use the id injected by pi/field; fall back to a local id when standalone.\n const selfId = `${cardName}-${name ?? \"select\"}`;\n const fieldId = injectedId ?? selfId;\n\n return (\n <RadixSelect\n value={value}\n defaultValue={defaultValue}\n onValueChange={handleChange}\n onOpenChange={handleOpenChange}\n disabled={disabled}\n required={required}\n aria-label={ariaLabel}\n >\n <SelectTrigger\n id={fieldId}\n aria-invalid={invalid || undefined}\n data-pihanga={cardName}\n >\n <SelectValue placeholder={placeholder ?? \"Select…\"} />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n {options.map((opt) => (\n <SelectItem\n key={opt.value}\n value={opt.value}\n disabled={opt.disabled}\n >\n {opt.label}\n </SelectItem>\n ))}\n </SelectGroup>\n </SelectContent>\n </RadixSelect>\n );\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"select.component.js","names":[],"sources":["../../../src/cards/select/select.component.tsx"],"sourcesContent":["import React, {useState} from \"react\";\nimport {type PiCardProps} from \"@pihanga2/core\";\nimport {\n Select as RadixSelect,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport {useFormContext} from \"@/cards/form/form.context\";\nimport type {PiSelectEvents, PiSelectProps} from \"./select.types\";\n\nexport const SelectComponent = (\n props: PiCardProps<PiSelectProps, PiSelectEvents>,\n): React.ReactNode => {\n const {\n name,\n value: propValue = \"\",\n defaultValue,\n selfManaged = false,\n options,\n placeholder,\n required,\n disabled,\n ariaLabel,\n cardName,\n onChanged,\n onOpened,\n onClosed,\n } = props;\n\n // `id` and `invalid` may be injected by a parent pi/field card via\n // Pihanga's extra-prop forwarding. They are not in the official type so\n // we read them through an escape hatch.\n const injectedId = (props as {id?: string}).id;\n const invalid = Boolean((props as {invalid?: boolean}).invalid);\n\n // Detect if we are inside a pi/form card via React context.\n const form = useFormContext();\n const useFormData = form.isInForm && Boolean(name);\n\n // Internal state used only when selfManaged=true and not bound to a form.\n const [managedValue, setManagedValue] = useState<string>(\n defaultValue ?? propValue,\n );\n\n const value = useFormData\n ? ((form.formData[name!] as string | undefined) ?? \"\")\n : selfManaged\n ? managedValue\n : propValue;\n\n function handleChange(newValue: string) {\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n if (selfManaged) {\n setManagedValue(newValue);\n }\n onChanged({name, value: newValue});\n }\n }\n\n function handleOpenChange(open: boolean) {\n if (open) {\n onOpened({});\n } else {\n onClosed({});\n }\n }\n\n // Use the id injected by pi/field; fall back to a local id when standalone.\n const selfId = `${cardName}-${name ?? \"select\"}`;\n const fieldId = injectedId ?? selfId;\n\n return (\n <RadixSelect\n value={value}\n defaultValue={defaultValue}\n onValueChange={handleChange}\n onOpenChange={handleOpenChange}\n disabled={disabled}\n required={required}\n aria-label={ariaLabel}\n >\n <SelectTrigger\n id={fieldId}\n aria-invalid={invalid || undefined}\n data-pihanga={cardName}\n >\n <SelectValue placeholder={placeholder ?? \"Select…\"} />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n {options.map((opt) => (\n <SelectItem\n key={opt.value}\n value={opt.value}\n disabled={opt.disabled}\n >\n {opt.label}\n </SelectItem>\n ))}\n </SelectGroup>\n </SelectContent>\n </RadixSelect>\n );\n};\n"],"mappings":";;;;;;AAaA,IAAa,KACX,MACoB;CACpB,IAAM,EACJ,SACA,OAAO,IAAY,IACnB,iBACA,iBAAc,IACd,YACA,gBACA,aACA,aACA,cACA,aACA,cACA,aACA,gBACE,GAKE,IAAc,EAAwB,IACtC,IAAU,EAAS,EAA8B,SAGjD,IAAO,EAAe,GACtB,IAAc,EAAK,YAAY,EAAQ,GAGvC,CAAC,GAAc,KAAmB,EACtC,KAAgB,CAClB,GAEM,IAAQ,IACR,EAAK,SAAS,MAAiC,KACjD,IACE,IACA;CAEN,SAAS,EAAa,GAAkB;EACtC,AAAI,IACF,EAAK,aAAa,GAAO,CAAQ,KAE7B,KACF,EAAgB,CAAQ,GAE1B,EAAU;GAAC;GAAM,OAAO;EAAQ,CAAC;CAErC;CAEA,SAAS,EAAiB,GAAe;EACvC,AAAI,IACF,EAAS,CAAC,CAAC,IAEX,EAAS,CAAC,CAAC;CAEf;CAGA,IAAM,IAAS,GAAG,EAAS,GAAG,KAAQ;CAGtC,OACE,kBAAC,GAAD;EACS;EACO;EACd,eAAe;EACf,cAAc;EACJ;EACA;EACV,cAAY;YAPd,CASE,kBAAC,GAAD;GACE,IAbU,KAAc;GAcxB,gBAAc,KAAW,KAAA;GACzB,gBAAc;aAEd,kBAAC,GAAD,EAAa,aAAa,KAAe,UAAY,CAAA;EACxC,CAAA,GACf,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UACG,EAAQ,KAAK,MACZ,kBAAC,GAAD;GAEE,OAAO,EAAI;GACX,UAAU,EAAI;aAEb,EAAI;EACK,GALL,EAAI,KAKC,CACb,EACU,CAAA,EACA,CAAA,CACJ;;AAEjB"}
|
|
@@ -5,12 +5,24 @@ export declare const PI_SELECT_ACTION: {
|
|
|
5
5
|
CLOSED: string;
|
|
6
6
|
OPENED: string;
|
|
7
7
|
};
|
|
8
|
+
export declare const onSelectChanged: <S extends import('@pihanga2/core').ReduxState>(register: import('@pihanga2/core').PiRegister, f: import('@pihanga2/core').ReduceF<S, import('@pihanga2/core').ReduxAction & {
|
|
9
|
+
cardID: string;
|
|
10
|
+
} & PiSelectChangedEvent>) => void;
|
|
11
|
+
/** @deprecated Use `onSelectChanged` instead. */
|
|
8
12
|
export declare const onPiSelectChanged: <S extends import('@pihanga2/core').ReduxState>(register: import('@pihanga2/core').PiRegister, f: import('@pihanga2/core').ReduceF<S, import('@pihanga2/core').ReduxAction & {
|
|
9
13
|
cardID: string;
|
|
10
14
|
} & PiSelectChangedEvent>) => void;
|
|
15
|
+
export declare const onSelectOpened: <S extends import('@pihanga2/core').ReduxState>(register: import('@pihanga2/core').PiRegister, f: import('@pihanga2/core').ReduceF<S, import('@pihanga2/core').ReduxAction & {
|
|
16
|
+
cardID: string;
|
|
17
|
+
} & PiSelectOpenedEvent>) => void;
|
|
18
|
+
/** @deprecated Use `onSelectOpened` instead. */
|
|
11
19
|
export declare const onPiSelectOpened: <S extends import('@pihanga2/core').ReduxState>(register: import('@pihanga2/core').PiRegister, f: import('@pihanga2/core').ReduceF<S, import('@pihanga2/core').ReduxAction & {
|
|
12
20
|
cardID: string;
|
|
13
21
|
} & PiSelectOpenedEvent>) => void;
|
|
22
|
+
export declare const onSelectClosed: <S extends import('@pihanga2/core').ReduxState>(register: import('@pihanga2/core').PiRegister, f: import('@pihanga2/core').ReduceF<S, import('@pihanga2/core').ReduxAction & {
|
|
23
|
+
cardID: string;
|
|
24
|
+
} & PiSelectClosedEvent>) => void;
|
|
25
|
+
/** @deprecated Use `onSelectClosed` instead. */
|
|
14
26
|
export declare const onPiSelectClosed: <S extends import('@pihanga2/core').ReduxState>(register: import('@pihanga2/core').PiRegister, f: import('@pihanga2/core').ReduceF<S, import('@pihanga2/core').ReduxAction & {
|
|
15
27
|
cardID: string;
|
|
16
28
|
} & PiSelectClosedEvent>) => void;
|
|
@@ -4,8 +4,8 @@ var r = "pi/select", i = e(r), a = n(r, [
|
|
|
4
4
|
"changed",
|
|
5
5
|
"opened",
|
|
6
6
|
"closed"
|
|
7
|
-
]), o = t(a.CHANGED), s = t(a.OPENED), c = t(a.CLOSED);
|
|
7
|
+
]), o = t(a.CHANGED), s = o, c = t(a.OPENED), l = c, u = t(a.CLOSED), d = u;
|
|
8
8
|
//#endregion
|
|
9
|
-
export { a as PI_SELECT_ACTION, r as PI_SELECT_CARD, i as Select,
|
|
9
|
+
export { a as PI_SELECT_ACTION, r as PI_SELECT_CARD, i as Select, s as onPiSelectChanged, d as onPiSelectClosed, l as onPiSelectOpened, o as onSelectChanged, u as onSelectClosed, c as onSelectOpened };
|
|
10
10
|
|
|
11
11
|
//# sourceMappingURL=select.types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.types.js","names":[],"sources":["../../../src/cards/select/select.types.ts"],"sourcesContent":["import {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\n\nexport const PI_SELECT_CARD = \"pi/select\";\n\nexport const Select = createCardDeclaration<PiSelectProps, PiSelectEvents>(\n PI_SELECT_CARD,\n);\n\nexport const PI_SELECT_ACTION = registerActions(PI_SELECT_CARD, [\n \"changed\",\n \"opened\",\n \"closed\",\n]);\n\nexport const
|
|
1
|
+
{"version":3,"file":"select.types.js","names":[],"sources":["../../../src/cards/select/select.types.ts"],"sourcesContent":["import {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\n\nexport const PI_SELECT_CARD = \"pi/select\";\n\nexport const Select = createCardDeclaration<PiSelectProps, PiSelectEvents>(\n PI_SELECT_CARD,\n);\n\nexport const PI_SELECT_ACTION = registerActions(PI_SELECT_CARD, [\n \"changed\",\n \"opened\",\n \"closed\",\n]);\n\nexport const onSelectChanged = createOnAction<PiSelectChangedEvent>(\n PI_SELECT_ACTION.CHANGED,\n);\n\n/** @deprecated Use `onSelectChanged` instead. */\nexport const onPiSelectChanged = onSelectChanged;\n\nexport const onSelectOpened = createOnAction<PiSelectOpenedEvent>(\n PI_SELECT_ACTION.OPENED,\n);\n\n/** @deprecated Use `onSelectOpened` instead. */\nexport const onPiSelectOpened = onSelectOpened;\n\nexport const onSelectClosed = createOnAction<PiSelectClosedEvent>(\n PI_SELECT_ACTION.CLOSED,\n);\n\n/** @deprecated Use `onSelectClosed` instead. */\nexport const onPiSelectClosed = onSelectClosed;\n\nexport type PiSelectOption = {\n /** The value stored in form state / dispatched in events. */\n value: string;\n /** Human-readable label shown in the dropdown. */\n label: string;\n /** When true, the option is shown but cannot be selected. */\n disabled?: boolean;\n};\n\nexport type PiSelectProps = {\n /**\n * Field name used to bind to FormContext when inside a pi/form card.\n * When provided the component reads its selected value from form data and\n * writes back via form.handleChange.\n */\n name?: string;\n\n /**\n * Controlled value used in standalone mode (outside a Form).\n * Ignored when `name` is set and the component is inside a pi/form.\n */\n value?: string;\n\n /**\n * When true the component manages its own selected-value state internally.\n * Selecting an item will still dispatch the normal `onChanged` action, but\n * the UI will immediately reflect the new selection without waiting for the\n * host application to update `value` via a reducer.\n *\n * Has no effect when the component is bound to a pi/form via `name`.\n */\n selfManaged?: boolean;\n\n /**\n * Default (uncontrolled) value. Mirrors Radix `defaultValue`.\n */\n defaultValue?: string;\n\n /** Available options to display in the dropdown. */\n options: PiSelectOption[];\n\n /** Placeholder text shown when no option is selected. */\n placeholder?: string;\n\n /** When true, the select is required (HTML form attribute). */\n required?: boolean;\n\n /** When true, the select is disabled and non-interactive. */\n disabled?: boolean;\n\n /** Accessible label for screen readers. */\n ariaLabel?: string;\n};\n\nexport type PiSelectChangedEvent = {\n /** Field name, mirrors the `name` prop if provided. */\n name?: string;\n /** The value of the newly selected option. */\n value: string;\n};\n\nexport type PiSelectOpenedEvent = Record<string, never>;\n\nexport type PiSelectClosedEvent = Record<string, never>;\n\nexport type PiSelectEvents = {\n onChanged: PiSelectChangedEvent;\n onOpened: PiSelectOpenedEvent;\n onClosed: PiSelectClosedEvent;\n};\n"],"mappings":";;AAMA,IAAa,IAAiB,aAEjB,IAAS,EACpB,CACF,GAEa,IAAmB,EAAgB,GAAgB;CAC9D;CACA;CACA;AACF,CAAC,GAEY,IAAkB,EAC7B,EAAiB,OACnB,GAGa,IAAoB,GAEpB,IAAiB,EAC5B,EAAiB,MACnB,GAGa,IAAmB,GAEnB,IAAiB,EAC5B,EAAiB,MACnB,GAGa,IAAmB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SliderComponent as e } from "./slider.component.js";
|
|
2
|
+
import { PI_SLIDER_ACTION as t, PI_SLIDER_CARD as n, Slider as r, onPiSliderChanged as i, onPiSliderCommitted as a, onSliderChanged as o, onSliderCommitted as s } from "./slider.types.js";
|
|
3
|
+
import { actionTypesToEvents as c, registerCardComponent as l } from "@pihanga2/core";
|
|
4
|
+
//#region src/cards/slider/index.ts
|
|
5
|
+
l({
|
|
6
|
+
name: n,
|
|
7
|
+
component: e,
|
|
8
|
+
events: c(t)
|
|
9
|
+
});
|
|
10
|
+
//#endregion
|
|
11
|
+
export { t as PI_SLIDER_ACTION, n as PI_SLIDER_CARD, r as Slider, i as onPiSliderChanged, a as onPiSliderCommitted, o as onSliderChanged, s as onSliderCommitted };
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/cards/slider/index.ts"],"sourcesContent":["import {actionTypesToEvents, registerCardComponent} from \"@pihanga2/core\";\n\nimport {SliderComponent} from \"./slider.component\";\nimport {PI_SLIDER_ACTION, PI_SLIDER_CARD} from \"./slider.types\";\n\nexport * from \"./slider.types\";\n\nregisterCardComponent({\n name: PI_SLIDER_CARD,\n component: SliderComponent,\n events: actionTypesToEvents(PI_SLIDER_ACTION),\n});\n"],"mappings":";;;;AAOA,EAAsB;CACpB,MAAM;CACN,WAAW;CACX,QAAQ,EAAoB,CAAgB;AAC9C,CAAC"}
|