@structyl/core 1.0.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 +117 -0
- package/dist/index.cjs +1516 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +282 -0
- package/dist/index.d.ts +282 -0
- package/dist/index.mjs +1469 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 your-lib contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# @structyl/core
|
|
2
|
+
|
|
3
|
+
> Headless React primitives that power the structyl component library.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
`@structyl/core` is the low-level foundation underneath every styled component in [structyl](https://structyl.dev). It provides the unstyled, accessible building blocks — polymorphic elements, the `asChild` slot pattern, scoped contexts, focus management, presence/animation handling, and Floating UI–based positioning. If you are building your own headless components (or extending structyl), this is the package you compose from; most app authors will consume `@structyl/primitives` or `@structyl/styled` instead.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# pnpm
|
|
14
|
+
pnpm add @structyl/core
|
|
15
|
+
|
|
16
|
+
# npm
|
|
17
|
+
npm install @structyl/core
|
|
18
|
+
|
|
19
|
+
# yarn
|
|
20
|
+
yarn add @structyl/core
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`react` and `react-dom` (v18 or v19) are peer dependencies.
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
Build a polymorphic, accessible primitive using `Primitive` (with built-in `asChild`) and a typed context created with `createContext`:
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
'use client';
|
|
31
|
+
|
|
32
|
+
import * as React from 'react';
|
|
33
|
+
import { Primitive, createContext } from '@structyl/core';
|
|
34
|
+
|
|
35
|
+
interface ToggleContextValue {
|
|
36
|
+
pressed: boolean;
|
|
37
|
+
onToggle: () => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const [ToggleProvider, useToggleContext] = createContext<ToggleContextValue>('Toggle');
|
|
41
|
+
|
|
42
|
+
function Toggle({ children }: { children: React.ReactNode }) {
|
|
43
|
+
const [pressed, setPressed] = React.useState(false);
|
|
44
|
+
return (
|
|
45
|
+
<ToggleProvider pressed={pressed} onToggle={() => setPressed((p) => !p)}>
|
|
46
|
+
{children}
|
|
47
|
+
</ToggleProvider>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const ToggleButton = React.forwardRef<
|
|
52
|
+
HTMLButtonElement,
|
|
53
|
+
React.ComponentPropsWithRef<typeof Primitive.button>
|
|
54
|
+
>((props, ref) => {
|
|
55
|
+
const { pressed, onToggle } = useToggleContext('ToggleButton');
|
|
56
|
+
return (
|
|
57
|
+
<Primitive.button
|
|
58
|
+
ref={ref}
|
|
59
|
+
type="button"
|
|
60
|
+
aria-pressed={pressed}
|
|
61
|
+
data-state={pressed ? 'on' : 'off'}
|
|
62
|
+
onClick={onToggle}
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
ToggleButton.displayName = 'ToggleButton';
|
|
68
|
+
|
|
69
|
+
// `asChild` renders the behavior on your own element instead of a <button>:
|
|
70
|
+
// <ToggleButton asChild><MyLink href="/" /></ToggleButton>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Features
|
|
74
|
+
|
|
75
|
+
- **Polymorphic `Primitive`** — render `Primitive.button`, `Primitive.div`, etc., with first-class ref forwarding and an `asChild` prop on every node.
|
|
76
|
+
- **`Slot` / `Slottable`** — merge props, class names, styles, and event handlers onto a consumer-supplied child to implement `asChild`.
|
|
77
|
+
- **Typed contexts** — `createContext`, `createContextScope`, and `composeContextScopes` give descriptive errors outside a provider and avoid context leakage in nested or shared component families.
|
|
78
|
+
- **Focus management** — `FocusScope` traps and loops focus, and `useFocusGuards` inserts sentinel guards so Tab cannot escape an open layer.
|
|
79
|
+
- **Layer dismissal** — `DismissableLayer` handles Escape, outside-pointer, and outside-focus interactions for popovers, dialogs, and menus.
|
|
80
|
+
- **Presence & animation** — `Presence` / `usePresence` keep an element mounted until its exit CSS animation or transition finishes.
|
|
81
|
+
- **Positioning** — the `Popper` namespace wraps `@floating-ui/react` for anchored content with flip, shift, size, and arrow support.
|
|
82
|
+
- **Roving focus & collections** — `RovingFocusGroup` and `createCollection` provide arrow-key navigation over DOM-ordered items.
|
|
83
|
+
- **Accessibility helpers** — `VisuallyHidden`, `AccessibleIcon`, and `DirectionProvider` / `useDirection` for screen-reader labels and RTL awareness.
|
|
84
|
+
- **SSR-safe** — all browser access is guarded; primitives are marked `'use client'` and work in the Next.js App Router.
|
|
85
|
+
|
|
86
|
+
## API
|
|
87
|
+
|
|
88
|
+
| Export | Kind | Description |
|
|
89
|
+
| --- | --- | --- |
|
|
90
|
+
| `Primitive` | Components | Polymorphic elements (`button`, `div`, `span`, …) with `asChild` and ref forwarding. |
|
|
91
|
+
| `Slot`, `Slottable` | Component | Render a child with merged props; the engine behind `asChild`. |
|
|
92
|
+
| `createContext` | Function | Create a typed context that throws a helpful error outside its provider. |
|
|
93
|
+
| `createContextScope` | Function | Create a scoped context factory to prevent leakage across nested/shared families. |
|
|
94
|
+
| `composeContextScopes` | Function | Merge multiple scope factories into one. |
|
|
95
|
+
| `Portal` | Component | Render children into a container (defaults to `document.body`). |
|
|
96
|
+
| `Presence`, `usePresence` | Component / Hook | Defer unmount until exit animations complete. |
|
|
97
|
+
| `FocusScope` | Component | Trap, loop, and restore focus within a region. |
|
|
98
|
+
| `useFocusGuards` | Hook | Inject focus sentinel guards around the document body. |
|
|
99
|
+
| `DismissableLayer` | Component | Handle Escape and outside pointer/focus dismissal. |
|
|
100
|
+
| `RovingFocusGroup` | Component | Arrow-key roving tabindex navigation. |
|
|
101
|
+
| `createCollection` | Function | Track child items in DOM order. |
|
|
102
|
+
| `Popper` | Namespace | `Popper`, `Popper.Anchor`, `Popper.Content`, `Popper.Arrow` (Floating UI). |
|
|
103
|
+
| `Arrow` | Component | Standalone SVG arrow primitive. |
|
|
104
|
+
| `VisuallyHidden` | Component | Hide content visually while keeping it accessible. |
|
|
105
|
+
| `AccessibleIcon` | Component | Decorate an icon with an `aria-hidden` element and a hidden label. |
|
|
106
|
+
| `DirectionProvider`, `useDirection` | Component / Hook | Provide and read text direction (`ltr` / `rtl`). |
|
|
107
|
+
| `useScrollLock` | Hook | Lock body scroll without layout shift (reference-counted). |
|
|
108
|
+
|
|
109
|
+
Type definitions are exported alongside each component (e.g. `PrimitivePropsWithRef`, `SlotProps`, `PortalProps`, `PresenceProps`, `Direction`).
|
|
110
|
+
|
|
111
|
+
## Part of structyl
|
|
112
|
+
|
|
113
|
+
This package is part of [structyl](https://github.com/imirfanul/structyl) — the React UI library with structure. See the full documentation at [structyl.dev](https://structyl.dev).
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT
|