@vinyasa/tokens 1.0.15 → 1.0.17

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 ADDED
@@ -0,0 +1,124 @@
1
+ # @vinyasa/tokens
2
+
3
+ The shared design-token and theming foundation for `@vinyasa/*` components: color, spacing, radius, typography, motion, focus rings, opacity, shadows, elevation, blur, and z-index tokens, plus static breakpoint/grid values and a `VinyasaProvider` that resolves and injects the themeable tokens 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 covering colors (`primary`/`onPrimary`, `secondary`/`onSecondary`, `tertiary`/`onTertiary`, `error`/`onError`, `focus`), spacing (`space1`–`space6`), radii, border width, typography (font family/size/weight/letter-spacing/line-height), motion (duration/easing), focus rings, opacity, shadows, elevation, blur, and z-index. This is what a component's own `.css.ts` file imports and references — never the primitives directly.
35
+
36
+ `breakpoints` and `grid` (from `layout.ts`) are the one exception — they're exported as plain static values, **not** part of `themeContract`. CSS custom properties can't appear inside `@media` query conditions (`@media (min-width: var(--x))` is invalid in every browser), so responsive breakpoints can never be runtime-themed the way colors or spacing can. Consume them as literals directly in your own component's build-time `@media` blocks.
37
+
38
+ 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.
39
+
40
+ ### Overriding values
41
+
42
+ Pass a partial theme — only the keys you override change, everything else keeps its default:
43
+
44
+ ```tsx
45
+ <VinyasaProvider theme={{ primary: '#7c3aed' }}>
46
+ <YourApp />
47
+ </VinyasaProvider>
48
+ ```
49
+
50
+ You can also build a full custom theme ahead of time with `createTheme`:
51
+
52
+ ```tsx
53
+ import { createTheme, VinyasaProvider } from '@vinyasa/tokens';
54
+
55
+ const brandTheme = createTheme({ primary: '#7c3aed', onPrimary: '#ffffff' });
56
+
57
+ <VinyasaProvider theme={brandTheme}>
58
+ <YourApp />
59
+ </VinyasaProvider>;
60
+ ```
61
+
62
+ Providers can be nested for scoped overrides — an inner `VinyasaProvider` only affects the subtree it wraps.
63
+
64
+ ### Reading the theme programmatically
65
+
66
+ ```tsx
67
+ import { useVinyasaTheme } from '@vinyasa/tokens';
68
+
69
+ function Component() {
70
+ const theme = useVinyasaTheme();
71
+ return <span style={{ color: theme.primary }}>...</span>;
72
+ }
73
+ ```
74
+
75
+ ### `colorScheme`, `contrast`, and `density`
76
+
77
+ ```tsx
78
+ <VinyasaProvider colorScheme="light" contrast="normal" density="comfortable">
79
+ ```
80
+
81
+ Only `light`/`normal`/`comfortable` values are authored today. `colorScheme`/`contrast` resolve together via `resolveBaseTheme`; `density` resolves separately via `resolveDensitySpacing` (it only ever varies the `space1`–`space6` keys, applied as an overlay after the base theme and before any explicit `theme` override) since color and spacing don't vary together. Both are structured so adding `dark`/`high`-contrast values or a `compact`/`spacious` spacing scale later is purely additive — no changes to the contract, the provider, or any component that consumes it. Requesting an unshipped combination falls back to the default with a console warning in development.
82
+
83
+ ## Consuming the contract in your own component
84
+
85
+ This is the pattern every `@vinyasa/*` component follows — reference `themeContract`, never hardcode a value:
86
+
87
+ ```ts
88
+ // YourComponent.css.ts
89
+ import { style } from '@vanilla-extract/css';
90
+ import { themeContract as vars } from '@vinyasa/tokens';
91
+
92
+ export const root = style({
93
+ backgroundColor: vars.primary,
94
+ color: vars.onPrimary,
95
+ padding: `${vars.space3} ${vars.space4}`,
96
+ borderRadius: vars.radiusFull,
97
+ });
98
+ ```
99
+
100
+ `pnpm create:package <name>` scaffolds new component packages wired to this contract by default.
101
+
102
+ ## API
103
+
104
+ | Export | Description |
105
+ | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
106
+ | `VinyasaProvider` | React component. Props: `theme?`, `colorScheme?`, `contrast?`, `density?`, `children`. |
107
+ | `useVinyasaTheme()` | Hook returning the currently resolved `VinyasaTheme` object. |
108
+ | `themeContract` | The token contract — import as `vars` in a component's `.css.ts` file. |
109
+ | `defaultTheme` | The default (light/normal/comfortable) theme values object. |
110
+ | `createTheme(overrides)` | Merges a partial theme onto `defaultTheme`, returning a full `VinyasaTheme`. |
111
+ | `resolveBaseTheme(colorScheme, contrast)` | Looks up the base theme for a scheme/contrast pair, with a dev-mode fallback warning. |
112
+ | `resolveDensitySpacing(density)` | Looks up the `space1`–`space6` overlay for a density, with a dev-mode fallback warning. |
113
+ | `breakpoints`, `grid` | Static layout values (not themeable — see above). From `layout.ts`. |
114
+ | `VinyasaTheme`, `ColorScheme`, `Contrast`, `Density`, `VinyasaProviderProps` | Types. |
115
+
116
+ ## Development
117
+
118
+ From the repository root:
119
+
120
+ ```bash
121
+ pnpm --filter @vinyasa/tokens build
122
+ pnpm --filter @vinyasa/tokens test
123
+ pnpm --filter @vinyasa/tokens lint
124
+ ```
@@ -29,9 +29,12 @@ var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  VinyasaProvider: ()=>VinyasaProvider,
32
+ breakpoints: ()=>breakpoints,
32
33
  createTheme: ()=>createTheme,
33
34
  defaultTheme: ()=>defaultTheme,
35
+ grid: ()=>grid,
34
36
  resolveBaseTheme: ()=>resolveBaseTheme,
37
+ resolveDensitySpacing: ()=>resolveDensitySpacing,
35
38
  themeContract: ()=>themeContract,
36
39
  useVinyasaTheme: ()=>useVinyasaTheme
37
40
  });
@@ -54,14 +57,50 @@ var themeContract = {
54
57
  radiusSm: 'var(--vinyasa-radius-sm)',
55
58
  radiusMd: 'var(--vinyasa-radius-md)',
56
59
  radiusFull: 'var(--vinyasa-radius-full)',
60
+ borderWidthThin: 'var(--vinyasa-border-width-thin)',
61
+ fontFamilySans: 'var(--vinyasa-font-family-sans)',
62
+ fontFamilyMono: 'var(--vinyasa-font-family-mono)',
63
+ fontSizeXs: 'var(--vinyasa-font-size-xs)',
57
64
  fontSizeSm: 'var(--vinyasa-font-size-sm)',
58
65
  fontSizeMd: 'var(--vinyasa-font-size-md)',
66
+ fontSizeLg: 'var(--vinyasa-font-size-lg)',
67
+ fontSizeXl: 'var(--vinyasa-font-size-xl)',
59
68
  fontWeightRegular: 'var(--vinyasa-font-weight-regular)',
69
+ fontWeightMedium: 'var(--vinyasa-font-weight-medium)',
60
70
  fontWeightSemibold: 'var(--vinyasa-font-weight-semibold)',
71
+ fontWeightBold: 'var(--vinyasa-font-weight-bold)',
72
+ letterSpacingTight: 'var(--vinyasa-letter-spacing-tight)',
73
+ letterSpacingNormal: 'var(--vinyasa-letter-spacing-normal)',
74
+ letterSpacingWide: 'var(--vinyasa-letter-spacing-wide)',
61
75
  lineHeightTight: 'var(--vinyasa-line-height-tight)',
62
76
  lineHeightNormal: 'var(--vinyasa-line-height-normal)',
77
+ lineHeightLoose: 'var(--vinyasa-line-height-loose)',
78
+ motionDurationInstant: 'var(--vinyasa-motion-duration-instant)',
63
79
  motionDurationFast: 'var(--vinyasa-motion-duration-fast)',
64
- motionEasingStandard: 'var(--vinyasa-motion-easing-standard)'
80
+ motionDurationNormal: 'var(--vinyasa-motion-duration-normal)',
81
+ motionDurationSlow: 'var(--vinyasa-motion-duration-slow)',
82
+ motionEasingStandard: 'var(--vinyasa-motion-easing-standard)',
83
+ motionEasingIn: 'var(--vinyasa-motion-easing-in)',
84
+ motionEasingOut: 'var(--vinyasa-motion-easing-out)',
85
+ motionEasingInOut: 'var(--vinyasa-motion-easing-in-out)',
86
+ focusRingWidth: 'var(--vinyasa-focus-ring-width)',
87
+ focusRingOffset: 'var(--vinyasa-focus-ring-offset)',
88
+ opacityDisabled: 'var(--vinyasa-opacity-disabled)',
89
+ opacityHover: 'var(--vinyasa-opacity-hover)',
90
+ shadowSm: 'var(--vinyasa-shadow-sm)',
91
+ shadowMd: 'var(--vinyasa-shadow-md)',
92
+ shadowLg: 'var(--vinyasa-shadow-lg)',
93
+ elevationRaised: 'var(--vinyasa-elevation-raised)',
94
+ elevationOverlay: 'var(--vinyasa-elevation-overlay)',
95
+ elevationModal: 'var(--vinyasa-elevation-modal)',
96
+ blurSm: 'var(--vinyasa-blur-sm)',
97
+ blurMd: 'var(--vinyasa-blur-md)',
98
+ blurLg: 'var(--vinyasa-blur-lg)',
99
+ zIndexDropdown: 'var(--vinyasa-z-index-dropdown)',
100
+ zIndexOverlay: 'var(--vinyasa-z-index-overlay)',
101
+ zIndexModal: 'var(--vinyasa-z-index-modal)',
102
+ zIndexToast: 'var(--vinyasa-z-index-toast)',
103
+ zIndexTooltip: 'var(--vinyasa-z-index-tooltip)'
65
104
  };
66
105
  const gray = {
67
106
  50: '#f9fafb',
@@ -100,21 +139,70 @@ const radius = {
100
139
  md: '0.5rem',
101
140
  full: '9999px'
102
141
  };
142
+ const borderWidth = {
143
+ thin: '1px'
144
+ };
145
+ const fontFamily = {
146
+ sans: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",
147
+ mono: "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"
148
+ };
103
149
  const fontSize = {
150
+ xs: '0.75rem',
104
151
  sm: '0.875rem',
105
- md: '1rem'
152
+ md: '1rem',
153
+ lg: '1.125rem',
154
+ xl: '1.25rem'
106
155
  };
107
156
  const fontWeight = {
108
157
  regular: '400',
109
- semibold: '600'
158
+ medium: '500',
159
+ semibold: '600',
160
+ bold: '700'
161
+ };
162
+ const letterSpacing = {
163
+ tight: '-0.01em',
164
+ normal: '0',
165
+ wide: '0.02em'
110
166
  };
111
167
  const lineHeight = {
112
168
  tight: '1',
113
- normal: '1.5'
169
+ normal: '1.5',
170
+ loose: '1.75'
114
171
  };
115
172
  const motion = {
173
+ durationInstant: '100ms',
116
174
  durationFast: '150ms',
117
- easingStandard: 'ease'
175
+ durationNormal: '250ms',
176
+ durationSlow: '400ms',
177
+ easingStandard: 'ease',
178
+ easingIn: 'ease-in',
179
+ easingOut: 'ease-out',
180
+ easingInOut: 'ease-in-out'
181
+ };
182
+ const focusRing = {
183
+ width: '2px',
184
+ offset: '2px'
185
+ };
186
+ const opacity = {
187
+ disabled: '0.5',
188
+ hover: '0.92'
189
+ };
190
+ const shadow = {
191
+ sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
192
+ md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)',
193
+ lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)'
194
+ };
195
+ const primitives_blur = {
196
+ sm: '4px',
197
+ md: '8px',
198
+ lg: '16px'
199
+ };
200
+ const zIndex = {
201
+ dropdown: '1000',
202
+ overlay: '1100',
203
+ modal: '1200',
204
+ toast: '1300',
205
+ tooltip: '1400'
118
206
  };
119
207
  function _define_property(obj, key, value) {
120
208
  if (key in obj) Object.defineProperty(obj, key, {
@@ -158,14 +246,50 @@ const defaultTheme = {
158
246
  radiusSm: radius.sm,
159
247
  radiusMd: radius.md,
160
248
  radiusFull: radius.full,
249
+ borderWidthThin: borderWidth.thin,
250
+ fontFamilySans: fontFamily.sans,
251
+ fontFamilyMono: fontFamily.mono,
252
+ fontSizeXs: fontSize.xs,
161
253
  fontSizeSm: fontSize.sm,
162
254
  fontSizeMd: fontSize.md,
255
+ fontSizeLg: fontSize.lg,
256
+ fontSizeXl: fontSize.xl,
163
257
  fontWeightRegular: fontWeight.regular,
258
+ fontWeightMedium: fontWeight.medium,
164
259
  fontWeightSemibold: fontWeight.semibold,
260
+ fontWeightBold: fontWeight.bold,
261
+ letterSpacingTight: letterSpacing.tight,
262
+ letterSpacingNormal: letterSpacing.normal,
263
+ letterSpacingWide: letterSpacing.wide,
165
264
  lineHeightTight: lineHeight.tight,
166
265
  lineHeightNormal: lineHeight.normal,
266
+ lineHeightLoose: lineHeight.loose,
267
+ motionDurationInstant: motion.durationInstant,
167
268
  motionDurationFast: motion.durationFast,
168
- motionEasingStandard: motion.easingStandard
269
+ motionDurationNormal: motion.durationNormal,
270
+ motionDurationSlow: motion.durationSlow,
271
+ motionEasingStandard: motion.easingStandard,
272
+ motionEasingIn: motion.easingIn,
273
+ motionEasingOut: motion.easingOut,
274
+ motionEasingInOut: motion.easingInOut,
275
+ focusRingWidth: focusRing.width,
276
+ focusRingOffset: focusRing.offset,
277
+ opacityDisabled: opacity.disabled,
278
+ opacityHover: opacity.hover,
279
+ shadowSm: shadow.sm,
280
+ shadowMd: shadow.md,
281
+ shadowLg: shadow.lg,
282
+ elevationRaised: shadow.sm,
283
+ elevationOverlay: shadow.md,
284
+ elevationModal: shadow.lg,
285
+ blurSm: primitives_blur.sm,
286
+ blurMd: primitives_blur.md,
287
+ blurLg: primitives_blur.lg,
288
+ zIndexDropdown: zIndex.dropdown,
289
+ zIndexOverlay: zIndex.overlay,
290
+ zIndexModal: zIndex.modal,
291
+ zIndexToast: zIndex.toast,
292
+ zIndexTooltip: zIndex.tooltip
169
293
  };
170
294
  const createTheme = (overrides = {})=>_object_spread({}, defaultTheme, overrides);
171
295
  const themes = {
@@ -182,6 +306,35 @@ const resolveBaseTheme = (colorScheme, contrast)=>{
182
306
  }
183
307
  return theme;
184
308
  };
309
+ const comfortableSpacing = {
310
+ space1: defaultTheme.space1,
311
+ space2: defaultTheme.space2,
312
+ space3: defaultTheme.space3,
313
+ space4: defaultTheme.space4,
314
+ space5: defaultTheme.space5,
315
+ space6: defaultTheme.space6
316
+ };
317
+ const density_densitySpacing = {
318
+ comfortable: comfortableSpacing
319
+ };
320
+ const resolveDensitySpacing = (density)=>{
321
+ const spacing = density_densitySpacing[density];
322
+ if (!spacing) {
323
+ if ('production' !== process.env.NODE_ENV) console.warn(`[vinyasa] no spacing values for density="${density}" yet; falling back to comfortable.`);
324
+ return comfortableSpacing;
325
+ }
326
+ return spacing;
327
+ };
328
+ const breakpoints = {
329
+ sm: '640px',
330
+ md: '768px',
331
+ lg: '1024px',
332
+ xl: '1280px'
333
+ };
334
+ const grid = {
335
+ columns: 12,
336
+ containerMaxWidth: '1280px'
337
+ };
185
338
  const jsx_runtime_namespaceObject = require("react/jsx-runtime");
186
339
  const dynamic_namespaceObject = require("@vanilla-extract/dynamic");
187
340
  const external_react_namespaceObject = require("react");
@@ -210,13 +363,17 @@ function VinyasaProvider_object_spread(target) {
210
363
  }
211
364
  const ThemeContext = /*#__PURE__*/ (0, external_react_namespaceObject.createContext)(defaultTheme);
212
365
  const useVinyasaTheme = ()=>(0, external_react_namespaceObject.useContext)(ThemeContext);
213
- const VinyasaProvider = ({ theme, colorScheme = 'light', contrast = 'normal', children })=>{
366
+ const VinyasaProvider = ({ theme, colorScheme = 'light', contrast = 'normal', density = 'comfortable', children })=>{
214
367
  const base = (0, external_react_namespaceObject.useMemo)(()=>resolveBaseTheme(colorScheme, contrast), [
215
368
  colorScheme,
216
369
  contrast
217
370
  ]);
218
- const resolvedTheme = (0, external_react_namespaceObject.useMemo)(()=>VinyasaProvider_object_spread({}, base, theme), [
371
+ const densitySpacing = (0, external_react_namespaceObject.useMemo)(()=>resolveDensitySpacing(density), [
372
+ density
373
+ ]);
374
+ const resolvedTheme = (0, external_react_namespaceObject.useMemo)(()=>VinyasaProvider_object_spread({}, base, densitySpacing, theme), [
219
375
  base,
376
+ densitySpacing,
220
377
  theme
221
378
  ]);
222
379
  const cssVars = (0, external_react_namespaceObject.useMemo)(()=>(0, dynamic_namespaceObject.assignInlineVars)(themeContract, resolvedTheme), [
@@ -231,21 +388,28 @@ const VinyasaProvider = ({ theme, colorScheme = 'light', contrast = 'normal', ch
231
388
  style: style,
232
389
  "data-vinyasa-color-scheme": colorScheme,
233
390
  "data-vinyasa-contrast": contrast,
391
+ "data-vinyasa-density": density,
234
392
  children: children
235
393
  })
236
394
  });
237
395
  };
238
396
  exports.VinyasaProvider = __webpack_exports__.VinyasaProvider;
397
+ exports.breakpoints = __webpack_exports__.breakpoints;
239
398
  exports.createTheme = __webpack_exports__.createTheme;
240
399
  exports.defaultTheme = __webpack_exports__.defaultTheme;
400
+ exports.grid = __webpack_exports__.grid;
241
401
  exports.resolveBaseTheme = __webpack_exports__.resolveBaseTheme;
402
+ exports.resolveDensitySpacing = __webpack_exports__.resolveDensitySpacing;
242
403
  exports.themeContract = __webpack_exports__.themeContract;
243
404
  exports.useVinyasaTheme = __webpack_exports__.useVinyasaTheme;
244
405
  for(var __rspack_i in __webpack_exports__)if (-1 === [
245
406
  "VinyasaProvider",
407
+ "breakpoints",
246
408
  "createTheme",
247
409
  "defaultTheme",
410
+ "grid",
248
411
  "resolveBaseTheme",
412
+ "resolveDensitySpacing",
249
413
  "themeContract",
250
414
  "useVinyasaTheme"
251
415
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode } from 'react';
2
+ import { type Density } from './density';
2
3
  import { type VinyasaTheme } from './theme';
3
4
  import { type ColorScheme, type Contrast } from './themes';
4
5
  export declare const useVinyasaTheme: () => VinyasaTheme;
@@ -6,6 +7,7 @@ export interface VinyasaProviderProps {
6
7
  theme?: Partial<VinyasaTheme>;
7
8
  colorScheme?: ColorScheme;
8
9
  contrast?: Contrast;
10
+ density?: Density;
9
11
  children: ReactNode;
10
12
  }
11
- export declare const VinyasaProvider: ({ theme, colorScheme, contrast, children, }: VinyasaProviderProps) => import("react").JSX.Element;
13
+ export declare const VinyasaProvider: ({ theme, colorScheme, contrast, density, children, }: VinyasaProviderProps) => import("react").JSX.Element;
@@ -17,12 +17,48 @@ export declare const themeContract: {
17
17
  radiusSm: `var(--${string})`;
18
18
  radiusMd: `var(--${string})`;
19
19
  radiusFull: `var(--${string})`;
20
+ borderWidthThin: `var(--${string})`;
21
+ fontFamilySans: `var(--${string})`;
22
+ fontFamilyMono: `var(--${string})`;
23
+ fontSizeXs: `var(--${string})`;
20
24
  fontSizeSm: `var(--${string})`;
21
25
  fontSizeMd: `var(--${string})`;
26
+ fontSizeLg: `var(--${string})`;
27
+ fontSizeXl: `var(--${string})`;
22
28
  fontWeightRegular: `var(--${string})`;
29
+ fontWeightMedium: `var(--${string})`;
23
30
  fontWeightSemibold: `var(--${string})`;
31
+ fontWeightBold: `var(--${string})`;
32
+ letterSpacingTight: `var(--${string})`;
33
+ letterSpacingNormal: `var(--${string})`;
34
+ letterSpacingWide: `var(--${string})`;
24
35
  lineHeightTight: `var(--${string})`;
25
36
  lineHeightNormal: `var(--${string})`;
37
+ lineHeightLoose: `var(--${string})`;
38
+ motionDurationInstant: `var(--${string})`;
26
39
  motionDurationFast: `var(--${string})`;
40
+ motionDurationNormal: `var(--${string})`;
41
+ motionDurationSlow: `var(--${string})`;
27
42
  motionEasingStandard: `var(--${string})`;
43
+ motionEasingIn: `var(--${string})`;
44
+ motionEasingOut: `var(--${string})`;
45
+ motionEasingInOut: `var(--${string})`;
46
+ focusRingWidth: `var(--${string})`;
47
+ focusRingOffset: `var(--${string})`;
48
+ opacityDisabled: `var(--${string})`;
49
+ opacityHover: `var(--${string})`;
50
+ shadowSm: `var(--${string})`;
51
+ shadowMd: `var(--${string})`;
52
+ shadowLg: `var(--${string})`;
53
+ elevationRaised: `var(--${string})`;
54
+ elevationOverlay: `var(--${string})`;
55
+ elevationModal: `var(--${string})`;
56
+ blurSm: `var(--${string})`;
57
+ blurMd: `var(--${string})`;
58
+ blurLg: `var(--${string})`;
59
+ zIndexDropdown: `var(--${string})`;
60
+ zIndexOverlay: `var(--${string})`;
61
+ zIndexModal: `var(--${string})`;
62
+ zIndexToast: `var(--${string})`;
63
+ zIndexTooltip: `var(--${string})`;
28
64
  };
@@ -0,0 +1,5 @@
1
+ import { type VinyasaTheme } from './theme';
2
+ export type Density = 'compact' | 'comfortable' | 'spacious';
3
+ type DensitySpacing = Pick<VinyasaTheme, 'space1' | 'space2' | 'space3' | 'space4' | 'space5' | 'space6'>;
4
+ export declare const resolveDensitySpacing: (density: Density) => DensitySpacing;
5
+ export {};
@@ -1,4 +1,6 @@
1
1
  export { themeContract } from './contract.css';
2
2
  export { createTheme, defaultTheme, type VinyasaTheme } from './theme';
3
3
  export { resolveBaseTheme, type ColorScheme, type Contrast } from './themes';
4
+ export { resolveDensitySpacing, type Density } from './density';
5
+ export { breakpoints, grid } from './layout';
4
6
  export { VinyasaProvider, useVinyasaTheme, type VinyasaProviderProps } from './VinyasaProvider';
package/dist/esm/index.js CHANGED
@@ -20,14 +20,50 @@ 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)',
24
+ fontFamilySans: 'var(--vinyasa-font-family-sans)',
25
+ fontFamilyMono: 'var(--vinyasa-font-family-mono)',
26
+ fontSizeXs: 'var(--vinyasa-font-size-xs)',
23
27
  fontSizeSm: 'var(--vinyasa-font-size-sm)',
24
28
  fontSizeMd: 'var(--vinyasa-font-size-md)',
29
+ fontSizeLg: 'var(--vinyasa-font-size-lg)',
30
+ fontSizeXl: 'var(--vinyasa-font-size-xl)',
25
31
  fontWeightRegular: 'var(--vinyasa-font-weight-regular)',
32
+ fontWeightMedium: 'var(--vinyasa-font-weight-medium)',
26
33
  fontWeightSemibold: 'var(--vinyasa-font-weight-semibold)',
34
+ fontWeightBold: 'var(--vinyasa-font-weight-bold)',
35
+ letterSpacingTight: 'var(--vinyasa-letter-spacing-tight)',
36
+ letterSpacingNormal: 'var(--vinyasa-letter-spacing-normal)',
37
+ letterSpacingWide: 'var(--vinyasa-letter-spacing-wide)',
27
38
  lineHeightTight: 'var(--vinyasa-line-height-tight)',
28
39
  lineHeightNormal: 'var(--vinyasa-line-height-normal)',
40
+ lineHeightLoose: 'var(--vinyasa-line-height-loose)',
41
+ motionDurationInstant: 'var(--vinyasa-motion-duration-instant)',
29
42
  motionDurationFast: 'var(--vinyasa-motion-duration-fast)',
30
- motionEasingStandard: 'var(--vinyasa-motion-easing-standard)'
43
+ motionDurationNormal: 'var(--vinyasa-motion-duration-normal)',
44
+ motionDurationSlow: 'var(--vinyasa-motion-duration-slow)',
45
+ motionEasingStandard: 'var(--vinyasa-motion-easing-standard)',
46
+ motionEasingIn: 'var(--vinyasa-motion-easing-in)',
47
+ motionEasingOut: 'var(--vinyasa-motion-easing-out)',
48
+ motionEasingInOut: 'var(--vinyasa-motion-easing-in-out)',
49
+ focusRingWidth: 'var(--vinyasa-focus-ring-width)',
50
+ focusRingOffset: 'var(--vinyasa-focus-ring-offset)',
51
+ opacityDisabled: 'var(--vinyasa-opacity-disabled)',
52
+ opacityHover: 'var(--vinyasa-opacity-hover)',
53
+ shadowSm: 'var(--vinyasa-shadow-sm)',
54
+ shadowMd: 'var(--vinyasa-shadow-md)',
55
+ shadowLg: 'var(--vinyasa-shadow-lg)',
56
+ elevationRaised: 'var(--vinyasa-elevation-raised)',
57
+ elevationOverlay: 'var(--vinyasa-elevation-overlay)',
58
+ elevationModal: 'var(--vinyasa-elevation-modal)',
59
+ blurSm: 'var(--vinyasa-blur-sm)',
60
+ blurMd: 'var(--vinyasa-blur-md)',
61
+ blurLg: 'var(--vinyasa-blur-lg)',
62
+ zIndexDropdown: 'var(--vinyasa-z-index-dropdown)',
63
+ zIndexOverlay: 'var(--vinyasa-z-index-overlay)',
64
+ zIndexModal: 'var(--vinyasa-z-index-modal)',
65
+ zIndexToast: 'var(--vinyasa-z-index-toast)',
66
+ zIndexTooltip: 'var(--vinyasa-z-index-tooltip)'
31
67
  };
32
68
  const gray = {
33
69
  50: '#f9fafb',
@@ -66,21 +102,70 @@ const radius = {
66
102
  md: '0.5rem',
67
103
  full: '9999px'
68
104
  };
105
+ const borderWidth = {
106
+ thin: '1px'
107
+ };
108
+ const fontFamily = {
109
+ sans: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",
110
+ mono: "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"
111
+ };
69
112
  const fontSize = {
113
+ xs: '0.75rem',
70
114
  sm: '0.875rem',
71
- md: '1rem'
115
+ md: '1rem',
116
+ lg: '1.125rem',
117
+ xl: '1.25rem'
72
118
  };
73
119
  const fontWeight = {
74
120
  regular: '400',
75
- semibold: '600'
121
+ medium: '500',
122
+ semibold: '600',
123
+ bold: '700'
124
+ };
125
+ const letterSpacing = {
126
+ tight: '-0.01em',
127
+ normal: '0',
128
+ wide: '0.02em'
76
129
  };
77
130
  const lineHeight = {
78
131
  tight: '1',
79
- normal: '1.5'
132
+ normal: '1.5',
133
+ loose: '1.75'
80
134
  };
81
135
  const motion = {
136
+ durationInstant: '100ms',
82
137
  durationFast: '150ms',
83
- easingStandard: 'ease'
138
+ durationNormal: '250ms',
139
+ durationSlow: '400ms',
140
+ easingStandard: 'ease',
141
+ easingIn: 'ease-in',
142
+ easingOut: 'ease-out',
143
+ easingInOut: 'ease-in-out'
144
+ };
145
+ const focusRing = {
146
+ width: '2px',
147
+ offset: '2px'
148
+ };
149
+ const opacity = {
150
+ disabled: '0.5',
151
+ hover: '0.92'
152
+ };
153
+ const shadow = {
154
+ sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
155
+ md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)',
156
+ lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)'
157
+ };
158
+ const primitives_blur = {
159
+ sm: '4px',
160
+ md: '8px',
161
+ lg: '16px'
162
+ };
163
+ const zIndex = {
164
+ dropdown: '1000',
165
+ overlay: '1100',
166
+ modal: '1200',
167
+ toast: '1300',
168
+ tooltip: '1400'
84
169
  };
85
170
  const defaultTheme = {
86
171
  primary: indigo["600"],
@@ -101,14 +186,50 @@ const defaultTheme = {
101
186
  radiusSm: radius.sm,
102
187
  radiusMd: radius.md,
103
188
  radiusFull: radius.full,
189
+ borderWidthThin: borderWidth.thin,
190
+ fontFamilySans: fontFamily.sans,
191
+ fontFamilyMono: fontFamily.mono,
192
+ fontSizeXs: fontSize.xs,
104
193
  fontSizeSm: fontSize.sm,
105
194
  fontSizeMd: fontSize.md,
195
+ fontSizeLg: fontSize.lg,
196
+ fontSizeXl: fontSize.xl,
106
197
  fontWeightRegular: fontWeight.regular,
198
+ fontWeightMedium: fontWeight.medium,
107
199
  fontWeightSemibold: fontWeight.semibold,
200
+ fontWeightBold: fontWeight.bold,
201
+ letterSpacingTight: letterSpacing.tight,
202
+ letterSpacingNormal: letterSpacing.normal,
203
+ letterSpacingWide: letterSpacing.wide,
108
204
  lineHeightTight: lineHeight.tight,
109
205
  lineHeightNormal: lineHeight.normal,
206
+ lineHeightLoose: lineHeight.loose,
207
+ motionDurationInstant: motion.durationInstant,
110
208
  motionDurationFast: motion.durationFast,
111
- motionEasingStandard: motion.easingStandard
209
+ motionDurationNormal: motion.durationNormal,
210
+ motionDurationSlow: motion.durationSlow,
211
+ motionEasingStandard: motion.easingStandard,
212
+ motionEasingIn: motion.easingIn,
213
+ motionEasingOut: motion.easingOut,
214
+ motionEasingInOut: motion.easingInOut,
215
+ focusRingWidth: focusRing.width,
216
+ focusRingOffset: focusRing.offset,
217
+ opacityDisabled: opacity.disabled,
218
+ opacityHover: opacity.hover,
219
+ shadowSm: shadow.sm,
220
+ shadowMd: shadow.md,
221
+ shadowLg: shadow.lg,
222
+ elevationRaised: shadow.sm,
223
+ elevationOverlay: shadow.md,
224
+ elevationModal: shadow.lg,
225
+ blurSm: primitives_blur.sm,
226
+ blurMd: primitives_blur.md,
227
+ blurLg: primitives_blur.lg,
228
+ zIndexDropdown: zIndex.dropdown,
229
+ zIndexOverlay: zIndex.overlay,
230
+ zIndexModal: zIndex.modal,
231
+ zIndexToast: zIndex.toast,
232
+ zIndexTooltip: zIndex.tooltip
112
233
  };
113
234
  const createTheme = (overrides = {})=>({
114
235
  ...defaultTheme,
@@ -127,18 +248,52 @@ const resolveBaseTheme = (colorScheme, contrast)=>{
127
248
  }
128
249
  return theme;
129
250
  };
251
+ const comfortableSpacing = {
252
+ space1: defaultTheme.space1,
253
+ space2: defaultTheme.space2,
254
+ space3: defaultTheme.space3,
255
+ space4: defaultTheme.space4,
256
+ space5: defaultTheme.space5,
257
+ space6: defaultTheme.space6
258
+ };
259
+ const density_densitySpacing = {
260
+ comfortable: comfortableSpacing
261
+ };
262
+ const resolveDensitySpacing = (density)=>{
263
+ const spacing = density_densitySpacing[density];
264
+ if (!spacing) {
265
+ if ('production' !== process.env.NODE_ENV) console.warn(`[vinyasa] no spacing values for density="${density}" yet; falling back to comfortable.`);
266
+ return comfortableSpacing;
267
+ }
268
+ return spacing;
269
+ };
270
+ const breakpoints = {
271
+ sm: '640px',
272
+ md: '768px',
273
+ lg: '1024px',
274
+ xl: '1280px'
275
+ };
276
+ const grid = {
277
+ columns: 12,
278
+ containerMaxWidth: '1280px'
279
+ };
130
280
  const ThemeContext = /*#__PURE__*/ createContext(defaultTheme);
131
281
  const useVinyasaTheme = ()=>useContext(ThemeContext);
132
- const VinyasaProvider = ({ theme, colorScheme = 'light', contrast = 'normal', children })=>{
282
+ const VinyasaProvider = ({ theme, colorScheme = 'light', contrast = 'normal', density = 'comfortable', children })=>{
133
283
  const base = useMemo(()=>resolveBaseTheme(colorScheme, contrast), [
134
284
  colorScheme,
135
285
  contrast
136
286
  ]);
287
+ const densitySpacing = useMemo(()=>resolveDensitySpacing(density), [
288
+ density
289
+ ]);
137
290
  const resolvedTheme = useMemo(()=>({
138
291
  ...base,
292
+ ...densitySpacing,
139
293
  ...theme
140
294
  }), [
141
295
  base,
296
+ densitySpacing,
142
297
  theme
143
298
  ]);
144
299
  const cssVars = useMemo(()=>assignInlineVars(themeContract, resolvedTheme), [
@@ -154,8 +309,9 @@ const VinyasaProvider = ({ theme, colorScheme = 'light', contrast = 'normal', ch
154
309
  style: style,
155
310
  "data-vinyasa-color-scheme": colorScheme,
156
311
  "data-vinyasa-contrast": contrast,
312
+ "data-vinyasa-density": density,
157
313
  children: children
158
314
  })
159
315
  });
160
316
  };
161
- export { VinyasaProvider, createTheme, defaultTheme, resolveBaseTheme, themeContract, useVinyasaTheme };
317
+ export { VinyasaProvider, breakpoints, createTheme, defaultTheme, grid, resolveBaseTheme, resolveDensitySpacing, themeContract, useVinyasaTheme };
@@ -0,0 +1,10 @@
1
+ export declare const breakpoints: {
2
+ readonly sm: "640px";
3
+ readonly md: "768px";
4
+ readonly lg: "1024px";
5
+ readonly xl: "1280px";
6
+ };
7
+ export declare const grid: {
8
+ readonly columns: 12;
9
+ readonly containerMaxWidth: "1280px";
10
+ };
@@ -35,19 +35,68 @@ export declare const radius: {
35
35
  readonly md: "0.5rem";
36
36
  readonly full: "9999px";
37
37
  };
38
+ export declare const borderWidth: {
39
+ readonly thin: "1px";
40
+ };
41
+ export declare const fontFamily: {
42
+ readonly sans: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
43
+ readonly mono: "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace";
44
+ };
38
45
  export declare const fontSize: {
46
+ readonly xs: "0.75rem";
39
47
  readonly sm: "0.875rem";
40
48
  readonly md: "1rem";
49
+ readonly lg: "1.125rem";
50
+ readonly xl: "1.25rem";
41
51
  };
42
52
  export declare const fontWeight: {
43
53
  readonly regular: "400";
54
+ readonly medium: "500";
44
55
  readonly semibold: "600";
56
+ readonly bold: "700";
57
+ };
58
+ export declare const letterSpacing: {
59
+ readonly tight: "-0.01em";
60
+ readonly normal: "0";
61
+ readonly wide: "0.02em";
45
62
  };
46
63
  export declare const lineHeight: {
47
64
  readonly tight: "1";
48
65
  readonly normal: "1.5";
66
+ readonly loose: "1.75";
49
67
  };
50
68
  export declare const motion: {
69
+ readonly durationInstant: "100ms";
51
70
  readonly durationFast: "150ms";
71
+ readonly durationNormal: "250ms";
72
+ readonly durationSlow: "400ms";
52
73
  readonly easingStandard: "ease";
74
+ readonly easingIn: "ease-in";
75
+ readonly easingOut: "ease-out";
76
+ readonly easingInOut: "ease-in-out";
77
+ };
78
+ export declare const focusRing: {
79
+ readonly width: "2px";
80
+ readonly offset: "2px";
81
+ };
82
+ export declare const opacity: {
83
+ readonly disabled: "0.5";
84
+ readonly hover: "0.92";
85
+ };
86
+ export declare const shadow: {
87
+ readonly sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)";
88
+ readonly md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)";
89
+ readonly lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)";
90
+ };
91
+ export declare const blur: {
92
+ readonly sm: "4px";
93
+ readonly md: "8px";
94
+ readonly lg: "16px";
95
+ };
96
+ export declare const zIndex: {
97
+ readonly dropdown: "1000";
98
+ readonly overlay: "1100";
99
+ readonly modal: "1200";
100
+ readonly toast: "1300";
101
+ readonly tooltip: "1400";
53
102
  };
@@ -17,14 +17,50 @@ export interface VinyasaTheme {
17
17
  radiusSm: string;
18
18
  radiusMd: string;
19
19
  radiusFull: string;
20
+ borderWidthThin: string;
21
+ fontFamilySans: string;
22
+ fontFamilyMono: string;
23
+ fontSizeXs: string;
20
24
  fontSizeSm: string;
21
25
  fontSizeMd: string;
26
+ fontSizeLg: string;
27
+ fontSizeXl: string;
22
28
  fontWeightRegular: string;
29
+ fontWeightMedium: string;
23
30
  fontWeightSemibold: string;
31
+ fontWeightBold: string;
32
+ letterSpacingTight: string;
33
+ letterSpacingNormal: string;
34
+ letterSpacingWide: string;
24
35
  lineHeightTight: string;
25
36
  lineHeightNormal: string;
37
+ lineHeightLoose: string;
38
+ motionDurationInstant: string;
26
39
  motionDurationFast: string;
40
+ motionDurationNormal: string;
41
+ motionDurationSlow: string;
27
42
  motionEasingStandard: string;
43
+ motionEasingIn: string;
44
+ motionEasingOut: string;
45
+ motionEasingInOut: string;
46
+ focusRingWidth: string;
47
+ focusRingOffset: string;
48
+ opacityDisabled: string;
49
+ opacityHover: string;
50
+ shadowSm: string;
51
+ shadowMd: string;
52
+ shadowLg: string;
53
+ elevationRaised: string;
54
+ elevationOverlay: string;
55
+ elevationModal: string;
56
+ blurSm: string;
57
+ blurMd: string;
58
+ blurLg: string;
59
+ zIndexDropdown: string;
60
+ zIndexOverlay: string;
61
+ zIndexModal: string;
62
+ zIndexToast: string;
63
+ zIndexTooltip: string;
28
64
  }
29
65
  export declare const defaultTheme: VinyasaTheme;
30
66
  export declare const createTheme: (overrides?: Partial<VinyasaTheme>) => VinyasaTheme;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vinyasa/tokens",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": [