@jiwambe/components 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +367 -0
- package/dist/client.d.ts +40 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +46 -0
- package/dist/client.js.map +1 -0
- package/dist/components/Accordion/Accordion.d.ts +74 -0
- package/dist/components/Accordion/Accordion.d.ts.map +1 -0
- package/dist/components/Accordion/Accordion.js +297 -0
- package/dist/components/Accordion/Accordion.js.map +1 -0
- package/dist/components/Box/Box.d.ts +56 -0
- package/dist/components/Box/Box.d.ts.map +1 -0
- package/dist/components/Box/Box.js +51 -0
- package/dist/components/Box/Box.js.map +1 -0
- package/dist/components/Breadcrumb/Breadcrumb.d.ts +66 -0
- package/dist/components/Breadcrumb/Breadcrumb.d.ts.map +1 -0
- package/dist/components/Button/Button.d.ts +54 -0
- package/dist/components/Button/Button.d.ts.map +1 -0
- package/dist/components/Button/Button.js +92 -0
- package/dist/components/Button/Button.js.map +1 -0
- package/dist/components/Card/Card.d.ts +54 -0
- package/dist/components/Card/Card.d.ts.map +1 -0
- package/dist/components/Card/Card.js +98 -0
- package/dist/components/Card/Card.js.map +1 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +61 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.d.ts.map +1 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.js +205 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.js.map +1 -0
- package/dist/components/Container/Container.d.ts +72 -0
- package/dist/components/Container/Container.d.ts.map +1 -0
- package/dist/components/Container/Container.js +69 -0
- package/dist/components/Container/Container.js.map +1 -0
- package/dist/components/DateInput/DateInput.d.ts +61 -0
- package/dist/components/DateInput/DateInput.d.ts.map +1 -0
- package/dist/components/DateInput/DateInput.js +234 -0
- package/dist/components/DateInput/DateInput.js.map +1 -0
- package/dist/components/Divider/Divider.d.ts +44 -0
- package/dist/components/Divider/Divider.d.ts.map +1 -0
- package/dist/components/Divider/Divider.js +35 -0
- package/dist/components/Divider/Divider.js.map +1 -0
- package/dist/components/Drawer/Drawer.d.ts +35 -0
- package/dist/components/Drawer/Drawer.d.ts.map +1 -0
- package/dist/components/Drawer/Drawer.js +37 -0
- package/dist/components/Drawer/Drawer.js.map +1 -0
- package/dist/components/FAQ/FAQ.d.ts +40 -0
- package/dist/components/FAQ/FAQ.d.ts.map +1 -0
- package/dist/components/FAQ/FAQ.js +161 -0
- package/dist/components/FAQ/FAQ.js.map +1 -0
- package/dist/components/Grid/Grid.d.ts +61 -0
- package/dist/components/Grid/Grid.d.ts.map +1 -0
- package/dist/components/Grid/Grid.js +95 -0
- package/dist/components/Grid/Grid.js.map +1 -0
- package/dist/components/Icon/Icon.d.ts +21 -0
- package/dist/components/Icon/Icon.d.ts.map +1 -0
- package/dist/components/Icon/Icon.js +167 -0
- package/dist/components/Icon/Icon.js.map +1 -0
- package/dist/components/Link/Link.d.ts +49 -0
- package/dist/components/Link/Link.d.ts.map +1 -0
- package/dist/components/Link/Link.js +70 -0
- package/dist/components/Link/Link.js.map +1 -0
- package/dist/components/List/List.d.ts +36 -0
- package/dist/components/List/List.d.ts.map +1 -0
- package/dist/components/List/List.js +42 -0
- package/dist/components/List/List.js.map +1 -0
- package/dist/components/List/index.d.ts +3 -0
- package/dist/components/List/index.d.ts.map +1 -0
- package/dist/components/Overlay/Overlay.d.ts +35 -0
- package/dist/components/Overlay/Overlay.d.ts.map +1 -0
- package/dist/components/Overlay/Overlay.js +51 -0
- package/dist/components/Overlay/Overlay.js.map +1 -0
- package/dist/components/PhoneInput/PhoneInput.d.ts +55 -0
- package/dist/components/PhoneInput/PhoneInput.d.ts.map +1 -0
- package/dist/components/PhoneInput/PhoneInput.js +255 -0
- package/dist/components/PhoneInput/PhoneInput.js.map +1 -0
- package/dist/components/Popover/Popover.d.ts +46 -0
- package/dist/components/Popover/Popover.d.ts.map +1 -0
- package/dist/components/Popover/Popover.js +57 -0
- package/dist/components/Popover/Popover.js.map +1 -0
- package/dist/components/ProductImage/ProductImage.d.ts +78 -0
- package/dist/components/ProductImage/ProductImage.d.ts.map +1 -0
- package/dist/components/ProductImage/ProductImage.js +220 -0
- package/dist/components/ProductImage/ProductImage.js.map +1 -0
- package/dist/components/RadioGroup/RadioGroup.d.ts +63 -0
- package/dist/components/RadioGroup/RadioGroup.d.ts.map +1 -0
- package/dist/components/RadioGroup/RadioGroup.js +233 -0
- package/dist/components/RadioGroup/RadioGroup.js.map +1 -0
- package/dist/components/Section/Section.d.ts +44 -0
- package/dist/components/Section/Section.d.ts.map +1 -0
- package/dist/components/Section/Section.js +48 -0
- package/dist/components/Section/Section.js.map +1 -0
- package/dist/components/Select/Select.d.ts +47 -0
- package/dist/components/Select/Select.d.ts.map +1 -0
- package/dist/components/Select/Select.js +153 -0
- package/dist/components/Select/Select.js.map +1 -0
- package/dist/components/SelectTab/SelectTab.d.ts +62 -0
- package/dist/components/SelectTab/SelectTab.d.ts.map +1 -0
- package/dist/components/SelectTab/SelectTab.js +192 -0
- package/dist/components/SelectTab/SelectTab.js.map +1 -0
- package/dist/components/Skeleton/Skeleton.d.ts +87 -0
- package/dist/components/Skeleton/Skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton/Skeleton.js +97 -0
- package/dist/components/Skeleton/Skeleton.js.map +1 -0
- package/dist/components/Skeleton/index.d.ts +3 -0
- package/dist/components/Skeleton/index.d.ts.map +1 -0
- package/dist/components/Slider/Slider.d.ts +47 -0
- package/dist/components/Slider/Slider.d.ts.map +1 -0
- package/dist/components/Slider/Slider.js +147 -0
- package/dist/components/Slider/Slider.js.map +1 -0
- package/dist/components/Stack/Stack.d.ts +145 -0
- package/dist/components/Stack/Stack.d.ts.map +1 -0
- package/dist/components/Stack/Stack.js +80 -0
- package/dist/components/Stack/Stack.js.map +1 -0
- package/dist/components/Tab/Tab.d.ts +38 -0
- package/dist/components/Tab/Tab.d.ts.map +1 -0
- package/dist/components/Tab/Tab.js +146 -0
- package/dist/components/Tab/Tab.js.map +1 -0
- package/dist/components/TextArea/TextArea.d.ts +32 -0
- package/dist/components/TextArea/TextArea.d.ts.map +1 -0
- package/dist/components/TextArea/TextArea.js +118 -0
- package/dist/components/TextArea/TextArea.js.map +1 -0
- package/dist/components/TextInput/TextInput.d.ts +35 -0
- package/dist/components/TextInput/TextInput.d.ts.map +1 -0
- package/dist/components/TextInput/TextInput.js +128 -0
- package/dist/components/TextInput/TextInput.js.map +1 -0
- package/dist/components/Toggle/Toggle.d.ts +83 -0
- package/dist/components/Toggle/Toggle.d.ts.map +1 -0
- package/dist/components/Toggle/Toggle.js +121 -0
- package/dist/components/Toggle/Toggle.js.map +1 -0
- package/dist/components/Typography/Typography.d.ts +321 -0
- package/dist/components/Typography/Typography.d.ts.map +1 -0
- package/dist/components/Typography/Typography.js +21 -0
- package/dist/components/Typography/Typography.js.map +1 -0
- package/dist/components/UploadInput/UploadInput.d.ts +39 -0
- package/dist/components/UploadInput/UploadInput.d.ts.map +1 -0
- package/dist/components/UploadInput/UploadInput.js +297 -0
- package/dist/components/UploadInput/UploadInput.js.map +1 -0
- package/dist/components/index.d.ts +65 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/jiwambe-plugin.d.ts +37 -0
- package/dist/plugin/jiwambe-plugin.d.ts.map +1 -0
- package/dist/plugin/jiwambe-plugin.js +640 -0
- package/dist/plugin/jiwambe-plugin.js.map +1 -0
- package/dist/server.d.ts +22 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +23 -0
- package/dist/server.js.map +1 -0
- package/dist/types/index.d.ts +103 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/layout.d.ts +138 -0
- package/dist/types/layout.d.ts.map +1 -0
- package/dist/types/list.d.ts +69 -0
- package/dist/types/list.d.ts.map +1 -0
- package/dist/types/list.js +9 -0
- package/dist/types/list.js.map +1 -0
- package/dist/types/skeleton.d.ts +38 -0
- package/dist/types/skeleton.d.ts.map +1 -0
- package/dist/types/skeleton.js +13 -0
- package/dist/types/skeleton.js.map +1 -0
- package/dist/types/spacing.d.ts +105 -0
- package/dist/types/spacing.d.ts.map +1 -0
- package/dist/utils/layoutClasses.d.ts +44 -0
- package/dist/utils/layoutClasses.d.ts.map +1 -0
- package/dist/utils/layoutClasses.js +88 -0
- package/dist/utils/layoutClasses.js.map +1 -0
- package/dist/utils/responsive-props.d.ts +60 -0
- package/dist/utils/responsive-props.d.ts.map +1 -0
- package/dist/utils/responsive-props.js +184 -0
- package/dist/utils/responsive-props.js.map +1 -0
- package/dist/utils/spacing.d.ts +52 -0
- package/dist/utils/spacing.d.ts.map +1 -0
- package/dist/utils/spacing.js +625 -0
- package/dist/utils/spacing.js.map +1 -0
- package/package.json +96 -0
- package/tailwind.preset.d.ts +3 -0
- package/tailwind.preset.ts +21 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useRef, useCallback, useEffect } from "react";
|
|
4
|
+
import Image from "next/image";
|
|
5
|
+
function ExpandIcon({ className }) {
|
|
6
|
+
return /* @__PURE__ */ jsxs(
|
|
7
|
+
"svg",
|
|
8
|
+
{
|
|
9
|
+
className,
|
|
10
|
+
width: "20",
|
|
11
|
+
height: "20",
|
|
12
|
+
viewBox: "0 0 20 20",
|
|
13
|
+
fill: "none",
|
|
14
|
+
stroke: "currentColor",
|
|
15
|
+
strokeWidth: "1.5",
|
|
16
|
+
strokeLinecap: "round",
|
|
17
|
+
strokeLinejoin: "round",
|
|
18
|
+
"aria-hidden": "true",
|
|
19
|
+
children: [
|
|
20
|
+
/* @__PURE__ */ jsx("polyline", { points: "15 3 17 3 17 5" }),
|
|
21
|
+
/* @__PURE__ */ jsx("polyline", { points: "3 15 3 17 5 17" }),
|
|
22
|
+
/* @__PURE__ */ jsx("polyline", { points: "17 15 17 17 15 17" }),
|
|
23
|
+
/* @__PURE__ */ jsx("polyline", { points: "3 5 3 3 5 3" })
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
function ChevronLeftIcon({ className }) {
|
|
29
|
+
return /* @__PURE__ */ jsx("svg", { className, width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M12.5 15L7.5 10L12.5 5" }) });
|
|
30
|
+
}
|
|
31
|
+
function ChevronRightIcon({ className }) {
|
|
32
|
+
return /* @__PURE__ */ jsx("svg", { className, width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M7.5 5L12.5 10L7.5 15" }) });
|
|
33
|
+
}
|
|
34
|
+
function ProductImage({ src, alt = "", width = 800, height = 800, showExpand = false, onExpand, className = "", ref, ...rest }) {
|
|
35
|
+
return /* @__PURE__ */ jsxs(
|
|
36
|
+
"div",
|
|
37
|
+
{
|
|
38
|
+
ref,
|
|
39
|
+
className: `relative overflow-hidden rounded-rad-md border border-border-heavy bg-fill-bg-secondary ${className}`,
|
|
40
|
+
...rest,
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center p-space-4", children: /* @__PURE__ */ jsx(
|
|
43
|
+
Image,
|
|
44
|
+
{
|
|
45
|
+
src,
|
|
46
|
+
alt,
|
|
47
|
+
width,
|
|
48
|
+
height,
|
|
49
|
+
className: "max-h-full max-w-full object-contain"
|
|
50
|
+
}
|
|
51
|
+
) }),
|
|
52
|
+
showExpand && /* @__PURE__ */ jsx(
|
|
53
|
+
"button",
|
|
54
|
+
{
|
|
55
|
+
type: "button",
|
|
56
|
+
onClick: onExpand,
|
|
57
|
+
"aria-label": "Expand image",
|
|
58
|
+
className: "absolute top-2 right-2 flex h-7 w-7 items-center justify-center rounded-rad-xs bg-fill-bg-primary/80 text-text-secondary hover:bg-fill-bg-primary hover:text-text-primary transition-colors",
|
|
59
|
+
children: /* @__PURE__ */ jsx(ExpandIcon, { className: "h-4 w-4" })
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
function ProductImageGallery({
|
|
67
|
+
images,
|
|
68
|
+
defaultIndex = 0,
|
|
69
|
+
activeIndex: activeProp,
|
|
70
|
+
onChange,
|
|
71
|
+
showExpand = true,
|
|
72
|
+
onExpand,
|
|
73
|
+
imageWidth = 800,
|
|
74
|
+
imageHeight = 600,
|
|
75
|
+
className = "",
|
|
76
|
+
ref,
|
|
77
|
+
...rest
|
|
78
|
+
}) {
|
|
79
|
+
const isControlled = activeProp !== void 0;
|
|
80
|
+
const [internal, setInternal] = useState(defaultIndex);
|
|
81
|
+
const active = isControlled ? activeProp : internal;
|
|
82
|
+
const thumbnailsRef = useRef(null);
|
|
83
|
+
const select = useCallback(
|
|
84
|
+
(idx) => {
|
|
85
|
+
if (!isControlled) setInternal(idx);
|
|
86
|
+
onChange == null ? void 0 : onChange(idx);
|
|
87
|
+
},
|
|
88
|
+
[isControlled, onChange]
|
|
89
|
+
);
|
|
90
|
+
const prev = useCallback(() => {
|
|
91
|
+
const next2 = active > 0 ? active - 1 : images.length - 1;
|
|
92
|
+
select(next2);
|
|
93
|
+
}, [active, images.length, select]);
|
|
94
|
+
const next = useCallback(() => {
|
|
95
|
+
const n = active < images.length - 1 ? active + 1 : 0;
|
|
96
|
+
select(n);
|
|
97
|
+
}, [active, images.length, select]);
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
var _a;
|
|
100
|
+
const el = (_a = thumbnailsRef.current) == null ? void 0 : _a.children[active];
|
|
101
|
+
el == null ? void 0 : el.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" });
|
|
102
|
+
}, [active]);
|
|
103
|
+
const handleKeyDown = (e) => {
|
|
104
|
+
if (e.key === "ArrowLeft") {
|
|
105
|
+
e.preventDefault();
|
|
106
|
+
prev();
|
|
107
|
+
}
|
|
108
|
+
if (e.key === "ArrowRight") {
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
next();
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
const currentImage = images[active];
|
|
114
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: `flex flex-col gap-space-3 ${className}`, ...rest, children: [
|
|
115
|
+
/* @__PURE__ */ jsxs(
|
|
116
|
+
"div",
|
|
117
|
+
{
|
|
118
|
+
className: "relative overflow-hidden rounded-rad-md bg-fill-bg-secondary border border-border-light",
|
|
119
|
+
tabIndex: 0,
|
|
120
|
+
role: "img",
|
|
121
|
+
"aria-label": (currentImage == null ? void 0 : currentImage.alt) ?? "Product image",
|
|
122
|
+
onKeyDown: handleKeyDown,
|
|
123
|
+
children: [
|
|
124
|
+
/* @__PURE__ */ jsx("div", { className: "flex aspect-[4/3] items-center justify-center p-space-4", children: /* @__PURE__ */ jsx(
|
|
125
|
+
Image,
|
|
126
|
+
{
|
|
127
|
+
src: currentImage == null ? void 0 : currentImage.src,
|
|
128
|
+
alt: (currentImage == null ? void 0 : currentImage.alt) ?? "",
|
|
129
|
+
width: imageWidth,
|
|
130
|
+
height: imageHeight,
|
|
131
|
+
className: "max-h-full max-w-full object-contain"
|
|
132
|
+
}
|
|
133
|
+
) }),
|
|
134
|
+
showExpand && /* @__PURE__ */ jsx(
|
|
135
|
+
"button",
|
|
136
|
+
{
|
|
137
|
+
type: "button",
|
|
138
|
+
onClick: () => onExpand == null ? void 0 : onExpand(active),
|
|
139
|
+
"aria-label": "Expand image",
|
|
140
|
+
className: "absolute top-2 right-2 flex h-7 w-7 items-center justify-center rounded-rad-xs bg-fill-bg-primary/80 text-text-secondary hover:bg-fill-bg-primary hover:text-text-primary transition-colors",
|
|
141
|
+
children: /* @__PURE__ */ jsx(ExpandIcon, { className: "h-4 w-4" })
|
|
142
|
+
}
|
|
143
|
+
),
|
|
144
|
+
images.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
145
|
+
/* @__PURE__ */ jsx(
|
|
146
|
+
"button",
|
|
147
|
+
{
|
|
148
|
+
type: "button",
|
|
149
|
+
onClick: prev,
|
|
150
|
+
"aria-label": "Previous image",
|
|
151
|
+
className: "absolute left-2 top-1/2 -translate-y-1/2 flex h-8 w-8 items-center justify-center rounded-full bg-fill-bg-primary/80 text-text-secondary hover:bg-fill-bg-primary hover:text-text-primary transition-colors",
|
|
152
|
+
children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-5 w-5" })
|
|
153
|
+
}
|
|
154
|
+
),
|
|
155
|
+
/* @__PURE__ */ jsx(
|
|
156
|
+
"button",
|
|
157
|
+
{
|
|
158
|
+
type: "button",
|
|
159
|
+
onClick: next,
|
|
160
|
+
"aria-label": "Next image",
|
|
161
|
+
className: "absolute right-2 top-1/2 -translate-y-1/2 flex h-8 w-8 items-center justify-center rounded-full bg-fill-bg-primary/80 text-text-secondary hover:bg-fill-bg-primary hover:text-text-primary transition-colors",
|
|
162
|
+
children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-5 w-5" })
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
] }),
|
|
166
|
+
images.length > 1 && /* @__PURE__ */ jsx("div", { className: "absolute bottom-3 left-1/2 -translate-x-1/2 flex gap-1.5", children: images.map((_, i) => /* @__PURE__ */ jsx(
|
|
167
|
+
"button",
|
|
168
|
+
{
|
|
169
|
+
type: "button",
|
|
170
|
+
onClick: () => select(i),
|
|
171
|
+
"aria-label": `Go to image ${i + 1}`,
|
|
172
|
+
className: `h-2 w-2 rounded-full transition-colors ${i === active ? "bg-green-900" : "bg-neutral-300 hover:bg-neutral-500"}`
|
|
173
|
+
},
|
|
174
|
+
i
|
|
175
|
+
)) })
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
),
|
|
179
|
+
images.length > 1 && /* @__PURE__ */ jsx(
|
|
180
|
+
"div",
|
|
181
|
+
{
|
|
182
|
+
ref: thumbnailsRef,
|
|
183
|
+
className: "flex gap-space-2 overflow-x-auto scrollbar-none",
|
|
184
|
+
role: "tablist",
|
|
185
|
+
"aria-label": "Image thumbnails",
|
|
186
|
+
children: images.map((img, i) => /* @__PURE__ */ jsxs(
|
|
187
|
+
"button",
|
|
188
|
+
{
|
|
189
|
+
type: "button",
|
|
190
|
+
role: "tab",
|
|
191
|
+
"aria-selected": i === active,
|
|
192
|
+
"aria-label": img.alt ?? `Image ${i + 1}`,
|
|
193
|
+
onClick: () => select(i),
|
|
194
|
+
className: `relative flex shrink-0 items-center justify-center overflow-hidden rounded-rad-sm border bg-fill-bg-secondary p-space-2 transition-all ${i === active ? "border-border-heavy ring-1 ring-border-heavy" : "border-border-light hover:border-border-heavy"}`,
|
|
195
|
+
style: { width: 80, height: 64 },
|
|
196
|
+
children: [
|
|
197
|
+
/* @__PURE__ */ jsx(
|
|
198
|
+
Image,
|
|
199
|
+
{
|
|
200
|
+
src: img.src,
|
|
201
|
+
alt: img.alt ?? "",
|
|
202
|
+
width: 80,
|
|
203
|
+
height: 64,
|
|
204
|
+
className: "max-h-full max-w-full object-contain"
|
|
205
|
+
}
|
|
206
|
+
),
|
|
207
|
+
showExpand && /* @__PURE__ */ jsx("span", { className: "absolute top-1 right-1 flex h-5 w-5 items-center justify-center rounded-[3px] bg-fill-bg-primary/70 text-text-secondary", children: /* @__PURE__ */ jsx(ExpandIcon, { className: "h-3 w-3" }) })
|
|
208
|
+
]
|
|
209
|
+
},
|
|
210
|
+
i
|
|
211
|
+
))
|
|
212
|
+
}
|
|
213
|
+
)
|
|
214
|
+
] });
|
|
215
|
+
}
|
|
216
|
+
export {
|
|
217
|
+
ProductImage,
|
|
218
|
+
ProductImageGallery
|
|
219
|
+
};
|
|
220
|
+
//# sourceMappingURL=ProductImage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProductImage.js","sources":["../../../src/components/ProductImage/ProductImage.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useCallback, useRef, useEffect } from 'react';\nimport Image from 'next/image';\n\n// ---------------------------------------------------------------------------\n// Icons\n// ---------------------------------------------------------------------------\n\nfunction ExpandIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"15 3 17 3 17 5\" />\n <polyline points=\"3 15 3 17 5 17\" />\n <polyline points=\"17 15 17 17 15 17\" />\n <polyline points=\"3 5 3 3 5 3\" />\n </svg>\n );\n}\n\nfunction ChevronLeftIcon({ className }: { className?: string }) {\n return (\n <svg className={className} width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M12.5 15L7.5 10L12.5 5\" />\n </svg>\n );\n}\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg className={className} width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M7.5 5L12.5 10L7.5 15\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// ProductImage — single framed product image\n// ---------------------------------------------------------------------------\n\n/**\n * Props for the ProductImage component. Renders a single image in a bordered container\n * with optional expand button. Uses next/image for optimization.\n */\nexport interface ProductImageProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Image source URL. */\n src: string;\n /** Alt text for the image. @default '' */\n alt?: string;\n /** Width for next/image. @default 800 */\n width?: number;\n /** Height for next/image. @default 800 */\n height?: number;\n /** When true, shows an expand/fullscreen icon overlay. @default false */\n showExpand?: boolean;\n /** Called when the expand icon is clicked. @default undefined */\n onExpand?: () => void;\n /** Forwarded ref for the root div. @default undefined */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Single product image in a bordered, rounded container. Uses next/image. Optional\n * expand button for opening in a lightbox or fullscreen (handle with onExpand).\n * For multiple images with thumbnails use ProductImageGallery.\n *\n * @example\n * <ProductImage src=\"/product.jpg\" alt=\"Product\" />\n *\n * @example\n * <ProductImage src={url} showExpand onExpand={() => openLightbox()} />\n */\nexport function ProductImage({ src, alt = '', width = 800, height = 800, showExpand = false, onExpand, className = '', ref, ...rest }: ProductImageProps) {\n return (\n <div\n ref={ref}\n className={`relative overflow-hidden rounded-rad-md border border-border-heavy bg-fill-bg-secondary ${className}`}\n {...rest}\n >\n <div className=\"flex items-center justify-center p-space-4\">\n <Image\n src={src}\n alt={alt}\n width={width}\n height={height}\n className=\"max-h-full max-w-full object-contain\"\n />\n </div>\n {showExpand && (\n <button\n type=\"button\"\n onClick={onExpand}\n aria-label=\"Expand image\"\n className=\"absolute top-2 right-2 flex h-7 w-7 items-center justify-center rounded-rad-xs bg-fill-bg-primary/80 text-text-secondary hover:bg-fill-bg-primary hover:text-text-primary transition-colors\"\n >\n <ExpandIcon className=\"h-4 w-4\" />\n </button>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// ProductImageGallery — horizontal thumbnail gallery with main image\n// ---------------------------------------------------------------------------\n\n/**\n * Shape of a single image in the gallery. Each item needs src; alt is optional.\n */\nexport interface GalleryImage {\n src: string;\n alt?: string;\n}\n\n/**\n * Props for ProductImageGallery. Main image area shows one image at a time with\n * optional prev/next arrows and expand; thumbnails strip below for multi-image selection.\n * Supports controlled (activeIndex/onChange) or uncontrolled (defaultIndex) selection.\n */\nexport interface ProductImageGalleryProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Array of images. Each: src (string), alt? (string). @see GalleryImage */\n images: GalleryImage[];\n /** Index of the initially selected image (uncontrolled). @default 0 */\n defaultIndex?: number;\n /** Controlled selected index. Use with onChange. @default undefined */\n activeIndex?: number;\n /** Called when the user selects another image (thumbnail or arrow). @default undefined */\n onChange?: (index: number) => void;\n /** When true, shows expand icon on the main image. @default true */\n showExpand?: boolean;\n /** Called when the expand icon is clicked; receives current image index. @default undefined */\n onExpand?: (index: number) => void;\n /** Width for next/image main image. @default 800 */\n imageWidth?: number;\n /** Height for next/image main image. Main area uses aspect ratio 4:3. @default 600 */\n imageHeight?: number;\n /** Forwarded ref for the root div. @default undefined */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Product image gallery with main image and horizontal thumbnail strip. Main image\n * has prev/next arrows and optional expand; thumbnails are selectable. Use for PDPs\n * or any multi-image product view. Single image use ProductImage instead.\n *\n * @example\n * <ProductImageGallery images={[{ src: '/a.jpg' }, { src: '/b.jpg', alt: 'Back' }]} />\n *\n * @example\n * <ProductImageGallery images={imgs} activeIndex={idx} onChange={setIdx} showExpand onExpand={openLightbox} />\n */\nexport function ProductImageGallery({\n images,\n defaultIndex = 0,\n activeIndex: activeProp,\n onChange,\n showExpand = true,\n onExpand,\n imageWidth = 800,\n imageHeight = 600,\n className = '',\n ref,\n ...rest\n}: ProductImageGalleryProps) {\n const isControlled = activeProp !== undefined;\n const [internal, setInternal] = useState(defaultIndex);\n const active = isControlled ? activeProp : internal;\n\n const thumbnailsRef = useRef<HTMLDivElement>(null);\n\n const select = useCallback(\n (idx: number) => {\n if (!isControlled) setInternal(idx);\n onChange?.(idx);\n },\n [isControlled, onChange],\n );\n\n const prev = useCallback(() => {\n const next = active > 0 ? active - 1 : images.length - 1;\n select(next);\n }, [active, images.length, select]);\n\n const next = useCallback(() => {\n const n = active < images.length - 1 ? active + 1 : 0;\n select(n);\n }, [active, images.length, select]);\n\n useEffect(() => {\n const el = thumbnailsRef.current?.children[active] as HTMLElement | undefined;\n el?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });\n }, [active]);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowLeft') { e.preventDefault(); prev(); }\n if (e.key === 'ArrowRight') { e.preventDefault(); next(); }\n };\n\n const currentImage = images[active];\n\n return (\n <div ref={ref} className={`flex flex-col gap-space-3 ${className}`} {...rest}>\n {/* Main image */}\n <div\n className=\"relative overflow-hidden rounded-rad-md bg-fill-bg-secondary border border-border-light\"\n tabIndex={0}\n role=\"img\"\n aria-label={currentImage?.alt ?? 'Product image'}\n onKeyDown={handleKeyDown}\n >\n <div className=\"flex aspect-[4/3] items-center justify-center p-space-4\">\n <Image\n src={currentImage?.src}\n alt={currentImage?.alt ?? ''}\n width={imageWidth}\n height={imageHeight}\n className=\"max-h-full max-w-full object-contain\"\n />\n </div>\n\n {showExpand && (\n <button\n type=\"button\"\n onClick={() => onExpand?.(active)}\n aria-label=\"Expand image\"\n className=\"absolute top-2 right-2 flex h-7 w-7 items-center justify-center rounded-rad-xs bg-fill-bg-primary/80 text-text-secondary hover:bg-fill-bg-primary hover:text-text-primary transition-colors\"\n >\n <ExpandIcon className=\"h-4 w-4\" />\n </button>\n )}\n\n {/* Navigation arrows */}\n {images.length > 1 && (\n <>\n <button\n type=\"button\"\n onClick={prev}\n aria-label=\"Previous image\"\n className=\"absolute left-2 top-1/2 -translate-y-1/2 flex h-8 w-8 items-center justify-center rounded-full bg-fill-bg-primary/80 text-text-secondary hover:bg-fill-bg-primary hover:text-text-primary transition-colors\"\n >\n <ChevronLeftIcon className=\"h-5 w-5\" />\n </button>\n <button\n type=\"button\"\n onClick={next}\n aria-label=\"Next image\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 flex h-8 w-8 items-center justify-center rounded-full bg-fill-bg-primary/80 text-text-secondary hover:bg-fill-bg-primary hover:text-text-primary transition-colors\"\n >\n <ChevronRightIcon className=\"h-5 w-5\" />\n </button>\n </>\n )}\n\n {/* Pagination dots */}\n {images.length > 1 && (\n <div className=\"absolute bottom-3 left-1/2 -translate-x-1/2 flex gap-1.5\">\n {images.map((_, i) => (\n <button\n key={i}\n type=\"button\"\n onClick={() => select(i)}\n aria-label={`Go to image ${i + 1}`}\n className={`h-2 w-2 rounded-full transition-colors ${\n i === active\n ? 'bg-green-900'\n : 'bg-neutral-300 hover:bg-neutral-500'\n }`}\n />\n ))}\n </div>\n )}\n </div>\n\n {/* Thumbnails strip */}\n {images.length > 1 && (\n <div\n ref={thumbnailsRef}\n className=\"flex gap-space-2 overflow-x-auto scrollbar-none\"\n role=\"tablist\"\n aria-label=\"Image thumbnails\"\n >\n {images.map((img, i) => (\n <button\n key={i}\n type=\"button\"\n role=\"tab\"\n aria-selected={i === active}\n aria-label={img.alt ?? `Image ${i + 1}`}\n onClick={() => select(i)}\n className={`relative flex shrink-0 items-center justify-center overflow-hidden rounded-rad-sm border bg-fill-bg-secondary p-space-2 transition-all ${\n i === active\n ? 'border-border-heavy ring-1 ring-border-heavy'\n : 'border-border-light hover:border-border-heavy'\n }`}\n style={{ width: 80, height: 64 }}\n >\n <Image\n src={img.src}\n alt={img.alt ?? ''}\n width={80}\n height={64}\n className=\"max-h-full max-w-full object-contain\"\n />\n {showExpand && (\n <span className=\"absolute top-1 right-1 flex h-5 w-5 items-center justify-center rounded-[3px] bg-fill-bg-primary/70 text-text-secondary\">\n <ExpandIcon className=\"h-3 w-3\" />\n </span>\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":";;;;AASA;AACE;AACE;AAAC;AAAA;AACC;AACM;AACC;AACC;AACH;AACE;AACK;AACE;AACC;AACH;AAEZ;AAAkC;AACA;AACG;AACN;AAAA;AAAA;AAGrC;AAEA;AACE;AAKF;AAEA;AACE;AAKF;AAsCO;AACL;AACE;AAAC;AAAA;AACC;AAC+G;AAC3G;AAEJ;AACE;AAAC;AAAA;AACC;AACA;AACA;AACA;AACU;AAAA;AAEd;AAEE;AAAC;AAAA;AACM;AACI;AACE;AACD;AAEsB;AAAA;AAAA;AAClC;AAAA;AAIR;AAmDO;AAA6B;AAClC;AACe;AACF;AACb;AACa;AACb;AACa;AACC;AACF;AACZ;AAEF;AACE;AACA;AACA;AAEA;AAEA;AAAe;AAEX;AACA;AAAW;AACb;AACuB;AAGzB;AACE;AACA;AAAW;AAGb;AACE;AACA;AAAQ;AAGV;;AACE;AACA;;AAGF;AACE;AAA6B;AAAoB;AAAA;AACjD;AAA8B;AAAoB;AAAA;AAAQ;AAG5D;AAEA;AAGI;AAAA;AAAC;AAAA;AACW;AACA;AACL;AAC4B;AACtB;AAEX;AACE;AAAC;AAAA;AACoB;AACO;AACnB;AACC;AACE;AAAA;AAEd;AAGE;AAAC;AAAA;AACM;AACqB;AACf;AACD;AAEsB;AAAA;AAAA;AAOhC;AAAA;AAAC;AAAA;AACM;AACI;AACE;AACD;AAE2B;AAAA;AAAA;AAEvC;AAAC;AAAA;AACM;AACI;AACE;AACD;AAE4B;AAAA;AAAA;AAE1C;AAOI;AAAC;AAAA;AAEM;AACkB;AACS;AAKhC;AAAA;AARK;AAWX;AAAA;AAAA;AAAA;AAMF;AAAC;AAAA;AACM;AACK;AACL;AACM;AAGT;AAAC;AAAA;AAEM;AACA;AACgB;AACgB;AACd;AAKvB;AAC4B;AAE5B;AAAA;AAAC;AAAA;AACU;AACO;AACT;AACC;AACE;AAAA;AAAA;AAKV;AAAA;AAAA;AAvBG;AA0BR;AAAA;AAAA;AAKX;;;;;"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Shape of a single radio option. Pass an array of these to RadioGroup's options prop.
|
|
4
|
+
*/
|
|
5
|
+
export interface RadioOption {
|
|
6
|
+
/** Value submitted when this option is selected. Must be unique in the group. */
|
|
7
|
+
value: string;
|
|
8
|
+
/** Label shown next to the radio. */
|
|
9
|
+
label: string;
|
|
10
|
+
/** When true, this option cannot be selected. @default undefined */
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Props for the RadioGroup component. Single selection; value/onChange for controlled,
|
|
15
|
+
* defaultValue for uncontrolled. value and onChange work together in controlled mode.
|
|
16
|
+
*/
|
|
17
|
+
export interface RadioGroupProps {
|
|
18
|
+
/** Main label above the group (legend). @default undefined */
|
|
19
|
+
label?: string;
|
|
20
|
+
/** Secondary label shown lighter beside the main label. @default undefined */
|
|
21
|
+
secondaryLabel?: string;
|
|
22
|
+
/** Supportive text below the label. @default undefined */
|
|
23
|
+
supportText?: string;
|
|
24
|
+
/** Name for the radio group (each input gets name={name}). @default derived from id */
|
|
25
|
+
name?: string;
|
|
26
|
+
/** Controlled selected value (option value string). Use with onChange. @default undefined */
|
|
27
|
+
value?: string;
|
|
28
|
+
/** Uncontrolled default selected value. @default undefined */
|
|
29
|
+
defaultValue?: string;
|
|
30
|
+
/** Called when selection changes. Receives the selected option value. @default undefined */
|
|
31
|
+
onChange?: (value: string) => void;
|
|
32
|
+
/** Options to render. Each: value, label, disabled?. @see RadioOption */
|
|
33
|
+
options: RadioOption[];
|
|
34
|
+
/** Disables the entire group. @default false */
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
/** Shows error state and optional errorMessage. @default false */
|
|
37
|
+
error?: boolean;
|
|
38
|
+
/** Error message shown in the alert below the group when error is true. @default undefined */
|
|
39
|
+
errorMessage?: string;
|
|
40
|
+
/** Shows required asterisk next to the label. @default undefined */
|
|
41
|
+
required?: boolean;
|
|
42
|
+
/** When true, the selected option shows a trailing checkmark icon. @default false */
|
|
43
|
+
showCheckIcon?: boolean;
|
|
44
|
+
/** Additional class name on the wrapper. @default undefined */
|
|
45
|
+
className?: string;
|
|
46
|
+
/** ID for the group (used for generated input ids and aria-describedby). @default undefined */
|
|
47
|
+
id?: string;
|
|
48
|
+
/** Forwarded ref for the fieldset. @default undefined */
|
|
49
|
+
ref?: React.Ref<HTMLFieldSetElement>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Single-selection radio group with label, support text, and optional error state.
|
|
53
|
+
* Renders a fieldset with design-token styling. Use for one-of-many choices (e.g. delivery
|
|
54
|
+
* method, plan). For multi-select use CheckboxGroup. value/onChange for controlled mode.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* <RadioGroup label="Plan" options={[{ value: 'a', label: 'Plan A' }]} onChange={setValue} />
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* <RadioGroup label="Option" value={selected} onChange={setSelected} options={opts} showCheckIcon error errorMessage="Required" />
|
|
61
|
+
*/
|
|
62
|
+
export declare function RadioGroup({ label, secondaryLabel, supportText, name: nameProp, value: valueProp, defaultValue, onChange, options, disabled, error, errorMessage, required, showCheckIcon, className, id: idProp, ref, }: RadioGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
63
|
+
//# sourceMappingURL=RadioGroup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioGroup.d.ts","sourceRoot":"","sources":["../../../src/components/RadioGroup/RadioGroup.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAMrC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,yEAAyE;IACzE,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8FAA8F;IAC9F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qFAAqF;IACrF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+FAA+F;IAC/F,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yDAAyD;IACzD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;CACtC;AAsJD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,cAAc,EACd,WAAW,EACX,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,SAAS,EAChB,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,QAAgB,EAChB,KAAa,EACb,YAAY,EACZ,QAAQ,EACR,aAAqB,EACrB,SAAS,EACT,EAAE,EAAE,MAAM,EACV,GAAG,GACJ,EAAE,eAAe,2CAmGjB"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
3
|
+
import React, { useId } from "react";
|
|
4
|
+
function CheckIcon({ className }) {
|
|
5
|
+
return /* @__PURE__ */ jsx(
|
|
6
|
+
"svg",
|
|
7
|
+
{
|
|
8
|
+
className,
|
|
9
|
+
viewBox: "0 0 24 24",
|
|
10
|
+
fill: "none",
|
|
11
|
+
stroke: "currentColor",
|
|
12
|
+
strokeWidth: "2",
|
|
13
|
+
strokeLinecap: "round",
|
|
14
|
+
strokeLinejoin: "round",
|
|
15
|
+
"aria-hidden": "true",
|
|
16
|
+
children: /* @__PURE__ */ jsx("path", { d: "M20 6L9 17l-5-5" })
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
function ErrorIcon({ className }) {
|
|
21
|
+
return /* @__PURE__ */ jsx(
|
|
22
|
+
"svg",
|
|
23
|
+
{
|
|
24
|
+
className,
|
|
25
|
+
viewBox: "0 0 20 20",
|
|
26
|
+
fill: "currentColor",
|
|
27
|
+
"aria-hidden": "true",
|
|
28
|
+
children: /* @__PURE__ */ jsx(
|
|
29
|
+
"path",
|
|
30
|
+
{
|
|
31
|
+
fillRule: "evenodd",
|
|
32
|
+
d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",
|
|
33
|
+
clipRule: "evenodd"
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
function RadioItem({
|
|
40
|
+
name,
|
|
41
|
+
value,
|
|
42
|
+
checked,
|
|
43
|
+
disabled,
|
|
44
|
+
error,
|
|
45
|
+
showCheckIcon,
|
|
46
|
+
label,
|
|
47
|
+
id,
|
|
48
|
+
onChange
|
|
49
|
+
}) {
|
|
50
|
+
const unselectedCircle = [
|
|
51
|
+
"pointer-events-none absolute inset-0 rounded-rad-rounded transition-all duration-150 border-solid border-[1.25px]",
|
|
52
|
+
!disabled && !error && "border-border-form-primary bg-fill-form-primary",
|
|
53
|
+
!disabled && !error && "group-hover:border-[1.5px] group-hover:border-border-form-primary-hover",
|
|
54
|
+
!disabled && !error && "group-active:border-[1.5px] group-active:border-border-form-primary-active",
|
|
55
|
+
!disabled && error && "border-border-err bg-fill-form-primary",
|
|
56
|
+
!disabled && error && "group-hover:border-[1.5px]",
|
|
57
|
+
disabled && "border-border-form-primary-disabled bg-fill-form-primary-disabled"
|
|
58
|
+
].filter(Boolean).join(" ");
|
|
59
|
+
const selectedCircle = [
|
|
60
|
+
"pointer-events-none absolute inset-0 rounded-rad-rounded transition-all duration-150",
|
|
61
|
+
!disabled && !error && "bg-fill-action-primary",
|
|
62
|
+
!disabled && !error && "group-hover:bg-fill-action-primary-hover",
|
|
63
|
+
!disabled && !error && "group-active:bg-fill-action-primary-active",
|
|
64
|
+
!disabled && error && "bg-fill-action-primary",
|
|
65
|
+
disabled && "bg-fill-action-primary-disabled"
|
|
66
|
+
].filter(Boolean).join(" ");
|
|
67
|
+
return /* @__PURE__ */ jsxs(
|
|
68
|
+
"label",
|
|
69
|
+
{
|
|
70
|
+
htmlFor: id,
|
|
71
|
+
className: `group flex items-center gap-space-3 ${disabled ? "cursor-not-allowed" : "cursor-pointer"}`,
|
|
72
|
+
children: [
|
|
73
|
+
/* @__PURE__ */ jsxs("span", { className: "relative flex h-6 w-6 shrink-0 items-center justify-center", children: [
|
|
74
|
+
/* @__PURE__ */ jsx(
|
|
75
|
+
"input",
|
|
76
|
+
{
|
|
77
|
+
type: "radio",
|
|
78
|
+
id,
|
|
79
|
+
name,
|
|
80
|
+
value,
|
|
81
|
+
checked,
|
|
82
|
+
disabled,
|
|
83
|
+
onChange: () => onChange(value),
|
|
84
|
+
className: "peer sr-only",
|
|
85
|
+
"aria-invalid": error || void 0
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
checked ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
89
|
+
/* @__PURE__ */ jsx("span", { className: selectedCircle }),
|
|
90
|
+
/* @__PURE__ */ jsx(
|
|
91
|
+
"svg",
|
|
92
|
+
{
|
|
93
|
+
className: "pointer-events-none relative h-3 w-3 shrink-0",
|
|
94
|
+
width: "12",
|
|
95
|
+
height: "12",
|
|
96
|
+
viewBox: "0 0 12 12",
|
|
97
|
+
fill: "none",
|
|
98
|
+
"aria-hidden": "true",
|
|
99
|
+
children: /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: "6", fill: "white" })
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
] }) : /* @__PURE__ */ jsx("span", { className: unselectedCircle }),
|
|
103
|
+
/* @__PURE__ */ jsx(
|
|
104
|
+
"span",
|
|
105
|
+
{
|
|
106
|
+
className: "pointer-events-none absolute rounded-rad-rounded border-[1.5px] border-border-focus border-solid opacity-0 peer-focus-visible:opacity-100 -inset-1",
|
|
107
|
+
"aria-hidden": "true"
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
] }),
|
|
111
|
+
/* @__PURE__ */ jsx(
|
|
112
|
+
"span",
|
|
113
|
+
{
|
|
114
|
+
className: `flex-1 text-form-text ${disabled ? "text-text-disabled" : "text-text-primary"}`,
|
|
115
|
+
children: label
|
|
116
|
+
}
|
|
117
|
+
),
|
|
118
|
+
showCheckIcon && checked && /* @__PURE__ */ jsx(
|
|
119
|
+
"span",
|
|
120
|
+
{
|
|
121
|
+
className: `flex h-6 w-6 shrink-0 items-center justify-center rounded-full ${disabled ? "bg-neutral-300 text-neutral-500" : "bg-green-900 text-neutral-0"}`,
|
|
122
|
+
"aria-hidden": "true",
|
|
123
|
+
children: /* @__PURE__ */ jsx(CheckIcon, { className: "h-3.5 w-3.5" })
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
function RadioGroup({
|
|
131
|
+
label,
|
|
132
|
+
secondaryLabel,
|
|
133
|
+
supportText,
|
|
134
|
+
name: nameProp,
|
|
135
|
+
value: valueProp,
|
|
136
|
+
defaultValue,
|
|
137
|
+
onChange,
|
|
138
|
+
options,
|
|
139
|
+
disabled = false,
|
|
140
|
+
error = false,
|
|
141
|
+
errorMessage,
|
|
142
|
+
required,
|
|
143
|
+
showCheckIcon = false,
|
|
144
|
+
className,
|
|
145
|
+
id: idProp,
|
|
146
|
+
ref
|
|
147
|
+
}) {
|
|
148
|
+
const autoId = useId();
|
|
149
|
+
const baseId = idProp ?? autoId;
|
|
150
|
+
const name = nameProp ?? baseId;
|
|
151
|
+
const isControlled = valueProp !== void 0;
|
|
152
|
+
const [internal, setInternal] = React.useState(defaultValue ?? "");
|
|
153
|
+
const value = isControlled ? valueProp : internal;
|
|
154
|
+
const handleChange = (v) => {
|
|
155
|
+
if (!isControlled) setInternal(v);
|
|
156
|
+
onChange == null ? void 0 : onChange(v);
|
|
157
|
+
};
|
|
158
|
+
const showErrorAlert = error && errorMessage;
|
|
159
|
+
return /* @__PURE__ */ jsxs(
|
|
160
|
+
"fieldset",
|
|
161
|
+
{
|
|
162
|
+
ref,
|
|
163
|
+
disabled,
|
|
164
|
+
className: `flex flex-col gap-space-2 border-none p-0 ${className ?? ""}`,
|
|
165
|
+
"aria-invalid": error || void 0,
|
|
166
|
+
"aria-describedby": showErrorAlert ? `${baseId}-error` : void 0,
|
|
167
|
+
children: [
|
|
168
|
+
(label || supportText) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-space-1", children: [
|
|
169
|
+
label && /* @__PURE__ */ jsxs(
|
|
170
|
+
"legend",
|
|
171
|
+
{
|
|
172
|
+
className: `text-form-label ${disabled ? "text-text-disabled" : "text-text-primary"}`,
|
|
173
|
+
children: [
|
|
174
|
+
label,
|
|
175
|
+
secondaryLabel && /* @__PURE__ */ jsx("span", { className: "ml-1 font-normal text-text-secondary", children: secondaryLabel }),
|
|
176
|
+
required && /* @__PURE__ */ jsx("span", { className: "ml-0.5 text-text-err", children: "*" })
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
),
|
|
180
|
+
supportText && /* @__PURE__ */ jsx(
|
|
181
|
+
"p",
|
|
182
|
+
{
|
|
183
|
+
className: `text-text-xs ${disabled ? "text-text-disabled" : "text-text-secondary"}`,
|
|
184
|
+
children: supportText
|
|
185
|
+
}
|
|
186
|
+
)
|
|
187
|
+
] }),
|
|
188
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-space-3", children: options.map((opt, index) => /* @__PURE__ */ jsx(
|
|
189
|
+
RadioItem,
|
|
190
|
+
{
|
|
191
|
+
id: `${baseId}-${index}`,
|
|
192
|
+
name,
|
|
193
|
+
value: opt.value,
|
|
194
|
+
checked: value === opt.value,
|
|
195
|
+
disabled: disabled || !!opt.disabled,
|
|
196
|
+
error,
|
|
197
|
+
showCheckIcon,
|
|
198
|
+
label: opt.label,
|
|
199
|
+
onChange: handleChange
|
|
200
|
+
},
|
|
201
|
+
opt.value
|
|
202
|
+
)) }),
|
|
203
|
+
showErrorAlert && /* @__PURE__ */ jsxs(
|
|
204
|
+
"div",
|
|
205
|
+
{
|
|
206
|
+
id: `${baseId}-error`,
|
|
207
|
+
role: "alert",
|
|
208
|
+
className: `flex items-start gap-space-4 rounded-rad-md p-space-4 ${disabled ? "bg-fill-bg-secondary" : "bg-fill-bg-err"}`,
|
|
209
|
+
children: [
|
|
210
|
+
/* @__PURE__ */ jsx(
|
|
211
|
+
ErrorIcon,
|
|
212
|
+
{
|
|
213
|
+
className: `h-5 w-5 shrink-0 ${disabled ? "text-icon-primary-disabled" : "text-icon-err"}`
|
|
214
|
+
}
|
|
215
|
+
),
|
|
216
|
+
/* @__PURE__ */ jsx(
|
|
217
|
+
"span",
|
|
218
|
+
{
|
|
219
|
+
className: `text-text-xs ${disabled ? "text-text-disabled" : "text-text-err"}`,
|
|
220
|
+
children: errorMessage
|
|
221
|
+
}
|
|
222
|
+
)
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
)
|
|
226
|
+
]
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
export {
|
|
231
|
+
RadioGroup
|
|
232
|
+
};
|
|
233
|
+
//# sourceMappingURL=RadioGroup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioGroup.js","sources":["../../../src/components/RadioGroup/RadioGroup.tsx"],"sourcesContent":["'use client';\n\nimport React, { useId } from 'react';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Shape of a single radio option. Pass an array of these to RadioGroup's options prop.\n */\nexport interface RadioOption {\n /** Value submitted when this option is selected. Must be unique in the group. */\n value: string;\n /** Label shown next to the radio. */\n label: string;\n /** When true, this option cannot be selected. @default undefined */\n disabled?: boolean;\n}\n\n/**\n * Props for the RadioGroup component. Single selection; value/onChange for controlled,\n * defaultValue for uncontrolled. value and onChange work together in controlled mode.\n */\nexport interface RadioGroupProps {\n /** Main label above the group (legend). @default undefined */\n label?: string;\n /** Secondary label shown lighter beside the main label. @default undefined */\n secondaryLabel?: string;\n /** Supportive text below the label. @default undefined */\n supportText?: string;\n /** Name for the radio group (each input gets name={name}). @default derived from id */\n name?: string;\n /** Controlled selected value (option value string). Use with onChange. @default undefined */\n value?: string;\n /** Uncontrolled default selected value. @default undefined */\n defaultValue?: string;\n /** Called when selection changes. Receives the selected option value. @default undefined */\n onChange?: (value: string) => void;\n /** Options to render. Each: value, label, disabled?. @see RadioOption */\n options: RadioOption[];\n /** Disables the entire group. @default false */\n disabled?: boolean;\n /** Shows error state and optional errorMessage. @default false */\n error?: boolean;\n /** Error message shown in the alert below the group when error is true. @default undefined */\n errorMessage?: string;\n /** Shows required asterisk next to the label. @default undefined */\n required?: boolean;\n /** When true, the selected option shows a trailing checkmark icon. @default false */\n showCheckIcon?: boolean;\n /** Additional class name on the wrapper. @default undefined */\n className?: string;\n /** ID for the group (used for generated input ids and aria-describedby). @default undefined */\n id?: string;\n /** Forwarded ref for the fieldset. @default undefined */\n ref?: React.Ref<HTMLFieldSetElement>;\n}\n\n// ---------------------------------------------------------------------------\n// Icons\n// ---------------------------------------------------------------------------\n\nfunction CheckIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n );\n}\n\nfunction ErrorIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Radio item (circle + label + optional check icon)\n// ---------------------------------------------------------------------------\n\ninterface RadioItemProps {\n name: string;\n value: string;\n checked: boolean;\n disabled: boolean;\n error: boolean;\n showCheckIcon: boolean;\n label: string;\n id: string;\n onChange: (value: string) => void;\n}\n\nfunction RadioItem({\n name,\n value,\n checked,\n disabled,\n error,\n showCheckIcon,\n label,\n id,\n onChange,\n}: RadioItemProps) {\n const unselectedCircle = [\n 'pointer-events-none absolute inset-0 rounded-rad-rounded transition-all duration-150 border-solid border-[1.25px]',\n !disabled && !error && 'border-border-form-primary bg-fill-form-primary',\n !disabled && !error && 'group-hover:border-[1.5px] group-hover:border-border-form-primary-hover',\n !disabled && !error && 'group-active:border-[1.5px] group-active:border-border-form-primary-active',\n !disabled && error && 'border-border-err bg-fill-form-primary',\n !disabled && error && 'group-hover:border-[1.5px]',\n disabled && 'border-border-form-primary-disabled bg-fill-form-primary-disabled',\n ].filter(Boolean).join(' ');\n\n const selectedCircle = [\n 'pointer-events-none absolute inset-0 rounded-rad-rounded transition-all duration-150',\n !disabled && !error && 'bg-fill-action-primary',\n !disabled && !error && 'group-hover:bg-fill-action-primary-hover',\n !disabled && !error && 'group-active:bg-fill-action-primary-active',\n !disabled && error && 'bg-fill-action-primary',\n disabled && 'bg-fill-action-primary-disabled',\n ].filter(Boolean).join(' ');\n\n return (\n <label\n htmlFor={id}\n className={`group flex items-center gap-space-3 ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`}\n >\n <span className=\"relative flex h-6 w-6 shrink-0 items-center justify-center\">\n <input\n type=\"radio\"\n id={id}\n name={name}\n value={value}\n checked={checked}\n disabled={disabled}\n onChange={() => onChange(value)}\n className=\"peer sr-only\"\n aria-invalid={error || undefined}\n />\n {checked ? (\n <>\n <span className={selectedCircle} />\n <svg\n className=\"pointer-events-none relative h-3 w-3 shrink-0\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"white\" />\n </svg>\n </>\n ) : (\n <span className={unselectedCircle} />\n )}\n <span\n className=\"pointer-events-none absolute rounded-rad-rounded border-[1.5px] border-border-focus border-solid opacity-0 peer-focus-visible:opacity-100 -inset-1\"\n aria-hidden=\"true\"\n />\n </span>\n <span\n className={`flex-1 text-form-text ${\n disabled ? 'text-text-disabled' : 'text-text-primary'\n }`}\n >\n {label}\n </span>\n {showCheckIcon && checked && (\n <span\n className={`flex h-6 w-6 shrink-0 items-center justify-center rounded-full ${\n disabled ? 'bg-neutral-300 text-neutral-500' : 'bg-green-900 text-neutral-0'\n }`}\n aria-hidden=\"true\"\n >\n <CheckIcon className=\"h-3.5 w-3.5\" />\n </span>\n )}\n </label>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Single-selection radio group with label, support text, and optional error state.\n * Renders a fieldset with design-token styling. Use for one-of-many choices (e.g. delivery\n * method, plan). For multi-select use CheckboxGroup. value/onChange for controlled mode.\n *\n * @example\n * <RadioGroup label=\"Plan\" options={[{ value: 'a', label: 'Plan A' }]} onChange={setValue} />\n *\n * @example\n * <RadioGroup label=\"Option\" value={selected} onChange={setSelected} options={opts} showCheckIcon error errorMessage=\"Required\" />\n */\nexport function RadioGroup({\n label,\n secondaryLabel,\n supportText,\n name: nameProp,\n value: valueProp,\n defaultValue,\n onChange,\n options,\n disabled = false,\n error = false,\n errorMessage,\n required,\n showCheckIcon = false,\n className,\n id: idProp,\n ref,\n}: RadioGroupProps) {\n const autoId = useId();\n const baseId = idProp ?? autoId;\n const name = nameProp ?? baseId;\n\n const isControlled = valueProp !== undefined;\n const [internal, setInternal] = React.useState(defaultValue ?? '');\n const value = isControlled ? valueProp : internal;\n\n const handleChange = (v: string) => {\n if (!isControlled) setInternal(v);\n onChange?.(v);\n };\n\n const showErrorAlert = error && errorMessage;\n\n return (\n <fieldset\n ref={ref}\n disabled={disabled}\n className={`flex flex-col gap-space-2 border-none p-0 ${className ?? ''}`}\n aria-invalid={error || undefined}\n aria-describedby={showErrorAlert ? `${baseId}-error` : undefined}\n >\n {/* Label + support text */}\n {(label || supportText) && (\n <div className=\"flex flex-col gap-space-1\">\n {label && (\n <legend\n className={`text-form-label ${\n disabled ? 'text-text-disabled' : 'text-text-primary'\n }`}\n >\n {label}\n {secondaryLabel && (\n <span className=\"ml-1 font-normal text-text-secondary\">\n {secondaryLabel}\n </span>\n )}\n {required && (\n <span className=\"ml-0.5 text-text-err\">*</span>\n )}\n </legend>\n )}\n {supportText && (\n <p\n className={`text-text-xs ${\n disabled ? 'text-text-disabled' : 'text-text-secondary'\n }`}\n >\n {supportText}\n </p>\n )}\n </div>\n )}\n\n {/* Options */}\n <div className=\"flex flex-col gap-space-3\">\n {options.map((opt, index) => (\n <RadioItem\n key={opt.value}\n id={`${baseId}-${index}`}\n name={name}\n value={opt.value}\n checked={value === opt.value}\n disabled={disabled || !!opt.disabled}\n error={error}\n showCheckIcon={showCheckIcon}\n label={opt.label}\n onChange={handleChange}\n />\n ))}\n </div>\n\n {/* Error alert */}\n {showErrorAlert && (\n <div\n id={`${baseId}-error`}\n role=\"alert\"\n className={`flex items-start gap-space-4 rounded-rad-md p-space-4 ${\n disabled ? 'bg-fill-bg-secondary' : 'bg-fill-bg-err'\n }`}\n >\n <ErrorIcon\n className={`h-5 w-5 shrink-0 ${\n disabled ? 'text-icon-primary-disabled' : 'text-icon-err'\n }`}\n />\n <span\n className={`text-text-xs ${\n disabled ? 'text-text-disabled' : 'text-text-err'\n }`}\n >\n {errorMessage}\n </span>\n </div>\n )}\n </fieldset>\n );\n}\n"],"names":[],"mappings":";;;AA+DA;AACE;AACE;AAAC;AAAA;AACC;AACQ;AACH;AACE;AACK;AACE;AACC;AACH;AAEc;AAAA;AAGhC;AAEA;AACE;AACE;AAAC;AAAA;AACC;AACQ;AACH;AACO;AAEZ;AAAC;AAAA;AACU;AACP;AACO;AAAA;AAAA;AACX;AAGN;AAkBA;AAAmB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEF;AACE;AAAyB;AACvB;AACuB;AACA;AACA;AACD;AACA;AACV;AAGd;AAAuB;AACrB;AACuB;AACA;AACA;AACD;AACV;AAGd;AACE;AAAC;AAAA;AACU;AAC2F;AAEpG;AACE;AAAA;AAAC;AAAA;AACM;AACL;AACA;AACA;AACA;AACA;AAC8B;AACpB;AACa;AAAA;AAAA;AAIrB;AAAiC;AACjC;AAAC;AAAA;AACW;AACJ;AACC;AACC;AACH;AACO;AAE6B;AAAA;AAAA;AAIV;AAErC;AAAC;AAAA;AACW;AACE;AAAA;AAAA;AAEhB;AACA;AAAC;AAAA;AAGC;AAEC;AAAA;AAAA;AAGD;AAAC;AAAA;AAGC;AACY;AAEuB;AAAA;AAAA;AACrC;AAAA;AAIR;AAiBO;AAAoB;AACzB;AACA;AACA;AACM;AACC;AACP;AACA;AACA;AACW;AACH;AACR;AACA;AACgB;AAChB;AACI;AAEN;AACE;AACA;AACA;AAEA;AACA;AACA;AAEA;AACE;AACA;AAAW;AAGb;AAEA;AACE;AAAC;AAAA;AACC;AACA;AACuE;AAChD;AACgC;AAGrD;AAEG;AACC;AAAC;AAAA;AAGC;AAEC;AAAA;AAIC;AAGwC;AAAA;AAAA;AAAA;AAK5C;AAAC;AAAA;AAGC;AAEC;AAAA;AAAA;AAGP;AAME;AAAC;AAAA;AAEuB;AACtB;AACW;AACY;AACK;AAC5B;AACA;AACW;AACD;AAAA;AATD;AAYf;AAIE;AAAC;AAAA;AACc;AACR;AAGL;AAEA;AAAA;AAAC;AAAA;AAGC;AAAA;AAAA;AAEF;AAAC;AAAA;AAGC;AAEC;AAAA;AAAA;AACH;AAAA;AAAA;AACF;AAAA;AAIR;;;;"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { SystemProps } from '../../utils/responsive-props';
|
|
3
|
+
/**
|
|
4
|
+
* Vertical padding preset for Section. Controls top/bottom padding at base and lg (940px) breakpoint.
|
|
5
|
+
* Overridden when py or pt/pb are provided via system props.
|
|
6
|
+
*/
|
|
7
|
+
export type SectionSize = 'sm' | 'md' | 'lg' | 'xl';
|
|
8
|
+
/**
|
|
9
|
+
* Props for the Section component. Extends system props (responsive spacing, etc.).
|
|
10
|
+
* size applies vertical padding presets unless py/pt/pb are set.
|
|
11
|
+
*/
|
|
12
|
+
export interface SectionProps extends Omit<React.HTMLAttributes<HTMLElement>, 'display'>, SystemProps {
|
|
13
|
+
/**
|
|
14
|
+
* Vertical padding preset. Ignored when py or pt/pb are provided.
|
|
15
|
+
* - 'sm' — base: space-4, lg: space-6
|
|
16
|
+
* - 'md' — base: space-6, lg: space-9
|
|
17
|
+
* - 'lg' — base: space-9, lg: space-16
|
|
18
|
+
* - 'xl' — base: space-16, lg: space-24
|
|
19
|
+
* @default undefined
|
|
20
|
+
*/
|
|
21
|
+
size?: SectionSize;
|
|
22
|
+
/** Forwarded ref for the section element. @default undefined */
|
|
23
|
+
ref?: React.Ref<HTMLElement>;
|
|
24
|
+
/** Section content. @default undefined */
|
|
25
|
+
children?: React.ReactNode;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Semantic section element with optional vertical padding presets (size) and full
|
|
29
|
+
* system props. Use as the wrapper for each major page block; combine with
|
|
30
|
+
* Container for width and gutters. Do not nest Section for inner layout — use Box or Stack.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* <Section size="lg">
|
|
34
|
+
* <Container>Page content</Container>
|
|
35
|
+
* </Section>
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* <Section size="md" py={{ base: 'space-8', xl: 'space-16' }}>Custom spacing</Section>
|
|
39
|
+
*/
|
|
40
|
+
export declare function Section({ size, children, className, style, ref, ...allRest }: SectionProps): import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
export declare namespace Section {
|
|
42
|
+
var displayName: string;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=Section.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Section.d.ts","sourceRoot":"","sources":["../../../src/components/Section/Section.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAC;AAEtC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEpD;;;GAGG;AACH,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC,EAAE,WAAW;IACnG;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,gEAAgE;IAChE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AASD;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAc,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,EAAE,YAAY,2CAiD/F;yBAjDe,OAAO"}
|