@pinfold/react 0.0.0-stage → 0.1.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 +58 -2
- package/accordion/lazy/package.json +6 -0
- package/accordion/package.json +6 -0
- package/dist/accordion/client.cjs +474 -0
- package/dist/accordion/client.d.cts +31 -0
- package/dist/accordion/client.d.ts +31 -0
- package/dist/accordion/client.js +473 -0
- package/dist/accordion/index.cjs +48 -0
- package/dist/accordion/index.d.cts +52 -0
- package/dist/accordion/index.d.ts +52 -0
- package/dist/accordion/index.js +13 -0
- package/dist/accordion/lazy.cjs +17 -0
- package/dist/accordion/lazy.d.cts +15 -0
- package/dist/accordion/lazy.d.ts +15 -0
- package/dist/accordion/lazy.js +16 -0
- package/dist/chunk-5ZMK623A.js +61 -0
- package/dist/chunk-BPPCPHHU.js +70 -0
- package/dist/chunk-DQWSDHRY.cjs +71 -0
- package/dist/chunk-Q232PTPW.js +115 -0
- package/dist/chunk-RJPT3NTP.cjs +62 -0
- package/dist/chunk-VPKVOJHA.cjs +116 -0
- package/dist/client.cjs +30 -0
- package/dist/client.d.cts +121 -0
- package/dist/client.d.ts +121 -0
- package/dist/client.js +29 -0
- package/dist/index.cjs +52 -0
- package/dist/index.d.cts +123 -0
- package/dist/index.d.ts +123 -0
- package/dist/index.js +10 -0
- package/dist/types-BZqk8btE.d.cts +278 -0
- package/dist/types-BZqk8btE.d.ts +278 -0
- package/dist/types-x01Q5sqz.d.cts +278 -0
- package/dist/types-x01Q5sqz.d.ts +278 -0
- package/dist/validate-D3GJ2276.js +37 -0
- package/dist/validate-ELH6OKK3.cjs +38 -0
- package/llms-full.txt +133 -0
- package/llms.txt +26 -0
- package/package.json +92 -4
- package/registry/accordion.json +20 -0
- package/registry/registry.json +25 -0
- package/schema/accordion.json +800 -0
package/llms-full.txt
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Pinfold
|
|
2
|
+
|
|
3
|
+
> Hooks-first, config-driven, accessible React UI (v0.1.0). One config object in, an accessible, themed, responsive component out. React 18+, Server Components, plain JS or TypeScript.
|
|
4
|
+
|
|
5
|
+
Rules for generating Pinfold code:
|
|
6
|
+
- Data goes in `items` (or raw records plus `fields`); everything else is optional with good defaults.
|
|
7
|
+
- Client: `const Faq = useAccordion({ items }); return <Faq />`. Server Component: `const Faq = defineAccordion({ items }); return <Faq />`. Same import path.
|
|
8
|
+
- Styles: `import '@pinfold/css/core.css'` once, then `@pinfold/css/<name>.css` per component, in the app entry. Never import CSS from library code.
|
|
9
|
+
- Global defaults: `defineConfig({ theme, radius, stylePack, defaults: { <name>: {...} } })` passed to `<PinfoldProvider config>`.
|
|
10
|
+
- Customise in this order: config, then `classNames`/`styles`/`slotProps`, then `render` per slot, then parts (`<Faq.Panel id>`), then prop getters.
|
|
11
|
+
- Never pass functions from a Server Component; plain data and server-rendered JSX only.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
- `npx pinfold init` (or `npm i @pinfold/react @pinfold/css`)
|
|
16
|
+
- shadcn: `npx shadcn add @pinfold/<name>` with `"registries": { "@pinfold": "https://pinfold.indranildev.in/r/{name}.json" }` in components.json
|
|
17
|
+
|
|
18
|
+
# Accordion
|
|
19
|
+
|
|
20
|
+
A vertically stacked set of headings that each reveal a section of content. Config in, accessible accordion out.
|
|
21
|
+
|
|
22
|
+
Import: `@pinfold/react/accordion` · Pattern: https://www.w3.org/WAI/ARIA/apg/patterns/accordion/
|
|
23
|
+
|
|
24
|
+
## Client hook
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { useAccordion } from '@pinfold/react/accordion';
|
|
28
|
+
|
|
29
|
+
export function Faq() {
|
|
30
|
+
const Faq = useAccordion({ items: [{ title: 'What is Pinfold?', content: 'Config in, accessible UI out.' }] });
|
|
31
|
+
return <Faq />;
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Server Component
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { defineAccordion } from '@pinfold/react/accordion';
|
|
39
|
+
|
|
40
|
+
export default async function Page() {
|
|
41
|
+
const Faq = defineAccordion({ items: await getFaq(), fields: { id: 'slug', title: 'question', content: 'answer' } });
|
|
42
|
+
return <Faq />;
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Options
|
|
47
|
+
|
|
48
|
+
Only `items` is required. Every other option has a default; global defaults come from `defineConfig({ defaults: { accordion: {...} } })`.
|
|
49
|
+
|
|
50
|
+
| Option | Type | Default | Description |
|
|
51
|
+
|---|---|---|---|
|
|
52
|
+
| `items` (required) | array | | The rows. The only required option. |
|
|
53
|
+
| `fields` | object | | Map raw records onto rows: `{ id: 'slug', title: 'question', content: 'answer' }`. |
|
|
54
|
+
| `mode` | "single" \| "multiple" | `"single"` | `single` closes the other rows when one opens. |
|
|
55
|
+
| `collapsible` | boolean | `true` | In single mode, lets the user close the open row. |
|
|
56
|
+
| `value` | string[] | | Controlled open ids. Pair with `onValueChange`. |
|
|
57
|
+
| `defaultValue` | string[] | | Initially open ids (uncontrolled). |
|
|
58
|
+
| `disabled` | boolean | `false` | Disables every row. |
|
|
59
|
+
| `orientation` | "vertical" \| "horizontal" | `"vertical"` | Arrow-key axis between headers. |
|
|
60
|
+
| `dir` | "ltr" \| "rtl" | | Text direction. Defaults to the provider. |
|
|
61
|
+
| `loop` | boolean | `true` | Focus wraps around at the ends. |
|
|
62
|
+
| `id` | string | | Id prefix. Defaults to `useId()`, which is SSR-safe. |
|
|
63
|
+
| `hiddenUntilFound` | boolean | `true` | Closed panels use `hidden="until-found"`, so the browser’s find-in-page opens them. |
|
|
64
|
+
| `mountPanels` | "always" \| "open" \| "first-open" | `"always"` | When panel content is in the DOM. `always` keeps it searchable and indexable. |
|
|
65
|
+
| `unmountClosed` (deprecated) | boolean | | Deprecated alias of `mountPanels: "open"`. |
|
|
66
|
+
| `syncWithHash` | boolean | `false` | A `#id` in the URL opens that row and scrolls to it; opening a row updates the hash. |
|
|
67
|
+
| `lazy` | "auto" \| "eager" \| "visible" \| "idle" | `"auto"` | When the code loads, for the `/lazy` entry. The accordion is light, so `auto` is eager. |
|
|
68
|
+
| `variant` | "solid" \| "outline" \| "separated" \| "filled" \| "ghost" | `"solid"` | Visual style. |
|
|
69
|
+
| `size` | "sm" \| "md" \| "lg" | `"md"` | Size preset. |
|
|
70
|
+
| `tone` | "primary" \| "neutral" \| "success" \| "warning" \| "danger" \| "info" | `"primary"` | Accent colour role. |
|
|
71
|
+
| `radius` | "none" \| "sm" \| "md" \| "lg" \| "full" | `"md"` | Corner radius preset. |
|
|
72
|
+
| `indicator` | "chevron" \| "plus" \| "caret" \| "arrow" \| "none" \| node | `"chevron"` | A built-in glyph, your own node, or `(state) => node`. |
|
|
73
|
+
| `indicatorPosition` | "start" \| "end" | `"end"` | Which edge the indicator sits on. |
|
|
74
|
+
| `headingLevel` | 1 \| 2 \| 3 \| 4 \| 5 \| 6 | `3` | Heading level around each trigger. |
|
|
75
|
+
| `animate` | boolean | `true` | Animate open and close. `prefers-reduced-motion` always wins. |
|
|
76
|
+
| `dividers` | boolean | `true` | Lines between rows. |
|
|
77
|
+
| `overflow` | object | | Text overflow per slot. Default: title wraps, description clamps to 2 lines. |
|
|
78
|
+
| `dimensions` | object | | Explicit sizes. Numbers are px. Each key overrides the size preset. |
|
|
79
|
+
| `unstyled` | boolean | `false` | Drops every Pinfold class; ARIA and `data-*` stay. For Tailwind or your own CSS. |
|
|
80
|
+
| `className` | string | | Class on the root. |
|
|
81
|
+
| `style` | object | | Inline style on the root. |
|
|
82
|
+
| `classNames` | object | | Classes per slot. |
|
|
83
|
+
| `styles` | object | | Inline styles per slot. |
|
|
84
|
+
| `slotProps` | object | | Any DOM props per slot. Handlers chain. |
|
|
85
|
+
| `render` | object | | Replace a slot element: `({ props, state, children }) => node`. |
|
|
86
|
+
| `renderItem` | function | | Replace a whole row: `({ state, props, header, panel }) => node`. |
|
|
87
|
+
| `onValueChange` | function | | `(ids, details)`. `details: { id, open, reason: 'click' \| 'keyboard' \| 'api' \| 'find-in-page' \| 'hash', event }`. |
|
|
88
|
+
| `onBeforeChange` | function | | `(details) => boolean \| void`. Return `false` to block the change. |
|
|
89
|
+
| `onItemToggle` | function | | `(id, open)`, after `onValueChange`. |
|
|
90
|
+
|
|
91
|
+
## Row options (`items[]`)
|
|
92
|
+
|
|
93
|
+
| Option | Type | Default | Description |
|
|
94
|
+
|---|---|---|---|
|
|
95
|
+
| `id` | string | | Stable key. Falls back to the array index. |
|
|
96
|
+
| `title` (required) | node | | The row heading. A node or `(state) => node`. |
|
|
97
|
+
| `content` | node | | The panel body. |
|
|
98
|
+
| `description` | node | | A secondary line under the title. |
|
|
99
|
+
| `icon` | node | | A leading visual. |
|
|
100
|
+
| `badge` | node | | A trailing chip before the indicator. |
|
|
101
|
+
| `indicator` | "chevron" \| "plus" \| "caret" \| "arrow" \| "none" \| node | | Overrides the accordion-wide indicator for this row. |
|
|
102
|
+
| `disabled` | boolean | | Blocks toggling. The row stays focusable. |
|
|
103
|
+
| `defaultOpen` | boolean | | Open on first render (uncontrolled only). |
|
|
104
|
+
| `classNames` | object | | Per-row classes, by slot. |
|
|
105
|
+
| `styles` | object | | Per-row inline styles, by slot. |
|
|
106
|
+
|
|
107
|
+
## Slots
|
|
108
|
+
|
|
109
|
+
`root`, `item`, `header`, `trigger`, `icon`, `label`, `title`, `description`, `badge`, `indicator`, `panel`, `content`
|
|
110
|
+
|
|
111
|
+
## Keyboard
|
|
112
|
+
|
|
113
|
+
- **Enter / Space**: Toggle the focused row.
|
|
114
|
+
- **ArrowDown / ArrowUp**: Next / previous header (ArrowRight / ArrowLeft when horizontal; flipped in RTL). Wraps when `loop`.
|
|
115
|
+
- **Home / End**: First / last header.
|
|
116
|
+
- **Tab**: Leaves the header list. Closed panels are not in the tab order.
|
|
117
|
+
|
|
118
|
+
## Accessibility
|
|
119
|
+
|
|
120
|
+
- Each trigger is a `<button>` inside a heading with `aria-level`.
|
|
121
|
+
- Triggers carry `aria-expanded` and `aria-controls` pointing at their panel.
|
|
122
|
+
- Each panel is `role="region"` with `aria-labelledby` pointing at its trigger.
|
|
123
|
+
- Disabled rows use `aria-disabled` and stay focusable.
|
|
124
|
+
- Closed panels leave the accessibility tree and the tab order.
|
|
125
|
+
|
|
126
|
+
## Data attributes
|
|
127
|
+
|
|
128
|
+
- `data-state` on item, header, trigger, panel: "open" | "closed"
|
|
129
|
+
- `data-disabled` on item, trigger: present when disabled
|
|
130
|
+
- `data-index` on item: row index
|
|
131
|
+
- `data-orientation` on root: "vertical" | "horizontal"
|
|
132
|
+
- `data-mode` on root: "single" | "multiple"
|
|
133
|
+
- `data-transition` on panel: "opening" | "closing", while animating
|
package/llms.txt
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Pinfold
|
|
2
|
+
|
|
3
|
+
> Hooks-first, config-driven, accessible React UI (v0.1.0). One config object in, an accessible, themed, responsive component out. React 18+, Server Components, plain JS or TypeScript.
|
|
4
|
+
|
|
5
|
+
Rules for generating Pinfold code:
|
|
6
|
+
- Data goes in `items` (or raw records plus `fields`); everything else is optional with good defaults.
|
|
7
|
+
- Client: `const Faq = useAccordion({ items }); return <Faq />`. Server Component: `const Faq = defineAccordion({ items }); return <Faq />`. Same import path.
|
|
8
|
+
- Styles: `import '@pinfold/css/core.css'` once, then `@pinfold/css/<name>.css` per component, in the app entry. Never import CSS from library code.
|
|
9
|
+
- Global defaults: `defineConfig({ theme, radius, stylePack, defaults: { <name>: {...} } })` passed to `<PinfoldProvider config>`.
|
|
10
|
+
- Customise in this order: config, then `classNames`/`styles`/`slotProps`, then `render` per slot, then parts (`<Faq.Panel id>`), then prop getters.
|
|
11
|
+
- Never pass functions from a Server Component; plain data and server-rendered JSX only.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
- `npx pinfold init` (or `npm i @pinfold/react @pinfold/css`)
|
|
16
|
+
- shadcn: `npx shadcn add @pinfold/<name>` with `"registries": { "@pinfold": "https://pinfold.indranildev.in/r/{name}.json" }` in components.json
|
|
17
|
+
|
|
18
|
+
## Components
|
|
19
|
+
|
|
20
|
+
- [Accordion](https://pinfold.indranildev.in/docs/accordion): A vertically stacked set of headings that each reveal a section of content. Config in, accessible accordion out. Import `@pinfold/react/accordion`. Schema: `schema/accordion.json`.
|
|
21
|
+
|
|
22
|
+
## Reference
|
|
23
|
+
|
|
24
|
+
- [Full reference](https://pinfold.indranildev.in/llms-full.txt): every option of every component (also `llms-full.txt` in this package)
|
|
25
|
+
- [Theming](https://pinfold.indranildev.in/docs/theming): `npx pinfold theme`, style packs (glass, bauhaus, brutalist, noise, soft), DTCG tokens
|
|
26
|
+
- Local MCP server: `npx pinfold mcp` (tools: list_components, get_component, get_schema, validate_config, get_install_steps)
|
package/package.json
CHANGED
|
@@ -1,6 +1,94 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pinfold/react",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Pinfold for React: hooks-first, config-driven, accessible components. One subpath per component.",
|
|
5
|
+
"author": "Indranil Bhattacharya",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"react",
|
|
8
|
+
"ui",
|
|
9
|
+
"components",
|
|
10
|
+
"accordion",
|
|
11
|
+
"hooks",
|
|
12
|
+
"accessibility",
|
|
13
|
+
"aria",
|
|
14
|
+
"design-system",
|
|
15
|
+
"pinfold"
|
|
16
|
+
],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"homepage": "https://pinfold.indranildev.in",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/IndranilBhattacharya/pinfold.git",
|
|
22
|
+
"directory": "packages/react"
|
|
23
|
+
},
|
|
24
|
+
"bugs": "https://github.com/IndranilBhattacharya/pinfold/issues",
|
|
25
|
+
"sideEffects": false,
|
|
26
|
+
"type": "module",
|
|
27
|
+
"main": "./dist/index.cjs",
|
|
28
|
+
"module": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"import": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"default": "./dist/index.js"
|
|
35
|
+
},
|
|
36
|
+
"require": {
|
|
37
|
+
"types": "./dist/index.d.cts",
|
|
38
|
+
"default": "./dist/index.cjs"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"./accordion": {
|
|
42
|
+
"import": {
|
|
43
|
+
"types": "./dist/accordion/index.d.ts",
|
|
44
|
+
"default": "./dist/accordion/index.js"
|
|
45
|
+
},
|
|
46
|
+
"require": {
|
|
47
|
+
"types": "./dist/accordion/index.d.cts",
|
|
48
|
+
"default": "./dist/accordion/index.cjs"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"./accordion/lazy": {
|
|
52
|
+
"import": {
|
|
53
|
+
"types": "./dist/accordion/lazy.d.ts",
|
|
54
|
+
"default": "./dist/accordion/lazy.js"
|
|
55
|
+
},
|
|
56
|
+
"require": {
|
|
57
|
+
"types": "./dist/accordion/lazy.d.cts",
|
|
58
|
+
"default": "./dist/accordion/lazy.cjs"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"./package.json": "./package.json"
|
|
62
|
+
},
|
|
63
|
+
"typesVersions": {
|
|
64
|
+
"*": {
|
|
65
|
+
"accordion": [
|
|
66
|
+
"./dist/accordion/index.d.cts"
|
|
67
|
+
],
|
|
68
|
+
"accordion/lazy": [
|
|
69
|
+
"./dist/accordion/lazy.d.cts"
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"files": [
|
|
74
|
+
"dist",
|
|
75
|
+
"accordion",
|
|
76
|
+
"registry",
|
|
77
|
+
"schema",
|
|
78
|
+
"llms.txt",
|
|
79
|
+
"llms-full.txt"
|
|
80
|
+
],
|
|
81
|
+
"scripts": {
|
|
82
|
+
"build": "rimraf dist && tsup && node ../../scripts/subpath-stubs.mjs && node ../../scripts/generate-artifacts.mjs"
|
|
83
|
+
},
|
|
84
|
+
"dependencies": {
|
|
85
|
+
"@pinfold/core": "0.1.0"
|
|
86
|
+
},
|
|
87
|
+
"peerDependencies": {
|
|
88
|
+
"react": ">=18"
|
|
89
|
+
},
|
|
90
|
+
"publishConfig": {
|
|
91
|
+
"access": "public",
|
|
92
|
+
"provenance": true
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "accordion",
|
|
4
|
+
"type": "registry:ui",
|
|
5
|
+
"title": "Accordion",
|
|
6
|
+
"description": "A vertically stacked set of headings that each reveal a section of content. Config in, accessible accordion out.",
|
|
7
|
+
"dependencies": [
|
|
8
|
+
"@pinfold/react@^0.1.0",
|
|
9
|
+
"@pinfold/css@^0.1.0"
|
|
10
|
+
],
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"path": "components/ui/accordion.tsx",
|
|
14
|
+
"type": "registry:ui",
|
|
15
|
+
"target": "components/ui/accordion.tsx",
|
|
16
|
+
"content": "import '@pinfold/css/core.css';\nimport '@pinfold/css/accordion.css';\n\n/**\n * Pinfold accordion. This file is yours: import from here across the app,\n * and change shared defaults in one place.\n * Docs: https://pinfold.indranildev.in/docs/accordion\n */\nexport { useAccordion, defineAccordion, Accordion } from '@pinfold/react/accordion';\nexport type { AccordionConfig, AccordionItemConfig, AccordionApi } from '@pinfold/react/accordion';\n"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"docs": "https://pinfold.indranildev.in/docs/accordion"
|
|
20
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry.json",
|
|
3
|
+
"name": "pinfold",
|
|
4
|
+
"homepage": "https://pinfold.indranildev.in",
|
|
5
|
+
"items": [
|
|
6
|
+
{
|
|
7
|
+
"name": "accordion",
|
|
8
|
+
"type": "registry:ui",
|
|
9
|
+
"title": "Accordion",
|
|
10
|
+
"description": "A vertically stacked set of headings that each reveal a section of content. Config in, accessible accordion out.",
|
|
11
|
+
"dependencies": [
|
|
12
|
+
"@pinfold/react@^0.1.0",
|
|
13
|
+
"@pinfold/css@^0.1.0"
|
|
14
|
+
],
|
|
15
|
+
"files": [
|
|
16
|
+
{
|
|
17
|
+
"path": "components/ui/accordion.tsx",
|
|
18
|
+
"type": "registry:ui",
|
|
19
|
+
"target": "components/ui/accordion.tsx"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"docs": "https://pinfold.indranildev.in/docs/accordion"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|