@vinyasa/tokens 1.0.15 → 1.0.16
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 +119 -0
- package/dist/cjs/index.cjs +5 -0
- package/dist/esm/contract.css.d.ts +1 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/primitives.d.ts +3 -0
- package/dist/esm/theme.d.ts +1 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# @vinyasa/tokens
|
|
2
|
+
|
|
3
|
+
The shared design-token and theming foundation for `@vinyasa/*` components: a color/spacing/typography/motion contract plus a `VinyasaProvider` that resolves and injects real values at runtime.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @vinyasa/tokens react react-dom
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
Wrap your app once, near the root:
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { VinyasaProvider } from '@vinyasa/tokens';
|
|
17
|
+
|
|
18
|
+
function App() {
|
|
19
|
+
return (
|
|
20
|
+
<VinyasaProvider>
|
|
21
|
+
<YourApp />
|
|
22
|
+
</VinyasaProvider>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`VinyasaProvider` resolves a theme and injects it as CSS custom properties on a `display: contents` wrapper element (no extra layout box), scoped to everything rendered inside it. Any `@vinyasa/*` component rendered under the provider picks up those values automatically — there's no separate stylesheet to import.
|
|
28
|
+
|
|
29
|
+
## How theming works
|
|
30
|
+
|
|
31
|
+
Values are organized in three tiers:
|
|
32
|
+
|
|
33
|
+
1. **Primitives** (`primitives.ts`) — raw, numeric-keyed scales with no meaning attached: `gray[900]`, `blue[500]`, `space[3]`.
|
|
34
|
+
2. **Semantic contract** (`themeContract`, exported from this package) — a flat, brand-role naming tier: `primary`/`onPrimary`, `secondary`/`onSecondary`, `tertiary`/`onTertiary`, `error`/`onError`, plus `focus`, spacing (`space1`–`space6`), radii, font size/weight, line height, motion timing, and `borderWidthThin`. This is what a component's own `.css.ts` file imports and references — never the primitives directly.
|
|
35
|
+
3. **Runtime theme** (`defaultTheme`, `createTheme`, `VinyasaProvider`) — the actual values, injected as CSS custom properties at render time (via `@vanilla-extract/dynamic`), not baked into a static stylesheet. This is what makes overriding a value a runtime prop, not a rebuild.
|
|
36
|
+
|
|
37
|
+
### Overriding values
|
|
38
|
+
|
|
39
|
+
Pass a partial theme — only the keys you override change, everything else keeps its default:
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
<VinyasaProvider theme={{ primary: '#7c3aed' }}>
|
|
43
|
+
<YourApp />
|
|
44
|
+
</VinyasaProvider>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
You can also build a full custom theme ahead of time with `createTheme`:
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { createTheme, VinyasaProvider } from '@vinyasa/tokens';
|
|
51
|
+
|
|
52
|
+
const brandTheme = createTheme({ primary: '#7c3aed', onPrimary: '#ffffff' });
|
|
53
|
+
|
|
54
|
+
<VinyasaProvider theme={brandTheme}>
|
|
55
|
+
<YourApp />
|
|
56
|
+
</VinyasaProvider>;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Providers can be nested for scoped overrides — an inner `VinyasaProvider` only affects the subtree it wraps.
|
|
60
|
+
|
|
61
|
+
### Reading the theme programmatically
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import { useVinyasaTheme } from '@vinyasa/tokens';
|
|
65
|
+
|
|
66
|
+
function Component() {
|
|
67
|
+
const theme = useVinyasaTheme();
|
|
68
|
+
return <span style={{ color: theme.primary }}>...</span>;
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `colorScheme` and `contrast`
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
<VinyasaProvider colorScheme="light" contrast="normal">
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Only `light`/`normal` values are authored today. The registry these resolve from (`resolveBaseTheme`) is structured so adding `dark` or `high`-contrast values later is purely additive — no changes to the contract, the provider, or any component that consumes it. Requesting an unshipped combination falls back to `light`/`normal` with a console warning in development.
|
|
79
|
+
|
|
80
|
+
## Consuming the contract in your own component
|
|
81
|
+
|
|
82
|
+
This is the pattern every `@vinyasa/*` component follows — reference `themeContract`, never hardcode a value:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
// YourComponent.css.ts
|
|
86
|
+
import { style } from '@vanilla-extract/css';
|
|
87
|
+
import { themeContract as vars } from '@vinyasa/tokens';
|
|
88
|
+
|
|
89
|
+
export const root = style({
|
|
90
|
+
backgroundColor: vars.primary,
|
|
91
|
+
color: vars.onPrimary,
|
|
92
|
+
padding: `${vars.space3} ${vars.space4}`,
|
|
93
|
+
borderRadius: vars.radiusFull,
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`pnpm create:package <name>` scaffolds new component packages wired to this contract by default.
|
|
98
|
+
|
|
99
|
+
## API
|
|
100
|
+
|
|
101
|
+
| Export | Description |
|
|
102
|
+
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
103
|
+
| `VinyasaProvider` | React component. Props: `theme?`, `colorScheme?`, `contrast?`, `children`. |
|
|
104
|
+
| `useVinyasaTheme()` | Hook returning the currently resolved `VinyasaTheme` object. |
|
|
105
|
+
| `themeContract` | The token contract — import as `vars` in a component's `.css.ts` file. |
|
|
106
|
+
| `defaultTheme` | The default (light/normal) theme values object. |
|
|
107
|
+
| `createTheme(overrides)` | Merges a partial theme onto `defaultTheme`, returning a full `VinyasaTheme`. |
|
|
108
|
+
| `resolveBaseTheme(colorScheme, contrast)` | Looks up the base theme for a scheme/contrast pair, with a dev-mode fallback warning. |
|
|
109
|
+
| `VinyasaTheme`, `ColorScheme`, `Contrast`, `VinyasaProviderProps` | Types. |
|
|
110
|
+
|
|
111
|
+
## Development
|
|
112
|
+
|
|
113
|
+
From the repository root:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
pnpm --filter @vinyasa/tokens build
|
|
117
|
+
pnpm --filter @vinyasa/tokens test
|
|
118
|
+
pnpm --filter @vinyasa/tokens lint
|
|
119
|
+
```
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -54,6 +54,7 @@ var themeContract = {
|
|
|
54
54
|
radiusSm: 'var(--vinyasa-radius-sm)',
|
|
55
55
|
radiusMd: 'var(--vinyasa-radius-md)',
|
|
56
56
|
radiusFull: 'var(--vinyasa-radius-full)',
|
|
57
|
+
borderWidthThin: 'var(--vinyasa-border-width-thin)',
|
|
57
58
|
fontSizeSm: 'var(--vinyasa-font-size-sm)',
|
|
58
59
|
fontSizeMd: 'var(--vinyasa-font-size-md)',
|
|
59
60
|
fontWeightRegular: 'var(--vinyasa-font-weight-regular)',
|
|
@@ -100,6 +101,9 @@ const radius = {
|
|
|
100
101
|
md: '0.5rem',
|
|
101
102
|
full: '9999px'
|
|
102
103
|
};
|
|
104
|
+
const borderWidth = {
|
|
105
|
+
thin: '1px'
|
|
106
|
+
};
|
|
103
107
|
const fontSize = {
|
|
104
108
|
sm: '0.875rem',
|
|
105
109
|
md: '1rem'
|
|
@@ -158,6 +162,7 @@ const defaultTheme = {
|
|
|
158
162
|
radiusSm: radius.sm,
|
|
159
163
|
radiusMd: radius.md,
|
|
160
164
|
radiusFull: radius.full,
|
|
165
|
+
borderWidthThin: borderWidth.thin,
|
|
161
166
|
fontSizeSm: fontSize.sm,
|
|
162
167
|
fontSizeMd: fontSize.md,
|
|
163
168
|
fontWeightRegular: fontWeight.regular,
|
|
@@ -17,6 +17,7 @@ export declare const themeContract: {
|
|
|
17
17
|
radiusSm: `var(--${string})`;
|
|
18
18
|
radiusMd: `var(--${string})`;
|
|
19
19
|
radiusFull: `var(--${string})`;
|
|
20
|
+
borderWidthThin: `var(--${string})`;
|
|
20
21
|
fontSizeSm: `var(--${string})`;
|
|
21
22
|
fontSizeMd: `var(--${string})`;
|
|
22
23
|
fontWeightRegular: `var(--${string})`;
|
package/dist/esm/index.js
CHANGED
|
@@ -20,6 +20,7 @@ var themeContract = {
|
|
|
20
20
|
radiusSm: 'var(--vinyasa-radius-sm)',
|
|
21
21
|
radiusMd: 'var(--vinyasa-radius-md)',
|
|
22
22
|
radiusFull: 'var(--vinyasa-radius-full)',
|
|
23
|
+
borderWidthThin: 'var(--vinyasa-border-width-thin)',
|
|
23
24
|
fontSizeSm: 'var(--vinyasa-font-size-sm)',
|
|
24
25
|
fontSizeMd: 'var(--vinyasa-font-size-md)',
|
|
25
26
|
fontWeightRegular: 'var(--vinyasa-font-weight-regular)',
|
|
@@ -66,6 +67,9 @@ const radius = {
|
|
|
66
67
|
md: '0.5rem',
|
|
67
68
|
full: '9999px'
|
|
68
69
|
};
|
|
70
|
+
const borderWidth = {
|
|
71
|
+
thin: '1px'
|
|
72
|
+
};
|
|
69
73
|
const fontSize = {
|
|
70
74
|
sm: '0.875rem',
|
|
71
75
|
md: '1rem'
|
|
@@ -101,6 +105,7 @@ const defaultTheme = {
|
|
|
101
105
|
radiusSm: radius.sm,
|
|
102
106
|
radiusMd: radius.md,
|
|
103
107
|
radiusFull: radius.full,
|
|
108
|
+
borderWidthThin: borderWidth.thin,
|
|
104
109
|
fontSizeSm: fontSize.sm,
|
|
105
110
|
fontSizeMd: fontSize.md,
|
|
106
111
|
fontWeightRegular: fontWeight.regular,
|
package/dist/esm/primitives.d.ts
CHANGED
package/dist/esm/theme.d.ts
CHANGED