@pihanga2/shadcn 0.2.11 → 0.2.13
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/cards/box/box.component.js +8 -7
- package/cards/box/box.component.js.map +1 -1
- package/cards/box/box.types.d.ts +2 -0
- package/cards/box/box.types.js.map +1 -1
- package/cards/graphin/graphin.types.d.ts +15 -0
- package/cards/stack/stack.component.js +22 -20
- package/cards/stack/stack.component.js.map +1 -1
- package/cards/stack/stack.types.d.ts +2 -0
- package/cards/stack/stack.types.js.map +1 -1
- package/cards/switch/switch.component.js +25 -21
- package/cards/switch/switch.component.js.map +1 -1
- package/cards/switch/switch.types.d.ts +8 -0
- package/cards/switch/switch.types.js.map +1 -1
- package/cards/toggleGroup/toggleGroup.component.js +30 -28
- package/cards/toggleGroup/toggleGroup.component.js.map +1 -1
- package/cards/toggleGroup/toggleGroup.types.d.ts +3 -1
- package/cards/toggleGroup/toggleGroup.types.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,20 +3,21 @@ import { Card as e } from "@pihanga2/core";
|
|
|
3
3
|
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
4
4
|
//#region src/cards/box/box.component.tsx
|
|
5
5
|
var r = (r) => {
|
|
6
|
-
let { content: i, singleContent: a, className: o, style: s, cardName: c } = r,
|
|
7
|
-
r.height && (
|
|
8
|
-
let
|
|
9
|
-
function
|
|
10
|
-
return
|
|
6
|
+
let { content: i, singleContent: a, className: o, style: s, cardName: c, data: l } = r, u = { ...s };
|
|
7
|
+
r.height && (u.height = `${r.height}px`), r.width && (u.width = `${r.width}px`), r.marginTop && (u.marginTop = `${r.marginTop}px`), r.marginBottom && (u.marginBottom = `${r.marginBottom}px`), r.marginLeft && (u.marginLeft = `${r.marginLeft}px`), r.marginRight && (u.marginRight = `${r.marginRight}px`), r.paddingTop && (u.paddingTop = `${r.paddingTop}px`), r.paddingBottom && (u.paddingBottom = `${r.paddingBottom}px`), r.paddingLeft && (u.paddingLeft = `${r.paddingLeft}px`), r.paddingRight && (u.paddingRight = `${r.paddingRight}px`);
|
|
8
|
+
let d = a ? [a] : i;
|
|
9
|
+
function f() {
|
|
10
|
+
return d ? d.map((n, r) => /* @__PURE__ */ t(e, {
|
|
11
11
|
cardName: n,
|
|
12
12
|
parentCard: c
|
|
13
13
|
}, r)) : null;
|
|
14
14
|
}
|
|
15
15
|
return /* @__PURE__ */ n("div", {
|
|
16
16
|
className: o,
|
|
17
|
-
style:
|
|
17
|
+
style: u,
|
|
18
18
|
"data-pihanga": c,
|
|
19
|
-
|
|
19
|
+
...l ? Object.fromEntries(Object.entries(l).map(([e, t]) => [`data-${e}`, t])) : {},
|
|
20
|
+
children: [f(), r.children]
|
|
20
21
|
});
|
|
21
22
|
};
|
|
22
23
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box.component.js","names":[],"sources":["../../../src/cards/box/box.component.tsx"],"sourcesContent":["import * as React from \"react\";\n\nimport {Card, type PiCardProps} from \"@pihanga2/core\";\nimport type {BoxProps} from \"./box.types\";\n\nexport const BoxComponent = (props: PiCardProps<BoxProps>): React.ReactNode => {\n const {content, singleContent, className, style, cardName} = props;\n\n const sy: Record<string, string | number> = {\n ...(style as Record<string, string | number> | undefined),\n };\n if (props.height) sy.height = `${props.height}px`;\n if (props.width) sy.width = `${props.width}px`;\n\n if (props.marginTop) sy.marginTop = `${props.marginTop}px`;\n if (props.marginBottom) sy.marginBottom = `${props.marginBottom}px`;\n if (props.marginLeft) sy.marginLeft = `${props.marginLeft}px`;\n if (props.marginRight) sy.marginRight = `${props.marginRight}px`;\n\n if (props.paddingTop) sy.paddingTop = `${props.paddingTop}px`;\n if (props.paddingBottom) sy.paddingBottom = `${props.paddingBottom}px`;\n if (props.paddingLeft) sy.paddingLeft = `${props.paddingLeft}px`;\n if (props.paddingRight) sy.paddingRight = `${props.paddingRight}px`;\n\n const cards = singleContent ? [singleContent] : content;\n function renderContent() {\n if (!cards) return null;\n return cards.map((cn, i) => (\n <Card cardName={cn} parentCard={cardName} key={i} />\n ));\n }\n\n return (\n <div
|
|
1
|
+
{"version":3,"file":"box.component.js","names":[],"sources":["../../../src/cards/box/box.component.tsx"],"sourcesContent":["import * as React from \"react\";\n\nimport {Card, type PiCardProps} from \"@pihanga2/core\";\nimport type {BoxProps} from \"./box.types\";\n\nexport const BoxComponent = (props: PiCardProps<BoxProps>): React.ReactNode => {\n const {content, singleContent, className, style, cardName, data} = props;\n\n const sy: Record<string, string | number> = {\n ...(style as Record<string, string | number> | undefined),\n };\n if (props.height) sy.height = `${props.height}px`;\n if (props.width) sy.width = `${props.width}px`;\n\n if (props.marginTop) sy.marginTop = `${props.marginTop}px`;\n if (props.marginBottom) sy.marginBottom = `${props.marginBottom}px`;\n if (props.marginLeft) sy.marginLeft = `${props.marginLeft}px`;\n if (props.marginRight) sy.marginRight = `${props.marginRight}px`;\n\n if (props.paddingTop) sy.paddingTop = `${props.paddingTop}px`;\n if (props.paddingBottom) sy.paddingBottom = `${props.paddingBottom}px`;\n if (props.paddingLeft) sy.paddingLeft = `${props.paddingLeft}px`;\n if (props.paddingRight) sy.paddingRight = `${props.paddingRight}px`;\n\n const cards = singleContent ? [singleContent] : content;\n function renderContent() {\n if (!cards) return null;\n return cards.map((cn, i) => (\n <Card cardName={cn} parentCard={cardName} key={i} />\n ));\n }\n\n const dataAttrs = data\n ? Object.fromEntries(Object.entries(data).map(([k, v]) => [`data-${k}`, v]))\n : {};\n\n return (\n <div\n className={className}\n style={sy}\n data-pihanga={cardName}\n {...dataAttrs}\n >\n {renderContent()}\n {props.children}\n </div>\n );\n};\n"],"mappings":";;;;AAKA,IAAa,KAAgB,MAAkD;CAC7E,IAAM,EAAC,YAAS,kBAAe,cAAW,UAAO,aAAU,YAAQ,GAE7D,IAAsC,EAC1C,GAAI,EACN;CAYA,AAXI,EAAM,WAAQ,EAAG,SAAS,GAAG,EAAM,OAAO,MAC1C,EAAM,UAAO,EAAG,QAAQ,GAAG,EAAM,MAAM,MAEvC,EAAM,cAAW,EAAG,YAAY,GAAG,EAAM,UAAU,MACnD,EAAM,iBAAc,EAAG,eAAe,GAAG,EAAM,aAAa,MAC5D,EAAM,eAAY,EAAG,aAAa,GAAG,EAAM,WAAW,MACtD,EAAM,gBAAa,EAAG,cAAc,GAAG,EAAM,YAAY,MAEzD,EAAM,eAAY,EAAG,aAAa,GAAG,EAAM,WAAW,MACtD,EAAM,kBAAe,EAAG,gBAAgB,GAAG,EAAM,cAAc,MAC/D,EAAM,gBAAa,EAAG,cAAc,GAAG,EAAM,YAAY,MACzD,EAAM,iBAAc,EAAG,eAAe,GAAG,EAAM,aAAa;CAEhE,IAAM,IAAQ,IAAgB,CAAC,CAAa,IAAI;CAChD,SAAS,IAAgB;EAEvB,OADK,IACE,EAAM,KAAK,GAAI,MACpB,kBAAC,GAAD;GAAM,UAAU;GAAI,YAAY;EAAmB,GAAJ,CAAI,CACpD,IAHkB;CAIrB;CAMA,OACE,kBAAC,OAAD;EACa;EACX,OAAO;EACP,gBAAc;EACd,GATc,IACd,OAAO,YAAY,OAAO,QAAQ,CAAI,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,IACzE,CAAC;YAGH,CAMG,EAAc,GACd,EAAM,QACJ;;AAET"}
|
package/cards/box/box.types.d.ts
CHANGED
|
@@ -42,6 +42,8 @@ export type BoxProps<S = object> = {
|
|
|
42
42
|
style?: S;
|
|
43
43
|
/** Additional Tailwind utility classes */
|
|
44
44
|
className?: string;
|
|
45
|
+
/** Arbitrary data attributes rendered as `data-{key}={value}` on the root element */
|
|
46
|
+
data?: Record<string, string>;
|
|
45
47
|
};
|
|
46
48
|
/**
|
|
47
49
|
* Factory function for declaring a `shad/box` card instance.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box.types.js","names":[],"sources":["../../../src/cards/box/box.types.ts"],"sourcesContent":["import {type PiCardRef, createCardDeclaration} from \"@pihanga2/core\";\n\nexport const BOX_CARD = \"shad/box\";\n\n/**\n * Responsive display grid breakpoints.\n *\n * Each key maps to a CSS display value applied at that viewport width:\n * - `xs`: < 640 px (default / mobile-first)\n * - `sm`: ≥ 640 px\n * - `md`: ≥ 768 px\n * - `lg`: ≥ 1024 px\n * - `xl`: ≥ 1280 px\n * - `xxl`: ≥ 1536 px\n */\nexport type DisplayGridT = {\n xs?: string;\n sm?: string;\n md?: string;\n lg?: string;\n xl?: string;\n xxl?: string;\n};\n\nexport type BoxProps<S = object> = {\n /** Child card refs rendered inside the box */\n content?: PiCardRef[];\n\n /** Single child to make dynmic selection (s) => ... possible */\n singleContent?: PiCardRef;\n\n /** Override the root element type */\n component?: React.ElementType;\n\n /** Fixed height in pixels */\n height?: number;\n /** Fixed width in pixels */\n width?: number;\n\n marginTop?: number;\n marginBottom?: number;\n marginLeft?: number;\n marginRight?: number;\n\n paddingTop?: number;\n paddingBottom?: number;\n paddingLeft?: number;\n paddingRight?: number;\n\n /** Card style object (use the `shad` key for Tailwind-compatible overrides) */\n style?: S;\n /** Additional Tailwind utility classes */\n className?: string;\n};\n\n/**\n * Factory function for declaring a `shad/box` card instance.\n *\n * ```ts\n * import {registerCard} from \"@pihanga2/core\";\n * import {Box} from \"@/cards/box\";\n *\n * registerCard(\"myApp/spacer\", Box({height: 24}));\n *\n * registerCard(\"myApp/contentRegion\", Box({\n * content: [\"myApp/card1\", \"myApp/card2\"],\n * paddingTop: 16,\n * className: \"rounded-lg border bg-card\",\n * }));\n * ```\n */\nexport const Box = createCardDeclaration<BoxProps>(BOX_CARD);\n"],"mappings":";;AAEA,IAAa,IAAW,
|
|
1
|
+
{"version":3,"file":"box.types.js","names":[],"sources":["../../../src/cards/box/box.types.ts"],"sourcesContent":["import {type PiCardRef, createCardDeclaration} from \"@pihanga2/core\";\n\nexport const BOX_CARD = \"shad/box\";\n\n/**\n * Responsive display grid breakpoints.\n *\n * Each key maps to a CSS display value applied at that viewport width:\n * - `xs`: < 640 px (default / mobile-first)\n * - `sm`: ≥ 640 px\n * - `md`: ≥ 768 px\n * - `lg`: ≥ 1024 px\n * - `xl`: ≥ 1280 px\n * - `xxl`: ≥ 1536 px\n */\nexport type DisplayGridT = {\n xs?: string;\n sm?: string;\n md?: string;\n lg?: string;\n xl?: string;\n xxl?: string;\n};\n\nexport type BoxProps<S = object> = {\n /** Child card refs rendered inside the box */\n content?: PiCardRef[];\n\n /** Single child to make dynmic selection (s) => ... possible */\n singleContent?: PiCardRef;\n\n /** Override the root element type */\n component?: React.ElementType;\n\n /** Fixed height in pixels */\n height?: number;\n /** Fixed width in pixels */\n width?: number;\n\n marginTop?: number;\n marginBottom?: number;\n marginLeft?: number;\n marginRight?: number;\n\n paddingTop?: number;\n paddingBottom?: number;\n paddingLeft?: number;\n paddingRight?: number;\n\n /** Card style object (use the `shad` key for Tailwind-compatible overrides) */\n style?: S;\n /** Additional Tailwind utility classes */\n className?: string;\n\n /** Arbitrary data attributes rendered as `data-{key}={value}` on the root element */\n data?: Record<string, string>;\n};\n\n/**\n * Factory function for declaring a `shad/box` card instance.\n *\n * ```ts\n * import {registerCard} from \"@pihanga2/core\";\n * import {Box} from \"@/cards/box\";\n *\n * registerCard(\"myApp/spacer\", Box({height: 24}));\n *\n * registerCard(\"myApp/contentRegion\", Box({\n * content: [\"myApp/card1\", \"myApp/card2\"],\n * paddingTop: 16,\n * className: \"rounded-lg border bg-card\",\n * }));\n * ```\n */\nexport const Box = createCardDeclaration<BoxProps>(BOX_CARD);\n"],"mappings":";;AAEA,IAAa,IAAW,YAwEX,IAAM,EAAgC,CAAQ"}
|
|
@@ -162,6 +162,15 @@ export type GraphinProps = {
|
|
|
162
162
|
* @example 2 // 200 % — start zoomed in on a small graph
|
|
163
163
|
*/
|
|
164
164
|
zoomLevel?: number;
|
|
165
|
+
/**
|
|
166
|
+
* When `false` node labels are hidden globally.
|
|
167
|
+
*
|
|
168
|
+
* You can also hide/show labels on a per-style basis by setting
|
|
169
|
+
* `showLabel: false` on individual entries in `nodeStyles`.
|
|
170
|
+
*
|
|
171
|
+
* @default true
|
|
172
|
+
*/
|
|
173
|
+
showLabels?: boolean;
|
|
165
174
|
/**
|
|
166
175
|
* When `true` every edge is rendered with an arrowhead at its **target**
|
|
167
176
|
* end, making the graph visually directed.
|
|
@@ -386,6 +395,12 @@ export type GraphinNodeStyleDef = {
|
|
|
386
395
|
labelFill?: string;
|
|
387
396
|
/** Label font size in pixels. */
|
|
388
397
|
labelFontSize?: number;
|
|
398
|
+
/**
|
|
399
|
+
* When `false`, hides the label for nodes using this style.
|
|
400
|
+
* Overrides the card-level `showLabels` prop for these nodes.
|
|
401
|
+
* @default true
|
|
402
|
+
*/
|
|
403
|
+
showLabel?: boolean;
|
|
389
404
|
};
|
|
390
405
|
/**
|
|
391
406
|
* Map from **style name** → visual spec.
|
|
@@ -4,65 +4,65 @@ import n from "clsx";
|
|
|
4
4
|
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
5
|
//#region src/cards/stack/stack.component.tsx
|
|
6
6
|
var a = (a) => {
|
|
7
|
-
let { content: o, direction: s, divider: c, spacing: l, justifyContent: u, alignItems: d, className: f, style: p, cardName: m } = a,
|
|
7
|
+
let { content: o, direction: s, divider: c, spacing: l, justifyContent: u, alignItems: d, className: f, style: p, cardName: m, data: h } = a, g = [
|
|
8
8
|
f,
|
|
9
9
|
(p ?? {}).root,
|
|
10
10
|
"flex"
|
|
11
11
|
];
|
|
12
12
|
if (s) switch (s) {
|
|
13
13
|
case "row":
|
|
14
|
-
|
|
14
|
+
g.push("flex-row");
|
|
15
15
|
break;
|
|
16
16
|
case "row-reverse":
|
|
17
|
-
|
|
17
|
+
g.push("flex-row-reverse");
|
|
18
18
|
break;
|
|
19
19
|
case "column":
|
|
20
|
-
|
|
20
|
+
g.push("flex-col");
|
|
21
21
|
break;
|
|
22
22
|
case "column-reverse":
|
|
23
|
-
|
|
23
|
+
g.push("flex-col-reverse");
|
|
24
24
|
break;
|
|
25
25
|
}
|
|
26
26
|
if (u) switch (u) {
|
|
27
27
|
case "flex-start":
|
|
28
|
-
|
|
28
|
+
g.push("justify-start");
|
|
29
29
|
break;
|
|
30
30
|
case "center":
|
|
31
|
-
|
|
31
|
+
g.push("justify-center");
|
|
32
32
|
break;
|
|
33
33
|
case "flex-end":
|
|
34
|
-
|
|
34
|
+
g.push("justify-end");
|
|
35
35
|
break;
|
|
36
36
|
case "space-between":
|
|
37
|
-
|
|
37
|
+
g.push("justify-between");
|
|
38
38
|
break;
|
|
39
39
|
case "space-around":
|
|
40
|
-
|
|
40
|
+
g.push("justify-around");
|
|
41
41
|
break;
|
|
42
42
|
case "space-evenly":
|
|
43
|
-
|
|
43
|
+
g.push("justify-evenly");
|
|
44
44
|
break;
|
|
45
45
|
}
|
|
46
46
|
if (d) switch (d) {
|
|
47
47
|
case "flex-start":
|
|
48
|
-
|
|
48
|
+
g.push("items-start");
|
|
49
49
|
break;
|
|
50
50
|
case "center":
|
|
51
|
-
|
|
51
|
+
g.push("items-center");
|
|
52
52
|
break;
|
|
53
53
|
case "stretch":
|
|
54
|
-
|
|
54
|
+
g.push("items-stretch");
|
|
55
55
|
break;
|
|
56
56
|
case "flex-end":
|
|
57
|
-
|
|
57
|
+
g.push("items-end");
|
|
58
58
|
break;
|
|
59
59
|
case "baseline":
|
|
60
|
-
|
|
60
|
+
g.push("items-baseline");
|
|
61
61
|
break;
|
|
62
62
|
default: console.warn("stack: unsupported 'alignItems' property", d);
|
|
63
63
|
}
|
|
64
|
-
l && l > 0 &&
|
|
65
|
-
function
|
|
64
|
+
l && l > 0 && g.push(`gap-${l}`);
|
|
65
|
+
function _() {
|
|
66
66
|
return o ? o.map((n, a) => /* @__PURE__ */ i(e, { children: [/* @__PURE__ */ r(t, {
|
|
67
67
|
cardName: n,
|
|
68
68
|
parentCard: m
|
|
@@ -71,10 +71,12 @@ var a = (a) => {
|
|
|
71
71
|
parentCard: m
|
|
72
72
|
}, `divider-${a}`)] }, a)) : null;
|
|
73
73
|
}
|
|
74
|
+
let v = h ? Object.fromEntries(Object.entries(h).map(([e, t]) => [`data-${e}`, t])) : {};
|
|
74
75
|
return /* @__PURE__ */ i("div", {
|
|
75
|
-
className: n(
|
|
76
|
+
className: n(g),
|
|
76
77
|
"data-pihanga": m,
|
|
77
|
-
|
|
78
|
+
...v,
|
|
79
|
+
children: [_(), a.children]
|
|
78
80
|
});
|
|
79
81
|
};
|
|
80
82
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack.component.js","names":[],"sources":["../../../src/cards/stack/stack.component.tsx"],"sourcesContent":["import * as React from \"react\";\nimport type {StackProps} from \"./stack.types\";\n\nimport {Card, type PiCardProps} from \"@pihanga2/core\";\nimport clsx from \"clsx\";\nimport {Fragment} from \"react\";\n\nexport type SelectSD = {\n root?: string;\n};\n\nexport const Component = (props: PiCardProps<StackProps>): React.ReactNode => {\n const {\n content,\n direction,\n divider,\n spacing,\n justifyContent,\n alignItems,\n className,\n style,\n cardName,\n } = props;\n const sd: SelectSD = (style as SelectSD | undefined) ?? {};\n\n const cn = [className, sd.root, \"flex\"];\n if (direction) {\n switch (direction) {\n // \"column-reverse\" | \"column\" | \"row-reverse\" | \"row\"\n case \"row\":\n cn.push(\"flex-row\");\n break;\n case \"row-reverse\":\n cn.push(\"flex-row-reverse\");\n break;\n case \"column\":\n cn.push(\"flex-col\");\n break;\n case \"column-reverse\":\n cn.push(\"flex-col-reverse\");\n break;\n }\n }\n if (justifyContent) {\n switch (justifyContent) {\n // \"flex-start\" | \"center\" | \"flex-end\" | \"space-between\" | \"space-around\" | \"space-evenly\"\n case \"flex-start\":\n cn.push(\"justify-start\");\n break;\n case \"center\":\n cn.push(\"justify-center\");\n break;\n case \"flex-end\":\n cn.push(\"justify-end\");\n break;\n case \"space-between\":\n cn.push(\"justify-between\");\n break;\n case \"space-around\":\n cn.push(\"justify-around\");\n break;\n case \"space-evenly\":\n cn.push(\"justify-evenly\");\n break;\n }\n }\n if (alignItems) {\n switch (alignItems) {\n // \"flex-start\" | \"center\" | \"flex-end\" | \"normal\" | \"stretch\" | \"start\" | \"end\" | \"baseline\" | \"initial\" | \"inherit\"\n case \"flex-start\":\n cn.push(\"items-start\");\n break;\n case \"center\":\n cn.push(\"items-center\");\n break;\n case \"stretch\":\n cn.push(\"items-stretch\");\n break;\n case \"flex-end\":\n cn.push(\"items-end\");\n break;\n case \"baseline\":\n cn.push(\"items-baseline\");\n break;\n default:\n console.warn(\"stack: unsupported 'alignItems' property\", alignItems);\n }\n }\n if (spacing && spacing > 0) {\n if (\n direction === undefined ||\n direction === \"row\" ||\n direction === \"row-reverse\"\n ) {\n cn.push(`gap-${spacing}`);\n } else {\n cn.push(`gap-${spacing}`);\n }\n }\n\n function renderContent() {\n if (!content) return null;\n\n return content.map((cn, i) => (\n <Fragment key={i}>\n <Card cardName={cn} parentCard={cardName} key={`item-${i}`} />\n {divider && i < content.length - 1 && (\n <Card cardName={divider} parentCard={cardName} key={`divider-${i}`} />\n )}\n </Fragment>\n ));\n }\n\n return (\n <div className={clsx(cn)} data-pihanga={cardName}>\n {renderContent()}\n {props.children}\n </div>\n );\n};\n"],"mappings":";;;;;AAWA,IAAa,KAAa,MAAoD;CAC5E,IAAM,EACJ,YACA,cACA,YACA,YACA,mBACA,eACA,cACA,UACA,
|
|
1
|
+
{"version":3,"file":"stack.component.js","names":[],"sources":["../../../src/cards/stack/stack.component.tsx"],"sourcesContent":["import * as React from \"react\";\nimport type {StackProps} from \"./stack.types\";\n\nimport {Card, type PiCardProps} from \"@pihanga2/core\";\nimport clsx from \"clsx\";\nimport {Fragment} from \"react\";\n\nexport type SelectSD = {\n root?: string;\n};\n\nexport const Component = (props: PiCardProps<StackProps>): React.ReactNode => {\n const {\n content,\n direction,\n divider,\n spacing,\n justifyContent,\n alignItems,\n className,\n style,\n cardName,\n data,\n } = props;\n const sd: SelectSD = (style as SelectSD | undefined) ?? {};\n\n const cn = [className, sd.root, \"flex\"];\n if (direction) {\n switch (direction) {\n // \"column-reverse\" | \"column\" | \"row-reverse\" | \"row\"\n case \"row\":\n cn.push(\"flex-row\");\n break;\n case \"row-reverse\":\n cn.push(\"flex-row-reverse\");\n break;\n case \"column\":\n cn.push(\"flex-col\");\n break;\n case \"column-reverse\":\n cn.push(\"flex-col-reverse\");\n break;\n }\n }\n if (justifyContent) {\n switch (justifyContent) {\n // \"flex-start\" | \"center\" | \"flex-end\" | \"space-between\" | \"space-around\" | \"space-evenly\"\n case \"flex-start\":\n cn.push(\"justify-start\");\n break;\n case \"center\":\n cn.push(\"justify-center\");\n break;\n case \"flex-end\":\n cn.push(\"justify-end\");\n break;\n case \"space-between\":\n cn.push(\"justify-between\");\n break;\n case \"space-around\":\n cn.push(\"justify-around\");\n break;\n case \"space-evenly\":\n cn.push(\"justify-evenly\");\n break;\n }\n }\n if (alignItems) {\n switch (alignItems) {\n // \"flex-start\" | \"center\" | \"flex-end\" | \"normal\" | \"stretch\" | \"start\" | \"end\" | \"baseline\" | \"initial\" | \"inherit\"\n case \"flex-start\":\n cn.push(\"items-start\");\n break;\n case \"center\":\n cn.push(\"items-center\");\n break;\n case \"stretch\":\n cn.push(\"items-stretch\");\n break;\n case \"flex-end\":\n cn.push(\"items-end\");\n break;\n case \"baseline\":\n cn.push(\"items-baseline\");\n break;\n default:\n console.warn(\"stack: unsupported 'alignItems' property\", alignItems);\n }\n }\n if (spacing && spacing > 0) {\n if (\n direction === undefined ||\n direction === \"row\" ||\n direction === \"row-reverse\"\n ) {\n cn.push(`gap-${spacing}`);\n } else {\n cn.push(`gap-${spacing}`);\n }\n }\n\n function renderContent() {\n if (!content) return null;\n\n return content.map((cn, i) => (\n <Fragment key={i}>\n <Card cardName={cn} parentCard={cardName} key={`item-${i}`} />\n {divider && i < content.length - 1 && (\n <Card cardName={divider} parentCard={cardName} key={`divider-${i}`} />\n )}\n </Fragment>\n ));\n }\n\n const dataAttrs = data\n ? Object.fromEntries(Object.entries(data).map(([k, v]) => [`data-${k}`, v]))\n : {};\n\n return (\n <div className={clsx(cn)} data-pihanga={cardName} {...dataAttrs}>\n {renderContent()}\n {props.children}\n </div>\n );\n};\n"],"mappings":";;;;;AAWA,IAAa,KAAa,MAAoD;CAC5E,IAAM,EACJ,YACA,cACA,YACA,YACA,mBACA,eACA,cACA,UACA,aACA,YACE,GAGE,IAAK;EAAC;GAFU,KAAkC,CAAC,GAE/B;EAAM;CAAM;CACtC,IAAI,GACF,QAAQ,GAAR;EAEE,KAAK;GACH,EAAG,KAAK,UAAU;GAClB;EACF,KAAK;GACH,EAAG,KAAK,kBAAkB;GAC1B;EACF,KAAK;GACH,EAAG,KAAK,UAAU;GAClB;EACF,KAAK;GACH,EAAG,KAAK,kBAAkB;GAC1B;CACJ;CAEF,IAAI,GACF,QAAQ,GAAR;EAEE,KAAK;GACH,EAAG,KAAK,eAAe;GACvB;EACF,KAAK;GACH,EAAG,KAAK,gBAAgB;GACxB;EACF,KAAK;GACH,EAAG,KAAK,aAAa;GACrB;EACF,KAAK;GACH,EAAG,KAAK,iBAAiB;GACzB;EACF,KAAK;GACH,EAAG,KAAK,gBAAgB;GACxB;EACF,KAAK;GACH,EAAG,KAAK,gBAAgB;GACxB;CACJ;CAEF,IAAI,GACF,QAAQ,GAAR;EAEE,KAAK;GACH,EAAG,KAAK,aAAa;GACrB;EACF,KAAK;GACH,EAAG,KAAK,cAAc;GACtB;EACF,KAAK;GACH,EAAG,KAAK,eAAe;GACvB;EACF,KAAK;GACH,EAAG,KAAK,WAAW;GACnB;EACF,KAAK;GACH,EAAG,KAAK,gBAAgB;GACxB;EACF,SACE,QAAQ,KAAK,4CAA4C,CAAU;CACvE;CAEF,AAAI,KAAW,IAAU,KAMrB,EAAG,KAAK,OAAO,GAAS;CAM5B,SAAS,IAAgB;EAGvB,OAFK,IAEE,EAAQ,KAAK,GAAI,MACtB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;GAAM,UAAU;GAAI,YAAY;EAA6B,GAAd,QAAQ,GAAM,GAC5D,KAAW,IAAI,EAAQ,SAAS,KAC/B,kBAAC,GAAD;GAAM,UAAU;GAAS,YAAY;EAAgC,GAAjB,WAAW,GAAM,CAE/D,EAAA,GALK,CAKL,CACX,IAToB;CAUvB;CAEA,IAAM,IAAY,IACd,OAAO,YAAY,OAAO,QAAQ,CAAI,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,IACzE,CAAC;CAEL,OACE,kBAAC,OAAD;EAAK,WAAW,EAAK,CAAE;EAAG,gBAAc;EAAU,GAAI;YAAtD,CACG,EAAc,GACd,EAAM,QACJ;;AAET"}
|
|
@@ -41,4 +41,6 @@ export type StackProps<S = object> = {
|
|
|
41
41
|
className?: string;
|
|
42
42
|
/** Card style object (use the `shad` key for Tailwind-compatible overrides) */
|
|
43
43
|
style?: S;
|
|
44
|
+
/** Arbitrary data attributes rendered as `data-{key}={value}` on the root element */
|
|
45
|
+
data?: Record<string, string>;
|
|
44
46
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack.types.js","names":[],"sources":["../../../src/cards/stack/stack.types.ts"],"sourcesContent":["import {type PiCardRef, createCardDeclaration} from \"@pihanga2/core\";\nimport type {AlignItemsT} from \"../types\";\n\nexport const STACK_CARD = \"pi/stack\";\n\n/**\n * Factory function for declaring a `stack` card instance.\n *\n * ```ts\n * import {registerCard} from \"@pihanga2/core\";\n * import {Stack} from \"@/cards/stack\";\n *\n * registerCard(\"myApp/toolbar\", Stack({\n * direction: \"row\",\n * spacing: 2,\n * alignItems: \"center\",\n * justifyContent: \"space-between\",\n * content: [\"myApp/logo\", \"myApp/navLinks\", \"myApp/userMenu\"],\n * }));\n * ```\n */\nexport const Stack = createCardDeclaration<StackProps>(STACK_CARD);\n\n/**\n * CSS `flex-direction` values supported by the Stack card.\n */\nexport type DirectionT = \"column-reverse\" | \"column\" | \"row-reverse\" | \"row\";\n\n/**\n * CSS `justify-content` values supported by the Stack card.\n */\nexport type JustifyContentT =\n | \"flex-start\"\n | \"center\"\n | \"flex-end\"\n | \"space-between\"\n | \"space-around\"\n | \"space-evenly\";\n\nexport type StackProps<S = object> = {\n /** Ordered list of child card refs to render */\n content: PiCardRef[];\n\n /** Flex direction — defaults to `\"column\"` */\n direction?: DirectionT;\n /** Optional card ref rendered as a separator between children */\n divider?: PiCardRef;\n /** Tailwind gap spacing units between children */\n spacing?: number;\n\n justifyContent?: JustifyContentT;\n alignItems?: AlignItemsT;\n\n /** Additional Tailwind utility classes */\n className?: string;\n /** Card style object (use the `shad` key for Tailwind-compatible overrides) */\n style?: S;\n};\n"],"mappings":";;AAGA,IAAa,IAAa,YAkBb,IAAQ,EAAkC,CAAU"}
|
|
1
|
+
{"version":3,"file":"stack.types.js","names":[],"sources":["../../../src/cards/stack/stack.types.ts"],"sourcesContent":["import {type PiCardRef, createCardDeclaration} from \"@pihanga2/core\";\nimport type {AlignItemsT} from \"../types\";\n\nexport const STACK_CARD = \"pi/stack\";\n\n/**\n * Factory function for declaring a `stack` card instance.\n *\n * ```ts\n * import {registerCard} from \"@pihanga2/core\";\n * import {Stack} from \"@/cards/stack\";\n *\n * registerCard(\"myApp/toolbar\", Stack({\n * direction: \"row\",\n * spacing: 2,\n * alignItems: \"center\",\n * justifyContent: \"space-between\",\n * content: [\"myApp/logo\", \"myApp/navLinks\", \"myApp/userMenu\"],\n * }));\n * ```\n */\nexport const Stack = createCardDeclaration<StackProps>(STACK_CARD);\n\n/**\n * CSS `flex-direction` values supported by the Stack card.\n */\nexport type DirectionT = \"column-reverse\" | \"column\" | \"row-reverse\" | \"row\";\n\n/**\n * CSS `justify-content` values supported by the Stack card.\n */\nexport type JustifyContentT =\n | \"flex-start\"\n | \"center\"\n | \"flex-end\"\n | \"space-between\"\n | \"space-around\"\n | \"space-evenly\";\n\nexport type StackProps<S = object> = {\n /** Ordered list of child card refs to render */\n content: PiCardRef[];\n\n /** Flex direction — defaults to `\"column\"` */\n direction?: DirectionT;\n /** Optional card ref rendered as a separator between children */\n divider?: PiCardRef;\n /** Tailwind gap spacing units between children */\n spacing?: number;\n\n justifyContent?: JustifyContentT;\n alignItems?: AlignItemsT;\n\n /** Additional Tailwind utility classes */\n className?: string;\n /** Card style object (use the `shad` key for Tailwind-compatible overrides) */\n style?: S;\n\n /** Arbitrary data attributes rendered as `data-{key}={value}` on the root element */\n data?: Record<string, string>;\n};\n"],"mappings":";;AAGA,IAAa,IAAa,YAkBb,IAAQ,EAAkC,CAAU"}
|
|
@@ -1,35 +1,39 @@
|
|
|
1
1
|
import { useFormContext as e } from "../form/form.context.js";
|
|
2
2
|
import { Label as t } from "../../components/ui/label.js";
|
|
3
3
|
import { Switch as n } from "../../components/ui/switch.js";
|
|
4
|
-
import "react";
|
|
4
|
+
import r from "react";
|
|
5
5
|
import "@pihanga2/core";
|
|
6
|
-
import { jsx as
|
|
6
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
7
7
|
//#region src/cards/switch/switch.component.tsx
|
|
8
|
-
var
|
|
9
|
-
let { name:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
var o = (o) => {
|
|
9
|
+
let { name: s, checked: c = !1, selfManaged: l = !1, disabled: u, label: d, className: f, cardName: p, onChanged: m } = o, h = o.id, g = e(), _ = g.isInForm && !!s, [v, y] = r.useState(c);
|
|
10
|
+
r.useEffect(() => {
|
|
11
|
+
l && y(c);
|
|
12
|
+
}, [c, l]);
|
|
13
|
+
let b = _ ? !!(g.formData[s] ?? !1) : l ? v : c;
|
|
14
|
+
function x(e) {
|
|
15
|
+
_ ? g.handleChange(s, e) : (l && y(e), m({
|
|
16
|
+
name: s,
|
|
13
17
|
checked: e
|
|
14
|
-
});
|
|
18
|
+
}));
|
|
15
19
|
}
|
|
16
|
-
let
|
|
17
|
-
return /* @__PURE__ */
|
|
18
|
-
"data-pihanga":
|
|
19
|
-
className: `flex items-center gap-2 ${
|
|
20
|
-
children: [/* @__PURE__ */
|
|
21
|
-
id:
|
|
22
|
-
checked:
|
|
23
|
-
onCheckedChange:
|
|
24
|
-
disabled:
|
|
25
|
-
}),
|
|
26
|
-
htmlFor:
|
|
20
|
+
let S = `${p}-${s ?? "switch"}`, C = h ?? S;
|
|
21
|
+
return /* @__PURE__ */ a("div", {
|
|
22
|
+
"data-pihanga": p,
|
|
23
|
+
className: `flex items-center gap-2 ${f ?? ""}`,
|
|
24
|
+
children: [/* @__PURE__ */ i(n, {
|
|
25
|
+
id: C,
|
|
26
|
+
checked: b,
|
|
27
|
+
onCheckedChange: x,
|
|
28
|
+
disabled: u
|
|
29
|
+
}), d && /* @__PURE__ */ i(t, {
|
|
30
|
+
htmlFor: C,
|
|
27
31
|
className: "cursor-pointer select-none",
|
|
28
|
-
children:
|
|
32
|
+
children: d
|
|
29
33
|
})]
|
|
30
34
|
});
|
|
31
35
|
};
|
|
32
36
|
//#endregion
|
|
33
|
-
export {
|
|
37
|
+
export { o as SwitchComponent };
|
|
34
38
|
|
|
35
39
|
//# sourceMappingURL=switch.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.component.js","names":[],"sources":["../../../src/cards/switch/switch.component.tsx"],"sourcesContent":["import React from \"react\";\nimport {type PiCardProps} from \"@pihanga2/core\";\nimport {Switch as SwitchUI} from \"@/components/ui/switch\";\nimport {Label} from \"@/components/ui/label\";\nimport {useFormContext} from \"@/cards/form/form.context\";\nimport type {PiSwitchEvents, PiSwitchProps} from \"./switch.types\";\n\nexport const SwitchComponent = (\n props: PiCardProps<PiSwitchProps, PiSwitchEvents>,\n): React.ReactNode => {\n const {\n name,\n checked: propChecked = false,\n disabled,\n label,\n className,\n cardName,\n onChanged,\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\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 const checked = useFormData\n ? Boolean(form.formData[name!] ?? false)\n : propChecked;\n\n function handleCheckedChange(newChecked: boolean) {\n if (useFormData) {\n form.handleChange(name!, newChecked);\n } else {\n onChanged({name, checked: newChecked});\n }\n }\n\n // Use the id injected by pi/field; fall back to a local id when standalone.\n const selfId = `${cardName}-${name ?? \"switch\"}`;\n const fieldId = injectedId ?? selfId;\n\n return (\n <div\n data-pihanga={cardName}\n className={`flex items-center gap-2 ${className ?? \"\"}`}\n >\n <SwitchUI\n id={fieldId}\n checked={checked}\n onCheckedChange={handleCheckedChange}\n disabled={disabled}\n />\n {label && (\n <Label htmlFor={fieldId} className=\"cursor-pointer select-none\">\n {label}\n </Label>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;AAOA,IAAa,KACX,MACoB;CACpB,IAAM,EACJ,SACA,SAAS,IAAc,IACvB,aACA,UACA,cACA,aACA,iBACE,GAKE,IAAc,EAAwB,IAGtC,IAAO,EAAe,GACtB,IAAc,EAAK,YAAY,EAAQ,
|
|
1
|
+
{"version":3,"file":"switch.component.js","names":[],"sources":["../../../src/cards/switch/switch.component.tsx"],"sourcesContent":["import React from \"react\";\nimport {type PiCardProps} from \"@pihanga2/core\";\nimport {Switch as SwitchUI} from \"@/components/ui/switch\";\nimport {Label} from \"@/components/ui/label\";\nimport {useFormContext} from \"@/cards/form/form.context\";\nimport type {PiSwitchEvents, PiSwitchProps} from \"./switch.types\";\n\nexport const SwitchComponent = (\n props: PiCardProps<PiSwitchProps, PiSwitchEvents>,\n): React.ReactNode => {\n const {\n name,\n checked: propChecked = false,\n selfManaged = false,\n disabled,\n label,\n className,\n cardName,\n onChanged,\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\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 // Self-managed internal state — seeded from propChecked, only active when\n // selfManaged=true and we are NOT inside a pi/form.\n const [internalChecked, setInternalChecked] = React.useState(propChecked);\n\n // Keep internal state in sync when the external prop changes (e.g. when the\n // playground switches to a different facet and propChecked changes).\n React.useEffect(() => {\n if (selfManaged) setInternalChecked(propChecked);\n }, [propChecked, selfManaged]);\n\n const checked = useFormData\n ? Boolean(form.formData[name!] ?? false)\n : selfManaged\n ? internalChecked\n : propChecked;\n\n function handleCheckedChange(newChecked: boolean) {\n if (useFormData) {\n form.handleChange(name!, newChecked);\n } else {\n if (selfManaged) setInternalChecked(newChecked);\n onChanged({name, checked: newChecked});\n }\n }\n\n // Use the id injected by pi/field; fall back to a local id when standalone.\n const selfId = `${cardName}-${name ?? \"switch\"}`;\n const fieldId = injectedId ?? selfId;\n\n return (\n <div\n data-pihanga={cardName}\n className={`flex items-center gap-2 ${className ?? \"\"}`}\n >\n <SwitchUI\n id={fieldId}\n checked={checked}\n onCheckedChange={handleCheckedChange}\n disabled={disabled}\n />\n {label && (\n <Label htmlFor={fieldId} className=\"cursor-pointer select-none\">\n {label}\n </Label>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;AAOA,IAAa,KACX,MACoB;CACpB,IAAM,EACJ,SACA,SAAS,IAAc,IACvB,iBAAc,IACd,aACA,UACA,cACA,aACA,iBACE,GAKE,IAAc,EAAwB,IAGtC,IAAO,EAAe,GACtB,IAAc,EAAK,YAAY,EAAQ,GAIvC,CAAC,GAAiB,KAAsB,EAAM,SAAS,CAAW;CAIxE,EAAM,gBAAgB;EACpB,AAAI,KAAa,EAAmB,CAAW;CACjD,GAAG,CAAC,GAAa,CAAW,CAAC;CAE7B,IAAM,IAAU,IACZ,GAAQ,EAAK,SAAS,MAAU,MAChC,IACE,IACA;CAEN,SAAS,EAAoB,GAAqB;EAChD,AAAI,IACF,EAAK,aAAa,GAAO,CAAU,KAE/B,KAAa,EAAmB,CAAU,GAC9C,EAAU;GAAC;GAAM,SAAS;EAAU,CAAC;CAEzC;CAGA,IAAM,IAAS,GAAG,EAAS,GAAG,KAAQ,YAChC,IAAU,KAAc;CAE9B,OACE,kBAAC,OAAD;EACE,gBAAc;EACd,WAAW,2BAA2B,KAAa;YAFrD,CAIE,kBAAC,GAAD;GACE,IAAI;GACK;GACT,iBAAiB;GACP;EACX,CAAA,GACA,KACC,kBAAC,GAAD;GAAO,SAAS;GAAS,WAAU;aAChC;EACI,CAAA,CAEN;;AAET"}
|
|
@@ -22,6 +22,14 @@ export type PiSwitchProps = {
|
|
|
22
22
|
* Ignored when `name` is set and the component is inside a pi/form.
|
|
23
23
|
*/
|
|
24
24
|
checked?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* When true the component manages its own checked state internally via
|
|
27
|
+
* React.useState, seeded from the `checked` prop.
|
|
28
|
+
* The onChanged event still fires on every toggle so external listeners can
|
|
29
|
+
* react. Useful in playground previews and self-contained demos where no
|
|
30
|
+
* Redux state is wired up.
|
|
31
|
+
*/
|
|
32
|
+
selfManaged?: boolean;
|
|
25
33
|
/** When true, the switch is disabled and non-interactive. */
|
|
26
34
|
disabled?: boolean;
|
|
27
35
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.types.js","names":[],"sources":["../../../src/cards/switch/switch.types.ts"],"sourcesContent":["import {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\n\nexport const PI_SWITCH_CARD = \"pi/switch\";\n\nexport const Switch = createCardDeclaration<PiSwitchProps, PiSwitchEvents>(\n PI_SWITCH_CARD,\n);\n\nexport const PI_SWITCH_ACTION = registerActions(PI_SWITCH_CARD, [\"changed\"]);\n\nexport const onSwitchChanged = createOnAction<PiSwitchChangedEvent>(\n PI_SWITCH_ACTION.CHANGED,\n);\n\n/** @deprecated Use `onSwitchChanged` instead. */\nexport const onPiSwitchChanged = onSwitchChanged;\n\n// ---------------------------------------------------------------------------\n// Props & Events\n// ---------------------------------------------------------------------------\n\nexport type PiSwitchProps = {\n /**\n * Field name used to bind to FormContext when inside a pi/form card.\n * When provided the component reads its checked state from form data and\n * writes back via form.handleChange.\n */\n name?: string;\n\n /**\n * Controlled checked state used in standalone mode (outside a Form).\n * Ignored when `name` is set and the component is inside a pi/form.\n */\n checked?: boolean;\n\n /** When true, the switch is disabled and non-interactive. */\n disabled?: boolean;\n\n /**\n * Optional label text rendered beside the switch.\n * The label is automatically associated with the switch via `htmlFor`.\n */\n label?: string;\n\n /** Extra Tailwind / CSS classes forwarded to the root wrapper element. */\n className?: string;\n};\n\nexport type PiSwitchChangedEvent = {\n /** Field name, mirrors the `name` prop if provided. */\n name?: string;\n /** New checked state after the toggle. */\n checked: boolean;\n};\n\nexport type PiSwitchEvents = {\n onChanged: PiSwitchChangedEvent;\n};\n"],"mappings":";;AAMA,IAAa,IAAiB,aAEjB,IAAS,EACpB,CACF,GAEa,IAAmB,EAAgB,GAAgB,CAAC,SAAS,CAAC,GAE9D,IAAkB,EAC7B,EAAiB,OACnB,GAGa,IAAoB"}
|
|
1
|
+
{"version":3,"file":"switch.types.js","names":[],"sources":["../../../src/cards/switch/switch.types.ts"],"sourcesContent":["import {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\n\nexport const PI_SWITCH_CARD = \"pi/switch\";\n\nexport const Switch = createCardDeclaration<PiSwitchProps, PiSwitchEvents>(\n PI_SWITCH_CARD,\n);\n\nexport const PI_SWITCH_ACTION = registerActions(PI_SWITCH_CARD, [\"changed\"]);\n\nexport const onSwitchChanged = createOnAction<PiSwitchChangedEvent>(\n PI_SWITCH_ACTION.CHANGED,\n);\n\n/** @deprecated Use `onSwitchChanged` instead. */\nexport const onPiSwitchChanged = onSwitchChanged;\n\n// ---------------------------------------------------------------------------\n// Props & Events\n// ---------------------------------------------------------------------------\n\nexport type PiSwitchProps = {\n /**\n * Field name used to bind to FormContext when inside a pi/form card.\n * When provided the component reads its checked state from form data and\n * writes back via form.handleChange.\n */\n name?: string;\n\n /**\n * Controlled checked state used in standalone mode (outside a Form).\n * Ignored when `name` is set and the component is inside a pi/form.\n */\n checked?: boolean;\n\n /**\n * When true the component manages its own checked state internally via\n * React.useState, seeded from the `checked` prop.\n * The onChanged event still fires on every toggle so external listeners can\n * react. Useful in playground previews and self-contained demos where no\n * Redux state is wired up.\n */\n selfManaged?: boolean;\n\n /** When true, the switch is disabled and non-interactive. */\n disabled?: boolean;\n\n /**\n * Optional label text rendered beside the switch.\n * The label is automatically associated with the switch via `htmlFor`.\n */\n label?: string;\n\n /** Extra Tailwind / CSS classes forwarded to the root wrapper element. */\n className?: string;\n};\n\nexport type PiSwitchChangedEvent = {\n /** Field name, mirrors the `name` prop if provided. */\n name?: string;\n /** New checked state after the toggle. */\n checked: boolean;\n};\n\nexport type PiSwitchEvents = {\n onChanged: PiSwitchChangedEvent;\n};\n"],"mappings":";;AAMA,IAAa,IAAiB,aAEjB,IAAS,EACpB,CACF,GAEa,IAAmB,EAAgB,GAAgB,CAAC,SAAS,CAAC,GAE9D,IAAkB,EAC7B,EAAiB,OACnB,GAGa,IAAoB"}
|
|
@@ -4,53 +4,55 @@ import r from "react";
|
|
|
4
4
|
import "@pihanga2/core";
|
|
5
5
|
import { jsx as i } from "react/jsx-runtime";
|
|
6
6
|
//#region src/cards/toggleGroup/toggleGroup.component.tsx
|
|
7
|
-
var a = (
|
|
8
|
-
let { name:
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
name:
|
|
7
|
+
var a = "bg-muted rounded-full p-1 border [&_[data-slot=toggle-group-item][data-state=on]]:bg-foreground [&_[data-slot=toggle-group-item][data-state=on]]:text-background [&_[data-slot=toggle-group-item][data-state=on]]:shadow-sm", o = (o) => {
|
|
8
|
+
let { name: s, items: c = [], type: l = "single", value: u, selfManaged: d = !1, variant: f = "default", size: p = "default", spacing: m = 0, disabled: h, className: g, cardName: _, onChanged: v } = o, y = f === "pill", b = y ? "default" : f, x = [y ? a : void 0, g].filter(Boolean).join(" ") || void 0, S = e(), C = S.isInForm && !!s, w = l === "multiple" ? Array.isArray(u) ? u : u == null ? [] : [String(u)] : typeof u == "string" ? u : "", [T, E] = r.useState(w), D = C ? S.formData[s] : void 0, O = C ? l === "multiple" ? Array.isArray(D) ? D : D == null ? [] : [String(D)] : D == null ? "" : String(D) : d ? T : u ?? (l === "multiple" ? [] : "");
|
|
9
|
+
function k(e) {
|
|
10
|
+
C ? S.handleChange(s, e) : (d && E(e), v({
|
|
11
|
+
name: s ?? _,
|
|
12
12
|
value: e
|
|
13
13
|
}));
|
|
14
14
|
}
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
name:
|
|
15
|
+
function A(e) {
|
|
16
|
+
C ? S.handleChange(s, e) : (d && E(e), v({
|
|
17
|
+
name: s ?? _,
|
|
18
18
|
value: e
|
|
19
19
|
}));
|
|
20
20
|
}
|
|
21
|
-
return
|
|
22
|
-
"data-pihanga":
|
|
21
|
+
return l === "single" ? /* @__PURE__ */ i(t, {
|
|
22
|
+
"data-pihanga": _,
|
|
23
23
|
type: "single",
|
|
24
|
-
value: typeof
|
|
25
|
-
onValueChange:
|
|
26
|
-
variant:
|
|
27
|
-
size:
|
|
28
|
-
spacing:
|
|
29
|
-
disabled:
|
|
30
|
-
className:
|
|
31
|
-
children:
|
|
24
|
+
value: typeof O == "string" ? O : "",
|
|
25
|
+
onValueChange: k,
|
|
26
|
+
variant: b,
|
|
27
|
+
size: p,
|
|
28
|
+
spacing: m,
|
|
29
|
+
disabled: h,
|
|
30
|
+
className: x,
|
|
31
|
+
children: c.map((e) => /* @__PURE__ */ i(n, {
|
|
32
32
|
value: e.value,
|
|
33
33
|
disabled: e.disabled,
|
|
34
|
+
className: y ? "!rounded-full" : void 0,
|
|
34
35
|
children: e.label
|
|
35
36
|
}, e.value))
|
|
36
37
|
}) : /* @__PURE__ */ i(t, {
|
|
37
|
-
"data-pihanga":
|
|
38
|
+
"data-pihanga": _,
|
|
38
39
|
type: "multiple",
|
|
39
|
-
value: Array.isArray(
|
|
40
|
-
onValueChange:
|
|
41
|
-
variant:
|
|
42
|
-
size:
|
|
43
|
-
spacing:
|
|
44
|
-
disabled:
|
|
45
|
-
className:
|
|
46
|
-
children:
|
|
40
|
+
value: Array.isArray(O) ? O : O ? [O] : [],
|
|
41
|
+
onValueChange: A,
|
|
42
|
+
variant: b,
|
|
43
|
+
size: p,
|
|
44
|
+
spacing: m,
|
|
45
|
+
disabled: h,
|
|
46
|
+
className: x,
|
|
47
|
+
children: c.map((e) => /* @__PURE__ */ i(n, {
|
|
47
48
|
value: e.value,
|
|
48
49
|
disabled: e.disabled,
|
|
50
|
+
className: y ? "!rounded-full" : void 0,
|
|
49
51
|
children: e.label
|
|
50
52
|
}, e.value))
|
|
51
53
|
});
|
|
52
54
|
};
|
|
53
55
|
//#endregion
|
|
54
|
-
export {
|
|
56
|
+
export { o as ToggleGroupComponent };
|
|
55
57
|
|
|
56
58
|
//# sourceMappingURL=toggleGroup.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggleGroup.component.js","names":[],"sources":["../../../src/cards/toggleGroup/toggleGroup.component.tsx"],"sourcesContent":["import React from \"react\";\nimport {type PiCardProps} from \"@pihanga2/core\";\nimport {\n ToggleGroup as ToggleGroupUI,\n ToggleGroupItem,\n} from \"@/components/ui/toggle-group\";\nimport {useFormContext} from \"@/cards/form/form.context\";\nimport type {\n PiToggleGroupEvents,\n PiToggleGroupProps,\n} from \"./toggleGroup.types\";\n\nexport const ToggleGroupComponent = (\n props: PiCardProps<PiToggleGroupProps, PiToggleGroupEvents>,\n): React.ReactNode => {\n const {\n name,\n items = [],\n type = \"single\",\n value: propValue,\n selfManaged = false,\n variant = \"default\",\n size = \"default\",\n spacing = 0,\n disabled,\n className,\n cardName,\n onChanged,\n } = props;\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 // ---------------------------------------------------------------------------\n // Self-managed (internal) state — only active when selfManaged=true and we\n // are NOT inside a pi/form card.\n // ---------------------------------------------------------------------------\n const initialSelfValue: string | string[] =\n type === \"multiple\"\n ? Array.isArray(propValue)\n ? propValue\n : propValue != null\n ? [String(propValue)]\n : []\n : typeof propValue === \"string\"\n ? propValue\n : \"\";\n\n const [internalValue, setInternalValue] = React.useState<string | string[]>(\n initialSelfValue,\n );\n\n // ---------------------------------------------------------------------------\n // Derive the effective value from the appropriate source.\n // 1. Form context (highest priority)\n // 2. Self-managed internal state\n // 3. Externally controlled prop value\n // ---------------------------------------------------------------------------\n const formRawValue = useFormData ? form.formData[name!] : undefined;\n const value: string | string[] = useFormData\n ? type === \"multiple\"\n ? Array.isArray(formRawValue)\n ? (formRawValue as string[])\n : formRawValue != null\n ? [String(formRawValue)]\n : []\n : formRawValue != null\n ? String(formRawValue)\n : \"\"\n : selfManaged\n ? internalValue\n : (propValue ?? (type === \"multiple\" ? [] : \"\"));\n\n function handleSingleChange(newValue: string) {\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n if (selfManaged) {\n setInternalValue(newValue);\n }\n onChanged({name: name ?? cardName, value: newValue});\n }\n }\n\n function handleMultipleChange(newValue: string[]) {\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n if (selfManaged) {\n setInternalValue(newValue);\n }\n onChanged({name: name ?? cardName, value: newValue});\n }\n }\n\n // Render single-selection group\n if (type === \"single\") {\n return (\n <ToggleGroupUI\n data-pihanga={cardName}\n type=\"single\"\n value={typeof value === \"string\" ? value : \"\"}\n onValueChange={handleSingleChange}\n variant={
|
|
1
|
+
{"version":3,"file":"toggleGroup.component.js","names":[],"sources":["../../../src/cards/toggleGroup/toggleGroup.component.tsx"],"sourcesContent":["import React from \"react\";\nimport {type PiCardProps} from \"@pihanga2/core\";\nimport {\n ToggleGroup as ToggleGroupUI,\n ToggleGroupItem,\n} from \"@/components/ui/toggle-group\";\nimport {useFormContext} from \"@/cards/form/form.context\";\nimport type {\n PiToggleGroupEvents,\n PiToggleGroupProps,\n} from \"./toggleGroup.types\";\n\n// Applied on the container when variant=\"pill\".\n// Item rounding is handled directly via the ToggleGroupItem className prop\n// (using !rounded-full) so Tailwind scans it and generates !important CSS.\nconst PILL_CLASS =\n \"bg-muted rounded-full p-1 border\" +\n \" [&_[data-slot=toggle-group-item][data-state=on]]:bg-foreground\" +\n \" [&_[data-slot=toggle-group-item][data-state=on]]:text-background\" +\n \" [&_[data-slot=toggle-group-item][data-state=on]]:shadow-sm\";\n\nexport const ToggleGroupComponent = (\n props: PiCardProps<PiToggleGroupProps, PiToggleGroupEvents>,\n): React.ReactNode => {\n const {\n name,\n items = [],\n type = \"single\",\n value: propValue,\n selfManaged = false,\n variant = \"default\",\n size = \"default\",\n spacing = 0,\n disabled,\n className,\n cardName,\n onChanged,\n } = props;\n\n // Pill variant: apply segmented-control styling and fall back to \"default\"\n // for the underlying UI primitive.\n const isPill = variant === \"pill\";\n const resolvedVariant = isPill ? \"default\" : variant;\n const resolvedClassName =\n [isPill ? PILL_CLASS : undefined, className].filter(Boolean).join(\" \") ||\n undefined;\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 // ---------------------------------------------------------------------------\n // Self-managed (internal) state — only active when selfManaged=true and we\n // are NOT inside a pi/form card.\n // ---------------------------------------------------------------------------\n const initialSelfValue: string | string[] =\n type === \"multiple\"\n ? Array.isArray(propValue)\n ? propValue\n : propValue != null\n ? [String(propValue)]\n : []\n : typeof propValue === \"string\"\n ? propValue\n : \"\";\n\n const [internalValue, setInternalValue] = React.useState<string | string[]>(\n initialSelfValue,\n );\n\n // ---------------------------------------------------------------------------\n // Derive the effective value from the appropriate source.\n // 1. Form context (highest priority)\n // 2. Self-managed internal state\n // 3. Externally controlled prop value\n // ---------------------------------------------------------------------------\n const formRawValue = useFormData ? form.formData[name!] : undefined;\n const value: string | string[] = useFormData\n ? type === \"multiple\"\n ? Array.isArray(formRawValue)\n ? (formRawValue as string[])\n : formRawValue != null\n ? [String(formRawValue)]\n : []\n : formRawValue != null\n ? String(formRawValue)\n : \"\"\n : selfManaged\n ? internalValue\n : (propValue ?? (type === \"multiple\" ? [] : \"\"));\n\n function handleSingleChange(newValue: string) {\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n if (selfManaged) {\n setInternalValue(newValue);\n }\n onChanged({name: name ?? cardName, value: newValue});\n }\n }\n\n function handleMultipleChange(newValue: string[]) {\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n if (selfManaged) {\n setInternalValue(newValue);\n }\n onChanged({name: name ?? cardName, value: newValue});\n }\n }\n\n // Render single-selection group\n if (type === \"single\") {\n return (\n <ToggleGroupUI\n data-pihanga={cardName}\n type=\"single\"\n value={typeof value === \"string\" ? value : \"\"}\n onValueChange={handleSingleChange}\n variant={resolvedVariant}\n size={size}\n spacing={spacing}\n disabled={disabled}\n className={resolvedClassName}\n >\n {items.map((item) => (\n <ToggleGroupItem\n key={item.value}\n value={item.value}\n disabled={item.disabled}\n className={isPill ? \"!rounded-full\" : undefined}\n >\n {item.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroupUI>\n );\n }\n\n // Render multiple-selection group\n return (\n <ToggleGroupUI\n data-pihanga={cardName}\n type=\"multiple\"\n value={Array.isArray(value) ? value : value ? [value] : []}\n onValueChange={handleMultipleChange}\n variant={resolvedVariant}\n size={size}\n spacing={spacing}\n disabled={disabled}\n className={resolvedClassName}\n >\n {items.map((item) => (\n <ToggleGroupItem\n key={item.value}\n value={item.value}\n disabled={item.disabled}\n className={isPill ? \"!rounded-full\" : undefined}\n >\n {item.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroupUI>\n );\n};\n"],"mappings":";;;;;;AAeA,IAAM,IACJ,+NAKW,KACX,MACoB;CACpB,IAAM,EACJ,SACA,WAAQ,CAAC,GACT,UAAO,UACP,OAAO,GACP,iBAAc,IACd,aAAU,WACV,UAAO,WACP,aAAU,GACV,aACA,cACA,aACA,iBACE,GAIE,IAAS,MAAY,QACrB,IAAkB,IAAS,YAAY,GACvC,IACJ,CAAC,IAAS,IAAa,KAAA,GAAW,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,KACrE,KAAA,GAGI,IAAO,EAAe,GACtB,IAAc,EAAK,YAAY,EAAQ,GAMvC,IACJ,MAAS,aACL,MAAM,QAAQ,CAAS,IACrB,IACA,KAAa,OAEX,CAAC,IADD,CAAC,OAAO,CAAS,CAAC,IAEtB,OAAO,KAAc,WACnB,IACA,IAEF,CAAC,GAAe,KAAoB,EAAM,SAC9C,CACF,GAQM,IAAe,IAAc,EAAK,SAAS,KAAS,KAAA,GACpD,IAA2B,IAC7B,MAAS,aACP,MAAM,QAAQ,CAAY,IACvB,IACD,KAAgB,OAEd,CAAC,IADD,CAAC,OAAO,CAAY,CAAC,IAEzB,KAAgB,OAEd,KADA,OAAO,CAAY,IAEvB,IACE,IACC,MAAc,MAAS,aAAa,CAAC,IAAI;CAEhD,SAAS,EAAmB,GAAkB;EAC5C,AAAI,IACF,EAAK,aAAa,GAAO,CAAQ,KAE7B,KACF,EAAiB,CAAQ,GAE3B,EAAU;GAAC,MAAM,KAAQ;GAAU,OAAO;EAAQ,CAAC;CAEvD;CAEA,SAAS,EAAqB,GAAoB;EAChD,AAAI,IACF,EAAK,aAAa,GAAO,CAAQ,KAE7B,KACF,EAAiB,CAAQ,GAE3B,EAAU;GAAC,MAAM,KAAQ;GAAU,OAAO;EAAQ,CAAC;CAEvD;CA+BA,OA5BI,MAAS,WAET,kBAAC,GAAD;EACE,gBAAc;EACd,MAAK;EACL,OAAO,OAAO,KAAU,WAAW,IAAQ;EAC3C,eAAe;EACf,SAAS;EACH;EACG;EACC;EACV,WAAW;YAEV,EAAM,KAAK,MACV,kBAAC,GAAD;GAEE,OAAO,EAAK;GACZ,UAAU,EAAK;GACf,WAAW,IAAS,kBAAkB,KAAA;aAErC,EAAK;EACS,GANV,EAAK,KAMK,CAClB;CACY,CAAA,IAMjB,kBAAC,GAAD;EACE,gBAAc;EACd,MAAK;EACL,OAAO,MAAM,QAAQ,CAAK,IAAI,IAAQ,IAAQ,CAAC,CAAK,IAAI,CAAC;EACzD,eAAe;EACf,SAAS;EACH;EACG;EACC;EACV,WAAW;YAEV,EAAM,KAAK,MACV,kBAAC,GAAD;GAEE,OAAO,EAAK;GACZ,UAAU,EAAK;GACf,WAAW,IAAS,kBAAkB,KAAA;aAErC,EAAK;EACS,GANV,EAAK,KAMK,CAClB;CACY,CAAA;AAEnB"}
|
|
@@ -63,10 +63,12 @@ export type PiToggleGroupProps = {
|
|
|
63
63
|
* Visual style variant of the toggle buttons.
|
|
64
64
|
* - `"default"` — transparent background, highlights on active.
|
|
65
65
|
* - `"outline"` — bordered buttons, grouped or spaced.
|
|
66
|
+
* - `"pill"` — segmented-control style: muted rounded-full container with a
|
|
67
|
+
* filled foreground pill on the active item.
|
|
66
68
|
*
|
|
67
69
|
* @default "default"
|
|
68
70
|
*/
|
|
69
|
-
variant?: "default" | "outline";
|
|
71
|
+
variant?: "default" | "outline" | "pill";
|
|
70
72
|
/**
|
|
71
73
|
* Size of each toggle button.
|
|
72
74
|
* @default "default"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggleGroup.types.js","names":[],"sources":["../../../src/cards/toggleGroup/toggleGroup.types.ts"],"sourcesContent":["import {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\n\nexport const PI_TOGGLE_GROUP_CARD = \"pi/toggle-group\";\n\nexport const ToggleGroup = createCardDeclaration<\n PiToggleGroupProps,\n PiToggleGroupEvents\n>(PI_TOGGLE_GROUP_CARD);\n\nexport const PI_TOGGLE_GROUP_ACTION = registerActions(PI_TOGGLE_GROUP_CARD, [\n \"changed\",\n]);\n\nexport const onToggleGroupChanged = createOnAction<PiToggleGroupChangedEvent>(\n PI_TOGGLE_GROUP_ACTION.CHANGED,\n);\n\n/** @deprecated Use `onToggleGroupChanged` instead. */\nexport const onPiToggleGroupChanged = onToggleGroupChanged;\n\n// ---------------------------------------------------------------------------\n// Item type\n// ---------------------------------------------------------------------------\n\nexport type PiToggleGroupItem = {\n /** The value associated with this toggle item. */\n value: string;\n /** Human-readable label rendered inside the toggle button. */\n label: string;\n /** When true, this individual item is disabled. */\n disabled?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Props & Events\n// ---------------------------------------------------------------------------\n\nexport type PiToggleGroupProps = {\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 * The list of toggle items to display.\n */\n items: PiToggleGroupItem[];\n\n /**\n * Selection mode.\n * - `\"single\"` — at most one item can be active at a time.\n * - `\"multiple\"` — any number of items can be active simultaneously.\n *\n * @default \"single\"\n */\n type?: \"single\" | \"multiple\";\n\n /**\n * Controlled selected value(s).\n * - In `\"single\"` mode: a `string` (or `undefined` for nothing selected).\n * - In `\"multiple\"` mode: an array of `string`.\n *\n * Ignored when `name` is set and the component is inside a pi/form.\n * Also ignored when `selfManaged` is `true`.\n */\n value?: string | string[];\n\n /**\n * When `true`, the component manages its own selection state internally\n * using `React.useState`. The `value` prop is used only as the initial\n * value (i.e. `defaultValue`) and subsequent changes do not require an\n * external state update. `onChanged` is still fired so callers can\n * observe changes without owning the state.\n *\n * Has no effect when inside a pi/form (form context always takes\n * precedence).\n *\n * @default false\n */\n selfManaged?: boolean;\n\n /**\n * Visual style variant of the toggle buttons.\n * - `\"default\"` — transparent background, highlights on active.\n * - `\"outline\"` — bordered buttons, grouped or spaced.\n *\n * @default \"default\"\n */\n variant?: \"default\" | \"outline\";\n\n /**\n * Size of each toggle button.\n * @default \"default\"\n */\n size?: \"default\" | \"sm\" | \"lg\";\n\n /**\n * Gap between toggle buttons (in Tailwind spacing units).\n * `0` = buttons are joined (no gap, rounded ends only).\n * Positive values add space between each button.\n *\n * @default 0\n */\n spacing?: number;\n\n /** When true, the entire group is disabled and non-interactive. */\n disabled?: boolean;\n\n /** Extra Tailwind / CSS classes forwarded to the root element. */\n className?: string;\n};\n\nexport type PiToggleGroupChangedEvent = {\n /** Field name, mirrors the `name` prop if provided. */\n name?: string;\n /**\n * New selected value(s).\n * - In `\"single\"` mode: a `string` (empty string when nothing selected).\n * - In `\"multiple\"` mode: an array of `string`.\n */\n value: string | string[];\n};\n\nexport type PiToggleGroupEvents = {\n onChanged: PiToggleGroupChangedEvent;\n};\n"],"mappings":";;AAMA,IAAa,IAAuB,mBAEvB,IAAc,EAGzB,CAAoB,GAET,IAAyB,EAAgB,GAAsB,CAC1E,SACF,CAAC,GAEY,IAAuB,EAClC,EAAuB,OACzB,GAGa,IAAyB"}
|
|
1
|
+
{"version":3,"file":"toggleGroup.types.js","names":[],"sources":["../../../src/cards/toggleGroup/toggleGroup.types.ts"],"sourcesContent":["import {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\n\nexport const PI_TOGGLE_GROUP_CARD = \"pi/toggle-group\";\n\nexport const ToggleGroup = createCardDeclaration<\n PiToggleGroupProps,\n PiToggleGroupEvents\n>(PI_TOGGLE_GROUP_CARD);\n\nexport const PI_TOGGLE_GROUP_ACTION = registerActions(PI_TOGGLE_GROUP_CARD, [\n \"changed\",\n]);\n\nexport const onToggleGroupChanged = createOnAction<PiToggleGroupChangedEvent>(\n PI_TOGGLE_GROUP_ACTION.CHANGED,\n);\n\n/** @deprecated Use `onToggleGroupChanged` instead. */\nexport const onPiToggleGroupChanged = onToggleGroupChanged;\n\n// ---------------------------------------------------------------------------\n// Item type\n// ---------------------------------------------------------------------------\n\nexport type PiToggleGroupItem = {\n /** The value associated with this toggle item. */\n value: string;\n /** Human-readable label rendered inside the toggle button. */\n label: string;\n /** When true, this individual item is disabled. */\n disabled?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Props & Events\n// ---------------------------------------------------------------------------\n\nexport type PiToggleGroupProps = {\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 * The list of toggle items to display.\n */\n items: PiToggleGroupItem[];\n\n /**\n * Selection mode.\n * - `\"single\"` — at most one item can be active at a time.\n * - `\"multiple\"` — any number of items can be active simultaneously.\n *\n * @default \"single\"\n */\n type?: \"single\" | \"multiple\";\n\n /**\n * Controlled selected value(s).\n * - In `\"single\"` mode: a `string` (or `undefined` for nothing selected).\n * - In `\"multiple\"` mode: an array of `string`.\n *\n * Ignored when `name` is set and the component is inside a pi/form.\n * Also ignored when `selfManaged` is `true`.\n */\n value?: string | string[];\n\n /**\n * When `true`, the component manages its own selection state internally\n * using `React.useState`. The `value` prop is used only as the initial\n * value (i.e. `defaultValue`) and subsequent changes do not require an\n * external state update. `onChanged` is still fired so callers can\n * observe changes without owning the state.\n *\n * Has no effect when inside a pi/form (form context always takes\n * precedence).\n *\n * @default false\n */\n selfManaged?: boolean;\n\n /**\n * Visual style variant of the toggle buttons.\n * - `\"default\"` — transparent background, highlights on active.\n * - `\"outline\"` — bordered buttons, grouped or spaced.\n * - `\"pill\"` — segmented-control style: muted rounded-full container with a\n * filled foreground pill on the active item.\n *\n * @default \"default\"\n */\n variant?: \"default\" | \"outline\" | \"pill\";\n\n /**\n * Size of each toggle button.\n * @default \"default\"\n */\n size?: \"default\" | \"sm\" | \"lg\";\n\n /**\n * Gap between toggle buttons (in Tailwind spacing units).\n * `0` = buttons are joined (no gap, rounded ends only).\n * Positive values add space between each button.\n *\n * @default 0\n */\n spacing?: number;\n\n /** When true, the entire group is disabled and non-interactive. */\n disabled?: boolean;\n\n /** Extra Tailwind / CSS classes forwarded to the root element. */\n className?: string;\n};\n\nexport type PiToggleGroupChangedEvent = {\n /** Field name, mirrors the `name` prop if provided. */\n name?: string;\n /**\n * New selected value(s).\n * - In `\"single\"` mode: a `string` (empty string when nothing selected).\n * - In `\"multiple\"` mode: an array of `string`.\n */\n value: string | string[];\n};\n\nexport type PiToggleGroupEvents = {\n onChanged: PiToggleGroupChangedEvent;\n};\n"],"mappings":";;AAMA,IAAa,IAAuB,mBAEvB,IAAc,EAGzB,CAAoB,GAET,IAAyB,EAAgB,GAAsB,CAC1E,SACF,CAAC,GAEY,IAAuB,EAClC,EAAuB,OACzB,GAGa,IAAyB"}
|