@entropix/react 0.1.0 → 0.1.1
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 +327 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# @entropix/react
|
|
2
|
+
|
|
3
|
+
React web components for the Entropix design system — accessible, styled with CSS custom properties, and powered by design tokens.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@entropix/react)
|
|
6
|
+
[](https://github.com/dev-manindepth/entropix/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @entropix/react @entropix/tokens
|
|
12
|
+
# or
|
|
13
|
+
pnpm add @entropix/react @entropix/tokens
|
|
14
|
+
# or
|
|
15
|
+
yarn add @entropix/react @entropix/tokens
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
**1. Import token CSS once** in your app entry (e.g., `globals.css` or `layout.tsx`):
|
|
21
|
+
|
|
22
|
+
```css
|
|
23
|
+
@import "@entropix/tokens/css";
|
|
24
|
+
@import "@entropix/tokens/themes/light";
|
|
25
|
+
@import "@entropix/tokens/themes/dark";
|
|
26
|
+
@import "@entropix/react/styles";
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Or import in JavaScript:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import "@entropix/tokens/css";
|
|
33
|
+
import "@entropix/tokens/themes/light";
|
|
34
|
+
import "@entropix/tokens/themes/dark";
|
|
35
|
+
import "@entropix/react/styles";
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**2. Use components:**
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import { Button, Toggle, Switch, Tabs, TabList, Tab, TabPanel } from "@entropix/react";
|
|
42
|
+
|
|
43
|
+
function App() {
|
|
44
|
+
return (
|
|
45
|
+
<div data-theme="light">
|
|
46
|
+
<Button variant="primary" size="md" onPress={() => alert("Clicked!")}>
|
|
47
|
+
Get Started
|
|
48
|
+
</Button>
|
|
49
|
+
|
|
50
|
+
<Toggle onChange={(checked) => console.log(checked)}>
|
|
51
|
+
Enable notifications
|
|
52
|
+
</Toggle>
|
|
53
|
+
|
|
54
|
+
<Tabs defaultSelectedKey="tab1">
|
|
55
|
+
<TabList>
|
|
56
|
+
<Tab value="tab1">Overview</Tab>
|
|
57
|
+
<Tab value="tab2">Details</Tab>
|
|
58
|
+
</TabList>
|
|
59
|
+
<TabPanel value="tab1">Overview content</TabPanel>
|
|
60
|
+
<TabPanel value="tab2">Details content</TabPanel>
|
|
61
|
+
</Tabs>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Components
|
|
68
|
+
|
|
69
|
+
### Button
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
<Button
|
|
73
|
+
variant="primary" // "primary" | "secondary" | "outline" | "ghost" | "danger"
|
|
74
|
+
size="md" // "sm" | "md" | "lg"
|
|
75
|
+
disabled={false}
|
|
76
|
+
loading={false}
|
|
77
|
+
onPress={() => {}}
|
|
78
|
+
as="a" // Polymorphic — render as any element
|
|
79
|
+
>
|
|
80
|
+
Click me
|
|
81
|
+
</Button>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
| Prop | Type | Default | Description |
|
|
85
|
+
|------|------|---------|-------------|
|
|
86
|
+
| `variant` | `string` | — | Visual variant (mapped via `data-variant` attribute) |
|
|
87
|
+
| `size` | `string` | — | Size variant (mapped via `data-size` attribute) |
|
|
88
|
+
| `disabled` | `boolean` | `false` | Disables the button |
|
|
89
|
+
| `loading` | `boolean` | `false` | Shows loading state |
|
|
90
|
+
| `onPress` | `() => void` | — | Click/press handler |
|
|
91
|
+
| `as` | `React.ElementType` | `"button"` | Render as a different element |
|
|
92
|
+
|
|
93
|
+
### Toggle
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
<Toggle
|
|
97
|
+
checked={isChecked}
|
|
98
|
+
defaultChecked={false}
|
|
99
|
+
onChange={(checked) => setChecked(checked)}
|
|
100
|
+
disabled={false}
|
|
101
|
+
label="Accessibility label"
|
|
102
|
+
/>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
| Prop | Type | Default | Description |
|
|
106
|
+
|------|------|---------|-------------|
|
|
107
|
+
| `checked` | `boolean` | — | Controlled checked state |
|
|
108
|
+
| `defaultChecked` | `boolean` | `false` | Initial state (uncontrolled) |
|
|
109
|
+
| `onChange` | `(checked: boolean) => void` | — | Change handler |
|
|
110
|
+
| `disabled` | `boolean` | `false` | Disables the toggle |
|
|
111
|
+
| `label` | `string` | — | Accessible label |
|
|
112
|
+
|
|
113
|
+
### Switch
|
|
114
|
+
|
|
115
|
+
Same API as Toggle but renders with `role="switch"` and switch-specific styling.
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<Switch onChange={(on) => console.log(on)} />
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Dialog
|
|
122
|
+
|
|
123
|
+
Compound component for modal dialogs with focus trapping and portal rendering.
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
<Dialog closeOnOverlayPress closeOnEscape modal role="dialog">
|
|
127
|
+
<DialogTrigger>Open Dialog</DialogTrigger>
|
|
128
|
+
<DialogOverlay />
|
|
129
|
+
<DialogContent>
|
|
130
|
+
<DialogTitle>Confirm Action</DialogTitle>
|
|
131
|
+
<DialogDescription>Are you sure you want to proceed?</DialogDescription>
|
|
132
|
+
<DialogClose>Close</DialogClose>
|
|
133
|
+
</DialogContent>
|
|
134
|
+
</Dialog>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
| Prop (Dialog) | Type | Default | Description |
|
|
138
|
+
|---------------|------|---------|-------------|
|
|
139
|
+
| `isOpen` | `boolean` | — | Controlled open state |
|
|
140
|
+
| `defaultOpen` | `boolean` | `false` | Initial state (uncontrolled) |
|
|
141
|
+
| `onOpenChange` | `(open: boolean) => void` | — | Open state change handler |
|
|
142
|
+
| `closeOnOverlayPress` | `boolean` | `true` | Close when clicking overlay |
|
|
143
|
+
| `closeOnEscape` | `boolean` | `true` | Close on Escape key |
|
|
144
|
+
| `modal` | `boolean` | `true` | Trap focus inside dialog |
|
|
145
|
+
| `role` | `"dialog" \| "alertdialog"` | `"dialog"` | ARIA role |
|
|
146
|
+
|
|
147
|
+
### Tabs
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
<Tabs
|
|
151
|
+
defaultSelectedKey="overview"
|
|
152
|
+
orientation="horizontal"
|
|
153
|
+
onSelectedKeyChange={(key) => console.log(key)}
|
|
154
|
+
>
|
|
155
|
+
<TabList>
|
|
156
|
+
<Tab value="overview">Overview</Tab>
|
|
157
|
+
<Tab value="api">API</Tab>
|
|
158
|
+
<Tab value="examples">Examples</Tab>
|
|
159
|
+
</TabList>
|
|
160
|
+
<TabPanel value="overview">Overview content</TabPanel>
|
|
161
|
+
<TabPanel value="api">API reference</TabPanel>
|
|
162
|
+
<TabPanel value="examples">Code examples</TabPanel>
|
|
163
|
+
</Tabs>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
| Prop (Tabs) | Type | Default | Description |
|
|
167
|
+
|-------------|------|---------|-------------|
|
|
168
|
+
| `selectedKey` | `string` | — | Controlled selected tab |
|
|
169
|
+
| `defaultSelectedKey` | `string` | — | Initial selected tab |
|
|
170
|
+
| `onSelectedKeyChange` | `(key: string) => void` | — | Selection change handler |
|
|
171
|
+
| `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Tab list direction |
|
|
172
|
+
| `disabled` | `boolean` | `false` | Disable all tabs |
|
|
173
|
+
| `disabledKeys` | `string[]` | `[]` | Disable specific tabs |
|
|
174
|
+
|
|
175
|
+
### Accordion
|
|
176
|
+
|
|
177
|
+
```tsx
|
|
178
|
+
<Accordion defaultExpandedKeys={["faq1"]} allowMultiple={false} collapsible>
|
|
179
|
+
<AccordionItem value="faq1">
|
|
180
|
+
<AccordionTrigger>What is Entropix?</AccordionTrigger>
|
|
181
|
+
<AccordionPanel>A cross-platform React design system.</AccordionPanel>
|
|
182
|
+
</AccordionItem>
|
|
183
|
+
<AccordionItem value="faq2">
|
|
184
|
+
<AccordionTrigger>How does theming work?</AccordionTrigger>
|
|
185
|
+
<AccordionPanel>Via CSS custom properties and data-theme attributes.</AccordionPanel>
|
|
186
|
+
</AccordionItem>
|
|
187
|
+
</Accordion>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
| Prop (Accordion) | Type | Default | Description |
|
|
191
|
+
|------------------|------|---------|-------------|
|
|
192
|
+
| `expandedKeys` | `string[]` | — | Controlled expanded items |
|
|
193
|
+
| `defaultExpandedKeys` | `string[]` | `[]` | Initial expanded items |
|
|
194
|
+
| `onExpandedKeysChange` | `(keys: string[]) => void` | — | Expansion change handler |
|
|
195
|
+
| `allowMultiple` | `boolean` | `false` | Allow multiple open sections |
|
|
196
|
+
| `collapsible` | `boolean` | `true` | Allow closing all sections |
|
|
197
|
+
|
|
198
|
+
### Menu
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
<Menu closeOnSelect loop>
|
|
202
|
+
<MenuTrigger>Actions</MenuTrigger>
|
|
203
|
+
<MenuContent>
|
|
204
|
+
<MenuItem index={0} onSelect={() => console.log("Edit")}>Edit</MenuItem>
|
|
205
|
+
<MenuItem index={1} onSelect={() => console.log("Delete")} disabled>Delete</MenuItem>
|
|
206
|
+
</MenuContent>
|
|
207
|
+
</Menu>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
| Prop (MenuItem) | Type | Default | Description |
|
|
211
|
+
|-----------------|------|---------|-------------|
|
|
212
|
+
| `index` | `number` | **required** | Item index for keyboard navigation |
|
|
213
|
+
| `onSelect` | `() => void` | — | Called when item is selected |
|
|
214
|
+
| `disabled` | `boolean` | `false` | Disables the item |
|
|
215
|
+
|
|
216
|
+
## Layout Primitives
|
|
217
|
+
|
|
218
|
+
### Stack
|
|
219
|
+
|
|
220
|
+
Vertical flex container with consistent spacing.
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
<Stack gap="md" align="center" fullWidth>
|
|
224
|
+
<Button>First</Button>
|
|
225
|
+
<Button>Second</Button>
|
|
226
|
+
</Stack>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
| Prop | Type | Default | Description |
|
|
230
|
+
|------|------|---------|-------------|
|
|
231
|
+
| `gap` | `"none" \| "xs" \| "sm" \| "md" \| "lg" \| "xl" \| "2xl"` | token default | Vertical spacing |
|
|
232
|
+
| `align` | `"start" \| "center" \| "end" \| "stretch"` | — | Cross-axis alignment |
|
|
233
|
+
| `fullWidth` | `boolean` | `false` | Stretch to full width |
|
|
234
|
+
| `as` | `React.ElementType` | `"div"` | Render as different element |
|
|
235
|
+
|
|
236
|
+
### Inline
|
|
237
|
+
|
|
238
|
+
Horizontal flex container.
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
<Inline gap="sm" align="center" justify="between" wrap>
|
|
242
|
+
<Button>Save</Button>
|
|
243
|
+
<Button variant="outline">Cancel</Button>
|
|
244
|
+
</Inline>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
| Prop | Type | Default | Description |
|
|
248
|
+
|------|------|---------|-------------|
|
|
249
|
+
| `gap` | `SpacingSize` | token default | Horizontal spacing |
|
|
250
|
+
| `align` | `"start" \| "center" \| "end" \| "stretch" \| "baseline"` | — | Cross-axis alignment |
|
|
251
|
+
| `justify` | `"start" \| "center" \| "end" \| "between" \| "around"` | — | Main-axis distribution |
|
|
252
|
+
| `wrap` | `boolean` | `false` | Allow wrapping |
|
|
253
|
+
|
|
254
|
+
### Container
|
|
255
|
+
|
|
256
|
+
Centered max-width container with responsive padding.
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
<Container maxWidth="lg" center>
|
|
260
|
+
<h1>Page content</h1>
|
|
261
|
+
</Container>
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
| Prop | Type | Default | Description |
|
|
265
|
+
|------|------|---------|-------------|
|
|
266
|
+
| `maxWidth` | `"xs" \| "sm" \| "md" \| "lg" \| "xl" \| "full"` | `"lg"` | Max width preset |
|
|
267
|
+
| `center` | `boolean` | `true` | Center horizontally |
|
|
268
|
+
|
|
269
|
+
### Divider
|
|
270
|
+
|
|
271
|
+
```tsx
|
|
272
|
+
<Divider orientation="horizontal" spacing="md" />
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Responsive Hooks
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
import { useBreakpoint, useBreakpointValue, useMediaQuery, BREAKPOINTS } from "@entropix/react";
|
|
279
|
+
|
|
280
|
+
// Get current breakpoint name
|
|
281
|
+
const bp = useBreakpoint(); // "base" | "sm" | "md" | "lg" | "xl" | "2xl"
|
|
282
|
+
|
|
283
|
+
// Check if at or above a breakpoint
|
|
284
|
+
const isDesktop = useBreakpointValue("lg"); // true/false
|
|
285
|
+
|
|
286
|
+
// Custom media query
|
|
287
|
+
const prefersDark = useMediaQuery("(prefers-color-scheme: dark)");
|
|
288
|
+
|
|
289
|
+
// Breakpoint pixel values
|
|
290
|
+
console.log(BREAKPOINTS); // { sm: 640, md: 768, lg: 1024, xl: 1280, "2xl": 1536 }
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Theming
|
|
294
|
+
|
|
295
|
+
Entropix uses CSS custom properties for theming. Set the `data-theme` attribute on any ancestor element:
|
|
296
|
+
|
|
297
|
+
```html
|
|
298
|
+
<!-- Light theme (default) -->
|
|
299
|
+
<div data-theme="light">...</div>
|
|
300
|
+
|
|
301
|
+
<!-- Dark theme -->
|
|
302
|
+
<div data-theme="dark">...</div>
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
All component styles use semantic token variables that automatically adapt to the active theme.
|
|
306
|
+
|
|
307
|
+
## CSS Architecture
|
|
308
|
+
|
|
309
|
+
Components use side-effect CSS imports — when you import a component, its styles are automatically included in your bundle. The `"sideEffects": ["**/*.css"]` in `package.json` ensures bundlers don't tree-shake the CSS.
|
|
310
|
+
|
|
311
|
+
CSS classes follow BEM-style naming: `.entropix-button`, `.entropix-button--primary`, `.entropix-button--md`.
|
|
312
|
+
|
|
313
|
+
To import all styles manually:
|
|
314
|
+
|
|
315
|
+
```css
|
|
316
|
+
@import "@entropix/react/styles";
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Related Packages
|
|
320
|
+
|
|
321
|
+
- [`@entropix/tokens`](https://www.npmjs.com/package/@entropix/tokens) — Design tokens (required peer)
|
|
322
|
+
- [`@entropix/core`](https://www.npmjs.com/package/@entropix/core) — Headless hooks (bundled dependency)
|
|
323
|
+
- [`@entropix/react-native`](https://www.npmjs.com/package/@entropix/react-native) — React Native components
|
|
324
|
+
|
|
325
|
+
## License
|
|
326
|
+
|
|
327
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entropix/react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "React (Web) components for the Entropix design system — styled with CSS custom properties and design tokens",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"dist"
|
|
52
52
|
],
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@entropix/core": "0.1.
|
|
54
|
+
"@entropix/core": "0.1.1"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"react": "^18.0.0 || ^19.0.0",
|