@darthcharles/greda 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -226
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/index.js +299 -299
- package/dist/index.js.map +1 -1
- package/dist/lib/utils.d.ts +1 -1
- package/dist/styles.css +1 -1
- package/dist/tokens.css +93 -0
- package/dist/utils.js +5 -6
- package/dist/utils.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,50 +1,82 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Greda
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Composable React components with a neutral base theme and CSS tokens you control.
|
|
4
|
+
Built from shadcn/ui New York and Radix primitives, with compiled styles and
|
|
5
|
+
TypeScript declarations. Supports React 18 and 19; no Tailwind setup required.
|
|
6
|
+
|
|
7
|
+
**[Explore Storybook](https://elegant-hotteok-cbb834.netlify.app/)** ·
|
|
8
|
+
[Theming guide](https://elegant-hotteok-cbb834.netlify.app/?path=/docs/introduction-overview--theming) ·
|
|
9
|
+
[Design tokens](https://elegant-hotteok-cbb834.netlify.app/?path=/story/design-tokens--overview)
|
|
6
10
|
|
|
7
11
|
## Quick start
|
|
8
12
|
|
|
13
|
+
Install into an existing React application with React and React DOM 18.2+ or 19:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @darthcharles/greda
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Import the stylesheet once at your application's entry point:
|
|
20
|
+
|
|
9
21
|
```tsx
|
|
10
|
-
import { Button, Input, Label } from "@darthcharles/greda";
|
|
11
22
|
import "@darthcharles/greda/styles.css";
|
|
12
|
-
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Then import the components you need:
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { Button } from "@darthcharles/greda";
|
|
13
29
|
|
|
14
30
|
export function Example() {
|
|
15
|
-
return
|
|
16
|
-
<>
|
|
17
|
-
<Label htmlFor="name">Name</Label>
|
|
18
|
-
<Input id="name" />
|
|
19
|
-
<Button>Continue</Button>
|
|
20
|
-
</>
|
|
21
|
-
);
|
|
31
|
+
return <Button>Continue</Button>;
|
|
22
32
|
}
|
|
23
33
|
```
|
|
24
34
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
The stylesheet includes a ready-to-use base theme, CSS tokens, and scoped
|
|
36
|
+
component styles. No custom theme or additional CSS is required to use Greda.
|
|
37
|
+
Your application controls its own page layout, backgrounds, and fonts. React
|
|
38
|
+
and React DOM remain peer dependencies outside the ESM bundle.
|
|
39
|
+
|
|
40
|
+
Visit [Storybook](https://elegant-hotteok-cbb834.netlify.app/) for component APIs,
|
|
41
|
+
variants, interaction examples, and accessibility guidance.
|
|
42
|
+
|
|
43
|
+
Greda and application markup share unprefixed utility classes such as
|
|
44
|
+
`bg-primary`, `text-foreground`, and `border-primary`. Pass them through
|
|
45
|
+
`className` to override component defaults. See the theming guide for supported
|
|
46
|
+
utilities and migration from `ds-*` classes.
|
|
47
|
+
|
|
48
|
+
## With Tailwind 4
|
|
49
|
+
|
|
50
|
+
Import Greda's tokens in your app's Tailwind CSS entry point. This registers the
|
|
51
|
+
theme so Tailwind can generate utilities without a preset or manual mappings:
|
|
30
52
|
|
|
31
53
|
```css
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
54
|
+
@import "tailwindcss";
|
|
55
|
+
@import "@darthcharles/greda/tokens.css";
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
<div className="bg-primary p-4 text-primary-foreground hover:bg-primary-hover">
|
|
60
|
+
Your content
|
|
61
|
+
</div>
|
|
37
62
|
```
|
|
38
63
|
|
|
39
|
-
|
|
64
|
+
To use Greda components too, add
|
|
65
|
+
`@import "@darthcharles/greda/styles.css" layer(components);` between those two
|
|
66
|
+
imports, instead of importing `styles.css` again in JavaScript. The layer lets
|
|
67
|
+
your generated utilities override component styles, including responsive variants.
|
|
68
|
+
The import-only theme integration requires Tailwind 4; Greda's precompiled
|
|
69
|
+
component styles also work without Tailwind.
|
|
40
70
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
71
|
+
## Theming
|
|
72
|
+
|
|
73
|
+
Customization is optional. To change the default theme, import your own
|
|
74
|
+
`theme.css` after the package stylesheet and override only the tokens you need.
|
|
75
|
+
Unspecified values keep their base defaults, and components and color utilities
|
|
76
|
+
automatically use your overrides:
|
|
45
77
|
|
|
46
78
|
```css
|
|
47
|
-
/*
|
|
79
|
+
/* theme.css */
|
|
48
80
|
:root {
|
|
49
81
|
--primary: 9.500 55.556% 42.353%;
|
|
50
82
|
--primary-hover: 9.714 56.150% 36.667%;
|
|
@@ -54,210 +86,40 @@ Token names and value formats are part of the versioned public API.
|
|
|
54
86
|
}
|
|
55
87
|
```
|
|
56
88
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
verify contrast in your theme. The base theme downloads no external fonts.
|
|
60
|
-
Comal's brand overrides belong in its consuming application.
|
|
61
|
-
|
|
62
|
-
Set `data-color-scheme="dark"` on `<html>` to opt into the base dark palette.
|
|
63
|
-
Brand identity and color scheme are independent. A consumer can customize dark
|
|
64
|
-
mode using `:root[data-color-scheme="dark"]` overrides.
|
|
65
|
-
|
|
66
|
-
Apply themes on `<html>` so portaled dialogs, selects, and tooltips inherit them.
|
|
67
|
-
For themes scoped to a subtree, pass the themed element to the content component's
|
|
68
|
-
`container` prop. `@darthcharles/greda/tokens.css` exports just the tokens;
|
|
69
|
-
`styles.css` already includes them.
|
|
70
|
-
|
|
71
|
-
### Base token reference
|
|
72
|
-
|
|
73
|
-
| Token | Default |
|
|
74
|
-
| --- | --- |
|
|
75
|
-
| `--background` | `0 0% 100%` |
|
|
76
|
-
| `--foreground` | `222 47% 11%` |
|
|
77
|
-
| `--card` | `0 0% 100%` |
|
|
78
|
-
| `--card-foreground` | `222 47% 11%` |
|
|
79
|
-
| `--popover` | `0 0% 100%` |
|
|
80
|
-
| `--popover-foreground` | `222 47% 11%` |
|
|
81
|
-
| `--accent` | `220 20% 94%` |
|
|
82
|
-
| `--accent-foreground` | `222 35% 20%` |
|
|
83
|
-
| `--primary` | `220 80% 45%` |
|
|
84
|
-
| `--primary-foreground` | `0 0% 100%` |
|
|
85
|
-
| `--primary-hover` | `220 80% 38%` |
|
|
86
|
-
| `--secondary` | `220 20% 94%` |
|
|
87
|
-
| `--secondary-foreground` | `222 35% 20%` |
|
|
88
|
-
| `--muted` | `220 15% 96%` |
|
|
89
|
-
| `--muted-foreground` | `220 10% 42%` |
|
|
90
|
-
| `--border` | `220 15% 82%` |
|
|
91
|
-
| `--input` | `220 15% 82%` |
|
|
92
|
-
| `--ring` | `220 80% 45%` |
|
|
93
|
-
| `--destructive` | `0 72% 43%` |
|
|
94
|
-
| `--destructive-foreground` | `0 0% 100%` |
|
|
95
|
-
| `--overlay` | `222 47% 11% / 0.4` |
|
|
96
|
-
| `--font-sans` | `system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif` |
|
|
97
|
-
| `--font-heading` | `var(--font-sans)` |
|
|
98
|
-
| `--font-size-xs` | `0.75rem` |
|
|
99
|
-
| `--font-size-sm` | `0.8125rem` |
|
|
100
|
-
| `--font-size-md` | `0.875rem` |
|
|
101
|
-
| `--font-size-lg` | `1.25rem` |
|
|
102
|
-
| `--font-weight-medium` | `500` |
|
|
103
|
-
| `--font-weight-bold` | `600` |
|
|
104
|
-
| `--line-height` | `1.5` |
|
|
105
|
-
| `--spacing-unit` | `0.25rem` |
|
|
106
|
-
| `--space-0` | `calc(var(--spacing-unit) * 0)` |
|
|
107
|
-
| `--space-0-5` | `calc(var(--spacing-unit) * 0.5)` |
|
|
108
|
-
| `--space-1` | `calc(var(--spacing-unit) * 1)` |
|
|
109
|
-
| `--space-1-5` | `calc(var(--spacing-unit) * 1.5)` |
|
|
110
|
-
| `--space-2` | `calc(var(--spacing-unit) * 2)` |
|
|
111
|
-
| `--space-2-5` | `calc(var(--spacing-unit) * 2.5)` |
|
|
112
|
-
| `--space-3` | `calc(var(--spacing-unit) * 3)` |
|
|
113
|
-
| `--space-3-5` | `calc(var(--spacing-unit) * 3.5)` |
|
|
114
|
-
| `--space-4` | `calc(var(--spacing-unit) * 4)` |
|
|
115
|
-
| `--space-5` | `calc(var(--spacing-unit) * 5)` |
|
|
116
|
-
| `--space-6` | `calc(var(--spacing-unit) * 6)` |
|
|
117
|
-
| `--space-8` | `calc(var(--spacing-unit) * 8)` |
|
|
118
|
-
| `--space-9` | `calc(var(--spacing-unit) * 9)` |
|
|
119
|
-
| `--space-10` | `calc(var(--spacing-unit) * 10)` |
|
|
120
|
-
| `--space-12` | `calc(var(--spacing-unit) * 12)` |
|
|
121
|
-
| `--space-16` | `calc(var(--spacing-unit) * 16)` |
|
|
122
|
-
| `--space-20` | `calc(var(--spacing-unit) * 20)` |
|
|
123
|
-
| `--space-24` | `calc(var(--spacing-unit) * 24)` |
|
|
124
|
-
| `--space-32` | `calc(var(--spacing-unit) * 32)` |
|
|
125
|
-
| `--radius` | `0.5rem` |
|
|
126
|
-
| `--radius-sm` | `calc(var(--radius) * 0.6)` |
|
|
127
|
-
| `--radius-full` | `9999px` |
|
|
128
|
-
| `--radius-lg` | `calc(var(--radius) * 1.5)` |
|
|
129
|
-
| `--border-width` | `1px` |
|
|
130
|
-
| `--dialog-width` | `32.5rem` |
|
|
131
|
-
| `--tooltip-width` | `20rem` |
|
|
132
|
-
| `--toast-width` | `24rem` |
|
|
133
|
-
| `--shadow-sm` | `0 1px 2px hsl(222 47% 11% / 0.08)` |
|
|
134
|
-
| `--shadow` | `0 8px 24px hsl(222 47% 11% / 0.12)` |
|
|
135
|
-
| `--shadow-dialog` | `0 24px 70px hsl(222 47% 11% / 0.24)` |
|
|
136
|
-
| `--focus-width` | `2px` |
|
|
137
|
-
| `--focus-offset` | `2px` |
|
|
138
|
-
| `--disabled-opacity` | `0.5` |
|
|
139
|
-
| `--duration` | `150ms` |
|
|
140
|
-
| `--z-overlay` | `50` |
|
|
141
|
-
| `--z-popover` | `60` |
|
|
142
|
-
| `--z-toast` | `70` |
|
|
143
|
-
|
|
144
|
-
The **Design Tokens** section in Storybook shows every token's value and a live
|
|
145
|
-
preview: color swatches, typography samples, spacing bars, corner shapes, shadows,
|
|
146
|
-
focus outlines, motion, opacity, sizing, and stacking layers. Its examples update
|
|
147
|
-
with the theme and color-scheme toolbar. The catalog reads directly from the token
|
|
148
|
-
stylesheet. Run `npm run docs:tokens` after editing tokens to refresh the reference
|
|
149
|
-
table in this README.
|
|
150
|
-
|
|
151
|
-
`--spacing-unit` scales the spacing utilities used by components. Named steps such
|
|
152
|
-
as `--space-1` (4px), `--space-2` (8px), `--space-4` (16px), and `--space-8` (32px)
|
|
153
|
-
derive from that unit. Override a single step to adjust every component utility
|
|
154
|
-
that uses it. Fractional steps use a hyphen, for example `--space-0-5` (2px).
|
|
89
|
+
Colors use space-separated HSL channels without an `hsl()` wrapper;
|
|
90
|
+
`--overlay` also includes alpha. Other tokens accept ordinary CSS values.
|
|
155
91
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
92
|
+
Spacing tokens such as `--space-4` are shared distances for padding, margin, and
|
|
93
|
+
gap. Use them directly in your own CSS when needed; layout rules are optional
|
|
94
|
+
examples, not theme setup. If you only need tokens, import
|
|
95
|
+
`@darthcharles/greda/tokens.css` instead of `styles.css`.
|
|
96
|
+
|
|
97
|
+
Set `data-color-scheme="dark"` on `<html>` for the base dark palette. Brand
|
|
98
|
+
overrides need matching dark colors. Apply themes to `<html>` so portaled
|
|
99
|
+
content inherits them; scoped themes use the content component's `container` prop.
|
|
161
100
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
are constrained to the viewport. Use composition and `className` for layout
|
|
167
|
-
changes and application-specific styling.
|
|
168
|
-
|
|
169
|
-
## Components and Storybook
|
|
170
|
-
|
|
171
|
-
| Component | Storybook source |
|
|
172
|
-
| --------- | -------------------------------------------------------------------- |
|
|
173
|
-
| Button | [src/stories/Button.stories.tsx](src/stories/Button.stories.tsx) |
|
|
174
|
-
| Input | [src/stories/Input.stories.tsx](src/stories/Input.stories.tsx) |
|
|
175
|
-
| Textarea | [src/stories/Textarea.stories.tsx](src/stories/Textarea.stories.tsx) |
|
|
176
|
-
| Label | [src/stories/Label.stories.tsx](src/stories/Label.stories.tsx) |
|
|
177
|
-
| Select | [src/stories/Select.stories.tsx](src/stories/Select.stories.tsx) |
|
|
178
|
-
| Dialog | [src/stories/Dialog.stories.tsx](src/stories/Dialog.stories.tsx) |
|
|
179
|
-
| Card | [src/stories/Card.stories.tsx](src/stories/Card.stories.tsx) |
|
|
180
|
-
| Badge | [src/stories/Badge.stories.tsx](src/stories/Badge.stories.tsx) |
|
|
181
|
-
| Checkbox | [src/stories/Checkbox.stories.tsx](src/stories/Checkbox.stories.tsx) |
|
|
182
|
-
| Tabs | [src/stories/Tabs.stories.tsx](src/stories/Tabs.stories.tsx) |
|
|
183
|
-
| Toast | [src/stories/Toast.stories.tsx](src/stories/Toast.stories.tsx) |
|
|
184
|
-
| Tooltip | [src/stories/Tooltip.stories.tsx](src/stories/Tooltip.stories.tsx) |
|
|
185
|
-
|
|
186
|
-
Each file contains default usage and relevant variants, sizes, disabled/loading,
|
|
187
|
-
validation, and keyboard documentation. The toolbar previews base/Comal themes
|
|
188
|
-
and light/dark color schemes. Noninteractive components do not invent loading
|
|
189
|
-
or disabled behavior. `npm run validate:stories` enforces one story file per
|
|
190
|
-
component. Storybook includes automatic prop documentation and an axe panel.
|
|
191
|
-
|
|
192
|
-
The public API follows shadcn's composition model:
|
|
193
|
-
|
|
194
|
-
- Button: `default`, `secondary`, `outline`, `ghost`, `destructive`, `link` variants;
|
|
195
|
-
`default`, `sm`, `lg`, `icon` sizes. `loading` sets `aria-busy` and disables native
|
|
196
|
-
buttons. Set a useful label such as `Saving…`. The default type is `button`;
|
|
197
|
-
pass `type="submit"` for forms. `asChild` supports links; disabled/loading
|
|
198
|
-
behavior is intended for native buttons.
|
|
199
|
-
- Input, Textarea, Label: native field props and refs. Associate visible labels
|
|
200
|
-
and connect errors using `aria-invalid` and `aria-describedby`.
|
|
201
|
-
- Select: SelectTrigger, SelectValue, SelectContent, SelectGroup, SelectLabel,
|
|
202
|
-
SelectItem, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton.
|
|
203
|
-
Controlled values use `onValueChange`.
|
|
204
|
-
- Dialog: DialogTrigger, DialogContent, DialogTitle, DialogDescription,
|
|
205
|
-
DialogHeader, DialogFooter, DialogClose, DialogOverlay, DialogPortal. Content
|
|
206
|
-
includes a built-in accessible close button. Include a title. Explicitly pass
|
|
207
|
-
`aria-describedby={undefined}` when there is no description.
|
|
208
|
-
- Card: CardHeader, CardTitle, CardDescription, CardContent, CardFooter.
|
|
209
|
-
- Badge: `default`, `secondary`, `outline`, `destructive` variants.
|
|
210
|
-
- Checkbox: boolean or `indeterminate` state; controlled `onCheckedChange`.
|
|
211
|
-
- Tabs: TabsList, TabsTrigger, TabsContent; horizontal/vertical orientation.
|
|
212
|
-
- Toast: ToastProvider, ToastViewport, ToastTitle, ToastDescription, ToastAction,
|
|
213
|
-
ToastClose. Supply one provider/viewport and control each toast's open state.
|
|
214
|
-
- Tooltip: TooltipProvider, TooltipTrigger, TooltipContent.
|
|
215
|
-
|
|
216
|
-
Radix remains a dependency of the shadcn components and supplies their keyboard
|
|
217
|
-
and ARIA behavior. Give icon buttons accessible names and keep critical errors
|
|
218
|
-
inline. `cn` is exported from the root and `@darthcharles/greda/utils`; it combines
|
|
219
|
-
conditional classes and merges conflicting `ds-` Tailwind utilities.
|
|
101
|
+
The [theming guide](https://elegant-hotteok-cbb834.netlify.app/?path=/docs/introduction-overview--theming)
|
|
102
|
+
covers fonts, dark mode, and scoped portals. Browse the
|
|
103
|
+
[interactive token catalog](https://elegant-hotteok-cbb834.netlify.app/?path=/story/design-tokens--overview)
|
|
104
|
+
or read the defaults in [tokens.css](src/styles/tokens.css).
|
|
220
105
|
|
|
221
106
|
## Development
|
|
222
107
|
|
|
223
|
-
Use Node 24
|
|
108
|
+
Use Node 24 and the committed npm lockfile:
|
|
224
109
|
|
|
225
110
|
```bash
|
|
111
|
+
nvm use
|
|
226
112
|
npm ci
|
|
227
|
-
npm run storybook
|
|
228
|
-
npm run check # types, interactions, stories, package, static catalog
|
|
229
|
-
npm run test:browser # render all stories, axe, theme/portal checks
|
|
230
|
-
npm pack # build a local package archive
|
|
113
|
+
npm run storybook
|
|
231
114
|
```
|
|
232
115
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
### shadcn source and updates
|
|
245
|
-
|
|
246
|
-
This package owns customized copies of the React 18-compatible New York component
|
|
247
|
-
sources and builds them with Tailwind 3.4. `components.json` records aliases, CSS,
|
|
248
|
-
style, and prefix settings. Original registry responses, hashes, and MIT license
|
|
249
|
-
are preserved in `upstream/shadcn-ui/`; see [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
|
250
|
-
|
|
251
|
-
To update, review changes against those snapshots and preserve the documented
|
|
252
|
-
local adaptations. `node scripts/fetch-shadcn.mjs` refreshes only the upstream
|
|
253
|
-
snapshots and manifest; it does not overwrite local components. Upstream CLI
|
|
254
|
-
updates may overwrite customizations, so review their diffs before keeping them.
|
|
255
|
-
|
|
256
|
-
### Versioning and publishing
|
|
257
|
-
|
|
258
|
-
Use `npm run changeset` for a change description, then `npm run version-packages`
|
|
259
|
-
to prepare the version and changelog. Compatible features use minors and fixes
|
|
260
|
-
use patches. Breaking prop, token, or export changes need explicit notes and a
|
|
261
|
-
minor bump before 1.0, then a major bump after 1.0. CI validates the package and
|
|
262
|
-
Storybook. `npm run release` validates and publishes through Changesets using
|
|
263
|
-
the maintainer's npm credentials. Publishing requires an explicit release action.
|
|
116
|
+
Storybook runs at [localhost:6006](http://localhost:6006). Run `npm run check`
|
|
117
|
+
for project validation, then `npm run test:browser` for Playwright checks.
|
|
118
|
+
|
|
119
|
+
See [Contributing](CONTRIBUTING.md) for build commands, Netlify hosting, upstream
|
|
120
|
+
sources, and release guidance.
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
[MIT](LICENSE) © 2026 Carlos Contreras. See
|
|
125
|
+
[Third-party notices](THIRD_PARTY_NOTICES.md) for upstream attribution.
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -13,7 +13,7 @@ Tailwind 3.4. Radix dependencies remain because they are used by those shadcn
|
|
|
13
13
|
components. The upstream Toast is maintained here as the explicit primitive API
|
|
14
14
|
requested for the initial component set.
|
|
15
15
|
|
|
16
|
-
Local adaptations: relative imports;
|
|
16
|
+
Local adaptations: relative imports; shared semantic color utilities; a scoped CSS baseline;
|
|
17
17
|
consumer token mapping; optional portal containers; button loading, 1px press feedback from the current Nova style, and a default
|
|
18
18
|
non-submit type; viewport bounds on dialogs; invalid-field styles; an accessible
|
|
19
19
|
toast close name; and a distinct indeterminate checkbox icon.
|