@puzzle-ui/ui 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -76
- package/dist/components/data-display/badge/index.cjs +1 -1
- package/dist/components/data-display/badge/index.cjs.map +1 -1
- package/dist/components/data-display/badge/index.js +1 -1
- package/dist/components/data-display/badge/index.js.map +1 -1
- package/dist/components/layout/grid/grid.css +63 -0
- package/dist/components/layout/grid/index.cjs +65 -0
- package/dist/components/layout/grid/index.cjs.map +1 -0
- package/dist/components/layout/grid/index.d.cts +38 -0
- package/dist/components/layout/grid/index.d.ts +38 -0
- package/dist/components/layout/grid/index.js +64 -0
- package/dist/components/layout/grid/index.js.map +1 -0
- package/dist/components/navigation/tree-view/index.cjs +1 -1
- package/dist/components/navigation/tree-view/index.cjs.map +1 -1
- package/dist/components/navigation/tree-view/index.d.cts +5 -1
- package/dist/components/navigation/tree-view/index.d.ts +5 -1
- package/dist/components/navigation/tree-view/index.js +1 -1
- package/dist/components/navigation/tree-view/index.js.map +1 -1
- package/dist/components/navigation/tree-view/tree-view.css +5 -3
- package/dist/index.cjs +76 -73
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -1,98 +1,82 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @puzzle-ui/ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Composable, token-driven React components for building React interfaces with Puzzle.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
>
|
|
7
|
-
> This project is under active development. APIs, component props,
|
|
8
|
-
> package exports, styling, and internal implementation may change
|
|
9
|
-
> without notice. Components may be incomplete, and testing,
|
|
10
|
-
> accessibility, documentation, and framework compatibility are not yet
|
|
11
|
-
> guaranteed. Use it for experimentation and evaluation only---not for
|
|
12
|
-
> production applications.
|
|
5
|
+
**Documentation:** [https://puzzle-ui.com/docs/ui](https://puzzle-ui.com/docs/ui)
|
|
13
6
|
|
|
14
|
-
|
|
7
|
+
Component API maturity is listed on each component's documentation page.
|
|
8
|
+
Paper, Skeleton, Label, Background, Breadcrumbs, Sidebar, and Backdrop are
|
|
9
|
+
Experimental because their current validation evidence is limited. Review
|
|
10
|
+
documented accessibility and framework details when integrating components.
|
|
15
11
|
|
|
16
|
-
|
|
12
|
+
`@puzzle-ui/ui` provides composable, router-independent React components:
|
|
13
|
+
actions, data display, editors, forms, layout, navigation, overlays,
|
|
14
|
+
typography, and utilities. Components use semantic HTML and native browser
|
|
15
|
+
behavior first, and all styling comes from the CSS custom properties supplied
|
|
16
|
+
by [`@puzzle-ui/theme`](https://puzzle-ui.com/docs/theme), so one `Theme`
|
|
17
|
+
provider styles your whole application.
|
|
17
18
|
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
- A package manager: npm, Bun, pnpm, or Yarn.
|
|
21
|
-
- An existing React application with a bundler that supports CSS imports, such as Vite.
|
|
22
|
-
- Familiarity with React and TypeScript. The UI and theme packages require React and React DOM 19 or later within the supported React 19 range.
|
|
23
|
-
|
|
24
|
-
## Set up a new project
|
|
25
|
-
|
|
26
|
-
Simple run our @puzzle-ui/create project template to get started.
|
|
27
|
-
|
|
28
|
-
npm:
|
|
19
|
+
## Install
|
|
29
20
|
|
|
30
21
|
```bash
|
|
31
|
-
|
|
22
|
+
npm install @puzzle-ui/ui @puzzle-ui/theme
|
|
23
|
+
# or
|
|
24
|
+
bun add @puzzle-ui/ui @puzzle-ui/theme
|
|
25
|
+
# or
|
|
26
|
+
pnpm add @puzzle-ui/ui @puzzle-ui/theme
|
|
27
|
+
# or
|
|
28
|
+
yarn add @puzzle-ui/ui @puzzle-ui/theme
|
|
32
29
|
```
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
bunx @puzzle-ui/create
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Puzzle can set up a new project for you with the following framework options:
|
|
41
|
-
|
|
42
|
-
- Basic React app
|
|
43
|
-
- Tanstack start
|
|
44
|
-
- Next.js
|
|
31
|
+
React and React DOM 19 are peer dependencies and should already be installed
|
|
32
|
+
in your application.
|
|
45
33
|
|
|
46
|
-
|
|
47
|
-
|
|
34
|
+
To start a new project with Puzzle preconfigured, run
|
|
35
|
+
[`npx @puzzle-ui/create`](https://puzzle-ui.com/docs/create).
|
|
48
36
|
|
|
49
|
-
##
|
|
37
|
+
## Usage
|
|
50
38
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
npm:
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
npm install @puzzle-ui/ui --save
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
bun:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
bun add @puzzle-ui/create
|
|
63
|
-
```
|
|
39
|
+
Wrap your application in `Theme` and import components from `@puzzle-ui/ui`:
|
|
64
40
|
|
|
65
|
-
|
|
41
|
+
```tsx
|
|
42
|
+
import { Theme } from "@puzzle-ui/theme";
|
|
43
|
+
import { Button, Stack, Text } from "@puzzle-ui/ui";
|
|
66
44
|
|
|
67
|
-
|
|
68
|
-
|
|
45
|
+
export const App = () => (
|
|
46
|
+
<Theme>
|
|
47
|
+
<Stack direction="col" gap="sm">
|
|
48
|
+
<Text>Build your interface with Puzzle.</Text>
|
|
49
|
+
<Button>Get started</Button>
|
|
50
|
+
</Stack>
|
|
51
|
+
</Theme>
|
|
52
|
+
);
|
|
69
53
|
```
|
|
70
54
|
|
|
71
|
-
|
|
55
|
+
## Component categories
|
|
72
56
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
57
|
+
| Category | Components |
|
|
58
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------- |
|
|
59
|
+
| Actions | Button, ButtonGroup, ToggleGroup |
|
|
60
|
+
| Data display | Alert, Avatar, Badge, Card, EmptyState, Image, Paper, Progress, Rating, Skeleton |
|
|
61
|
+
| Editors | TextEditor, TextEditorToolbar, TextRenderer |
|
|
62
|
+
| Forms | Autocomplete, Checkbox, ColorPicker, DatePicker, FileUpload, FormField, inputs, Radio, Select, Slider, Switch |
|
|
63
|
+
| Layout | AppBar, AspectRatio, Container, Grid, GridItem, PageLayout, ResizablePanels, ScrollArea, Section, Separator, Sidebar, Stack |
|
|
64
|
+
| Navigation | Accordion, Breadcrumbs, Carousel, Link, Pagination, Tabs, TreeView |
|
|
65
|
+
| Overlays | Command, ContextMenu, Dialog, Drawer, DropdownMenu, Notification, Popover, Tooltip |
|
|
66
|
+
| Typography | Heading, Text |
|
|
67
|
+
| Utilities | Portal, Preview, ScrollLock, Transition |
|
|
76
68
|
|
|
77
|
-
|
|
69
|
+
Browse every component with live examples, props, and accessibility guidance
|
|
70
|
+
in the [component documentation](https://puzzle-ui.com/docs/ui).
|
|
78
71
|
|
|
79
|
-
##
|
|
72
|
+
## Framework integration
|
|
80
73
|
|
|
81
|
-
|
|
74
|
+
Components do not depend on a router or framework. Use the `components`
|
|
75
|
+
prop of `Theme` to provide your framework's link and image components; see
|
|
76
|
+
[Component Overrides](https://puzzle-ui.com/docs/theme/components).
|
|
82
77
|
|
|
83
|
-
|
|
84
|
-
import { Theme } from "@puzzle-ui/theme";
|
|
85
|
-
import { Button } from "@puzzle-ui/ui";
|
|
78
|
+
## Related packages
|
|
86
79
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
<h1>Hello, Puzzle</h1>
|
|
91
|
-
<p>Build your interface with reusable components and shared tokens.</p>
|
|
92
|
-
<Button onClick={() => window.alert("Welcome to Puzzle!")}>
|
|
93
|
-
Get started
|
|
94
|
-
</Button>
|
|
95
|
-
</main>
|
|
96
|
-
</Theme>
|
|
97
|
-
);
|
|
98
|
-
```
|
|
80
|
+
- [`@puzzle-ui/theme`](https://puzzle-ui.com/docs/theme) — design tokens and the `Theme` provider.
|
|
81
|
+
- [`@puzzle-ui/icons`](https://puzzle-ui.com/docs/icons) — icon components.
|
|
82
|
+
- [`@puzzle-ui/hooks`](https://puzzle-ui.com/docs/hooks) — reusable React hooks.
|
|
@@ -21,7 +21,7 @@ const Badge = ({ content, size = 20, color = "primary", anchorOrigin = {
|
|
|
21
21
|
anchorOrigin.horizontal,
|
|
22
22
|
anchorOverlap
|
|
23
23
|
], children == null && "puzzle-badge-standalone", !isHex && `puzzle-badge-${color}`, className);
|
|
24
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
24
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(children == null ? "span" : "div", {
|
|
25
25
|
className: classes,
|
|
26
26
|
children: [children, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
27
27
|
className: (0, _puzzle_ui_core.cn)("puzzle-badge-indicator", isSingleCharacter && "puzzle-badge-indicator--single"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["isHexColor","isDarkColor","cn"],"sources":["../../../../src/components/data-display/badge/index.tsx"],"sourcesContent":["import { cn, isDarkColor, isHexColor } from \"@puzzle-ui/core\";\nimport { type ReactNode } from \"react\";\nimport \"./badge.css\";\n\ntype AnchorOrigin = {\n vertical: \"top\" | \"bottom\";\n horizontal: \"left\" | \"right\";\n};\n\ntype AnchorOffset = {\n vertical: number;\n horizontal: number;\n};\n\ntype AnchorOverlap = \"rectangular\" | \"circular\";\ntype BadgeColor =\n | \"primary\"\n | \"secondary\"\n | \"accent\"\n | \"danger\"\n | \"info\"\n | `#${string}`;\n\ntype BadgeProps = {\n content: ReactNode;\n size?: number;\n color?: BadgeColor;\n anchorOrigin?: AnchorOrigin;\n anchorOffset?: AnchorOffset;\n anchorOverlap?: AnchorOverlap;\n className?: string;\n children?: ReactNode;\n};\n\nconst Badge = ({\n content,\n size = 20,\n color = \"primary\",\n anchorOrigin = { vertical: \"top\", horizontal: \"right\" },\n anchorOffset = { vertical: 0, horizontal: 0 },\n anchorOverlap = \"rectangular\",\n className,\n children,\n}: BadgeProps) => {\n if (!Number.isFinite(anchorOffset.vertical) || !Number.isFinite(anchorOffset.horizontal)) {\n throw new TypeError(\"Badge anchorOffset values must be finite numbers.\");\n }\n\n const resolvedSize = Math.max(size, 16);\n const isHex = isHexColor(color);\n const isDark = isHex ? isDarkColor(color) : false;\n\n const textContent =\n typeof content === \"string\" || typeof content === \"number\"\n ? String(content).trim()\n : null;\n const isSingleCharacter =\n textContent != null && Array.from(textContent).length === 1;\n\n const classes = cn(\n \"puzzle-badge\",\n children != null && [\n anchorOrigin.vertical,\n anchorOrigin.horizontal,\n anchorOverlap,\n ],\n children == null && \"puzzle-badge-standalone\",\n !isHex && `puzzle-badge-${color}`,\n className,\n );\n\n return (\n <
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["isHexColor","isDarkColor","cn"],"sources":["../../../../src/components/data-display/badge/index.tsx"],"sourcesContent":["import { cn, isDarkColor, isHexColor } from \"@puzzle-ui/core\";\nimport { type ReactNode } from \"react\";\nimport \"./badge.css\";\n\ntype AnchorOrigin = {\n vertical: \"top\" | \"bottom\";\n horizontal: \"left\" | \"right\";\n};\n\ntype AnchorOffset = {\n vertical: number;\n horizontal: number;\n};\n\ntype AnchorOverlap = \"rectangular\" | \"circular\";\ntype BadgeColor =\n | \"primary\"\n | \"secondary\"\n | \"accent\"\n | \"danger\"\n | \"info\"\n | `#${string}`;\n\ntype BadgeProps = {\n content: ReactNode;\n size?: number;\n color?: BadgeColor;\n anchorOrigin?: AnchorOrigin;\n anchorOffset?: AnchorOffset;\n anchorOverlap?: AnchorOverlap;\n className?: string;\n children?: ReactNode;\n};\n\nconst Badge = ({\n content,\n size = 20,\n color = \"primary\",\n anchorOrigin = { vertical: \"top\", horizontal: \"right\" },\n anchorOffset = { vertical: 0, horizontal: 0 },\n anchorOverlap = \"rectangular\",\n className,\n children,\n}: BadgeProps) => {\n if (!Number.isFinite(anchorOffset.vertical) || !Number.isFinite(anchorOffset.horizontal)) {\n throw new TypeError(\"Badge anchorOffset values must be finite numbers.\");\n }\n\n const resolvedSize = Math.max(size, 16);\n const isHex = isHexColor(color);\n const isDark = isHex ? isDarkColor(color) : false;\n\n const textContent =\n typeof content === \"string\" || typeof content === \"number\"\n ? String(content).trim()\n : null;\n const isSingleCharacter =\n textContent != null && Array.from(textContent).length === 1;\n\n const classes = cn(\n \"puzzle-badge\",\n children != null && [\n anchorOrigin.vertical,\n anchorOrigin.horizontal,\n anchorOverlap,\n ],\n children == null && \"puzzle-badge-standalone\",\n !isHex && `puzzle-badge-${color}`,\n className,\n );\n\n const Component = children == null ? \"span\" : \"div\";\n\n return (\n <Component className={classes}>\n {children}\n <span\n className={cn(\n \"puzzle-badge-indicator\",\n isSingleCharacter && \"puzzle-badge-indicator--single\",\n )}\n style={{\n fontSize: `clamp(0.7rem, calc(${resolvedSize}px - 1em), 4rem)`,\n minHeight: `${resolvedSize}px`,\n minWidth: `${resolvedSize}px`,\n translate: children != null\n ? `${anchorOffset.horizontal * (anchorOrigin.horizontal === \"left\" ? 1 : -1)}px ${anchorOffset.vertical * (anchorOrigin.vertical === \"top\" ? 1 : -1)}px`\n : undefined,\n backgroundColor: isHex ? color : undefined,\n color: isHex\n ? isDark\n ? \"var(--puzzle-color-light-foreground)\"\n : \"var(--puzzle-color-dark-foreground)\"\n : undefined,\n }}\n >\n {content}\n </span>\n </Component>\n );\n};\n\nexport {\n Badge,\n type BadgeProps,\n type BadgeColor,\n type AnchorOrigin,\n type AnchorOffset,\n type AnchorOverlap,\n};\n"],"mappings":";;;;;AAkCA,MAAM,SAAS,EACb,SACA,OAAO,IACP,QAAQ,WACR,eAAe;CAAE,UAAU;CAAO,YAAY;AAAQ,GACtD,eAAe;CAAE,UAAU;CAAG,YAAY;AAAE,GAC5C,gBAAgB,eAChB,WACA,eACgB;CAChB,IAAI,CAAC,OAAO,SAAS,aAAa,QAAQ,KAAK,CAAC,OAAO,SAAS,aAAa,UAAU,GACrF,MAAM,IAAI,UAAU,mDAAmD;CAGzE,MAAM,eAAe,KAAK,IAAI,MAAM,EAAE;CACtC,MAAM,SAAA,GAAQA,gBAAAA,WAAAA,CAAW,KAAK;CAC9B,MAAM,SAAS,SAAA,GAAQC,gBAAAA,YAAAA,CAAY,KAAK,IAAI;CAE5C,MAAM,cACJ,OAAO,YAAY,YAAY,OAAO,YAAY,WAC9C,OAAO,OAAO,CAAC,CAAC,KAAK,IACrB;CACN,MAAM,oBACJ,eAAe,QAAQ,MAAM,KAAK,WAAW,CAAC,CAAC,WAAW;CAE5D,MAAM,WAAA,GAAUC,gBAAAA,GAAAA,CACd,gBACA,YAAY,QAAQ;EAClB,aAAa;EACb,aAAa;EACb;CACF,GACA,YAAY,QAAQ,2BACpB,CAAC,SAAS,gBAAgB,SAC1B,SACF;CAIA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAHgB,YAAY,OAAO,SAAS,OAG5C;EAAW,WAAW;EAAtB,UAAA,CACG,UACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;GACE,YAAA,GAAWA,gBAAAA,GAAAA,CACT,0BACA,qBAAqB,gCACvB;GACA,OAAO;IACL,UAAU,sBAAsB,aAAa;IAC7C,WAAW,GAAG,aAAa;IAC3B,UAAU,GAAG,aAAa;IAC1B,WAAW,YAAY,OACnB,GAAG,aAAa,cAAc,aAAa,eAAe,SAAS,IAAI,IAAI,KAAK,aAAa,YAAY,aAAa,aAAa,QAAQ,IAAI,IAAI,MACnJ,KAAA;IACJ,iBAAiB,QAAQ,QAAQ,KAAA;IACjC,OAAO,QACH,SACE,yCACA,wCACF,KAAA;GACN;GAEC,UAAA;EACG,CAAA,CACG;;AAEf"}
|
|
@@ -21,7 +21,7 @@ const Badge = ({ content, size = 20, color = "primary", anchorOrigin = {
|
|
|
21
21
|
anchorOrigin.horizontal,
|
|
22
22
|
anchorOverlap
|
|
23
23
|
], children == null && "puzzle-badge-standalone", !isHex && `puzzle-badge-${color}`, className);
|
|
24
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
24
|
+
return /* @__PURE__ */ jsxs(children == null ? "span" : "div", {
|
|
25
25
|
className: classes,
|
|
26
26
|
children: [children, /* @__PURE__ */ jsx("span", {
|
|
27
27
|
className: cn("puzzle-badge-indicator", isSingleCharacter && "puzzle-badge-indicator--single"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/data-display/badge/index.tsx"],"sourcesContent":["import { cn, isDarkColor, isHexColor } from \"@puzzle-ui/core\";\nimport { type ReactNode } from \"react\";\nimport \"./badge.css\";\n\ntype AnchorOrigin = {\n vertical: \"top\" | \"bottom\";\n horizontal: \"left\" | \"right\";\n};\n\ntype AnchorOffset = {\n vertical: number;\n horizontal: number;\n};\n\ntype AnchorOverlap = \"rectangular\" | \"circular\";\ntype BadgeColor =\n | \"primary\"\n | \"secondary\"\n | \"accent\"\n | \"danger\"\n | \"info\"\n | `#${string}`;\n\ntype BadgeProps = {\n content: ReactNode;\n size?: number;\n color?: BadgeColor;\n anchorOrigin?: AnchorOrigin;\n anchorOffset?: AnchorOffset;\n anchorOverlap?: AnchorOverlap;\n className?: string;\n children?: ReactNode;\n};\n\nconst Badge = ({\n content,\n size = 20,\n color = \"primary\",\n anchorOrigin = { vertical: \"top\", horizontal: \"right\" },\n anchorOffset = { vertical: 0, horizontal: 0 },\n anchorOverlap = \"rectangular\",\n className,\n children,\n}: BadgeProps) => {\n if (!Number.isFinite(anchorOffset.vertical) || !Number.isFinite(anchorOffset.horizontal)) {\n throw new TypeError(\"Badge anchorOffset values must be finite numbers.\");\n }\n\n const resolvedSize = Math.max(size, 16);\n const isHex = isHexColor(color);\n const isDark = isHex ? isDarkColor(color) : false;\n\n const textContent =\n typeof content === \"string\" || typeof content === \"number\"\n ? String(content).trim()\n : null;\n const isSingleCharacter =\n textContent != null && Array.from(textContent).length === 1;\n\n const classes = cn(\n \"puzzle-badge\",\n children != null && [\n anchorOrigin.vertical,\n anchorOrigin.horizontal,\n anchorOverlap,\n ],\n children == null && \"puzzle-badge-standalone\",\n !isHex && `puzzle-badge-${color}`,\n className,\n );\n\n return (\n <
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/data-display/badge/index.tsx"],"sourcesContent":["import { cn, isDarkColor, isHexColor } from \"@puzzle-ui/core\";\nimport { type ReactNode } from \"react\";\nimport \"./badge.css\";\n\ntype AnchorOrigin = {\n vertical: \"top\" | \"bottom\";\n horizontal: \"left\" | \"right\";\n};\n\ntype AnchorOffset = {\n vertical: number;\n horizontal: number;\n};\n\ntype AnchorOverlap = \"rectangular\" | \"circular\";\ntype BadgeColor =\n | \"primary\"\n | \"secondary\"\n | \"accent\"\n | \"danger\"\n | \"info\"\n | `#${string}`;\n\ntype BadgeProps = {\n content: ReactNode;\n size?: number;\n color?: BadgeColor;\n anchorOrigin?: AnchorOrigin;\n anchorOffset?: AnchorOffset;\n anchorOverlap?: AnchorOverlap;\n className?: string;\n children?: ReactNode;\n};\n\nconst Badge = ({\n content,\n size = 20,\n color = \"primary\",\n anchorOrigin = { vertical: \"top\", horizontal: \"right\" },\n anchorOffset = { vertical: 0, horizontal: 0 },\n anchorOverlap = \"rectangular\",\n className,\n children,\n}: BadgeProps) => {\n if (!Number.isFinite(anchorOffset.vertical) || !Number.isFinite(anchorOffset.horizontal)) {\n throw new TypeError(\"Badge anchorOffset values must be finite numbers.\");\n }\n\n const resolvedSize = Math.max(size, 16);\n const isHex = isHexColor(color);\n const isDark = isHex ? isDarkColor(color) : false;\n\n const textContent =\n typeof content === \"string\" || typeof content === \"number\"\n ? String(content).trim()\n : null;\n const isSingleCharacter =\n textContent != null && Array.from(textContent).length === 1;\n\n const classes = cn(\n \"puzzle-badge\",\n children != null && [\n anchorOrigin.vertical,\n anchorOrigin.horizontal,\n anchorOverlap,\n ],\n children == null && \"puzzle-badge-standalone\",\n !isHex && `puzzle-badge-${color}`,\n className,\n );\n\n const Component = children == null ? \"span\" : \"div\";\n\n return (\n <Component className={classes}>\n {children}\n <span\n className={cn(\n \"puzzle-badge-indicator\",\n isSingleCharacter && \"puzzle-badge-indicator--single\",\n )}\n style={{\n fontSize: `clamp(0.7rem, calc(${resolvedSize}px - 1em), 4rem)`,\n minHeight: `${resolvedSize}px`,\n minWidth: `${resolvedSize}px`,\n translate: children != null\n ? `${anchorOffset.horizontal * (anchorOrigin.horizontal === \"left\" ? 1 : -1)}px ${anchorOffset.vertical * (anchorOrigin.vertical === \"top\" ? 1 : -1)}px`\n : undefined,\n backgroundColor: isHex ? color : undefined,\n color: isHex\n ? isDark\n ? \"var(--puzzle-color-light-foreground)\"\n : \"var(--puzzle-color-dark-foreground)\"\n : undefined,\n }}\n >\n {content}\n </span>\n </Component>\n );\n};\n\nexport {\n Badge,\n type BadgeProps,\n type BadgeColor,\n type AnchorOrigin,\n type AnchorOffset,\n type AnchorOverlap,\n};\n"],"mappings":";;;;;AAkCA,MAAM,SAAS,EACb,SACA,OAAO,IACP,QAAQ,WACR,eAAe;CAAE,UAAU;CAAO,YAAY;AAAQ,GACtD,eAAe;CAAE,UAAU;CAAG,YAAY;AAAE,GAC5C,gBAAgB,eAChB,WACA,eACgB;CAChB,IAAI,CAAC,OAAO,SAAS,aAAa,QAAQ,KAAK,CAAC,OAAO,SAAS,aAAa,UAAU,GACrF,MAAM,IAAI,UAAU,mDAAmD;CAGzE,MAAM,eAAe,KAAK,IAAI,MAAM,EAAE;CACtC,MAAM,QAAQ,WAAW,KAAK;CAC9B,MAAM,SAAS,QAAQ,YAAY,KAAK,IAAI;CAE5C,MAAM,cACJ,OAAO,YAAY,YAAY,OAAO,YAAY,WAC9C,OAAO,OAAO,CAAC,CAAC,KAAK,IACrB;CACN,MAAM,oBACJ,eAAe,QAAQ,MAAM,KAAK,WAAW,CAAC,CAAC,WAAW;CAE5D,MAAM,UAAU,GACd,gBACA,YAAY,QAAQ;EAClB,aAAa;EACb,aAAa;EACb;CACF,GACA,YAAY,QAAQ,2BACpB,CAAC,SAAS,gBAAgB,SAC1B,SACF;CAIA,OACE,qBAHgB,YAAY,OAAO,SAAS,OAG5C;EAAW,WAAW;EAAtB,UAAA,CACG,UACD,oBAAC,QAAD;GACE,WAAW,GACT,0BACA,qBAAqB,gCACvB;GACA,OAAO;IACL,UAAU,sBAAsB,aAAa;IAC7C,WAAW,GAAG,aAAa;IAC3B,UAAU,GAAG,aAAa;IAC1B,WAAW,YAAY,OACnB,GAAG,aAAa,cAAc,aAAa,eAAe,SAAS,IAAI,IAAI,KAAK,aAAa,YAAY,aAAa,aAAa,QAAQ,IAAI,IAAI,MACnJ,KAAA;IACJ,iBAAiB,QAAQ,QAAQ,KAAA;IACjC,OAAO,QACH,SACE,yCACA,wCACF,KAAA;GACN;GAEC,UAAA;EACG,CAAA,CACG;;AAEf"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
.puzzle-grid {
|
|
2
|
+
grid-template-columns: var(--puzzle-grid-columns-mobile);
|
|
3
|
+
grid-template-rows: var(--puzzle-grid-rows-mobile);
|
|
4
|
+
row-gap: var(--puzzle-grid-row-gap-mobile);
|
|
5
|
+
column-gap: var(--puzzle-grid-column-gap-mobile);
|
|
6
|
+
justify-items: var(--puzzle-grid-align-h-mobile);
|
|
7
|
+
align-items: var(--puzzle-grid-align-v-mobile);
|
|
8
|
+
grid-auto-flow: var(--puzzle-grid-auto-flow-mobile);
|
|
9
|
+
min-width: 0;
|
|
10
|
+
display: grid;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.puzzle-grid > * {
|
|
14
|
+
min-width: 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.puzzle-grid-item {
|
|
18
|
+
grid-column: var(--puzzle-grid-item-column-start-mobile) / var(--puzzle-grid-item-column-end-mobile);
|
|
19
|
+
grid-row-end: var(--puzzle-grid-item-row-span-mobile);
|
|
20
|
+
grid-row-start: var(--puzzle-grid-item-row-start-mobile);
|
|
21
|
+
justify-self: var(--puzzle-grid-item-align-h-mobile);
|
|
22
|
+
align-self: var(--puzzle-grid-item-align-v-mobile);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@media (width >= 768px) {
|
|
26
|
+
.puzzle-grid {
|
|
27
|
+
grid-template-columns: var(--puzzle-grid-columns-tablet);
|
|
28
|
+
grid-template-rows: var(--puzzle-grid-rows-tablet);
|
|
29
|
+
row-gap: var(--puzzle-grid-row-gap-tablet);
|
|
30
|
+
column-gap: var(--puzzle-grid-column-gap-tablet);
|
|
31
|
+
justify-items: var(--puzzle-grid-align-h-tablet);
|
|
32
|
+
align-items: var(--puzzle-grid-align-v-tablet);
|
|
33
|
+
grid-auto-flow: var(--puzzle-grid-auto-flow-tablet);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.puzzle-grid-item {
|
|
37
|
+
grid-column: var(--puzzle-grid-item-column-start-tablet) / var(--puzzle-grid-item-column-end-tablet);
|
|
38
|
+
grid-row-end: var(--puzzle-grid-item-row-span-tablet);
|
|
39
|
+
grid-row-start: var(--puzzle-grid-item-row-start-tablet);
|
|
40
|
+
justify-self: var(--puzzle-grid-item-align-h-tablet);
|
|
41
|
+
align-self: var(--puzzle-grid-item-align-v-tablet);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@media (width >= 1024px) {
|
|
46
|
+
.puzzle-grid {
|
|
47
|
+
grid-template-columns: var(--puzzle-grid-columns-desktop);
|
|
48
|
+
grid-template-rows: var(--puzzle-grid-rows-desktop);
|
|
49
|
+
row-gap: var(--puzzle-grid-row-gap-desktop);
|
|
50
|
+
column-gap: var(--puzzle-grid-column-gap-desktop);
|
|
51
|
+
justify-items: var(--puzzle-grid-align-h-desktop);
|
|
52
|
+
align-items: var(--puzzle-grid-align-v-desktop);
|
|
53
|
+
grid-auto-flow: var(--puzzle-grid-auto-flow-desktop);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.puzzle-grid-item {
|
|
57
|
+
grid-column: var(--puzzle-grid-item-column-start-desktop) / var(--puzzle-grid-item-column-end-desktop);
|
|
58
|
+
grid-row-end: var(--puzzle-grid-item-row-span-desktop);
|
|
59
|
+
grid-row-start: var(--puzzle-grid-item-row-start-desktop);
|
|
60
|
+
justify-self: var(--puzzle-grid-item-align-h-desktop);
|
|
61
|
+
align-self: var(--puzzle-grid-item-align-v-desktop);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
;/* empty css */
|
|
2
|
+
let _puzzle_ui_core = require("@puzzle-ui/core");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
// src/components/layout/grid/index.tsx
|
|
5
|
+
const responsiveStyle = (property, value, format = (value) => value) => {
|
|
6
|
+
const styles = {};
|
|
7
|
+
if (value === void 0) return styles;
|
|
8
|
+
let current = typeof value === "object" ? value.mobile : value;
|
|
9
|
+
for (const breakpoint of _puzzle_ui_core.BREAKPOINTS) {
|
|
10
|
+
if (typeof value === "object") current = value[breakpoint] ?? current;
|
|
11
|
+
styles[`--puzzle-grid-${property}-${breakpoint}`] = format(current);
|
|
12
|
+
}
|
|
13
|
+
return styles;
|
|
14
|
+
};
|
|
15
|
+
const positiveInteger = (value, prop) => {
|
|
16
|
+
if (!Number.isInteger(value) || value < 1) throw new RangeError(`Grid ${prop} must be a positive integer.`);
|
|
17
|
+
return value;
|
|
18
|
+
};
|
|
19
|
+
const tracks = (value) => typeof value === "number" ? `repeat(${positiveInteger(value, "columns/rows")}, minmax(0, 1fr))` : value;
|
|
20
|
+
const span = (value) => `span ${positiveInteger(value, "span")}`;
|
|
21
|
+
const line = (value) => {
|
|
22
|
+
if (typeof value === "number" && (!Number.isInteger(value) || value === 0)) throw new RangeError("Grid start lines must be non-zero integers or auto.");
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
25
|
+
const gaps = {
|
|
26
|
+
"0": "0",
|
|
27
|
+
xs: "var(--puzzle-space-1, 0.25rem)",
|
|
28
|
+
sm: "var(--puzzle-space-2, 0.5rem)",
|
|
29
|
+
md: "var(--puzzle-space-4, 1rem)",
|
|
30
|
+
lg: "var(--puzzle-space-8, 2rem)",
|
|
31
|
+
xl: "var(--puzzle-space-16, 4rem)"
|
|
32
|
+
};
|
|
33
|
+
const Grid = ({ as, columns = 1, rows = "none", minChildWidth, gap = "md", rowGap = gap, columnGap = gap, alignH = "stretch", alignV = "stretch", autoFlow = "row", children, className, style, ...props }) => (0, react.createElement)(as ?? "div", {
|
|
34
|
+
...props,
|
|
35
|
+
className: (0, _puzzle_ui_core.cn)("puzzle-grid", className),
|
|
36
|
+
style: {
|
|
37
|
+
...responsiveStyle("columns", columns, tracks),
|
|
38
|
+
...responsiveStyle("columns", minChildWidth, (width) => `repeat(auto-fit, minmax(min(100%, ${width}), 1fr))`),
|
|
39
|
+
...responsiveStyle("rows", rows, tracks),
|
|
40
|
+
...responsiveStyle("row-gap", rowGap, (value) => gaps[value]),
|
|
41
|
+
...responsiveStyle("column-gap", columnGap, (value) => gaps[value]),
|
|
42
|
+
...responsiveStyle("align-h", alignH),
|
|
43
|
+
...responsiveStyle("align-v", alignV),
|
|
44
|
+
...responsiveStyle("auto-flow", autoFlow),
|
|
45
|
+
...style
|
|
46
|
+
}
|
|
47
|
+
}, children);
|
|
48
|
+
const GridItem = ({ as, colSpan = 1, rowSpan = 1, colStart, rowStart = "auto", alignH = "auto", alignV = "auto", children, className, style, ...props }) => (0, react.createElement)(as ?? "div", {
|
|
49
|
+
...props,
|
|
50
|
+
className: (0, _puzzle_ui_core.cn)("puzzle-grid-item", className),
|
|
51
|
+
style: {
|
|
52
|
+
...responsiveStyle("item-column-end", colSpan, (value) => value === "full" ? "-1" : span(value)),
|
|
53
|
+
...responsiveStyle("item-column-start", colSpan, (value) => value === "full" ? "1" : "auto"),
|
|
54
|
+
...responsiveStyle("item-row-span", rowSpan, span),
|
|
55
|
+
...responsiveStyle("item-column-start", colStart, line),
|
|
56
|
+
...responsiveStyle("item-row-start", rowStart, line),
|
|
57
|
+
...responsiveStyle("item-align-h", alignH),
|
|
58
|
+
...responsiveStyle("item-align-v", alignV),
|
|
59
|
+
...style
|
|
60
|
+
}
|
|
61
|
+
}, children);
|
|
62
|
+
exports.Grid = Grid;
|
|
63
|
+
exports.GridItem = GridItem;
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["BREAKPOINTS","createElement","cn"],"sources":["../../../../src/components/layout/grid/index.tsx"],"sourcesContent":["import { BREAKPOINTS, cn, type ResponsiveValue } from \"@puzzle-ui/core\";\nimport {\n createElement,\n type ComponentPropsWithRef,\n type CSSProperties,\n type ElementType,\n type ReactNode,\n} from \"react\";\nimport \"./grid.css\";\n\ntype GridGap = \"0\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\ntype GridAlignment = \"start\" | \"center\" | \"end\" | \"stretch\";\ntype GridTracks = number | string;\ntype GridSpan = number | \"full\";\ntype GridLine = number | \"auto\";\ntype GridAutoFlow = NonNullable<CSSProperties[\"gridAutoFlow\"]>;\n\ntype RootProps<C extends ElementType> = {\n as?: C;\n children?: ReactNode;\n className?: string;\n style?: CSSProperties;\n};\n\ntype GridOwnProps<C extends ElementType> = RootProps<C> & {\n columns?: ResponsiveValue<GridTracks>;\n rows?: ResponsiveValue<GridTracks>;\n minChildWidth?: ResponsiveValue<string>;\n gap?: ResponsiveValue<GridGap>;\n rowGap?: ResponsiveValue<GridGap>;\n columnGap?: ResponsiveValue<GridGap>;\n alignH?: ResponsiveValue<GridAlignment>;\n alignV?: ResponsiveValue<GridAlignment>;\n autoFlow?: ResponsiveValue<GridAutoFlow>;\n};\n\ntype GridProps<C extends ElementType = \"div\"> = GridOwnProps<C> &\n Omit<ComponentPropsWithRef<C>, keyof GridOwnProps<C>>;\n\ntype GridItemOwnProps<C extends ElementType> = RootProps<C> & {\n colSpan?: ResponsiveValue<GridSpan>;\n rowSpan?: ResponsiveValue<number>;\n colStart?: ResponsiveValue<GridLine>;\n rowStart?: ResponsiveValue<GridLine>;\n alignH?: ResponsiveValue<GridAlignment | \"auto\">;\n alignV?: ResponsiveValue<GridAlignment | \"auto\">;\n};\n\ntype GridItemProps<C extends ElementType = \"div\"> = GridItemOwnProps<C> &\n Omit<ComponentPropsWithRef<C>, keyof GridItemOwnProps<C>>;\n\ntype GridStyle = CSSProperties &\n Record<`--puzzle-grid-${string}`, string | number | undefined>;\n\nconst responsiveStyle = <T extends string | number>(\n property: string,\n value: ResponsiveValue<T>,\n format: (value: T) => string | number = (value) => value,\n): GridStyle => {\n const styles: GridStyle = {};\n if (value === undefined) return styles;\n\n let current = typeof value === \"object\" ? value.mobile : value;\n for (const breakpoint of BREAKPOINTS) {\n if (typeof value === \"object\") {\n current = value[breakpoint] ?? current;\n }\n styles[`--puzzle-grid-${property}-${breakpoint}`] = format(current);\n }\n return styles;\n};\n\nconst positiveInteger = (value: number, prop: string) => {\n if (!Number.isInteger(value) || value < 1) {\n throw new RangeError(`Grid ${prop} must be a positive integer.`);\n }\n return value;\n};\n\nconst tracks = (value: GridTracks) =>\n typeof value === \"number\"\n ? `repeat(${positiveInteger(value, \"columns/rows\")}, minmax(0, 1fr))`\n : value;\n\nconst span = (value: number) => `span ${positiveInteger(value, \"span\")}`;\n\nconst line = (value: GridLine) => {\n if (typeof value === \"number\" && (!Number.isInteger(value) || value === 0)) {\n throw new RangeError(\"Grid start lines must be non-zero integers or auto.\");\n }\n return value;\n};\n\nconst gaps: Record<GridGap, string> = {\n \"0\": \"0\",\n xs: \"var(--puzzle-space-1, 0.25rem)\",\n sm: \"var(--puzzle-space-2, 0.5rem)\",\n md: \"var(--puzzle-space-4, 1rem)\",\n lg: \"var(--puzzle-space-8, 2rem)\",\n xl: \"var(--puzzle-space-16, 4rem)\",\n};\n\nconst Grid = <C extends ElementType = \"div\">({\n as,\n columns = 1,\n rows = \"none\",\n minChildWidth,\n gap = \"md\",\n rowGap = gap,\n columnGap = gap,\n alignH = \"stretch\",\n alignV = \"stretch\",\n autoFlow = \"row\",\n children,\n className,\n style,\n ...props\n}: GridProps<C>) =>\n createElement(\n as ?? \"div\",\n {\n ...props,\n className: cn(\"puzzle-grid\", className),\n style: {\n ...responsiveStyle(\"columns\", columns, tracks),\n ...responsiveStyle(\n \"columns\",\n minChildWidth,\n (width) => `repeat(auto-fit, minmax(min(100%, ${width}), 1fr))`,\n ),\n ...responsiveStyle(\"rows\", rows, tracks),\n ...responsiveStyle(\"row-gap\", rowGap, (value) => gaps[value]),\n ...responsiveStyle(\"column-gap\", columnGap, (value) => gaps[value]),\n ...responsiveStyle(\"align-h\", alignH),\n ...responsiveStyle(\"align-v\", alignV),\n ...responsiveStyle(\"auto-flow\", autoFlow),\n ...style,\n },\n },\n children,\n );\n\nconst GridItem = <C extends ElementType = \"div\">({\n as,\n colSpan = 1,\n rowSpan = 1,\n colStart,\n rowStart = \"auto\",\n alignH = \"auto\",\n alignV = \"auto\",\n children,\n className,\n style,\n ...props\n}: GridItemProps<C>) =>\n createElement(\n as ?? \"div\",\n {\n ...props,\n className: cn(\"puzzle-grid-item\", className),\n style: {\n ...responsiveStyle(\"item-column-end\", colSpan, (value) =>\n value === \"full\" ? \"-1\" : span(value),\n ),\n ...responsiveStyle(\"item-column-start\", colSpan, (value) =>\n value === \"full\" ? \"1\" : \"auto\",\n ),\n ...responsiveStyle(\"item-row-span\", rowSpan, span),\n ...responsiveStyle(\"item-column-start\", colStart, line),\n ...responsiveStyle(\"item-row-start\", rowStart, line),\n ...responsiveStyle(\"item-align-h\", alignH),\n ...responsiveStyle(\"item-align-v\", alignV),\n ...style,\n },\n },\n children,\n );\n\nexport {\n Grid,\n GridItem,\n type GridProps,\n type GridItemProps,\n type GridGap,\n type GridAlignment,\n type GridTracks,\n type GridSpan,\n type GridLine,\n type GridAutoFlow,\n};\n"],"mappings":";;;;AAsDA,MAAM,mBACJ,UACA,OACA,UAAyC,UAAU,UACrC;CACd,MAAM,SAAoB,CAAC;CAC3B,IAAI,UAAU,KAAA,GAAW,OAAO;CAEhC,IAAI,UAAU,OAAO,UAAU,WAAW,MAAM,SAAS;CACzD,KAAK,MAAM,cAAcA,gBAAAA,aAAa;EACpC,IAAI,OAAO,UAAU,UACnB,UAAU,MAAM,eAAe;EAEjC,OAAO,iBAAiB,SAAS,GAAG,gBAAgB,OAAO,OAAO;CACpE;CACA,OAAO;AACT;AAEA,MAAM,mBAAmB,OAAe,SAAiB;CACvD,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GACtC,MAAM,IAAI,WAAW,QAAQ,KAAK,6BAA6B;CAEjE,OAAO;AACT;AAEA,MAAM,UAAU,UACd,OAAO,UAAU,WACb,UAAU,gBAAgB,OAAO,cAAc,EAAE,qBACjD;AAEN,MAAM,QAAQ,UAAkB,QAAQ,gBAAgB,OAAO,MAAM;AAErE,MAAM,QAAQ,UAAoB;CAChC,IAAI,OAAO,UAAU,aAAa,CAAC,OAAO,UAAU,KAAK,KAAK,UAAU,IACtE,MAAM,IAAI,WAAW,qDAAqD;CAE5E,OAAO;AACT;AAEA,MAAM,OAAgC;CACpC,KAAK;CACL,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAEA,MAAM,QAAuC,EAC3C,IACA,UAAU,GACV,OAAO,QACP,eACA,MAAM,MACN,SAAS,KACT,YAAY,KACZ,SAAS,WACT,SAAS,WACT,WAAW,OACX,UACA,WACA,OACA,GAAG,aAAA,GAEHC,MAAAA,cAAAA,CACE,MAAM,OACN;CACE,GAAG;CACH,YAAA,GAAWC,gBAAAA,GAAAA,CAAG,eAAe,SAAS;CACtC,OAAO;EACL,GAAG,gBAAgB,WAAW,SAAS,MAAM;EAC7C,GAAG,gBACD,WACA,gBACC,UAAU,qCAAqC,MAAM,SACxD;EACA,GAAG,gBAAgB,QAAQ,MAAM,MAAM;EACvC,GAAG,gBAAgB,WAAW,SAAS,UAAU,KAAK,MAAM;EAC5D,GAAG,gBAAgB,cAAc,YAAY,UAAU,KAAK,MAAM;EAClE,GAAG,gBAAgB,WAAW,MAAM;EACpC,GAAG,gBAAgB,WAAW,MAAM;EACpC,GAAG,gBAAgB,aAAa,QAAQ;EACxC,GAAG;CACL;AACF,GACA,QACF;AAEF,MAAM,YAA2C,EAC/C,IACA,UAAU,GACV,UAAU,GACV,UACA,WAAW,QACX,SAAS,QACT,SAAS,QACT,UACA,WACA,OACA,GAAG,aAAA,GAEHD,MAAAA,cAAAA,CACE,MAAM,OACN;CACE,GAAG;CACH,YAAA,GAAWC,gBAAAA,GAAAA,CAAG,oBAAoB,SAAS;CAC3C,OAAO;EACL,GAAG,gBAAgB,mBAAmB,UAAU,UAC9C,UAAU,SAAS,OAAO,KAAK,KAAK,CACtC;EACA,GAAG,gBAAgB,qBAAqB,UAAU,UAChD,UAAU,SAAS,MAAM,MAC3B;EACA,GAAG,gBAAgB,iBAAiB,SAAS,IAAI;EACjD,GAAG,gBAAgB,qBAAqB,UAAU,IAAI;EACtD,GAAG,gBAAgB,kBAAkB,UAAU,IAAI;EACnD,GAAG,gBAAgB,gBAAgB,MAAM;EACzC,GAAG,gBAAgB,gBAAgB,MAAM;EACzC,GAAG;CACL;AACF,GACA,QACF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CSSProperties, ComponentPropsWithRef, ElementType, ReactNode } from "react";
|
|
2
|
+
import { ResponsiveValue } from "@puzzle-ui/core";
|
|
3
|
+
type GridGap = "0" | "xs" | "sm" | "md" | "lg" | "xl";
|
|
4
|
+
type GridAlignment = "start" | "center" | "end" | "stretch";
|
|
5
|
+
type GridTracks = number | string;
|
|
6
|
+
type GridSpan = number | "full";
|
|
7
|
+
type GridLine = number | "auto";
|
|
8
|
+
type GridAutoFlow = NonNullable<CSSProperties["gridAutoFlow"]>;
|
|
9
|
+
type RootProps<C extends ElementType> = {
|
|
10
|
+
as?: C;
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
className?: string;
|
|
13
|
+
style?: CSSProperties;
|
|
14
|
+
};
|
|
15
|
+
type GridOwnProps<C extends ElementType> = RootProps<C> & {
|
|
16
|
+
columns?: ResponsiveValue<GridTracks>;
|
|
17
|
+
rows?: ResponsiveValue<GridTracks>;
|
|
18
|
+
minChildWidth?: ResponsiveValue<string>;
|
|
19
|
+
gap?: ResponsiveValue<GridGap>;
|
|
20
|
+
rowGap?: ResponsiveValue<GridGap>;
|
|
21
|
+
columnGap?: ResponsiveValue<GridGap>;
|
|
22
|
+
alignH?: ResponsiveValue<GridAlignment>;
|
|
23
|
+
alignV?: ResponsiveValue<GridAlignment>;
|
|
24
|
+
autoFlow?: ResponsiveValue<GridAutoFlow>;
|
|
25
|
+
};
|
|
26
|
+
type GridProps<C extends ElementType = "div"> = GridOwnProps<C> & Omit<ComponentPropsWithRef<C>, keyof GridOwnProps<C>>;
|
|
27
|
+
type GridItemOwnProps<C extends ElementType> = RootProps<C> & {
|
|
28
|
+
colSpan?: ResponsiveValue<GridSpan>;
|
|
29
|
+
rowSpan?: ResponsiveValue<number>;
|
|
30
|
+
colStart?: ResponsiveValue<GridLine>;
|
|
31
|
+
rowStart?: ResponsiveValue<GridLine>;
|
|
32
|
+
alignH?: ResponsiveValue<GridAlignment | "auto">;
|
|
33
|
+
alignV?: ResponsiveValue<GridAlignment | "auto">;
|
|
34
|
+
};
|
|
35
|
+
type GridItemProps<C extends ElementType = "div"> = GridItemOwnProps<C> & Omit<ComponentPropsWithRef<C>, keyof GridItemOwnProps<C>>;
|
|
36
|
+
declare const Grid: <C extends ElementType = "div">({ as, columns, rows, minChildWidth, gap, rowGap, columnGap, alignH, alignV, autoFlow, children, className, style, ...props }: GridProps<C>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
37
|
+
declare const GridItem: <C extends ElementType = "div">({ as, colSpan, rowSpan, colStart, rowStart, alignH, alignV, children, className, style, ...props }: GridItemProps<C>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
38
|
+
export { Grid, type GridAlignment, type GridAutoFlow, type GridGap, GridItem, type GridItemProps, type GridLine, type GridProps, type GridSpan, type GridTracks };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ResponsiveValue } from "@puzzle-ui/core";
|
|
2
|
+
import { CSSProperties, ComponentPropsWithRef, ElementType, ReactNode } from "react";
|
|
3
|
+
type GridGap = "0" | "xs" | "sm" | "md" | "lg" | "xl";
|
|
4
|
+
type GridAlignment = "start" | "center" | "end" | "stretch";
|
|
5
|
+
type GridTracks = number | string;
|
|
6
|
+
type GridSpan = number | "full";
|
|
7
|
+
type GridLine = number | "auto";
|
|
8
|
+
type GridAutoFlow = NonNullable<CSSProperties["gridAutoFlow"]>;
|
|
9
|
+
type RootProps<C extends ElementType> = {
|
|
10
|
+
as?: C;
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
className?: string;
|
|
13
|
+
style?: CSSProperties;
|
|
14
|
+
};
|
|
15
|
+
type GridOwnProps<C extends ElementType> = RootProps<C> & {
|
|
16
|
+
columns?: ResponsiveValue<GridTracks>;
|
|
17
|
+
rows?: ResponsiveValue<GridTracks>;
|
|
18
|
+
minChildWidth?: ResponsiveValue<string>;
|
|
19
|
+
gap?: ResponsiveValue<GridGap>;
|
|
20
|
+
rowGap?: ResponsiveValue<GridGap>;
|
|
21
|
+
columnGap?: ResponsiveValue<GridGap>;
|
|
22
|
+
alignH?: ResponsiveValue<GridAlignment>;
|
|
23
|
+
alignV?: ResponsiveValue<GridAlignment>;
|
|
24
|
+
autoFlow?: ResponsiveValue<GridAutoFlow>;
|
|
25
|
+
};
|
|
26
|
+
type GridProps<C extends ElementType = "div"> = GridOwnProps<C> & Omit<ComponentPropsWithRef<C>, keyof GridOwnProps<C>>;
|
|
27
|
+
type GridItemOwnProps<C extends ElementType> = RootProps<C> & {
|
|
28
|
+
colSpan?: ResponsiveValue<GridSpan>;
|
|
29
|
+
rowSpan?: ResponsiveValue<number>;
|
|
30
|
+
colStart?: ResponsiveValue<GridLine>;
|
|
31
|
+
rowStart?: ResponsiveValue<GridLine>;
|
|
32
|
+
alignH?: ResponsiveValue<GridAlignment | "auto">;
|
|
33
|
+
alignV?: ResponsiveValue<GridAlignment | "auto">;
|
|
34
|
+
};
|
|
35
|
+
type GridItemProps<C extends ElementType = "div"> = GridItemOwnProps<C> & Omit<ComponentPropsWithRef<C>, keyof GridItemOwnProps<C>>;
|
|
36
|
+
declare const Grid: <C extends ElementType = "div">({ as, columns, rows, minChildWidth, gap, rowGap, columnGap, alignH, alignV, autoFlow, children, className, style, ...props }: GridProps<C>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
37
|
+
declare const GridItem: <C extends ElementType = "div">({ as, colSpan, rowSpan, colStart, rowStart, alignH, alignV, children, className, style, ...props }: GridItemProps<C>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
38
|
+
export { Grid, type GridAlignment, type GridAutoFlow, type GridGap, GridItem, type GridItemProps, type GridLine, type GridProps, type GridSpan, type GridTracks };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import "./grid.css";
|
|
2
|
+
import { BREAKPOINTS, cn } from "@puzzle-ui/core";
|
|
3
|
+
import { createElement } from "react";
|
|
4
|
+
// src/components/layout/grid/index.tsx
|
|
5
|
+
const responsiveStyle = (property, value, format = (value) => value) => {
|
|
6
|
+
const styles = {};
|
|
7
|
+
if (value === void 0) return styles;
|
|
8
|
+
let current = typeof value === "object" ? value.mobile : value;
|
|
9
|
+
for (const breakpoint of BREAKPOINTS) {
|
|
10
|
+
if (typeof value === "object") current = value[breakpoint] ?? current;
|
|
11
|
+
styles[`--puzzle-grid-${property}-${breakpoint}`] = format(current);
|
|
12
|
+
}
|
|
13
|
+
return styles;
|
|
14
|
+
};
|
|
15
|
+
const positiveInteger = (value, prop) => {
|
|
16
|
+
if (!Number.isInteger(value) || value < 1) throw new RangeError(`Grid ${prop} must be a positive integer.`);
|
|
17
|
+
return value;
|
|
18
|
+
};
|
|
19
|
+
const tracks = (value) => typeof value === "number" ? `repeat(${positiveInteger(value, "columns/rows")}, minmax(0, 1fr))` : value;
|
|
20
|
+
const span = (value) => `span ${positiveInteger(value, "span")}`;
|
|
21
|
+
const line = (value) => {
|
|
22
|
+
if (typeof value === "number" && (!Number.isInteger(value) || value === 0)) throw new RangeError("Grid start lines must be non-zero integers or auto.");
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
25
|
+
const gaps = {
|
|
26
|
+
"0": "0",
|
|
27
|
+
xs: "var(--puzzle-space-1, 0.25rem)",
|
|
28
|
+
sm: "var(--puzzle-space-2, 0.5rem)",
|
|
29
|
+
md: "var(--puzzle-space-4, 1rem)",
|
|
30
|
+
lg: "var(--puzzle-space-8, 2rem)",
|
|
31
|
+
xl: "var(--puzzle-space-16, 4rem)"
|
|
32
|
+
};
|
|
33
|
+
const Grid = ({ as, columns = 1, rows = "none", minChildWidth, gap = "md", rowGap = gap, columnGap = gap, alignH = "stretch", alignV = "stretch", autoFlow = "row", children, className, style, ...props }) => createElement(as ?? "div", {
|
|
34
|
+
...props,
|
|
35
|
+
className: cn("puzzle-grid", className),
|
|
36
|
+
style: {
|
|
37
|
+
...responsiveStyle("columns", columns, tracks),
|
|
38
|
+
...responsiveStyle("columns", minChildWidth, (width) => `repeat(auto-fit, minmax(min(100%, ${width}), 1fr))`),
|
|
39
|
+
...responsiveStyle("rows", rows, tracks),
|
|
40
|
+
...responsiveStyle("row-gap", rowGap, (value) => gaps[value]),
|
|
41
|
+
...responsiveStyle("column-gap", columnGap, (value) => gaps[value]),
|
|
42
|
+
...responsiveStyle("align-h", alignH),
|
|
43
|
+
...responsiveStyle("align-v", alignV),
|
|
44
|
+
...responsiveStyle("auto-flow", autoFlow),
|
|
45
|
+
...style
|
|
46
|
+
}
|
|
47
|
+
}, children);
|
|
48
|
+
const GridItem = ({ as, colSpan = 1, rowSpan = 1, colStart, rowStart = "auto", alignH = "auto", alignV = "auto", children, className, style, ...props }) => createElement(as ?? "div", {
|
|
49
|
+
...props,
|
|
50
|
+
className: cn("puzzle-grid-item", className),
|
|
51
|
+
style: {
|
|
52
|
+
...responsiveStyle("item-column-end", colSpan, (value) => value === "full" ? "-1" : span(value)),
|
|
53
|
+
...responsiveStyle("item-column-start", colSpan, (value) => value === "full" ? "1" : "auto"),
|
|
54
|
+
...responsiveStyle("item-row-span", rowSpan, span),
|
|
55
|
+
...responsiveStyle("item-column-start", colStart, line),
|
|
56
|
+
...responsiveStyle("item-row-start", rowStart, line),
|
|
57
|
+
...responsiveStyle("item-align-h", alignH),
|
|
58
|
+
...responsiveStyle("item-align-v", alignV),
|
|
59
|
+
...style
|
|
60
|
+
}
|
|
61
|
+
}, children);
|
|
62
|
+
export { Grid, GridItem };
|
|
63
|
+
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/layout/grid/index.tsx"],"sourcesContent":["import { BREAKPOINTS, cn, type ResponsiveValue } from \"@puzzle-ui/core\";\nimport {\n createElement,\n type ComponentPropsWithRef,\n type CSSProperties,\n type ElementType,\n type ReactNode,\n} from \"react\";\nimport \"./grid.css\";\n\ntype GridGap = \"0\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\ntype GridAlignment = \"start\" | \"center\" | \"end\" | \"stretch\";\ntype GridTracks = number | string;\ntype GridSpan = number | \"full\";\ntype GridLine = number | \"auto\";\ntype GridAutoFlow = NonNullable<CSSProperties[\"gridAutoFlow\"]>;\n\ntype RootProps<C extends ElementType> = {\n as?: C;\n children?: ReactNode;\n className?: string;\n style?: CSSProperties;\n};\n\ntype GridOwnProps<C extends ElementType> = RootProps<C> & {\n columns?: ResponsiveValue<GridTracks>;\n rows?: ResponsiveValue<GridTracks>;\n minChildWidth?: ResponsiveValue<string>;\n gap?: ResponsiveValue<GridGap>;\n rowGap?: ResponsiveValue<GridGap>;\n columnGap?: ResponsiveValue<GridGap>;\n alignH?: ResponsiveValue<GridAlignment>;\n alignV?: ResponsiveValue<GridAlignment>;\n autoFlow?: ResponsiveValue<GridAutoFlow>;\n};\n\ntype GridProps<C extends ElementType = \"div\"> = GridOwnProps<C> &\n Omit<ComponentPropsWithRef<C>, keyof GridOwnProps<C>>;\n\ntype GridItemOwnProps<C extends ElementType> = RootProps<C> & {\n colSpan?: ResponsiveValue<GridSpan>;\n rowSpan?: ResponsiveValue<number>;\n colStart?: ResponsiveValue<GridLine>;\n rowStart?: ResponsiveValue<GridLine>;\n alignH?: ResponsiveValue<GridAlignment | \"auto\">;\n alignV?: ResponsiveValue<GridAlignment | \"auto\">;\n};\n\ntype GridItemProps<C extends ElementType = \"div\"> = GridItemOwnProps<C> &\n Omit<ComponentPropsWithRef<C>, keyof GridItemOwnProps<C>>;\n\ntype GridStyle = CSSProperties &\n Record<`--puzzle-grid-${string}`, string | number | undefined>;\n\nconst responsiveStyle = <T extends string | number>(\n property: string,\n value: ResponsiveValue<T>,\n format: (value: T) => string | number = (value) => value,\n): GridStyle => {\n const styles: GridStyle = {};\n if (value === undefined) return styles;\n\n let current = typeof value === \"object\" ? value.mobile : value;\n for (const breakpoint of BREAKPOINTS) {\n if (typeof value === \"object\") {\n current = value[breakpoint] ?? current;\n }\n styles[`--puzzle-grid-${property}-${breakpoint}`] = format(current);\n }\n return styles;\n};\n\nconst positiveInteger = (value: number, prop: string) => {\n if (!Number.isInteger(value) || value < 1) {\n throw new RangeError(`Grid ${prop} must be a positive integer.`);\n }\n return value;\n};\n\nconst tracks = (value: GridTracks) =>\n typeof value === \"number\"\n ? `repeat(${positiveInteger(value, \"columns/rows\")}, minmax(0, 1fr))`\n : value;\n\nconst span = (value: number) => `span ${positiveInteger(value, \"span\")}`;\n\nconst line = (value: GridLine) => {\n if (typeof value === \"number\" && (!Number.isInteger(value) || value === 0)) {\n throw new RangeError(\"Grid start lines must be non-zero integers or auto.\");\n }\n return value;\n};\n\nconst gaps: Record<GridGap, string> = {\n \"0\": \"0\",\n xs: \"var(--puzzle-space-1, 0.25rem)\",\n sm: \"var(--puzzle-space-2, 0.5rem)\",\n md: \"var(--puzzle-space-4, 1rem)\",\n lg: \"var(--puzzle-space-8, 2rem)\",\n xl: \"var(--puzzle-space-16, 4rem)\",\n};\n\nconst Grid = <C extends ElementType = \"div\">({\n as,\n columns = 1,\n rows = \"none\",\n minChildWidth,\n gap = \"md\",\n rowGap = gap,\n columnGap = gap,\n alignH = \"stretch\",\n alignV = \"stretch\",\n autoFlow = \"row\",\n children,\n className,\n style,\n ...props\n}: GridProps<C>) =>\n createElement(\n as ?? \"div\",\n {\n ...props,\n className: cn(\"puzzle-grid\", className),\n style: {\n ...responsiveStyle(\"columns\", columns, tracks),\n ...responsiveStyle(\n \"columns\",\n minChildWidth,\n (width) => `repeat(auto-fit, minmax(min(100%, ${width}), 1fr))`,\n ),\n ...responsiveStyle(\"rows\", rows, tracks),\n ...responsiveStyle(\"row-gap\", rowGap, (value) => gaps[value]),\n ...responsiveStyle(\"column-gap\", columnGap, (value) => gaps[value]),\n ...responsiveStyle(\"align-h\", alignH),\n ...responsiveStyle(\"align-v\", alignV),\n ...responsiveStyle(\"auto-flow\", autoFlow),\n ...style,\n },\n },\n children,\n );\n\nconst GridItem = <C extends ElementType = \"div\">({\n as,\n colSpan = 1,\n rowSpan = 1,\n colStart,\n rowStart = \"auto\",\n alignH = \"auto\",\n alignV = \"auto\",\n children,\n className,\n style,\n ...props\n}: GridItemProps<C>) =>\n createElement(\n as ?? \"div\",\n {\n ...props,\n className: cn(\"puzzle-grid-item\", className),\n style: {\n ...responsiveStyle(\"item-column-end\", colSpan, (value) =>\n value === \"full\" ? \"-1\" : span(value),\n ),\n ...responsiveStyle(\"item-column-start\", colSpan, (value) =>\n value === \"full\" ? \"1\" : \"auto\",\n ),\n ...responsiveStyle(\"item-row-span\", rowSpan, span),\n ...responsiveStyle(\"item-column-start\", colStart, line),\n ...responsiveStyle(\"item-row-start\", rowStart, line),\n ...responsiveStyle(\"item-align-h\", alignH),\n ...responsiveStyle(\"item-align-v\", alignV),\n ...style,\n },\n },\n children,\n );\n\nexport {\n Grid,\n GridItem,\n type GridProps,\n type GridItemProps,\n type GridGap,\n type GridAlignment,\n type GridTracks,\n type GridSpan,\n type GridLine,\n type GridAutoFlow,\n};\n"],"mappings":";;;;AAsDA,MAAM,mBACJ,UACA,OACA,UAAyC,UAAU,UACrC;CACd,MAAM,SAAoB,CAAC;CAC3B,IAAI,UAAU,KAAA,GAAW,OAAO;CAEhC,IAAI,UAAU,OAAO,UAAU,WAAW,MAAM,SAAS;CACzD,KAAK,MAAM,cAAc,aAAa;EACpC,IAAI,OAAO,UAAU,UACnB,UAAU,MAAM,eAAe;EAEjC,OAAO,iBAAiB,SAAS,GAAG,gBAAgB,OAAO,OAAO;CACpE;CACA,OAAO;AACT;AAEA,MAAM,mBAAmB,OAAe,SAAiB;CACvD,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GACtC,MAAM,IAAI,WAAW,QAAQ,KAAK,6BAA6B;CAEjE,OAAO;AACT;AAEA,MAAM,UAAU,UACd,OAAO,UAAU,WACb,UAAU,gBAAgB,OAAO,cAAc,EAAE,qBACjD;AAEN,MAAM,QAAQ,UAAkB,QAAQ,gBAAgB,OAAO,MAAM;AAErE,MAAM,QAAQ,UAAoB;CAChC,IAAI,OAAO,UAAU,aAAa,CAAC,OAAO,UAAU,KAAK,KAAK,UAAU,IACtE,MAAM,IAAI,WAAW,qDAAqD;CAE5E,OAAO;AACT;AAEA,MAAM,OAAgC;CACpC,KAAK;CACL,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAEA,MAAM,QAAuC,EAC3C,IACA,UAAU,GACV,OAAO,QACP,eACA,MAAM,MACN,SAAS,KACT,YAAY,KACZ,SAAS,WACT,SAAS,WACT,WAAW,OACX,UACA,WACA,OACA,GAAG,YAEH,cACE,MAAM,OACN;CACE,GAAG;CACH,WAAW,GAAG,eAAe,SAAS;CACtC,OAAO;EACL,GAAG,gBAAgB,WAAW,SAAS,MAAM;EAC7C,GAAG,gBACD,WACA,gBACC,UAAU,qCAAqC,MAAM,SACxD;EACA,GAAG,gBAAgB,QAAQ,MAAM,MAAM;EACvC,GAAG,gBAAgB,WAAW,SAAS,UAAU,KAAK,MAAM;EAC5D,GAAG,gBAAgB,cAAc,YAAY,UAAU,KAAK,MAAM;EAClE,GAAG,gBAAgB,WAAW,MAAM;EACpC,GAAG,gBAAgB,WAAW,MAAM;EACpC,GAAG,gBAAgB,aAAa,QAAQ;EACxC,GAAG;CACL;AACF,GACA,QACF;AAEF,MAAM,YAA2C,EAC/C,IACA,UAAU,GACV,UAAU,GACV,UACA,WAAW,QACX,SAAS,QACT,SAAS,QACT,UACA,WACA,OACA,GAAG,YAEH,cACE,MAAM,OACN;CACE,GAAG;CACH,WAAW,GAAG,oBAAoB,SAAS;CAC3C,OAAO;EACL,GAAG,gBAAgB,mBAAmB,UAAU,UAC9C,UAAU,SAAS,OAAO,KAAK,KAAK,CACtC;EACA,GAAG,gBAAgB,qBAAqB,UAAU,UAChD,UAAU,SAAS,MAAM,MAC3B;EACA,GAAG,gBAAgB,iBAAiB,SAAS,IAAI;EACjD,GAAG,gBAAgB,qBAAqB,UAAU,IAAI;EACtD,GAAG,gBAAgB,kBAAkB,UAAU,IAAI;EACnD,GAAG,gBAAgB,gBAAgB,MAAM;EACzC,GAAG,gBAAgB,gBAAgB,MAAM;EACzC,GAAG;CACL;AACF,GACA,QACF"}
|
|
@@ -12,7 +12,7 @@ const getTextValue = (item) => {
|
|
|
12
12
|
return "";
|
|
13
13
|
};
|
|
14
14
|
const normalizeSearchText = (value) => value.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLocaleLowerCase();
|
|
15
|
-
const TreeView = ({ items, selectionMode = "single", defaultExpandedIds = [], expandedIds, onExpandedChange, defaultSelectedIds = [], selectedIds, onSelectionChange, defaultFocusedId, onFocusedChange, loadChildren, onLoadChildrenError, onItemActivate, getItemActive, renderItem, renderIcon, renderLabel, expandOnItemClick =
|
|
15
|
+
const TreeView = ({ items, selectionMode = "single", defaultExpandedIds = [], expandedIds, onExpandedChange, defaultSelectedIds = [], selectedIds, onSelectionChange, defaultFocusedId, onFocusedChange, loadChildren, onLoadChildrenError, onItemActivate, getItemActive, renderItem, renderIcon, renderLabel, expandOnItemClick = true, typeahead = true, size = "md", indentation, loadingLabel = "Loading…", loadErrorLabel = "Could not load children. Collapse and expand to retry.", itemClassName, className, style, dir, ...rootProps }) => {
|
|
16
16
|
const generatedId = (0, react.useId)();
|
|
17
17
|
const isExpandedControlled = expandedIds !== void 0;
|
|
18
18
|
const isSelectionControlled = selectedIds !== void 0;
|