@phcdevworks/spectre-ui 0.0.2 → 0.0.4
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 +180 -46
- package/dist/base.css +12 -5
- package/dist/components.css +249 -63
- package/dist/index.cjs +25 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +25 -14
- package/dist/index.js.map +1 -1
- package/dist/utilities.css +2 -2
- package/package.json +42 -29
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# @phcdevworks/spectre-ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Framework-agnostic styling layer that powers Spectre Blocks, Spectre Astro, Spectre 11ty, and every Spectre integration.
|
|
4
|
+
|
|
5
|
+
> 📋 **[View Roadmap](https://github.com/phcdevworks/spectre-ui/blob/main/ROADMAP.md)** | 🤝 **[Contributing Guide](CONTRIBUTING.md)** | 📝 **[Changelog](CHANGELOG.md)**
|
|
4
6
|
|
|
5
7
|
## Overview
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
`@phcdevworks/spectre-ui` is the core styling layer of the Spectre design system. It consumes `@phcdevworks/spectre-tokens` and ships precompiled CSS, type-safe recipe helpers, and a Tailwind preset so downstream frameworks can stay in sync without duplicating logic. One design system runs the entire Spectre Suite; this package handles the implementation.
|
|
8
10
|
|
|
9
11
|
- ✅ Token-powered styles built on `@phcdevworks/spectre-tokens`
|
|
10
12
|
- ✅ Precompiled `base`, `components`, and `utilities` CSS bundles
|
|
@@ -22,21 +24,20 @@ npm install @phcdevworks/spectre-ui
|
|
|
22
24
|
|
|
23
25
|
### 1. Import Spectre CSS
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
Import the CSS bundles anywhere in your app, layout, or build pipeline.
|
|
26
28
|
|
|
27
29
|
```css
|
|
28
|
-
|
|
29
|
-
@import "@phcdevworks/spectre-ui/
|
|
30
|
-
@import "@phcdevworks/spectre-ui/
|
|
31
|
-
@import "@phcdevworks/spectre-ui/dist/utilities.css";
|
|
30
|
+
@import "@phcdevworks/spectre-ui/base.css";
|
|
31
|
+
@import "@phcdevworks/spectre-ui/components.css";
|
|
32
|
+
@import "@phcdevworks/spectre-ui/utilities.css";
|
|
32
33
|
```
|
|
33
34
|
|
|
34
|
-
### 2.
|
|
35
|
+
### 2. Tailwind integration
|
|
35
36
|
|
|
36
|
-
Spectre ships an opinionated Tailwind preset that mirrors the tokens exactly.
|
|
37
|
+
Spectre ships an opinionated Tailwind preset that mirrors the design tokens exactly.
|
|
37
38
|
|
|
38
39
|
```ts
|
|
39
|
-
// tailwind.config.
|
|
40
|
+
// tailwind.config.ts
|
|
40
41
|
import { spectrePreset } from "@phcdevworks/spectre-ui";
|
|
41
42
|
|
|
42
43
|
export default {
|
|
@@ -45,23 +46,7 @@ export default {
|
|
|
45
46
|
};
|
|
46
47
|
```
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```ts
|
|
51
|
-
import {
|
|
52
|
-
spectreTokens,
|
|
53
|
-
createSpectreTailwindTheme,
|
|
54
|
-
} from "@phcdevworks/spectre-ui";
|
|
55
|
-
|
|
56
|
-
const theme = createSpectreTailwindTheme({
|
|
57
|
-
tokens: spectreTokens,
|
|
58
|
-
overrides: {
|
|
59
|
-
colors: {
|
|
60
|
-
brand: "#7928CA",
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
```
|
|
49
|
+
Works with Tailwind 3.x and 4.x through the classic config API.
|
|
65
50
|
|
|
66
51
|
### 3. Use Spectre recipes
|
|
67
52
|
|
|
@@ -92,6 +77,118 @@ const inputClasses = getInputClasses({
|
|
|
92
77
|
// "sp-input sp-input--error sp-input--sm sp-input--full"
|
|
93
78
|
```
|
|
94
79
|
|
|
80
|
+
## Component Surfaces
|
|
81
|
+
|
|
82
|
+
### Button variants
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
getButtonClasses({ variant: "primary" }); // CTA baseline
|
|
86
|
+
getButtonClasses({ variant: "secondary" }); // Outlined
|
|
87
|
+
getButtonClasses({ variant: "ghost" }); // Low-emphasis
|
|
88
|
+
getButtonClasses({ variant: "danger" }); // Destructive
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Each variant ships with full state coverage: `default`, `hover`, `active`, `disabled`, and tone modifiers (`success`, `warning`, `danger`).
|
|
92
|
+
|
|
93
|
+
```css
|
|
94
|
+
.cta-button {
|
|
95
|
+
background: var(--sp-component-button-primary-bg);
|
|
96
|
+
color: var(--sp-component-button-primary-text);
|
|
97
|
+
}
|
|
98
|
+
.cta-button:hover {
|
|
99
|
+
background: var(--sp-component-button-primary-bg-hover);
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Input states
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
getInputClasses({ state: "default" });
|
|
107
|
+
getInputClasses({ state: "error" });
|
|
108
|
+
getInputClasses({ state: "success" });
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```css
|
|
112
|
+
.input:focus {
|
|
113
|
+
border-color: var(--sp-component-input-border-focus);
|
|
114
|
+
outline: var(--sp-focus-ring-width) var(--sp-focus-ring-style)
|
|
115
|
+
var(--sp-component-input-ring-focus);
|
|
116
|
+
}
|
|
117
|
+
.input.error {
|
|
118
|
+
border-color: var(--sp-component-input-border-error);
|
|
119
|
+
background: var(--sp-component-input-bg-error);
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Card variants
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
getCardClasses({ variant: "elevated" }); // Default shadow
|
|
127
|
+
getCardClasses({ variant: "outline" }); // Bordered
|
|
128
|
+
getCardClasses({ variant: "ghost" }); // Transparent
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Surface & Typography Roles
|
|
132
|
+
|
|
133
|
+
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.
|
|
134
|
+
|
|
135
|
+
- `surface.page`, `surface.card`, `surface.input`, `surface.overlay`: semantic backgrounds for the app canvas, containers/tiles, form fields, and modal/dropdown layers.
|
|
136
|
+
- `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.
|
|
137
|
+
- `component.card.text`/`textMuted`, `component.input.text`/`placeholder`, and `component.button.textDefault`/`textOnPrimary` alias the underlying `text.onSurface` roles to keep component defaults aligned.
|
|
138
|
+
|
|
139
|
+
### Tailwind utilities
|
|
140
|
+
|
|
141
|
+
The Tailwind preset exposes semantic helpers:
|
|
142
|
+
|
|
143
|
+
- `bg-surface-page`, `bg-surface-card`, `bg-surface-input`
|
|
144
|
+
- `text-on-page`, `text-on-surface`
|
|
145
|
+
|
|
146
|
+
Use them to mix utility-first UIs with Spectre's semantic palette.
|
|
147
|
+
|
|
148
|
+
### Mode infrastructure
|
|
149
|
+
|
|
150
|
+
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.
|
|
151
|
+
|
|
152
|
+
## Usage Examples
|
|
153
|
+
|
|
154
|
+
### Surface-aware components
|
|
155
|
+
|
|
156
|
+
```css
|
|
157
|
+
.hero-panel {
|
|
158
|
+
--sp-surface-card: var(--sp-color-neutral-900);
|
|
159
|
+
--sp-text-on-surface-default: var(--sp-color-neutral-50);
|
|
160
|
+
--sp-text-on-surface-muted: var(--sp-color-neutral-200);
|
|
161
|
+
--sp-component-button-primary-bg: var(--sp-color-accent-400);
|
|
162
|
+
--sp-component-button-primary-text: var(--sp-color-neutral-900);
|
|
163
|
+
--sp-component-card-border: transparent;
|
|
164
|
+
--sp-component-input-border: var(--sp-color-accent-400);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
```html
|
|
169
|
+
<section class="hero-panel">
|
|
170
|
+
<button class="sp-btn sp-btn--primary">Surface Button</button>
|
|
171
|
+
<div class="sp-card sp-card--elevated">
|
|
172
|
+
<p>Cards inherit the contextual surface + text roles automatically.</p>
|
|
173
|
+
</div>
|
|
174
|
+
<input class="sp-input" placeholder="Email address" />
|
|
175
|
+
</section>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Tailwind semantic utilities
|
|
179
|
+
|
|
180
|
+
```jsx
|
|
181
|
+
export function SignupCard() {
|
|
182
|
+
return (
|
|
183
|
+
<div className="bg-surface-card text-on-surface sp-card sp-card--padded">
|
|
184
|
+
<h2 className="text-on-page font-semibold">Join the beta</h2>
|
|
185
|
+
<input className="sp-input mt-4" placeholder="you@spectre.dev" />
|
|
186
|
+
<button className="sp-btn sp-btn--primary mt-4">Request access</button>
|
|
187
|
+
</div>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
95
192
|
## CSS Path Constants
|
|
96
193
|
|
|
97
194
|
Utilities for referencing the published CSS files programmatically:
|
|
@@ -104,14 +201,42 @@ import {
|
|
|
104
201
|
spectreStyles,
|
|
105
202
|
} from "@phcdevworks/spectre-ui";
|
|
106
203
|
|
|
107
|
-
// spectreStyles.base → "@phcdevworks/spectre-ui/
|
|
108
|
-
// spectreStyles.components → "@phcdevworks/spectre-ui/
|
|
109
|
-
// spectreStyles.utilities → "@phcdevworks/spectre-ui/
|
|
204
|
+
// spectreStyles.base → "@phcdevworks/spectre-ui/base.css"
|
|
205
|
+
// spectreStyles.components → "@phcdevworks/spectre-ui/components.css"
|
|
206
|
+
// spectreStyles.utilities → "@phcdevworks/spectre-ui/utilities.css"
|
|
110
207
|
```
|
|
111
208
|
|
|
112
|
-
##
|
|
209
|
+
## Repository Layout
|
|
113
210
|
|
|
114
|
-
|
|
211
|
+
| Folder | Responsibility |
|
|
212
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
213
|
+
| `src/` | TypeScript source: recipes, Tailwind preset, token re-exports, CSS constants. |
|
|
214
|
+
| `src/styles/` | Raw CSS files (`base.css`, `components.css`, `utilities.css`) copied to `dist/` during build. |
|
|
215
|
+
| `dist/` | Generated artifacts: `index.js`, `index.cjs`, `index.d.ts`, and CSS files. Regenerated via `npm run build`. |
|
|
216
|
+
|
|
217
|
+
Designers update tokens in `@phcdevworks/spectre-tokens`. Engineering evolves recipes, presets, and CSS in this package.
|
|
218
|
+
|
|
219
|
+
## Build & Release
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
npm run build
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
`tsup` compiles the TypeScript library (ESM, CJS, `.d.ts`) and copies CSS files to `dist/`. Because `dist/` is generated, releases are reproducible from `src/`.
|
|
226
|
+
|
|
227
|
+
For release history and version notes, see the **[Changelog](CHANGELOG.md)**.
|
|
228
|
+
|
|
229
|
+
## Design Principles
|
|
230
|
+
|
|
231
|
+
1. **Single source of truth** – All Spectre products consume these styles and recipes.
|
|
232
|
+
2. **No style duplication** – Downstream frameworks never re-encode Spectre logic.
|
|
233
|
+
3. **Token-first** – The Tailwind preset, CSS, and recipes are generated from tokens.
|
|
234
|
+
4. **Framework agnostic** – Works with any bundler, CMS, or runtime.
|
|
235
|
+
5. **Type-safe ergonomics** – Every helper exports strict types for confident usage.
|
|
236
|
+
|
|
237
|
+
## TypeScript Support
|
|
238
|
+
|
|
239
|
+
Type definitions are bundled automatically:
|
|
115
240
|
|
|
116
241
|
```ts
|
|
117
242
|
import type {
|
|
@@ -120,28 +245,37 @@ import type {
|
|
|
120
245
|
ButtonVariant,
|
|
121
246
|
InputState,
|
|
122
247
|
CardVariant,
|
|
248
|
+
ButtonRecipeOptions,
|
|
249
|
+
CardRecipeOptions,
|
|
250
|
+
InputRecipeOptions,
|
|
123
251
|
} from "@phcdevworks/spectre-ui";
|
|
124
252
|
```
|
|
125
253
|
|
|
126
|
-
|
|
254
|
+
## Part of the Spectre Suite
|
|
127
255
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
4. **Framework agnostic** – works with any bundler, CMS, or runtime.
|
|
134
|
-
5. **Type-safe ergonomics** – every helper exports strict types for confident usage.
|
|
256
|
+
- **Spectre Tokens** – Design-token foundation
|
|
257
|
+
- **Spectre UI** – Core styling layer (this package)
|
|
258
|
+
- **Spectre Blocks** – WordPress block library
|
|
259
|
+
- **Spectre Astro** – Astro integration
|
|
260
|
+
- **Spectre 11ty** – Eleventy integration
|
|
135
261
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
- **Tailwind CSS**: ^3.4.0 or ^4.0.0 (if you consume the preset)
|
|
139
|
-
- **Build tooling**: ESM-compatible bundler capable of importing CSS from npm
|
|
262
|
+
For the project's future direction, see the **[Roadmap](https://github.com/phcdevworks/spectre-ui/blob/main/ROADMAP.md)**.
|
|
140
263
|
|
|
141
264
|
## Contributing
|
|
142
265
|
|
|
143
|
-
|
|
266
|
+
Issues and pull requests are welcome. If you are proposing style or recipe changes, update `src/` and include regenerated builds.
|
|
267
|
+
|
|
268
|
+
For detailed contribution guidelines, see **[CONTRIBUTING.md](CONTRIBUTING.md)**.
|
|
144
269
|
|
|
145
270
|
## License
|
|
146
271
|
|
|
147
|
-
MIT © PHCDevworks
|
|
272
|
+
MIT © PHCDevworks — See **[LICENSE](LICENSE)** for details.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## ❤️ Support Spectre
|
|
277
|
+
|
|
278
|
+
If Spectre UI helps your workflow, consider sponsoring:
|
|
279
|
+
|
|
280
|
+
- [GitHub Sponsors](https://github.com/sponsors/phcdevworks)
|
|
281
|
+
- [Buy Me a Coffee](https://buymeacoffee.com/phcdevworks)
|
package/dist/base.css
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
@layer base {
|
|
2
2
|
|
|
3
|
+
:root {
|
|
4
|
+
--sp-surface-page: var(--sp-color-neutral-50, #f8fafc);
|
|
5
|
+
--sp-surface-card: #ffffff;
|
|
6
|
+
--sp-surface-input: var(--sp-form-default-bg, #ffffff);
|
|
7
|
+
--sp-surface-overlay: rgba(15, 23, 42, var(--sp-opacity-overlay, 0.5));
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
*,
|
|
4
11
|
*::before,
|
|
5
12
|
*::after {
|
|
@@ -17,8 +24,8 @@
|
|
|
17
24
|
font-family: var(--sp-font-family-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
|
|
18
25
|
font-size: var(--sp-font-md-size, 1rem);
|
|
19
26
|
line-height: var(--sp-font-md-line-height, 1.5);
|
|
20
|
-
color: var(--sp-
|
|
21
|
-
background-color: var(--sp-
|
|
27
|
+
color: var(--sp-text-on-page-default);
|
|
28
|
+
background-color: var(--sp-surface-page);
|
|
22
29
|
}
|
|
23
30
|
|
|
24
31
|
img,
|
|
@@ -45,7 +52,7 @@
|
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
a {
|
|
48
|
-
color: var(--sp-
|
|
55
|
+
color: var(--sp-color-primary, inherit);
|
|
49
56
|
text-decoration: none;
|
|
50
57
|
}
|
|
51
58
|
|
|
@@ -54,12 +61,12 @@
|
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
:focus-visible {
|
|
57
|
-
outline: 2px solid var(--sp-
|
|
64
|
+
outline: 2px solid var(--sp-color-primary, currentColor);
|
|
58
65
|
outline-offset: 2px;
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
::selection {
|
|
62
|
-
background-color: var(--sp-
|
|
69
|
+
background-color: var(--sp-color-primary-soft, rgba(79, 70, 229, 0.15));
|
|
63
70
|
color: inherit;
|
|
64
71
|
}
|
|
65
72
|
}
|
package/dist/components.css
CHANGED
|
@@ -1,5 +1,76 @@
|
|
|
1
1
|
@layer components {
|
|
2
2
|
|
|
3
|
+
:root {
|
|
4
|
+
/* button roles */
|
|
5
|
+
--sp-component-button-border-base: var(--sp-component-button-ghost-bg, var(--sp-button-ghost-bg));
|
|
6
|
+
--sp-component-button-shadow: var(--sp-shadow-sm);
|
|
7
|
+
--sp-component-button-primary-bg: var(--sp-button-primary-bg);
|
|
8
|
+
--sp-component-button-primary-bg-hover: var(--sp-button-primary-bghover);
|
|
9
|
+
--sp-component-button-primary-bg-active: var(--sp-button-primary-bgactive);
|
|
10
|
+
--sp-component-button-primary-bg-disabled: var(--sp-button-primary-bgdisabled);
|
|
11
|
+
--sp-component-button-primary-text: var(--sp-button-primary-text);
|
|
12
|
+
--sp-component-button-primary-text-disabled: var(--sp-button-primary-textdisabled);
|
|
13
|
+
--sp-component-button-secondary-bg: var(--sp-button-secondary-bg);
|
|
14
|
+
--sp-component-button-secondary-bg-hover: var(--sp-button-secondary-bghover);
|
|
15
|
+
--sp-component-button-secondary-bg-active: var(--sp-button-secondary-bgactive);
|
|
16
|
+
--sp-component-button-secondary-bg-disabled: var(--sp-button-secondary-bgdisabled);
|
|
17
|
+
--sp-component-button-secondary-text: var(--sp-button-secondary-text);
|
|
18
|
+
--sp-component-button-secondary-text-disabled: var(--sp-button-secondary-textdisabled);
|
|
19
|
+
--sp-component-button-secondary-border: var(--sp-button-secondary-border);
|
|
20
|
+
--sp-component-button-secondary-border-disabled: var(--sp-button-secondary-borderdisabled);
|
|
21
|
+
--sp-component-button-ghost-bg: var(--sp-button-ghost-bg);
|
|
22
|
+
--sp-component-button-ghost-bg-hover: var(--sp-button-ghost-bghover);
|
|
23
|
+
--sp-component-button-ghost-bg-active: var(--sp-button-ghost-bgactive);
|
|
24
|
+
--sp-component-button-ghost-bg-disabled: var(--sp-button-ghost-bgdisabled);
|
|
25
|
+
--sp-component-button-ghost-text: var(--sp-button-ghost-text);
|
|
26
|
+
--sp-component-button-ghost-text-disabled: var(--sp-button-ghost-textdisabled);
|
|
27
|
+
--sp-component-button-danger-bg: var(--sp-button-danger-bg);
|
|
28
|
+
--sp-component-button-danger-bg-hover: var(--sp-button-danger-bghover);
|
|
29
|
+
--sp-component-button-danger-bg-active: var(--sp-button-danger-bgactive);
|
|
30
|
+
--sp-component-button-danger-bg-disabled: var(--sp-button-danger-bgdisabled);
|
|
31
|
+
--sp-component-button-danger-text: var(--sp-button-danger-text);
|
|
32
|
+
--sp-component-button-danger-text-disabled: var(--sp-button-danger-textdisabled);
|
|
33
|
+
--sp-component-button-success-bg: var(--sp-button-success-bg);
|
|
34
|
+
--sp-component-button-success-bg-hover: var(--sp-button-success-bghover);
|
|
35
|
+
--sp-component-button-success-bg-active: var(--sp-button-success-bgactive);
|
|
36
|
+
--sp-component-button-success-bg-disabled: var(--sp-button-success-bgdisabled);
|
|
37
|
+
--sp-component-button-success-text: var(--sp-button-success-text);
|
|
38
|
+
--sp-component-button-success-text-disabled: var(--sp-button-success-textdisabled);
|
|
39
|
+
|
|
40
|
+
/* card roles */
|
|
41
|
+
--sp-component-card-bg: var(--sp-surface-card, var(--sp-color-neutral-50));
|
|
42
|
+
--sp-component-card-text: var(--sp-text-on-surface-default, var(--sp-color-neutral-900));
|
|
43
|
+
--sp-component-card-text-muted: var(--sp-text-on-surface-muted, var(--sp-color-neutral-600));
|
|
44
|
+
--sp-component-card-border: var(--sp-color-neutral-200);
|
|
45
|
+
--sp-component-card-border-base: var(--sp-component-card-ghost-border, var(--sp-component-card-bg));
|
|
46
|
+
--sp-component-card-shadow: var(--sp-shadow-sm);
|
|
47
|
+
--sp-component-card-shadow-elevated: var(--sp-shadow-lg);
|
|
48
|
+
--sp-component-card-shadow-flat: var(--sp-shadow-none);
|
|
49
|
+
--sp-component-card-shadow-outline: var(--sp-shadow-none);
|
|
50
|
+
--sp-component-card-shadow-ghost: var(--sp-shadow-none);
|
|
51
|
+
--sp-component-card-outline-bg: var(--sp-component-card-bg);
|
|
52
|
+
--sp-component-card-outline-border: var(--sp-component-card-border);
|
|
53
|
+
--sp-component-card-ghost-bg: var(--sp-component-button-ghost-bg, var(--sp-button-ghost-bg));
|
|
54
|
+
--sp-component-card-ghost-border: var(--sp-component-card-ghost-bg);
|
|
55
|
+
|
|
56
|
+
/* input roles */
|
|
57
|
+
--sp-component-input-border: var(--sp-form-default-border);
|
|
58
|
+
--sp-component-input-bg: var(--sp-surface-input, var(--sp-form-default-bg));
|
|
59
|
+
--sp-component-input-text: var(--sp-text-on-surface-default, var(--sp-form-default-text));
|
|
60
|
+
--sp-component-input-placeholder: var(--sp-text-on-surface-muted, var(--sp-form-default-placeholder));
|
|
61
|
+
--sp-component-input-border-focus: var(--sp-form-focus-border);
|
|
62
|
+
--sp-component-input-ring: var(--sp-form-focus-ring, var(--sp-color-focus-primary));
|
|
63
|
+
--sp-component-input-border-invalid: var(--sp-form-invalid-border);
|
|
64
|
+
--sp-component-input-bg-invalid: var(--sp-form-invalid-bg);
|
|
65
|
+
--sp-component-input-text-invalid: var(--sp-form-invalid-text);
|
|
66
|
+
--sp-component-input-border-valid: var(--sp-form-valid-border);
|
|
67
|
+
--sp-component-input-bg-valid: var(--sp-form-valid-bg);
|
|
68
|
+
--sp-component-input-text-valid: var(--sp-form-valid-text);
|
|
69
|
+
--sp-component-input-bg-disabled: var(--sp-form-disabled-bg);
|
|
70
|
+
--sp-component-input-text-disabled: var(--sp-form-disabled-text);
|
|
71
|
+
--sp-component-input-border-disabled: var(--sp-form-disabled-border);
|
|
72
|
+
}
|
|
73
|
+
|
|
3
74
|
/* BUTTONS -------------------------------------------------------------- */
|
|
4
75
|
.sp-btn {
|
|
5
76
|
display: inline-flex;
|
|
@@ -8,11 +79,16 @@
|
|
|
8
79
|
gap: var(--sp-space-2xs, 0.25rem);
|
|
9
80
|
padding: var(--sp-space-2xs, 0.25rem) var(--sp-space-md, 1rem);
|
|
10
81
|
border-radius: var(--sp-radius-md, 4px);
|
|
11
|
-
border: 1px solid
|
|
82
|
+
border: 1px solid var(
|
|
83
|
+
--sp-component-button-border-base,
|
|
84
|
+
var(--sp-component-button-ghost-bg, var(--sp-button-ghost-bg))
|
|
85
|
+
);
|
|
12
86
|
font-family: var(--sp-font-family-sans, system-ui);
|
|
13
87
|
font-size: var(--sp-font-md-size, 1rem);
|
|
14
88
|
line-height: 1;
|
|
15
89
|
font-weight: var(--sp-font-md-weight, 500);
|
|
90
|
+
text-decoration: none;
|
|
91
|
+
appearance: none;
|
|
16
92
|
transition:
|
|
17
93
|
background-color var(--sp-duration-fast, 150ms) var(--sp-easing-out, ease),
|
|
18
94
|
color var(--sp-duration-fast, 150ms) var(--sp-easing-out, ease),
|
|
@@ -23,8 +99,25 @@
|
|
|
23
99
|
}
|
|
24
100
|
|
|
25
101
|
.sp-btn:disabled,
|
|
26
|
-
.sp-btn[aria-disabled="true"]
|
|
102
|
+
.sp-btn[aria-disabled="true"],
|
|
103
|
+
.sp-btn.sp-btn--disabled {
|
|
27
104
|
cursor: not-allowed;
|
|
105
|
+
opacity: var(--sp-opacity-disabled, 0.5);
|
|
106
|
+
pointer-events: none;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.sp-btn--loading {
|
|
110
|
+
pointer-events: none;
|
|
111
|
+
opacity: var(--sp-opacity-loading, 0.7);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.sp-btn--full {
|
|
115
|
+
width: 100%;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.sp-btn--icon {
|
|
119
|
+
padding-inline: var(--sp-space-sm, 0.75rem);
|
|
120
|
+
padding-block: var(--sp-space-3xs, 0.125rem);
|
|
28
121
|
}
|
|
29
122
|
|
|
30
123
|
/* sizes */
|
|
@@ -48,128 +141,157 @@
|
|
|
48
141
|
|
|
49
142
|
/* primary */
|
|
50
143
|
.sp-btn--primary {
|
|
51
|
-
background-color: var(--sp-button-primary-bg
|
|
52
|
-
color: var(--sp-button-primary-text
|
|
53
|
-
box-shadow: var(
|
|
144
|
+
background-color: var(--sp-component-button-primary-bg);
|
|
145
|
+
color: var(--sp-component-button-primary-text);
|
|
146
|
+
box-shadow: var(
|
|
147
|
+
--sp-component-button-shadow,
|
|
148
|
+
var(--sp-shadow-sm)
|
|
149
|
+
);
|
|
54
150
|
}
|
|
55
151
|
|
|
56
152
|
.sp-btn--primary.sp-btn--hover,
|
|
57
153
|
.sp-btn--primary:hover {
|
|
58
|
-
background-color: var(--sp-button-primary-
|
|
154
|
+
background-color: var(--sp-component-button-primary-bg-hover);
|
|
59
155
|
}
|
|
60
156
|
|
|
61
157
|
.sp-btn--primary.sp-btn--active,
|
|
62
158
|
.sp-btn--primary:active {
|
|
63
|
-
background-color: var(--sp-button-primary-
|
|
159
|
+
background-color: var(--sp-component-button-primary-bg-active);
|
|
64
160
|
}
|
|
65
161
|
|
|
66
162
|
.sp-btn--primary.sp-btn--disabled,
|
|
67
163
|
.sp-btn--primary:disabled {
|
|
68
|
-
background-color: var(--sp-button-primary-
|
|
69
|
-
color: var(--sp-button-primary-
|
|
164
|
+
background-color: var(--sp-component-button-primary-bg-disabled);
|
|
165
|
+
color: var(--sp-component-button-primary-text-disabled);
|
|
70
166
|
box-shadow: none;
|
|
71
167
|
}
|
|
72
168
|
|
|
73
169
|
/* secondary */
|
|
74
170
|
.sp-btn--secondary {
|
|
75
|
-
background-color: var(--sp-button-secondary-bg
|
|
76
|
-
color: var(--sp-button-secondary-text
|
|
77
|
-
border-color: var(--sp-button-secondary-border
|
|
171
|
+
background-color: var(--sp-component-button-secondary-bg);
|
|
172
|
+
color: var(--sp-component-button-secondary-text);
|
|
173
|
+
border-color: var(--sp-component-button-secondary-border);
|
|
78
174
|
}
|
|
79
175
|
|
|
80
176
|
.sp-btn--secondary.sp-btn--hover,
|
|
81
177
|
.sp-btn--secondary:hover {
|
|
82
|
-
background-color: var(--sp-button-secondary-
|
|
178
|
+
background-color: var(--sp-component-button-secondary-bg-hover);
|
|
83
179
|
}
|
|
84
180
|
|
|
85
181
|
.sp-btn--secondary.sp-btn--active,
|
|
86
182
|
.sp-btn--secondary:active {
|
|
87
|
-
background-color: var(--sp-button-secondary-
|
|
183
|
+
background-color: var(--sp-component-button-secondary-bg-active);
|
|
88
184
|
}
|
|
89
185
|
|
|
90
186
|
.sp-btn--secondary.sp-btn--disabled,
|
|
91
187
|
.sp-btn--secondary:disabled {
|
|
92
|
-
background-color: var(--sp-button-secondary-
|
|
93
|
-
color: var(--sp-button-secondary-
|
|
94
|
-
border-color: var(--sp-button-secondary-
|
|
188
|
+
background-color: var(--sp-component-button-secondary-bg-disabled);
|
|
189
|
+
color: var(--sp-component-button-secondary-text-disabled);
|
|
190
|
+
border-color: var(--sp-component-button-secondary-border-disabled);
|
|
95
191
|
}
|
|
96
192
|
|
|
97
193
|
/* ghost */
|
|
98
194
|
.sp-btn--ghost {
|
|
99
|
-
background-color:
|
|
100
|
-
color: var(--sp-button-ghost-text
|
|
195
|
+
background-color: var(--sp-component-button-ghost-bg);
|
|
196
|
+
color: var(--sp-component-button-ghost-text);
|
|
101
197
|
}
|
|
102
198
|
|
|
103
199
|
.sp-btn--ghost.sp-btn--hover,
|
|
104
200
|
.sp-btn--ghost:hover {
|
|
105
|
-
background-color: var(--sp-button-ghost-
|
|
201
|
+
background-color: var(--sp-component-button-ghost-bg-hover);
|
|
106
202
|
}
|
|
107
203
|
|
|
108
204
|
.sp-btn--ghost.sp-btn--active,
|
|
109
205
|
.sp-btn--ghost:active {
|
|
110
|
-
background-color: var(--sp-button-ghost-
|
|
206
|
+
background-color: var(--sp-component-button-ghost-bg-active);
|
|
111
207
|
}
|
|
112
208
|
|
|
113
209
|
.sp-btn--ghost.sp-btn--disabled,
|
|
114
210
|
.sp-btn--ghost:disabled {
|
|
115
|
-
color: var(--sp-button-ghost-
|
|
116
|
-
background-color:
|
|
211
|
+
color: var(--sp-component-button-ghost-text-disabled);
|
|
212
|
+
background-color: var(--sp-component-button-ghost-bg-disabled);
|
|
117
213
|
}
|
|
118
214
|
|
|
119
215
|
/* danger */
|
|
120
216
|
.sp-btn--danger {
|
|
121
|
-
background-color: var(--sp-button-danger-bg
|
|
122
|
-
color: var(--sp-button-danger-text
|
|
217
|
+
background-color: var(--sp-component-button-danger-bg);
|
|
218
|
+
color: var(--sp-component-button-danger-text);
|
|
123
219
|
}
|
|
124
220
|
|
|
125
221
|
.sp-btn--danger.sp-btn--hover,
|
|
126
222
|
.sp-btn--danger:hover {
|
|
127
|
-
background-color: var(--sp-button-danger-
|
|
223
|
+
background-color: var(--sp-component-button-danger-bg-hover);
|
|
128
224
|
}
|
|
129
225
|
|
|
130
226
|
.sp-btn--danger.sp-btn--active,
|
|
131
227
|
.sp-btn--danger:active {
|
|
132
|
-
background-color: var(--sp-button-danger-
|
|
228
|
+
background-color: var(--sp-component-button-danger-bg-active);
|
|
133
229
|
}
|
|
134
230
|
|
|
135
231
|
.sp-btn--danger.sp-btn--disabled,
|
|
136
232
|
.sp-btn--danger:disabled {
|
|
137
|
-
background-color: var(--sp-button-danger-
|
|
138
|
-
color: var(--sp-button-danger-
|
|
233
|
+
background-color: var(--sp-component-button-danger-bg-disabled);
|
|
234
|
+
color: var(--sp-component-button-danger-text-disabled);
|
|
139
235
|
}
|
|
140
236
|
|
|
141
237
|
/* success */
|
|
142
238
|
.sp-btn--success {
|
|
143
|
-
background-color: var(--sp-button-success-bg
|
|
144
|
-
color: var(--sp-button-success-text
|
|
239
|
+
background-color: var(--sp-component-button-success-bg);
|
|
240
|
+
color: var(--sp-component-button-success-text);
|
|
145
241
|
}
|
|
146
242
|
|
|
147
243
|
.sp-btn--success.sp-btn--hover,
|
|
148
244
|
.sp-btn--success:hover {
|
|
149
|
-
background-color: var(--sp-button-success-
|
|
245
|
+
background-color: var(--sp-component-button-success-bg-hover);
|
|
150
246
|
}
|
|
151
247
|
|
|
152
248
|
.sp-btn--success.sp-btn--active,
|
|
153
249
|
.sp-btn--success:active {
|
|
154
|
-
background-color: var(--sp-button-success-
|
|
250
|
+
background-color: var(--sp-component-button-success-bg-active);
|
|
155
251
|
}
|
|
156
252
|
|
|
157
253
|
.sp-btn--success.sp-btn--disabled,
|
|
158
254
|
.sp-btn--success:disabled {
|
|
159
|
-
background-color: var(--sp-button-success-
|
|
160
|
-
color: var(--sp-button-success-
|
|
255
|
+
background-color: var(--sp-component-button-success-bg-disabled);
|
|
256
|
+
color: var(--sp-component-button-success-text-disabled);
|
|
161
257
|
}
|
|
162
258
|
|
|
163
259
|
/* INPUTS --------------------------------------------------------------- */
|
|
164
260
|
|
|
261
|
+
.sp-input-wrapper {
|
|
262
|
+
display: grid;
|
|
263
|
+
gap: var(--sp-space-4xs, 0.125rem);
|
|
264
|
+
width: 100%;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.sp-label {
|
|
268
|
+
color: var(--sp-component-input-text, var(--sp-text-on-surface-default, var(--sp-form-default-text)));
|
|
269
|
+
font-size: var(--sp-font-sm-size, 0.875rem);
|
|
270
|
+
font-weight: var(--sp-font-sm-weight, 500);
|
|
271
|
+
line-height: var(--sp-font-sm-line-height, 1.25rem);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.sp-helper-text {
|
|
275
|
+
color: var(--sp-text-on-surface-muted);
|
|
276
|
+
font-size: var(--sp-font-xs-size, 0.75rem);
|
|
277
|
+
line-height: var(--sp-font-xs-line-height, 1rem);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.sp-error-message {
|
|
281
|
+
color: var(--sp-color-danger, #dc2626);
|
|
282
|
+
font-size: var(--sp-font-xs-size, 0.75rem);
|
|
283
|
+
line-height: var(--sp-font-xs-line-height, 1rem);
|
|
284
|
+
}
|
|
285
|
+
|
|
165
286
|
.sp-input {
|
|
166
287
|
width: 100%;
|
|
167
288
|
display: block;
|
|
289
|
+
appearance: none;
|
|
168
290
|
padding: var(--sp-space-2xs, 0.25rem) var(--sp-space-md, 1rem);
|
|
169
291
|
border-radius: var(--sp-radius-md, 4px);
|
|
170
|
-
border: 1px solid var(--sp-form-default-border
|
|
171
|
-
background-color: var(--sp-form-default-bg
|
|
172
|
-
color: var(--sp-form-default-text
|
|
292
|
+
border: 1px solid var(--sp-component-input-border, var(--sp-form-default-border));
|
|
293
|
+
background-color: var(--sp-component-input-bg, var(--sp-surface-input, var(--sp-form-default-bg)));
|
|
294
|
+
color: var(--sp-component-input-text, var(--sp-text-on-surface-default, var(--sp-form-default-text)));
|
|
173
295
|
font-family: var(--sp-font-family-sans, system-ui);
|
|
174
296
|
font-size: var(--sp-font-md-size, 1rem);
|
|
175
297
|
line-height: var(--sp-font-md-line-height, 1.5rem);
|
|
@@ -180,32 +302,61 @@
|
|
|
180
302
|
}
|
|
181
303
|
|
|
182
304
|
.sp-input::placeholder {
|
|
183
|
-
color: var(--sp-form-default-placeholder
|
|
305
|
+
color: var(--sp-component-input-placeholder, var(--sp-text-on-surface-muted, var(--sp-form-default-placeholder)));
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.sp-input--sm {
|
|
309
|
+
padding: var(--sp-space-3xs, 0.125rem) var(--sp-space-sm, 0.75rem);
|
|
310
|
+
font-size: var(--sp-font-sm-size, 0.875rem);
|
|
311
|
+
line-height: var(--sp-font-sm-line-height, 1.25rem);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.sp-input--md {
|
|
315
|
+
padding: var(--sp-space-2xs, 0.25rem) var(--sp-space-md, 1rem);
|
|
316
|
+
font-size: var(--sp-font-md-size, 1rem);
|
|
317
|
+
line-height: var(--sp-font-md-line-height, 1.5rem);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.sp-input--lg {
|
|
321
|
+
padding: var(--sp-space-xs, 0.5rem) var(--sp-space-lg, 1.5rem);
|
|
322
|
+
font-size: var(--sp-font-lg-size, 1.125rem);
|
|
323
|
+
line-height: var(--sp-font-lg-line-height, 1.75rem);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.sp-input--full {
|
|
327
|
+
width: 100%;
|
|
184
328
|
}
|
|
185
329
|
|
|
186
330
|
.sp-input:focus,
|
|
187
331
|
.sp-input--focus {
|
|
188
|
-
border-color: var(
|
|
189
|
-
|
|
332
|
+
border-color: var(
|
|
333
|
+
--sp-component-input-border-focus,
|
|
334
|
+
var(--sp-component-input-border, var(--sp-form-focus-border))
|
|
335
|
+
);
|
|
336
|
+
box-shadow: 0 0 0 var(--sp-focus-ring-width, 2px) var(
|
|
337
|
+
--sp-component-input-ring,
|
|
338
|
+
var(--sp-form-focus-ring, var(--sp-color-focus-primary))
|
|
339
|
+
);
|
|
190
340
|
outline: none;
|
|
191
341
|
}
|
|
192
342
|
|
|
193
343
|
.sp-input--error {
|
|
194
|
-
border-color: var(--sp-form-invalid-border
|
|
195
|
-
background-color: var(--sp-form-invalid-bg
|
|
196
|
-
color: var(--sp-form-invalid-text
|
|
344
|
+
border-color: var(--sp-component-input-border-invalid, var(--sp-form-invalid-border));
|
|
345
|
+
background-color: var(--sp-component-input-bg-invalid, var(--sp-form-invalid-bg));
|
|
346
|
+
color: var(--sp-component-input-text-invalid, var(--sp-form-invalid-text));
|
|
197
347
|
}
|
|
198
348
|
|
|
199
349
|
.sp-input--success {
|
|
200
|
-
border-color: var(--sp-form-valid-border
|
|
201
|
-
background-color: var(--sp-form-valid-bg
|
|
202
|
-
color: var(--sp-form-valid-text
|
|
350
|
+
border-color: var(--sp-component-input-border-valid, var(--sp-form-valid-border));
|
|
351
|
+
background-color: var(--sp-component-input-bg-valid, var(--sp-form-valid-bg));
|
|
352
|
+
color: var(--sp-component-input-text-valid, var(--sp-form-valid-text));
|
|
203
353
|
}
|
|
204
354
|
|
|
205
355
|
.sp-input--disabled {
|
|
206
|
-
background-color: var(--sp-form-disabled-bg
|
|
207
|
-
color: var(--sp-form-disabled-text
|
|
208
|
-
border-color: var(--sp-form-disabled-border
|
|
356
|
+
background-color: var(--sp-component-input-bg-disabled, var(--sp-form-disabled-bg));
|
|
357
|
+
color: var(--sp-component-input-text-disabled, var(--sp-form-disabled-text));
|
|
358
|
+
border-color: var(--sp-component-input-border-disabled, var(--sp-form-disabled-border));
|
|
359
|
+
cursor: not-allowed;
|
|
209
360
|
}
|
|
210
361
|
|
|
211
362
|
.sp-input--disabled,
|
|
@@ -216,32 +367,67 @@
|
|
|
216
367
|
/* CARDS ---------------------------------------------------------------- */
|
|
217
368
|
|
|
218
369
|
.sp-card {
|
|
219
|
-
background-color: var(--sp-card-bg
|
|
220
|
-
color: var(--sp-card-text
|
|
370
|
+
background-color: var(--sp-component-card-bg);
|
|
371
|
+
color: var(--sp-component-card-text);
|
|
221
372
|
border-radius: var(--sp-radius-lg, 8px);
|
|
222
373
|
padding: var(--sp-space-lg, 1.5rem);
|
|
223
|
-
box-shadow: var(--sp-shadow
|
|
224
|
-
border: 1px solid
|
|
374
|
+
box-shadow: var(--sp-component-card-shadow, var(--sp-shadow-sm));
|
|
375
|
+
border: 1px solid var(
|
|
376
|
+
--sp-component-card-border-base,
|
|
377
|
+
var(--sp-component-card-ghost-border, var(--sp-component-card-bg))
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.sp-card p,
|
|
382
|
+
.sp-card span {
|
|
383
|
+
color: var(--sp-component-card-text-muted);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.sp-card h3,
|
|
387
|
+
.sp-card h4 {
|
|
388
|
+
color: var(--sp-component-card-text);
|
|
225
389
|
}
|
|
226
390
|
|
|
227
391
|
.sp-card--elevated {
|
|
228
|
-
box-shadow: var(--sp-shadow-
|
|
392
|
+
box-shadow: var(--sp-component-card-shadow-elevated, var(--sp-shadow-lg));
|
|
229
393
|
}
|
|
230
394
|
|
|
231
395
|
.sp-card--flat {
|
|
232
|
-
box-shadow: var(--sp-shadow-
|
|
233
|
-
border-color: var(--sp-
|
|
396
|
+
box-shadow: var(--sp-component-card-shadow-flat, var(--sp-shadow-none));
|
|
397
|
+
border-color: var(--sp-component-card-border);
|
|
234
398
|
}
|
|
235
399
|
|
|
236
400
|
.sp-card--outline {
|
|
237
|
-
background-color: var(--sp-card-outline-bg,
|
|
238
|
-
border-color: var(--sp-card-outline-border,
|
|
239
|
-
box-shadow: var(--sp-shadow-
|
|
401
|
+
background-color: var(--sp-component-card-outline-bg, var(--sp-component-card-bg));
|
|
402
|
+
border-color: var(--sp-component-card-outline-border, var(--sp-component-card-border));
|
|
403
|
+
box-shadow: var(--sp-component-card-shadow-outline, var(--sp-shadow-none));
|
|
240
404
|
}
|
|
241
405
|
|
|
242
406
|
.sp-card--ghost {
|
|
243
|
-
background-color:
|
|
244
|
-
border-color:
|
|
245
|
-
box-shadow: none;
|
|
407
|
+
background-color: var(--sp-component-card-ghost-bg);
|
|
408
|
+
border-color: var(--sp-component-card-ghost-border);
|
|
409
|
+
box-shadow: var(--sp-component-card-shadow-ghost, var(--sp-shadow-none));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.sp-card--padded {
|
|
413
|
+
padding: var(--sp-space-xl, 2rem);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.sp-card--full {
|
|
417
|
+
height: 100%;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.sp-card--interactive {
|
|
421
|
+
cursor: pointer;
|
|
422
|
+
transition:
|
|
423
|
+
transform var(--sp-duration-fast, 150ms) var(--sp-easing-out, ease),
|
|
424
|
+
box-shadow var(--sp-duration-fast, 150ms) var(--sp-easing-out, ease);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.sp-card--interactive:hover,
|
|
428
|
+
.sp-card--interactive:focus-visible,
|
|
429
|
+
.sp-card--interactive:focus-within {
|
|
430
|
+
transform: translateY(-1px);
|
|
431
|
+
box-shadow: var(--sp-component-card-shadow-elevated, var(--sp-shadow-lg));
|
|
246
432
|
}
|
|
247
433
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -17,29 +17,40 @@ function createSpectreTailwindTheme(options) {
|
|
|
17
17
|
const { tokens, overrides } = options;
|
|
18
18
|
const mergedTokens = {
|
|
19
19
|
...tokens,
|
|
20
|
-
...overrides
|
|
20
|
+
...overrides
|
|
21
21
|
};
|
|
22
|
+
const colors = {
|
|
23
|
+
page: mergedTokens.surface?.page,
|
|
24
|
+
card: mergedTokens.surface?.card,
|
|
25
|
+
input: mergedTokens.surface?.input,
|
|
26
|
+
text: {
|
|
27
|
+
page: mergedTokens.text?.onPage?.default,
|
|
28
|
+
"page-muted": mergedTokens.text?.onPage?.muted,
|
|
29
|
+
surface: mergedTokens.text?.onSurface?.default,
|
|
30
|
+
"surface-muted": mergedTokens.text?.onSurface?.muted
|
|
31
|
+
},
|
|
32
|
+
primary: mergedTokens.buttons?.primary?.bg ?? mergedTokens.colors?.primary
|
|
33
|
+
};
|
|
34
|
+
const spacing = mergedTokens.spacing ?? {};
|
|
35
|
+
const borderRadius = mergedTokens.radii ?? {};
|
|
36
|
+
const boxShadow = mergedTokens.shadows ?? {};
|
|
37
|
+
const fontFamily = mergedTokens.typography?.families ?? {};
|
|
22
38
|
const theme2 = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
boxShadow: mergedTokens.shadows ?? {},
|
|
29
|
-
fontFamily: mergedTokens.typography?.families ?? {}
|
|
39
|
+
colors,
|
|
40
|
+
spacing,
|
|
41
|
+
borderRadius,
|
|
42
|
+
boxShadow,
|
|
43
|
+
fontFamily
|
|
30
44
|
};
|
|
31
45
|
return { theme: theme2 };
|
|
32
46
|
}
|
|
33
47
|
|
|
34
48
|
// src/tailwind/preset.ts
|
|
35
|
-
var { theme } = createSpectreTailwindTheme({
|
|
36
|
-
tokens: spectreTokens.tokens
|
|
37
|
-
});
|
|
49
|
+
var { theme } = createSpectreTailwindTheme({ tokens: spectreTokens.tokens });
|
|
38
50
|
var spectrePreset = {
|
|
39
|
-
// Required for Tailwind's Config type with exactOptionalPropertyTypes
|
|
40
51
|
content: [],
|
|
41
|
-
theme: theme ?? {}
|
|
42
|
-
|
|
52
|
+
theme: theme ?? {}
|
|
53
|
+
// ensure theme is never undefined
|
|
43
54
|
};
|
|
44
55
|
|
|
45
56
|
// src/recipes/button.ts
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/css-constants.ts","../src/tailwind/theme.ts","../src/tailwind/preset.ts","../src/recipes/button.ts","../src/recipes/card.ts","../src/recipes/input.ts"],"names":["theme","spectreTokens"],"mappings":"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","file":"index.cjs","sourcesContent":["export const spectreBaseStylesPath = \"@phcdevworks/spectre-ui/dist/base.css\";\nexport const spectreComponentsStylesPath = \"@phcdevworks/spectre-ui/dist/components.css\";\nexport const spectreUtilitiesStylesPath = \"@phcdevworks/spectre-ui/dist/utilities.css\";\n\nexport const spectreStyles = {\n base: spectreBaseStylesPath,\n components: spectreComponentsStylesPath,\n utilities: spectreUtilitiesStylesPath,\n};\n","import type { Config as TailwindConfig } from 'tailwindcss';\nimport type { SpectreTokens } from '../tokens';\n\nexport interface SpectreTailwindTheme {\n theme: TailwindConfig['theme'];\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions,\n): SpectreTailwindTheme {\n const { tokens, overrides } = options;\n\n // Shallow merge overrides into tokens\n const mergedTokens: SpectreTokens = {\n ...tokens,\n ...(overrides ?? {}),\n };\n\n const theme: TailwindConfig['theme'] = {\n // Safely map core token groups into Tailwind theme fields.\n // Use `as any` where necessary to avoid overfitting types right now.\n colors: (mergedTokens as any).colors ?? {},\n spacing: (mergedTokens as any).spacing ?? {},\n borderRadius: (mergedTokens as any).radii ?? {},\n boxShadow: (mergedTokens as any).shadows ?? {},\n fontFamily: (mergedTokens as any).typography?.families ?? {},\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from 'tailwindcss';\nimport { spectreTokens } from '../tokens';\nimport { createSpectreTailwindTheme } from './theme';\n\nconst { theme } = createSpectreTailwindTheme({\n tokens: spectreTokens,\n});\n\nexport const spectrePreset: TailwindConfig = {\n // Required for Tailwind's Config type with exactOptionalPropertyTypes\n content: [],\n theme: theme ?? {},\n plugins: [],\n};\n\nexport const spectreTailwindPreset: TailwindConfig = spectrePreset;\n","export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\nexport type ButtonTone = 'default' | 'success' | 'warning' | 'danger';\n\nexport interface ButtonRecipeOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n tone?: ButtonTone;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n}\n\n/**\n * Generate Spectre button classes.\n *\n * Rules:\n * - Base: \"sp-btn\"\n * - Variant: \"sp-btn--primary\" / \"sp-btn--secondary\" / \"sp-btn--ghost\" / \"sp-btn--danger\"\n * - default variant is \"primary\"\n * - Size: \"sp-btn--sm\" / \"sp-btn--md\" / \"sp-btn--lg\"\n * - default size is \"md\"\n * - Tone: \"sp-btn--tone-success\" / \"sp-btn--tone-warning\" / \"sp-btn--tone-danger\"\n * - default tone is \"default\" (no tone class)\n * - fullWidth: add \"sp-btn--full\"\n * - loading: add \"sp-btn--loading\"\n * - disabled: add \"sp-btn--disabled\"\n * - iconOnly: add \"sp-btn--icon\"\n *\n * Must return a single space-joined, trimmed class string.\n */\nexport function getButtonClasses(opts: ButtonRecipeOptions = {}): string {\n const {\n variant = 'primary',\n size = 'md',\n tone = 'default',\n fullWidth = false,\n loading = false,\n disabled = false,\n iconOnly = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-btn');\n\n // Variant\n const variantMap: Record<ButtonVariant, string> = {\n primary: 'sp-btn--primary',\n secondary: 'sp-btn--secondary',\n ghost: 'sp-btn--ghost',\n danger: 'sp-btn--danger',\n };\n classes.push(variantMap[variant]);\n\n // Size\n const sizeMap: Record<ButtonSize, string> = {\n sm: 'sp-btn--sm',\n md: 'sp-btn--md',\n lg: 'sp-btn--lg',\n };\n classes.push(sizeMap[size]);\n\n // Tone (optional)\n if (tone !== 'default') {\n const toneMap: Record<Exclude<ButtonTone, 'default'>, string> = {\n success: 'sp-btn--tone-success',\n warning: 'sp-btn--tone-warning',\n danger: 'sp-btn--tone-danger',\n };\n classes.push(toneMap[tone as Exclude<ButtonTone, 'default'>]);\n }\n\n // Flags\n if (fullWidth) classes.push('sp-btn--full');\n if (loading) classes.push('sp-btn--loading');\n if (disabled) classes.push('sp-btn--disabled');\n if (iconOnly) classes.push('sp-btn--icon');\n\n // Final class string\n return classes.filter(Boolean).join(' ').trim();\n}\n","export type CardVariant = 'elevated' | 'outline' | 'ghost';\n\nexport interface CardRecipeOptions {\n variant?: CardVariant;\n interactive?: boolean; // hover/focus styles\n padded?: boolean; // apply default padding\n fullHeight?: boolean;\n}\n\n/**\n * Generate Spectre card classes.\n *\n * Rules:\n * - Base class: \"sp-card\"\n * - Variant (default: elevated):\n * - \"sp-card--elevated\"\n * - \"sp-card--outline\"\n * - \"sp-card--ghost\"\n * - interactive: add \"sp-card--interactive\"\n * - padded: add \"sp-card--padded\"\n * - fullHeight: add \"sp-card--full\"\n */\nexport function getCardClasses(opts: CardRecipeOptions = {}): string {\n const {\n variant = 'elevated',\n interactive = false,\n padded = false,\n fullHeight = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-card');\n\n // Variant\n const variantMap: Record<CardVariant, string> = {\n elevated: 'sp-card--elevated',\n outline: 'sp-card--outline',\n ghost: 'sp-card--ghost',\n };\n classes.push(variantMap[variant]);\n\n // Flags\n if (interactive) classes.push('sp-card--interactive');\n if (padded) classes.push('sp-card--padded');\n if (fullHeight) classes.push('sp-card--full');\n\n return classes.filter(Boolean).join(' ').trim();\n}\n","export type InputState = 'default' | 'error' | 'success';\nexport type InputSize = 'sm' | 'md' | 'lg';\n\nexport interface InputRecipeOptions {\n state?: InputState;\n size?: InputSize;\n fullWidth?: boolean;\n}\n\n/**\n * Generate Spectre input classes.\n *\n * Rules:\n * - Base class: \"sp-input\"\n * - State:\n * - \"default\" => no state modifier\n * - \"error\" => \"sp-input--error\"\n * - \"success\" => \"sp-input--success\"\n * - Size (default: md):\n * - \"sp-input--sm\"\n * - \"sp-input--md\"\n * - \"sp-input--lg\"\n * - fullWidth: add \"sp-input--full\"\n */\nexport function getInputClasses(opts: InputRecipeOptions = {}): string {\n const {\n state = 'default',\n size = 'md',\n fullWidth = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-input');\n\n // State\n if (state === 'error') {\n classes.push('sp-input--error');\n } else if (state === 'success') {\n classes.push('sp-input--success');\n }\n\n // Size\n const sizeMap: Record<InputSize, string> = {\n sm: 'sp-input--sm',\n md: 'sp-input--md',\n lg: 'sp-input--lg',\n };\n classes.push(sizeMap[size]);\n\n // Flags\n if (fullWidth) {\n classes.push('sp-input--full');\n }\n\n return classes.filter(Boolean).join(' ').trim();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/css-constants.ts","../src/tailwind/theme.ts","../src/tailwind/preset.ts","../src/recipes/button.ts","../src/recipes/card.ts","../src/recipes/input.ts"],"names":["theme","spectreTokens"],"mappings":"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","file":"index.cjs","sourcesContent":["export const spectreBaseStylesPath = \"@phcdevworks/spectre-ui/dist/base.css\";\nexport const spectreComponentsStylesPath = \"@phcdevworks/spectre-ui/dist/components.css\";\nexport const spectreUtilitiesStylesPath = \"@phcdevworks/spectre-ui/dist/utilities.css\";\n\nexport const spectreStyles = {\n base: spectreBaseStylesPath,\n components: spectreComponentsStylesPath,\n utilities: spectreUtilitiesStylesPath,\n};\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\nexport interface SpectreTailwindTheme {\n theme: TailwindConfig[\"theme\"];\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions,\n): SpectreTailwindTheme {\n const { tokens, overrides } = options;\n\n // Shallow merge overrides into tokens\n const mergedTokens: SpectreTokens = {\n ...(tokens as SpectreTokens),\n ...(overrides as Partial<SpectreTokens> | undefined),\n };\n\n // Minimal, semantic color mapping\n const colors: Record<string, unknown> = {\n page: mergedTokens.surface?.page,\n card: mergedTokens.surface?.card,\n input: mergedTokens.surface?.input,\n text: {\n page: mergedTokens.text?.onPage?.default,\n \"page-muted\": mergedTokens.text?.onPage?.muted,\n surface: mergedTokens.text?.onSurface?.default,\n \"surface-muted\": mergedTokens.text?.onSurface?.muted,\n },\n primary:\n (mergedTokens as any).buttons?.primary?.bg ??\n (mergedTokens as any).colors?.primary,\n };\n\n const spacing: Record<string, unknown> =\n (mergedTokens as any).spacing ?? {};\n\n const borderRadius: Record<string, unknown> =\n (mergedTokens as any).radii ?? {};\n\n const boxShadow: Record<string, unknown> =\n (mergedTokens as any).shadows ?? {};\n\n const fontFamily: Record<string, unknown> =\n (mergedTokens as any).typography?.families ?? {};\n\n const theme: TailwindConfig[\"theme\"] = {\n colors: colors as any,\n spacing: spacing as any,\n borderRadius: borderRadius as any,\n boxShadow: boxShadow as any,\n fontFamily: fontFamily as any,\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport { spectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\nconst { theme } = createSpectreTailwindTheme({ tokens: spectreTokens });\n\nexport const spectrePreset: TailwindConfig = {\n content: [],\n theme: theme ?? {}, // ensure theme is never undefined\n};\n\nexport default spectrePreset;\n","export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\nexport type ButtonTone = 'default' | 'success' | 'warning' | 'danger';\n\nexport interface ButtonRecipeOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n tone?: ButtonTone;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n}\n\n/**\n * Generate Spectre button classes.\n *\n * Rules:\n * - Base: \"sp-btn\"\n * - Variant: \"sp-btn--primary\" / \"sp-btn--secondary\" / \"sp-btn--ghost\" / \"sp-btn--danger\"\n * - default variant is \"primary\"\n * - Size: \"sp-btn--sm\" / \"sp-btn--md\" / \"sp-btn--lg\"\n * - default size is \"md\"\n * - Tone: \"sp-btn--tone-success\" / \"sp-btn--tone-warning\" / \"sp-btn--tone-danger\"\n * - default tone is \"default\" (no tone class)\n * - fullWidth: add \"sp-btn--full\"\n * - loading: add \"sp-btn--loading\"\n * - disabled: add \"sp-btn--disabled\"\n * - iconOnly: add \"sp-btn--icon\"\n *\n * Must return a single space-joined, trimmed class string.\n */\nexport function getButtonClasses(opts: ButtonRecipeOptions = {}): string {\n const {\n variant = 'primary',\n size = 'md',\n tone = 'default',\n fullWidth = false,\n loading = false,\n disabled = false,\n iconOnly = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-btn');\n\n // Variant\n const variantMap: Record<ButtonVariant, string> = {\n primary: 'sp-btn--primary',\n secondary: 'sp-btn--secondary',\n ghost: 'sp-btn--ghost',\n danger: 'sp-btn--danger',\n };\n classes.push(variantMap[variant]);\n\n // Size\n const sizeMap: Record<ButtonSize, string> = {\n sm: 'sp-btn--sm',\n md: 'sp-btn--md',\n lg: 'sp-btn--lg',\n };\n classes.push(sizeMap[size]);\n\n // Tone (optional)\n if (tone !== 'default') {\n const toneMap: Record<Exclude<ButtonTone, 'default'>, string> = {\n success: 'sp-btn--tone-success',\n warning: 'sp-btn--tone-warning',\n danger: 'sp-btn--tone-danger',\n };\n classes.push(toneMap[tone as Exclude<ButtonTone, 'default'>]);\n }\n\n // Flags\n if (fullWidth) classes.push('sp-btn--full');\n if (loading) classes.push('sp-btn--loading');\n if (disabled) classes.push('sp-btn--disabled');\n if (iconOnly) classes.push('sp-btn--icon');\n\n // Final class string\n return classes.filter(Boolean).join(' ').trim();\n}\n","export type CardVariant = 'elevated' | 'outline' | 'ghost';\n\nexport interface CardRecipeOptions {\n variant?: CardVariant;\n interactive?: boolean; // hover/focus styles\n padded?: boolean; // apply default padding\n fullHeight?: boolean;\n}\n\n/**\n * Generate Spectre card classes.\n *\n * Rules:\n * - Base class: \"sp-card\"\n * - Variant (default: elevated):\n * - \"sp-card--elevated\"\n * - \"sp-card--outline\"\n * - \"sp-card--ghost\"\n * - interactive: add \"sp-card--interactive\"\n * - padded: add \"sp-card--padded\"\n * - fullHeight: add \"sp-card--full\"\n */\nexport function getCardClasses(opts: CardRecipeOptions = {}): string {\n const {\n variant = 'elevated',\n interactive = false,\n padded = false,\n fullHeight = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-card');\n\n // Variant\n const variantMap: Record<CardVariant, string> = {\n elevated: 'sp-card--elevated',\n outline: 'sp-card--outline',\n ghost: 'sp-card--ghost',\n };\n classes.push(variantMap[variant]);\n\n // Flags\n if (interactive) classes.push('sp-card--interactive');\n if (padded) classes.push('sp-card--padded');\n if (fullHeight) classes.push('sp-card--full');\n\n return classes.filter(Boolean).join(' ').trim();\n}\n","export type InputState = 'default' | 'error' | 'success';\nexport type InputSize = 'sm' | 'md' | 'lg';\n\nexport interface InputRecipeOptions {\n state?: InputState;\n size?: InputSize;\n fullWidth?: boolean;\n}\n\n/**\n * Generate Spectre input classes.\n *\n * Rules:\n * - Base class: \"sp-input\"\n * - State:\n * - \"default\" => no state modifier\n * - \"error\" => \"sp-input--error\"\n * - \"success\" => \"sp-input--success\"\n * - Size (default: md):\n * - \"sp-input--sm\"\n * - \"sp-input--md\"\n * - \"sp-input--lg\"\n * - fullWidth: add \"sp-input--full\"\n */\nexport function getInputClasses(opts: InputRecipeOptions = {}): string {\n const {\n state = 'default',\n size = 'md',\n fullWidth = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-input');\n\n // State\n if (state === 'error') {\n classes.push('sp-input--error');\n } else if (state === 'success') {\n classes.push('sp-input--success');\n }\n\n // Size\n const sizeMap: Record<InputSize, string> = {\n sm: 'sp-input--sm',\n md: 'sp-input--md',\n lg: 'sp-input--lg',\n };\n classes.push(sizeMap[size]);\n\n // Flags\n if (fullWidth) {\n classes.push('sp-input--full');\n }\n\n return classes.filter(Boolean).join(' ').trim();\n}\n"]}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -16,29 +16,40 @@ function createSpectreTailwindTheme(options) {
|
|
|
16
16
|
const { tokens, overrides } = options;
|
|
17
17
|
const mergedTokens = {
|
|
18
18
|
...tokens,
|
|
19
|
-
...overrides
|
|
19
|
+
...overrides
|
|
20
20
|
};
|
|
21
|
+
const colors = {
|
|
22
|
+
page: mergedTokens.surface?.page,
|
|
23
|
+
card: mergedTokens.surface?.card,
|
|
24
|
+
input: mergedTokens.surface?.input,
|
|
25
|
+
text: {
|
|
26
|
+
page: mergedTokens.text?.onPage?.default,
|
|
27
|
+
"page-muted": mergedTokens.text?.onPage?.muted,
|
|
28
|
+
surface: mergedTokens.text?.onSurface?.default,
|
|
29
|
+
"surface-muted": mergedTokens.text?.onSurface?.muted
|
|
30
|
+
},
|
|
31
|
+
primary: mergedTokens.buttons?.primary?.bg ?? mergedTokens.colors?.primary
|
|
32
|
+
};
|
|
33
|
+
const spacing = mergedTokens.spacing ?? {};
|
|
34
|
+
const borderRadius = mergedTokens.radii ?? {};
|
|
35
|
+
const boxShadow = mergedTokens.shadows ?? {};
|
|
36
|
+
const fontFamily = mergedTokens.typography?.families ?? {};
|
|
21
37
|
const theme2 = {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
boxShadow: mergedTokens.shadows ?? {},
|
|
28
|
-
fontFamily: mergedTokens.typography?.families ?? {}
|
|
38
|
+
colors,
|
|
39
|
+
spacing,
|
|
40
|
+
borderRadius,
|
|
41
|
+
boxShadow,
|
|
42
|
+
fontFamily
|
|
29
43
|
};
|
|
30
44
|
return { theme: theme2 };
|
|
31
45
|
}
|
|
32
46
|
|
|
33
47
|
// src/tailwind/preset.ts
|
|
34
|
-
var { theme } = createSpectreTailwindTheme({
|
|
35
|
-
tokens: tokens
|
|
36
|
-
});
|
|
48
|
+
var { theme } = createSpectreTailwindTheme({ tokens: tokens });
|
|
37
49
|
var spectrePreset = {
|
|
38
|
-
// Required for Tailwind's Config type with exactOptionalPropertyTypes
|
|
39
50
|
content: [],
|
|
40
|
-
theme: theme ?? {}
|
|
41
|
-
|
|
51
|
+
theme: theme ?? {}
|
|
52
|
+
// ensure theme is never undefined
|
|
42
53
|
};
|
|
43
54
|
|
|
44
55
|
// src/recipes/button.ts
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/css-constants.ts","../src/tailwind/theme.ts","../src/tailwind/preset.ts","../src/recipes/button.ts","../src/recipes/card.ts","../src/recipes/input.ts"],"names":["theme","spectreTokens"],"mappings":"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","file":"index.js","sourcesContent":["export const spectreBaseStylesPath = \"@phcdevworks/spectre-ui/dist/base.css\";\nexport const spectreComponentsStylesPath = \"@phcdevworks/spectre-ui/dist/components.css\";\nexport const spectreUtilitiesStylesPath = \"@phcdevworks/spectre-ui/dist/utilities.css\";\n\nexport const spectreStyles = {\n base: spectreBaseStylesPath,\n components: spectreComponentsStylesPath,\n utilities: spectreUtilitiesStylesPath,\n};\n","import type { Config as TailwindConfig } from 'tailwindcss';\nimport type { SpectreTokens } from '../tokens';\n\nexport interface SpectreTailwindTheme {\n theme: TailwindConfig['theme'];\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions,\n): SpectreTailwindTheme {\n const { tokens, overrides } = options;\n\n // Shallow merge overrides into tokens\n const mergedTokens: SpectreTokens = {\n ...tokens,\n ...(overrides ?? {}),\n };\n\n const theme: TailwindConfig['theme'] = {\n // Safely map core token groups into Tailwind theme fields.\n // Use `as any` where necessary to avoid overfitting types right now.\n colors: (mergedTokens as any).colors ?? {},\n spacing: (mergedTokens as any).spacing ?? {},\n borderRadius: (mergedTokens as any).radii ?? {},\n boxShadow: (mergedTokens as any).shadows ?? {},\n fontFamily: (mergedTokens as any).typography?.families ?? {},\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from 'tailwindcss';\nimport { spectreTokens } from '../tokens';\nimport { createSpectreTailwindTheme } from './theme';\n\nconst { theme } = createSpectreTailwindTheme({\n tokens: spectreTokens,\n});\n\nexport const spectrePreset: TailwindConfig = {\n // Required for Tailwind's Config type with exactOptionalPropertyTypes\n content: [],\n theme: theme ?? {},\n plugins: [],\n};\n\nexport const spectreTailwindPreset: TailwindConfig = spectrePreset;\n","export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\nexport type ButtonTone = 'default' | 'success' | 'warning' | 'danger';\n\nexport interface ButtonRecipeOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n tone?: ButtonTone;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n}\n\n/**\n * Generate Spectre button classes.\n *\n * Rules:\n * - Base: \"sp-btn\"\n * - Variant: \"sp-btn--primary\" / \"sp-btn--secondary\" / \"sp-btn--ghost\" / \"sp-btn--danger\"\n * - default variant is \"primary\"\n * - Size: \"sp-btn--sm\" / \"sp-btn--md\" / \"sp-btn--lg\"\n * - default size is \"md\"\n * - Tone: \"sp-btn--tone-success\" / \"sp-btn--tone-warning\" / \"sp-btn--tone-danger\"\n * - default tone is \"default\" (no tone class)\n * - fullWidth: add \"sp-btn--full\"\n * - loading: add \"sp-btn--loading\"\n * - disabled: add \"sp-btn--disabled\"\n * - iconOnly: add \"sp-btn--icon\"\n *\n * Must return a single space-joined, trimmed class string.\n */\nexport function getButtonClasses(opts: ButtonRecipeOptions = {}): string {\n const {\n variant = 'primary',\n size = 'md',\n tone = 'default',\n fullWidth = false,\n loading = false,\n disabled = false,\n iconOnly = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-btn');\n\n // Variant\n const variantMap: Record<ButtonVariant, string> = {\n primary: 'sp-btn--primary',\n secondary: 'sp-btn--secondary',\n ghost: 'sp-btn--ghost',\n danger: 'sp-btn--danger',\n };\n classes.push(variantMap[variant]);\n\n // Size\n const sizeMap: Record<ButtonSize, string> = {\n sm: 'sp-btn--sm',\n md: 'sp-btn--md',\n lg: 'sp-btn--lg',\n };\n classes.push(sizeMap[size]);\n\n // Tone (optional)\n if (tone !== 'default') {\n const toneMap: Record<Exclude<ButtonTone, 'default'>, string> = {\n success: 'sp-btn--tone-success',\n warning: 'sp-btn--tone-warning',\n danger: 'sp-btn--tone-danger',\n };\n classes.push(toneMap[tone as Exclude<ButtonTone, 'default'>]);\n }\n\n // Flags\n if (fullWidth) classes.push('sp-btn--full');\n if (loading) classes.push('sp-btn--loading');\n if (disabled) classes.push('sp-btn--disabled');\n if (iconOnly) classes.push('sp-btn--icon');\n\n // Final class string\n return classes.filter(Boolean).join(' ').trim();\n}\n","export type CardVariant = 'elevated' | 'outline' | 'ghost';\n\nexport interface CardRecipeOptions {\n variant?: CardVariant;\n interactive?: boolean; // hover/focus styles\n padded?: boolean; // apply default padding\n fullHeight?: boolean;\n}\n\n/**\n * Generate Spectre card classes.\n *\n * Rules:\n * - Base class: \"sp-card\"\n * - Variant (default: elevated):\n * - \"sp-card--elevated\"\n * - \"sp-card--outline\"\n * - \"sp-card--ghost\"\n * - interactive: add \"sp-card--interactive\"\n * - padded: add \"sp-card--padded\"\n * - fullHeight: add \"sp-card--full\"\n */\nexport function getCardClasses(opts: CardRecipeOptions = {}): string {\n const {\n variant = 'elevated',\n interactive = false,\n padded = false,\n fullHeight = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-card');\n\n // Variant\n const variantMap: Record<CardVariant, string> = {\n elevated: 'sp-card--elevated',\n outline: 'sp-card--outline',\n ghost: 'sp-card--ghost',\n };\n classes.push(variantMap[variant]);\n\n // Flags\n if (interactive) classes.push('sp-card--interactive');\n if (padded) classes.push('sp-card--padded');\n if (fullHeight) classes.push('sp-card--full');\n\n return classes.filter(Boolean).join(' ').trim();\n}\n","export type InputState = 'default' | 'error' | 'success';\nexport type InputSize = 'sm' | 'md' | 'lg';\n\nexport interface InputRecipeOptions {\n state?: InputState;\n size?: InputSize;\n fullWidth?: boolean;\n}\n\n/**\n * Generate Spectre input classes.\n *\n * Rules:\n * - Base class: \"sp-input\"\n * - State:\n * - \"default\" => no state modifier\n * - \"error\" => \"sp-input--error\"\n * - \"success\" => \"sp-input--success\"\n * - Size (default: md):\n * - \"sp-input--sm\"\n * - \"sp-input--md\"\n * - \"sp-input--lg\"\n * - fullWidth: add \"sp-input--full\"\n */\nexport function getInputClasses(opts: InputRecipeOptions = {}): string {\n const {\n state = 'default',\n size = 'md',\n fullWidth = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-input');\n\n // State\n if (state === 'error') {\n classes.push('sp-input--error');\n } else if (state === 'success') {\n classes.push('sp-input--success');\n }\n\n // Size\n const sizeMap: Record<InputSize, string> = {\n sm: 'sp-input--sm',\n md: 'sp-input--md',\n lg: 'sp-input--lg',\n };\n classes.push(sizeMap[size]);\n\n // Flags\n if (fullWidth) {\n classes.push('sp-input--full');\n }\n\n return classes.filter(Boolean).join(' ').trim();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/css-constants.ts","../src/tailwind/theme.ts","../src/tailwind/preset.ts","../src/recipes/button.ts","../src/recipes/card.ts","../src/recipes/input.ts"],"names":["theme","spectreTokens"],"mappings":"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","file":"index.js","sourcesContent":["export const spectreBaseStylesPath = \"@phcdevworks/spectre-ui/dist/base.css\";\nexport const spectreComponentsStylesPath = \"@phcdevworks/spectre-ui/dist/components.css\";\nexport const spectreUtilitiesStylesPath = \"@phcdevworks/spectre-ui/dist/utilities.css\";\n\nexport const spectreStyles = {\n base: spectreBaseStylesPath,\n components: spectreComponentsStylesPath,\n utilities: spectreUtilitiesStylesPath,\n};\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\nexport interface SpectreTailwindTheme {\n theme: TailwindConfig[\"theme\"];\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions,\n): SpectreTailwindTheme {\n const { tokens, overrides } = options;\n\n // Shallow merge overrides into tokens\n const mergedTokens: SpectreTokens = {\n ...(tokens as SpectreTokens),\n ...(overrides as Partial<SpectreTokens> | undefined),\n };\n\n // Minimal, semantic color mapping\n const colors: Record<string, unknown> = {\n page: mergedTokens.surface?.page,\n card: mergedTokens.surface?.card,\n input: mergedTokens.surface?.input,\n text: {\n page: mergedTokens.text?.onPage?.default,\n \"page-muted\": mergedTokens.text?.onPage?.muted,\n surface: mergedTokens.text?.onSurface?.default,\n \"surface-muted\": mergedTokens.text?.onSurface?.muted,\n },\n primary:\n (mergedTokens as any).buttons?.primary?.bg ??\n (mergedTokens as any).colors?.primary,\n };\n\n const spacing: Record<string, unknown> =\n (mergedTokens as any).spacing ?? {};\n\n const borderRadius: Record<string, unknown> =\n (mergedTokens as any).radii ?? {};\n\n const boxShadow: Record<string, unknown> =\n (mergedTokens as any).shadows ?? {};\n\n const fontFamily: Record<string, unknown> =\n (mergedTokens as any).typography?.families ?? {};\n\n const theme: TailwindConfig[\"theme\"] = {\n colors: colors as any,\n spacing: spacing as any,\n borderRadius: borderRadius as any,\n boxShadow: boxShadow as any,\n fontFamily: fontFamily as any,\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport { spectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\nconst { theme } = createSpectreTailwindTheme({ tokens: spectreTokens });\n\nexport const spectrePreset: TailwindConfig = {\n content: [],\n theme: theme ?? {}, // ensure theme is never undefined\n};\n\nexport default spectrePreset;\n","export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\nexport type ButtonTone = 'default' | 'success' | 'warning' | 'danger';\n\nexport interface ButtonRecipeOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n tone?: ButtonTone;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n}\n\n/**\n * Generate Spectre button classes.\n *\n * Rules:\n * - Base: \"sp-btn\"\n * - Variant: \"sp-btn--primary\" / \"sp-btn--secondary\" / \"sp-btn--ghost\" / \"sp-btn--danger\"\n * - default variant is \"primary\"\n * - Size: \"sp-btn--sm\" / \"sp-btn--md\" / \"sp-btn--lg\"\n * - default size is \"md\"\n * - Tone: \"sp-btn--tone-success\" / \"sp-btn--tone-warning\" / \"sp-btn--tone-danger\"\n * - default tone is \"default\" (no tone class)\n * - fullWidth: add \"sp-btn--full\"\n * - loading: add \"sp-btn--loading\"\n * - disabled: add \"sp-btn--disabled\"\n * - iconOnly: add \"sp-btn--icon\"\n *\n * Must return a single space-joined, trimmed class string.\n */\nexport function getButtonClasses(opts: ButtonRecipeOptions = {}): string {\n const {\n variant = 'primary',\n size = 'md',\n tone = 'default',\n fullWidth = false,\n loading = false,\n disabled = false,\n iconOnly = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-btn');\n\n // Variant\n const variantMap: Record<ButtonVariant, string> = {\n primary: 'sp-btn--primary',\n secondary: 'sp-btn--secondary',\n ghost: 'sp-btn--ghost',\n danger: 'sp-btn--danger',\n };\n classes.push(variantMap[variant]);\n\n // Size\n const sizeMap: Record<ButtonSize, string> = {\n sm: 'sp-btn--sm',\n md: 'sp-btn--md',\n lg: 'sp-btn--lg',\n };\n classes.push(sizeMap[size]);\n\n // Tone (optional)\n if (tone !== 'default') {\n const toneMap: Record<Exclude<ButtonTone, 'default'>, string> = {\n success: 'sp-btn--tone-success',\n warning: 'sp-btn--tone-warning',\n danger: 'sp-btn--tone-danger',\n };\n classes.push(toneMap[tone as Exclude<ButtonTone, 'default'>]);\n }\n\n // Flags\n if (fullWidth) classes.push('sp-btn--full');\n if (loading) classes.push('sp-btn--loading');\n if (disabled) classes.push('sp-btn--disabled');\n if (iconOnly) classes.push('sp-btn--icon');\n\n // Final class string\n return classes.filter(Boolean).join(' ').trim();\n}\n","export type CardVariant = 'elevated' | 'outline' | 'ghost';\n\nexport interface CardRecipeOptions {\n variant?: CardVariant;\n interactive?: boolean; // hover/focus styles\n padded?: boolean; // apply default padding\n fullHeight?: boolean;\n}\n\n/**\n * Generate Spectre card classes.\n *\n * Rules:\n * - Base class: \"sp-card\"\n * - Variant (default: elevated):\n * - \"sp-card--elevated\"\n * - \"sp-card--outline\"\n * - \"sp-card--ghost\"\n * - interactive: add \"sp-card--interactive\"\n * - padded: add \"sp-card--padded\"\n * - fullHeight: add \"sp-card--full\"\n */\nexport function getCardClasses(opts: CardRecipeOptions = {}): string {\n const {\n variant = 'elevated',\n interactive = false,\n padded = false,\n fullHeight = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-card');\n\n // Variant\n const variantMap: Record<CardVariant, string> = {\n elevated: 'sp-card--elevated',\n outline: 'sp-card--outline',\n ghost: 'sp-card--ghost',\n };\n classes.push(variantMap[variant]);\n\n // Flags\n if (interactive) classes.push('sp-card--interactive');\n if (padded) classes.push('sp-card--padded');\n if (fullHeight) classes.push('sp-card--full');\n\n return classes.filter(Boolean).join(' ').trim();\n}\n","export type InputState = 'default' | 'error' | 'success';\nexport type InputSize = 'sm' | 'md' | 'lg';\n\nexport interface InputRecipeOptions {\n state?: InputState;\n size?: InputSize;\n fullWidth?: boolean;\n}\n\n/**\n * Generate Spectre input classes.\n *\n * Rules:\n * - Base class: \"sp-input\"\n * - State:\n * - \"default\" => no state modifier\n * - \"error\" => \"sp-input--error\"\n * - \"success\" => \"sp-input--success\"\n * - Size (default: md):\n * - \"sp-input--sm\"\n * - \"sp-input--md\"\n * - \"sp-input--lg\"\n * - fullWidth: add \"sp-input--full\"\n */\nexport function getInputClasses(opts: InputRecipeOptions = {}): string {\n const {\n state = 'default',\n size = 'md',\n fullWidth = false,\n } = opts;\n\n const classes: string[] = [];\n\n // Base\n classes.push('sp-input');\n\n // State\n if (state === 'error') {\n classes.push('sp-input--error');\n } else if (state === 'success') {\n classes.push('sp-input--success');\n }\n\n // Size\n const sizeMap: Record<InputSize, string> = {\n sm: 'sp-input--sm',\n md: 'sp-input--md',\n lg: 'sp-input--lg',\n };\n classes.push(sizeMap[size]);\n\n // Flags\n if (fullWidth) {\n classes.push('sp-input--full');\n }\n\n return classes.filter(Boolean).join(' ').trim();\n}\n"]}
|
package/dist/utilities.css
CHANGED
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
.sp-shadow-soft {
|
|
30
|
-
box-shadow: var(--sp-shadow-md
|
|
30
|
+
box-shadow: var(--sp-shadow-md);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
.sp-shadow-strong {
|
|
34
|
-
box-shadow: var(--sp-shadow-lg
|
|
34
|
+
box-shadow: var(--sp-shadow-lg);
|
|
35
35
|
}
|
|
36
36
|
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,52 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phcdevworks/spectre-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Framework-agnostic UI layer for the Spectre design system. Provides base CSS, component classes, utilities, and a Tailwind preset powered by @phcdevworks/spectre-tokens.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"phcdevworks",
|
|
7
|
+
"spectre",
|
|
8
|
+
"spectre-ui",
|
|
9
|
+
"design-system",
|
|
10
|
+
"design-tokens",
|
|
11
|
+
"component-library",
|
|
12
|
+
"ui-library",
|
|
13
|
+
"ui-components",
|
|
14
|
+
"tailwindcss",
|
|
15
|
+
"css-utilities",
|
|
16
|
+
"css-framework",
|
|
17
|
+
"tokens",
|
|
18
|
+
"utilities"
|
|
19
|
+
],
|
|
20
|
+
"author": "PHCDevworks",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"funding": [
|
|
23
|
+
{
|
|
24
|
+
"type": "github",
|
|
25
|
+
"url": "https://github.com/sponsors/phcdevworks"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"type": "buymeacoffee",
|
|
29
|
+
"url": "https://buymeacoffee.com/phcdevworks"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/phcdevworks/spectre-ui.git"
|
|
35
|
+
},
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/phcdevworks/spectre-ui/issues"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/phcdevworks/spectre-ui#readme",
|
|
40
|
+
"type": "module",
|
|
5
41
|
"main": "./dist/index.cjs",
|
|
6
42
|
"module": "./dist/index.js",
|
|
7
43
|
"types": "./dist/index.d.ts",
|
|
8
|
-
"type": "module",
|
|
9
44
|
"exports": {
|
|
10
45
|
".": {
|
|
11
46
|
"types": "./dist/index.d.ts",
|
|
12
47
|
"import": "./dist/index.js",
|
|
13
48
|
"require": "./dist/index.cjs"
|
|
14
49
|
},
|
|
15
|
-
"./dist/base.css": "./dist/base.css",
|
|
16
|
-
"./dist/components.css": "./dist/components.css",
|
|
17
|
-
"./dist/utilities.css": "./dist/utilities.css",
|
|
18
50
|
"./base.css": "./dist/base.css",
|
|
19
51
|
"./components.css": "./dist/components.css",
|
|
20
52
|
"./utilities.css": "./dist/utilities.css"
|
|
@@ -28,28 +60,9 @@
|
|
|
28
60
|
"scripts": {
|
|
29
61
|
"build": "tsup --config tsup.config.ts",
|
|
30
62
|
"dev": "tsup --config tsup.config.ts --watch",
|
|
31
|
-
"clean": "rm -rf dist"
|
|
32
|
-
|
|
33
|
-
"repository": {
|
|
34
|
-
"type": "git",
|
|
35
|
-
"url": "git+https://github.com/phcdevworks/spectre-ui.git"
|
|
36
|
-
},
|
|
37
|
-
"keywords": [
|
|
38
|
-
"spectre",
|
|
39
|
-
"design-system",
|
|
40
|
-
"tailwindcss",
|
|
41
|
-
"components",
|
|
42
|
-
"utilities",
|
|
43
|
-
"tokens",
|
|
44
|
-
"ui-library",
|
|
45
|
-
"phcdevworks"
|
|
46
|
-
],
|
|
47
|
-
"author": "PHCDevworks",
|
|
48
|
-
"license": "MIT",
|
|
49
|
-
"bugs": {
|
|
50
|
-
"url": "https://github.com/phcdevworks/spectre-ui/issues"
|
|
63
|
+
"clean": "rm -rf dist",
|
|
64
|
+
"test": "vitest run"
|
|
51
65
|
},
|
|
52
|
-
"homepage": "https://github.com/phcdevworks/spectre-ui#readme",
|
|
53
66
|
"publishConfig": {
|
|
54
67
|
"access": "public"
|
|
55
68
|
},
|
|
@@ -57,14 +70,14 @@
|
|
|
57
70
|
"tailwindcss": "^3.4.0 || ^4.0.0"
|
|
58
71
|
},
|
|
59
72
|
"dependencies": {
|
|
60
|
-
"@phcdevworks/spectre-tokens": "^0.0.
|
|
61
|
-
"user": "^0.0.0"
|
|
73
|
+
"@phcdevworks/spectre-tokens": "^0.0.4"
|
|
62
74
|
},
|
|
63
75
|
"devDependencies": {
|
|
64
76
|
"autoprefixer": "^10.4.20",
|
|
65
77
|
"postcss": "^8.4.35",
|
|
66
78
|
"tailwindcss": "^3.4.15",
|
|
67
79
|
"tsup": "^8.5.1",
|
|
68
|
-
"typescript": "^5.9.3"
|
|
80
|
+
"typescript": "^5.9.3",
|
|
81
|
+
"vitest": "^2.1.4"
|
|
69
82
|
}
|
|
70
83
|
}
|