@phcdevworks/spectre-ui 0.4.0 β 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/README.md +62 -423
- package/dist/base.css +7 -8
- package/dist/components.css +337 -31
- package/dist/index.cjs +98 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +614 -108
- package/dist/index.d.cts +30 -3
- package/dist/index.d.ts +30 -3
- package/dist/index.js +84 -9
- package/dist/index.js.map +1 -1
- package/dist/tailwind/index.cjs +8 -1
- package/dist/tailwind/index.cjs.map +1 -1
- package/dist/tailwind/index.js +8 -1
- package/dist/tailwind/index.js.map +1 -1
- package/dist/utilities.css +163 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,49 +1,41 @@
|
|
|
1
1
|
# @phcdevworks/spectre-ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
### **The Blueprint (Layer 2 of the Spectre 8-Layer Arsenal)**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`@phcdevworks/spectre-ui` is the structural engine of the Spectre design system. It consumes the raw "DNA" from `@phcdevworks/spectre-tokens` and translates it into standard CSS, a localized Tailwind preset, and type-safe class recipes.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
π€ **[Contributing Guide](CONTRIBUTING.md)** | π **[Changelog](CHANGELOG.md)** | ποΈ **[Spectre Arsenal](https://github.com/phcdevworks)**
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
---
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
- β
Precompiled `base`, `components`, and `utilities` CSS bundles
|
|
13
|
-
- β
Type-safe recipes (`getButtonClasses`, `getCardClasses`, `getInputClasses`)
|
|
14
|
-
- β
Tailwind preset + helpers to generate a Spectre theme
|
|
15
|
-
- β
Framework-agnostic: works anywhere CSS and JavaScript run
|
|
11
|
+
## ποΈ Core Architecture
|
|
16
12
|
|
|
17
|
-
|
|
13
|
+
This package operates as a pure structural layer. It follows a strict **Zero-Hex Enforcement** policyβvisual values are imported via `--sp-*` variables, ensuring that if tokens change, the entire UI layer updates automatically.
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
- π **Token-Driven**: Fully compatible with `@phcdevworks/spectre-tokens` v2.0.0.
|
|
16
|
+
- π¦ **Precompiled CSS**: Ships `base`, `components`, and `utilities` bundles.
|
|
17
|
+
- π§ͺ **Type-Safe Recipes**: Pure JS/TS functions for generating framework-agnostic class strings.
|
|
18
|
+
- πͺοΈ **Tailwind Preset**: Mirrors the design scale into the Tailwind utility engine.
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
---
|
|
24
21
|
|
|
25
|
-
|
|
22
|
+
## π Quick Start
|
|
26
23
|
|
|
27
|
-
|
|
24
|
+
### Installation
|
|
28
25
|
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
import "@phcdevworks/spectre-ui/index.css";
|
|
26
|
+
```bash
|
|
27
|
+
npm install @phcdevworks/spectre-ui
|
|
32
28
|
```
|
|
33
29
|
|
|
34
|
-
|
|
30
|
+
### 1. Import CSS
|
|
31
|
+
For most applications, importing the unified `index.css` is recommended.
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
```css
|
|
39
|
-
@import "@phcdevworks/spectre-ui/base.css";
|
|
40
|
-
@import "@phcdevworks/spectre-ui/components.css";
|
|
41
|
-
@import "@phcdevworks/spectre-ui/utilities.css";
|
|
33
|
+
```ts
|
|
34
|
+
import "@phcdevworks/spectre-ui/index.css";
|
|
42
35
|
```
|
|
43
36
|
|
|
44
|
-
### 2. Tailwind
|
|
45
|
-
|
|
46
|
-
Spectre ships utilities to create Tailwind presets that mirror the design tokens exactly.
|
|
37
|
+
### 2. Tailwind Integration
|
|
38
|
+
Synchronize your Tailwind theme with the Spectre token scale.
|
|
47
39
|
|
|
48
40
|
```ts
|
|
49
41
|
// tailwind.config.ts
|
|
@@ -53,430 +45,77 @@ import { spectreTokens } from "@phcdevworks/spectre-tokens";
|
|
|
53
45
|
const spectrePreset = createSpectreTailwindPreset({ tokens: spectreTokens });
|
|
54
46
|
|
|
55
47
|
export default {
|
|
56
|
-
content: ["./src/**/*.{js,ts,jsx,tsx
|
|
48
|
+
content: ["./src/**/*.{js,ts,jsx,tsx}"],
|
|
57
49
|
presets: [spectrePreset],
|
|
58
50
|
};
|
|
59
51
|
```
|
|
60
52
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
**Custom preset:** Need to customize the preset or provide your own tokens?
|
|
64
|
-
|
|
65
|
-
```ts
|
|
66
|
-
// tailwind.config.ts
|
|
67
|
-
import { createSpectreTailwindPreset } from "@phcdevworks/spectre-ui/tailwind";
|
|
68
|
-
import { spectreTokens } from "@phcdevworks/spectre-tokens";
|
|
69
|
-
|
|
70
|
-
const customPreset = createSpectreTailwindPreset({
|
|
71
|
-
tokens: spectreTokens,
|
|
72
|
-
themeOverrides: {
|
|
73
|
-
colors: {
|
|
74
|
-
brand: {
|
|
75
|
-
500: "#ff6b6b",
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
export default {
|
|
82
|
-
content: ["./src/**/*.{js,ts,jsx,tsx,astro}"],
|
|
83
|
-
presets: [customPreset],
|
|
84
|
-
};
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**Plain theme object:** Need a plain theme object without presets? Generate it from the first-party tokens.
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
// tailwind.config.ts
|
|
91
|
-
import { createSpectreTailwindTheme } from "@phcdevworks/spectre-ui/tailwind";
|
|
92
|
-
import { spectreTokens } from "@phcdevworks/spectre-tokens";
|
|
93
|
-
|
|
94
|
-
const { theme } = createSpectreTailwindTheme({
|
|
95
|
-
tokens: spectreTokens,
|
|
96
|
-
overrides: {
|
|
97
|
-
spacing: {
|
|
98
|
-
...spectreTokens.spacing,
|
|
99
|
-
gutter: "1.125rem",
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
export default {
|
|
105
|
-
content: ["./src/**/*.{js,ts,jsx,tsx,astro}"],
|
|
106
|
-
theme,
|
|
107
|
-
};
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### 3. Use Spectre recipes
|
|
111
|
-
|
|
112
|
-
Recipes wrap Spectre's class combinations so every framework composes styles consistently.
|
|
113
|
-
|
|
114
|
-
```ts
|
|
115
|
-
import {
|
|
116
|
-
getButtonClasses,
|
|
117
|
-
getCardClasses,
|
|
118
|
-
getInputClasses,
|
|
119
|
-
getBadgeClasses,
|
|
120
|
-
getIconBoxClasses,
|
|
121
|
-
} from "@phcdevworks/spectre-ui";
|
|
122
|
-
|
|
123
|
-
const buttonClasses = getButtonClasses({
|
|
124
|
-
variant: "primary",
|
|
125
|
-
size: "lg",
|
|
126
|
-
fullWidth: true,
|
|
127
|
-
});
|
|
128
|
-
// "sp-btn sp-btn--primary sp-btn--lg sp-btn--full"
|
|
129
|
-
|
|
130
|
-
const cardClasses = getCardClasses({ variant: "outline", padded: true });
|
|
131
|
-
// "sp-card sp-card--outline sp-card--padded"
|
|
132
|
-
|
|
133
|
-
const inputClasses = getInputClasses({
|
|
134
|
-
state: "error",
|
|
135
|
-
size: "sm",
|
|
136
|
-
fullWidth: true,
|
|
137
|
-
});
|
|
138
|
-
// "sp-input sp-input--error sp-input--sm sp-input--full"
|
|
139
|
-
|
|
140
|
-
const badgeClasses = getBadgeClasses({ variant: "success", size: "sm" });
|
|
141
|
-
// "sp-badge sp-badge--success sp-badge--sm"
|
|
142
|
-
|
|
143
|
-
const iconBoxClasses = getIconBoxClasses({ variant: "info", size: "lg" });
|
|
144
|
-
// "sp-iconbox sp-iconbox--info sp-iconbox--lg"
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Component Surfaces
|
|
148
|
-
|
|
149
|
-
### Button variants
|
|
150
|
-
|
|
151
|
-
```ts
|
|
152
|
-
getButtonClasses({ variant: "primary" }); // CTA baseline
|
|
153
|
-
getButtonClasses({ variant: "secondary" }); // Outlined
|
|
154
|
-
getButtonClasses({ variant: "ghost" }); // Low-emphasis
|
|
155
|
-
getButtonClasses({ variant: "danger" }); // Destructive
|
|
156
|
-
getButtonClasses({ variant: "success" }); // Positive actions
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Each variant ships with full state coverage: `default`, `hover`, `active`, `disabled`.
|
|
160
|
-
|
|
161
|
-
```css
|
|
162
|
-
.cta-button {
|
|
163
|
-
background: var(--sp-component-button-primary-bg);
|
|
164
|
-
color: var(--sp-component-button-primary-text);
|
|
165
|
-
}
|
|
166
|
-
.cta-button:hover {
|
|
167
|
-
background: var(--sp-component-button-primary-bg-hover);
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### Input states
|
|
172
|
-
|
|
173
|
-
```ts
|
|
174
|
-
getInputClasses({ state: "default" });
|
|
175
|
-
getInputClasses({ state: "error" });
|
|
176
|
-
getInputClasses({ state: "success" });
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
```css
|
|
180
|
-
.input:focus {
|
|
181
|
-
border-color: var(--sp-component-input-border-focus);
|
|
182
|
-
outline: var(--sp-focus-ring-width) var(--sp-focus-ring-style) var(--sp-component-input-ring-focus);
|
|
183
|
-
}
|
|
184
|
-
.input.error {
|
|
185
|
-
border-color: var(--sp-component-input-border-error);
|
|
186
|
-
background: var(--sp-component-input-bg-error);
|
|
187
|
-
}
|
|
188
|
-
```
|
|
53
|
+
---
|
|
189
54
|
|
|
190
|
-
|
|
55
|
+
## π§© Class Recipes
|
|
191
56
|
|
|
192
|
-
|
|
193
|
-
getCardClasses({ variant: "elevated" }); // Default shadow
|
|
194
|
-
getCardClasses({ variant: "outline" }); // Bordered
|
|
195
|
-
getCardClasses({ variant: "ghost" }); // Transparent
|
|
196
|
-
```
|
|
57
|
+
Recipes are the API contract for all Spectre framework adapters. They ensure `.sp-btn--primary` always behaves identical whether used in React, Astro, or WordPress.
|
|
197
58
|
|
|
198
|
-
###
|
|
59
|
+
### Core Components
|
|
60
|
+
| Recipe | Primary Variants | Sizes |
|
|
61
|
+
| :--- | :--- | :--- |
|
|
62
|
+
| `getButtonClasses` | `primary`, `secondary`, `ghost`, `danger`, `success` | `sm`, `md`, `lg` |
|
|
63
|
+
| `getBadgeClasses` | `primary`, `success`, `warning`, `danger` | `sm`, `md`, `lg` |
|
|
64
|
+
| `getCardClasses` | `elevated`, `outline`, `ghost` | `padded` |
|
|
65
|
+
| `getInputClasses` | `default`, `error`, `success` | `sm`, `md`, `lg` |
|
|
66
|
+
| `getIconBoxClasses` | `primary`, `success`, `warning`, `danger`, `info` | `sm`, `md`, `lg` |
|
|
199
67
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
Available sizes: `sm`, `md`, `lg`
|
|
68
|
+
### Specialized Components
|
|
69
|
+
| Recipe | Description |
|
|
70
|
+
| :--- | :--- |
|
|
71
|
+
| `getPricingCardClasses` | Semantic structure for pricing tables and plans. |
|
|
72
|
+
| `getTestimonialClasses` | Compound classes for quotes, authors, and roles. |
|
|
73
|
+
| `getRatingClasses` | Layout recipes for star ratings and count labels. |
|
|
208
74
|
|
|
209
75
|
```ts
|
|
210
|
-
|
|
211
|
-
// "sp-badge sp-badge--success sp-badge--sm"
|
|
212
|
-
```
|
|
76
|
+
import { getButtonClasses, getPricingCardClasses } from "@phcdevworks/spectre-ui";
|
|
213
77
|
|
|
214
|
-
|
|
78
|
+
// Generate a primary CTA class string
|
|
79
|
+
const cta = getButtonClasses({ variant: "primary", size: "lg" });
|
|
80
|
+
// Result: "sp-btn sp-btn--primary sp-btn--lg"
|
|
215
81
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
getIconBoxClasses({ variant: "success" }); // Success state
|
|
219
|
-
getIconBoxClasses({ variant: "warning" }); // Warning state
|
|
220
|
-
getIconBoxClasses({ variant: "danger" }); // Danger/error state
|
|
221
|
-
getIconBoxClasses({ variant: "info" }); // Info state
|
|
82
|
+
// Generate pricing card layout
|
|
83
|
+
const pricing = getPricingCardClasses({ featured: true });
|
|
222
84
|
```
|
|
223
85
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
```ts
|
|
227
|
-
getIconBoxClasses({ variant: "info", size: "lg" });
|
|
228
|
-
// "sp-iconbox sp-iconbox--info sp-iconbox--lg"
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
## Surface & Typography Roles
|
|
232
|
-
|
|
233
|
-
Spectre exposes semantic layers that decouple structural styles from raw palette values. Override these roles at any scope (root, layout, or component wrapper) to restyle whole experiences without editing CSS.
|
|
234
|
-
|
|
235
|
-
- `surface.page`, `surface.card`, `surface.input`, `surface.overlay`: semantic backgrounds for the app canvas, containers/tiles, form fields, and modal/dropdown layers.
|
|
236
|
-
- `text.onPage.*` vs `text.onSurface.*`: use `onPage` for copy sitting directly on the page canvas; use `onSurface` for text inside cards, tiles, inputs, overlays, and other elevated surfaces.
|
|
237
|
-
- `component.card.text`/`textMuted`, `component.input.text`/`placeholder`, and `component.button.textDefault`/`textOnPrimary` alias the underlying `text.onSurface` roles to keep component defaults aligned.
|
|
238
|
-
|
|
239
|
-
### Tailwind utilities
|
|
240
|
-
|
|
241
|
-
The Tailwind preset exposes semantic helpers:
|
|
242
|
-
|
|
243
|
-
- `bg-surface-page`, `bg-surface-card`, `bg-surface-input`
|
|
244
|
-
- `text-on-page`, `text-on-surface`
|
|
245
|
-
|
|
246
|
-
Use them to mix utility-first UIs with Spectre's semantic palette.
|
|
247
|
-
|
|
248
|
-
### Mode infrastructure
|
|
249
|
-
|
|
250
|
-
Spectre reserves the `data-sp-mode` attribute (or any wrapper selector) for future automatic light/dark modes. Override the semantic variables inside those selectors today and you're ready for upcoming multi-mode token drops.
|
|
251
|
-
|
|
252
|
-
## Usage Examples
|
|
253
|
-
|
|
254
|
-
### Surface-aware components
|
|
255
|
-
|
|
256
|
-
```css
|
|
257
|
-
.hero-panel {
|
|
258
|
-
--sp-surface-card: var(--sp-color-neutral-900);
|
|
259
|
-
--sp-text-on-surface-default: var(--sp-color-neutral-50);
|
|
260
|
-
--sp-text-on-surface-muted: var(--sp-color-neutral-200);
|
|
261
|
-
--sp-component-button-primary-bg: var(--sp-color-accent-400);
|
|
262
|
-
--sp-component-button-primary-text: var(--sp-color-neutral-900);
|
|
263
|
-
--sp-component-card-border: transparent;
|
|
264
|
-
--sp-component-input-border: var(--sp-color-accent-400);
|
|
265
|
-
}
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
```html
|
|
269
|
-
<section class="hero-panel">
|
|
270
|
-
<button class="sp-btn sp-btn--primary">Surface Button</button>
|
|
271
|
-
<div class="sp-card sp-card--elevated">
|
|
272
|
-
<p>Cards inherit the contextual surface + text roles automatically.</p>
|
|
273
|
-
</div>
|
|
274
|
-
<input class="sp-input" placeholder="Email address" />
|
|
275
|
-
</section>
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
### Tailwind semantic utilities
|
|
279
|
-
|
|
280
|
-
```jsx
|
|
281
|
-
export function SignupCard() {
|
|
282
|
-
return (
|
|
283
|
-
<div className="bg-surface-card text-on-surface sp-card sp-card--padded">
|
|
284
|
-
<h2 className="text-on-page font-semibold">Join the beta</h2>
|
|
285
|
-
<input className="sp-input mt-4" placeholder="you@spectre.dev" />
|
|
286
|
-
<button className="sp-btn sp-btn--primary mt-4">Request access</button>
|
|
287
|
-
</div>
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
## CSS Path Constants
|
|
293
|
-
|
|
294
|
-
Utilities for referencing the published CSS files programmatically:
|
|
295
|
-
|
|
296
|
-
```ts
|
|
297
|
-
import {
|
|
298
|
-
spectreBaseStylesPath,
|
|
299
|
-
spectreComponentsStylesPath,
|
|
300
|
-
spectreUtilitiesStylesPath,
|
|
301
|
-
spectreStyles,
|
|
302
|
-
} from "@phcdevworks/spectre-ui";
|
|
303
|
-
|
|
304
|
-
// spectreStyles.base β "@phcdevworks/spectre-ui/base.css"
|
|
305
|
-
// spectreStyles.components β "@phcdevworks/spectre-ui/components.css"
|
|
306
|
-
// spectreStyles.utilities β "@phcdevworks/spectre-ui/utilities.css"
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
## Repository Layout
|
|
86
|
+
---
|
|
310
87
|
|
|
311
|
-
|
|
312
|
-
| ------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
313
|
-
| `src/` | TypeScript source: recipes, Tailwind preset, token re-exports, CSS constants. |
|
|
314
|
-
| `src/styles/` | Raw CSS files (`base.css`, `components.css`, `utilities.css`) copied to `dist/` during build. |
|
|
315
|
-
| `dist/` | Generated artifacts: `index.js`, `index.cjs`, `index.d.ts`, and CSS files. Regenerated via `npm run build`. |
|
|
88
|
+
## ποΈ The Spectre Suite Hierarchy
|
|
316
89
|
|
|
317
|
-
|
|
90
|
+
Spectre is built on a non-negotiable hierarchy to prevent style leakage and duplication:
|
|
318
91
|
|
|
319
|
-
|
|
92
|
+
1. **Layer 1: Tokens** ([@phcdevworks/spectre-tokens](https://github.com/phcdevworks/spectre-tokens)) β The source of truth for all design values.
|
|
93
|
+
2. **Layer 2: UI (This Package)** β Translates tokens into CSS structure and recipes.
|
|
94
|
+
3. **Layer 3: Adapters** (WordPress, Astro, etc.) β Thin bridges that map Layer 2 to specific frameworks.
|
|
320
95
|
|
|
321
|
-
The
|
|
96
|
+
> **The Golden Rule**: Tokens define *meaning*. UI defines *structure*. Adapters define *delivery*.
|
|
322
97
|
|
|
323
|
-
|
|
324
|
-
npm test
|
|
325
|
-
```
|
|
98
|
+
---
|
|
326
99
|
|
|
327
|
-
|
|
100
|
+
## π οΈ Development
|
|
328
101
|
|
|
329
|
-
|
|
102
|
+
### Build Pipeline
|
|
103
|
+
Compiles TypeScript, processes PostCSS, and bundles artifacts into `dist/`.
|
|
330
104
|
|
|
331
105
|
```bash
|
|
332
106
|
npm run build
|
|
333
107
|
```
|
|
334
108
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
1. **TypeScript & CSS Copy (via tsup):**
|
|
338
|
-
|
|
339
|
-
- Compiles the TypeScript source to ESM, CJS, and type definitions in `dist/`.
|
|
340
|
-
- Copies raw CSS files (`base.css`, `components.css`, `utilities.css`) from `src/styles/` to `dist/`.
|
|
341
|
-
|
|
342
|
-
2. **CSS Bundling (via PostCSS):**
|
|
343
|
-
|
|
344
|
-
- Processes `src/styles/index.css` with PostCSS (including imports and plugins) and outputs the bundled CSS as `dist/index.css`.
|
|
345
|
-
|
|
346
|
-
The `npm run build` script runs both steps in sequence:
|
|
109
|
+
### Testing
|
|
110
|
+
Run the Vitest suite to verify recipe outputs and token-first compliance.
|
|
347
111
|
|
|
348
112
|
```bash
|
|
349
|
-
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
This ensures all JavaScript, type definitions, and CSS bundles are up to date in `dist/` for publishing.
|
|
353
|
-
|
|
354
|
-
For release history and version notes, see the **[Changelog](CHANGELOG.md)**.
|
|
355
|
-
|
|
356
|
-
## Spectre Design Philosophy
|
|
357
|
-
|
|
358
|
-
Spectre is a **specification-driven design system** built on three strict layers:
|
|
359
|
-
|
|
360
|
-
### 1. @phcdevworks/spectre-tokens (Foundation)
|
|
361
|
-
|
|
362
|
-
**Purpose**: Single source of truth for design values (colors, surfaces, text roles, space, radii, shadows, etc.)
|
|
363
|
-
|
|
364
|
-
**Exports**: CSS variables (`--sp-*`), TypeScript token object, Tailwind-compatible theme mappings
|
|
365
|
-
|
|
366
|
-
**Rules**:
|
|
367
|
-
|
|
368
|
-
- Tokens define semantic meaning, not UI behavior
|
|
369
|
-
- UI must never invent new colors or values
|
|
370
|
-
- Designers own `tokens/*.json`; engineers maintain `src/` transforms
|
|
371
|
-
- Contrast targets and accessibility constraints are encoded at the token level
|
|
372
|
-
|
|
373
|
-
**Status**: v0.1.0 released with stable semantic roles (`surface.*`, `text.*`, `component.*`) and considered correct/locked
|
|
374
|
-
|
|
375
|
-
### 2. @phcdevworks/spectre-ui (Framework-Agnostic UI Layer)
|
|
376
|
-
|
|
377
|
-
**Purpose**: Converts tokens into real CSS and class recipes
|
|
378
|
-
|
|
379
|
-
**Ships**:
|
|
380
|
-
|
|
381
|
-
- `index.css` (canonical CSS bundle: tokens + base + components + utilities)
|
|
382
|
-
- `base.css` (resets + globals)
|
|
383
|
-
- `components.css` (`.sp-btn`, `.sp-card`, `.sp-input`, etc.)
|
|
384
|
-
- `utilities.css` (`.sp-stack`, `.sp-container`, etc.)
|
|
385
|
-
- Type-safe recipes: `getButtonClasses`, `getCardClasses`, `getInputClasses`
|
|
386
|
-
|
|
387
|
-
**Rules**:
|
|
388
|
-
|
|
389
|
-
- UI must consume tokens, not redefine design values
|
|
390
|
-
- Literal values in CSS are fallbacks only
|
|
391
|
-
- Every CSS selector has a matching recipe where applicable
|
|
392
|
-
- Tailwind preset is optional and non-authoritative
|
|
393
|
-
|
|
394
|
-
**Status**: v0.4.0 released with refactored component styles and enhanced CSS variable system
|
|
395
|
-
|
|
396
|
-
### 3. Framework Adapters (WordPress, Astro, 11ty)
|
|
397
|
-
|
|
398
|
-
**Purpose**: Thin adapter layer around spectre-ui; automatically syncs and enqueues the Spectre UI CSS bundle
|
|
399
|
-
|
|
400
|
-
**Rules**:
|
|
401
|
-
|
|
402
|
-
- Adapters never define styles, never duplicate CSS, never load tokens directly
|
|
403
|
-
- Adapters only synchronize and load CSS
|
|
404
|
-
- All design values come from tokens, all CSS comes from spectre-ui
|
|
405
|
-
|
|
406
|
-
**Status**: WordPress and Astro adapters at v0.1.0 with frontend and editor integration
|
|
407
|
-
|
|
408
|
-
### Golden Rule (Non-Negotiable)
|
|
409
|
-
|
|
410
|
-
**Tokens define meaning. UI defines structure. Adapters only translate.**
|
|
411
|
-
|
|
412
|
-
Frameworks never invent CSS or design valuesβthey only load what spectre-ui provides.
|
|
413
|
-
|
|
414
|
-
- If it's a design token β belongs in `@phcdevworks/spectre-tokens`
|
|
415
|
-
- If it's a CSS class or style β belongs in `@phcdevworks/spectre-ui`
|
|
416
|
-
- If it's framework integration (hooks, blocks, components) β belongs in the adapter
|
|
417
|
-
|
|
418
|
-
## Design Principles
|
|
419
|
-
|
|
420
|
-
1. **Single source of truth** β All Spectre products consume these styles and recipes.
|
|
421
|
-
2. **No style duplication** β Downstream frameworks never re-encode Spectre logic.
|
|
422
|
-
3. **Token-first** β The Tailwind preset, CSS, and recipes are generated from tokens.
|
|
423
|
-
4. **Framework agnostic** β Works with any bundler, CMS, or runtime.
|
|
424
|
-
5. **Type-safe ergonomics** β Every helper exports strict types for confident usage.
|
|
425
|
-
|
|
426
|
-
## TypeScript Support
|
|
427
|
-
|
|
428
|
-
Type definitions are bundled automatically:
|
|
429
|
-
|
|
430
|
-
```ts
|
|
431
|
-
import type {
|
|
432
|
-
ButtonVariant,
|
|
433
|
-
ButtonSize,
|
|
434
|
-
InputState,
|
|
435
|
-
InputSize,
|
|
436
|
-
CardVariant,
|
|
437
|
-
BadgeVariant,
|
|
438
|
-
BadgeSize,
|
|
439
|
-
IconBoxVariant,
|
|
440
|
-
IconBoxSize,
|
|
441
|
-
ButtonRecipeOptions,
|
|
442
|
-
CardRecipeOptions,
|
|
443
|
-
InputRecipeOptions,
|
|
444
|
-
BadgeRecipeOptions,
|
|
445
|
-
IconBoxRecipeOptions,
|
|
446
|
-
} from "@phcdevworks/spectre-ui";
|
|
447
|
-
|
|
448
|
-
import type {
|
|
449
|
-
SpectreTailwindTheme,
|
|
450
|
-
CreateSpectreTailwindThemeOptions,
|
|
451
|
-
CreateSpectreTailwindPresetOptions,
|
|
452
|
-
} from "@phcdevworks/spectre-ui/tailwind";
|
|
453
|
-
|
|
454
|
-
import type { SpectreTokens } from "@phcdevworks/spectre-tokens";
|
|
113
|
+
npm test
|
|
455
114
|
```
|
|
456
115
|
|
|
457
|
-
## Part of the Spectre Suite
|
|
458
|
-
|
|
459
|
-
- **Spectre Tokens** β Design-token foundation
|
|
460
|
-
- **Spectre UI** β Core styling layer (this package)
|
|
461
|
-
- **Spectre Blocks** β WordPress block library
|
|
462
|
-
- **Spectre Astro** β Astro integration
|
|
463
|
-
- **Spectre 11ty** β Eleventy integration
|
|
464
|
-
|
|
465
|
-
## Contributing
|
|
466
|
-
|
|
467
|
-
Issues and pull requests are welcome. If you are proposing style or recipe changes, update `src/` and include regenerated builds.
|
|
468
|
-
|
|
469
|
-
For detailed contribution guidelines, see **[CONTRIBUTING.md](CONTRIBUTING.md)**.
|
|
470
|
-
|
|
471
|
-
## License
|
|
472
|
-
|
|
473
|
-
MIT Β© PHCDevworks β See **[LICENSE](LICENSE)** for details.
|
|
474
|
-
|
|
475
116
|
---
|
|
476
117
|
|
|
477
|
-
## β€οΈ Support
|
|
478
|
-
|
|
479
|
-
If Spectre UI helps your workflow, consider sponsoring:
|
|
118
|
+
## β€οΈ Support & Community
|
|
480
119
|
|
|
481
|
-
- [GitHub Sponsors](https://github.com/sponsors/phcdevworks)
|
|
482
|
-
-
|
|
120
|
+
- **Sponsor**: [GitHub Sponsors](https://github.com/sponsors/phcdevworks) | [Buy Me a Coffee](https://buymeacoffee.com/phcdevworks)
|
|
121
|
+
- **License**: MIT Β© [PHCDevworks](https://phcdevworks.com)
|
package/dist/base.css
CHANGED
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
body {
|
|
16
16
|
min-height: 100vh;
|
|
17
|
-
font-family: var(--sp-font-family-sans
|
|
18
|
-
font-size: var(--sp-font-md-size
|
|
19
|
-
line-height: var(--sp-font-md-line-height
|
|
17
|
+
font-family: var(--sp-font-family-sans);
|
|
18
|
+
font-size: var(--sp-font-md-size);
|
|
19
|
+
line-height: var(--sp-font-md-line-height);
|
|
20
20
|
color: var(--sp-text-on-page-default);
|
|
21
21
|
background-color: var(--sp-surface-page);
|
|
22
22
|
}
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
a {
|
|
48
|
-
color: var(--sp-color-brand-600
|
|
48
|
+
color: var(--sp-color-brand-600);
|
|
49
49
|
text-decoration: none;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -54,13 +54,12 @@
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
:focus-visible {
|
|
57
|
-
outline: var(--sp-focus-ring-width
|
|
58
|
-
|
|
59
|
-
outline-offset: var(--sp-focus-ring-offset, 2px);
|
|
57
|
+
outline: var(--sp-focus-ring-width) solid var(--sp-color-focus-primary);
|
|
58
|
+
outline-offset: var(--sp-focus-ring-offset);
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
::selection {
|
|
63
|
-
background-color: var(--sp-color-brand-100
|
|
62
|
+
background-color: var(--sp-color-brand-100);
|
|
64
63
|
color: inherit;
|
|
65
64
|
}
|
|
66
65
|
}
|