@headspace_designsystem/hsds-web-library 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +184 -0
- package/dist/components/Button/Button.d.ts +3 -0
- package/dist/components/Button/Button.d.ts.map +1 -0
- package/dist/components/Button/Button.types.d.ts +18 -0
- package/dist/components/Button/Button.types.d.ts.map +1 -0
- package/dist/components/Button/index.d.ts +3 -0
- package/dist/components/Button/index.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/demo.d.ts +2 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/hsds-web-library.es.js +1927 -0
- package/dist/hsds-web-library.es.js.map +1 -0
- package/dist/hsds-web-library.umd.js +19 -0
- package/dist/hsds-web-library.umd.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/theme/ThemeProvider.d.ts +14 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/index.d.ts +4 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/theme.d.ts +3 -0
- package/dist/theme/theme.d.ts.map +1 -0
- package/dist/theme/types.d.ts +88 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/tokens/index.d.ts +3 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/primitives/borders.d.ts +41 -0
- package/dist/tokens/primitives/borders.d.ts.map +1 -0
- package/dist/tokens/primitives/colors.d.ts +67 -0
- package/dist/tokens/primitives/colors.d.ts.map +1 -0
- package/dist/tokens/primitives/index.d.ts +6 -0
- package/dist/tokens/primitives/index.d.ts.map +1 -0
- package/dist/tokens/primitives/shadows.d.ts +38 -0
- package/dist/tokens/primitives/shadows.d.ts.map +1 -0
- package/dist/tokens/primitives/spacing.d.ts +29 -0
- package/dist/tokens/primitives/spacing.d.ts.map +1 -0
- package/dist/tokens/primitives/typography.d.ts +46 -0
- package/dist/tokens/primitives/typography.d.ts.map +1 -0
- package/dist/tokens/semantic/colors.d.ts +154 -0
- package/dist/tokens/semantic/colors.d.ts.map +1 -0
- package/dist/tokens/semantic/index.d.ts +3 -0
- package/dist/tokens/semantic/index.d.ts.map +1 -0
- package/dist/tokens/semantic/typography.d.ts +253 -0
- package/dist/tokens/semantic/typography.d.ts.map +1 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# hsds_web_library
|
|
2
|
+
|
|
3
|
+
HeadSpace Design System — Web Component Library
|
|
4
|
+
|
|
5
|
+
A TypeScript-first design token library and React component system built with [Emotion](https://emotion.sh/) for CSS-in-JS. This library translates the HeadSpace design system directly into code, giving engineers production-ready, typed, accessible components and giving designers a single source of truth that flows from Figma to the browser.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What this is
|
|
10
|
+
|
|
11
|
+
| For designers | For engineers |
|
|
12
|
+
|---|---|
|
|
13
|
+
| Contribute styling changes directly in code, not just in Figma | Install components as a package — no building from scratch |
|
|
14
|
+
| Token changes propagate automatically to all components | Full TypeScript autocomplete on every design token |
|
|
15
|
+
| Components match Figma 1:1 | Versioned releases via npm — no stale, deprecated components |
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Token Architecture
|
|
20
|
+
|
|
21
|
+
All visual decisions flow in one direction:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Primitive tokens Raw HeadSpace palette
|
|
25
|
+
↓ (warmGrey100, blue200, ...)
|
|
26
|
+
Semantic tokens Intent-driven aliases
|
|
27
|
+
↓ (foreground, background, border, ...)
|
|
28
|
+
HsdsTheme object Typed Emotion theme assembled from tokens
|
|
29
|
+
↓
|
|
30
|
+
ThemeProvider React context that injects theme into the tree
|
|
31
|
+
↓
|
|
32
|
+
Components Button, Input, Card, ... — all read from theme
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Why two layers?**
|
|
36
|
+
If the primary blue changes, you update one hex value in `primitives/colors.ts`. Every semantic token that references it (`Primary/primary`, `Foreground/foregroundLink`, etc.) picks it up instantly — no hunt-and-replace across 50 components.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
### 1. Install
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install @headspace/hsds-web-library
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`react`, `react-dom`, `@emotion/react`, and `@emotion/styled` are peer dependencies — your app must already have them installed.
|
|
49
|
+
|
|
50
|
+
### 2. Wrap your app with the ThemeProvider
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import { HsdsThemeProvider } from '@headspace/hsds-web-library';
|
|
54
|
+
|
|
55
|
+
function App() {
|
|
56
|
+
return (
|
|
57
|
+
<HsdsThemeProvider>
|
|
58
|
+
<YourApp />
|
|
59
|
+
</HsdsThemeProvider>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 3. Access tokens in your own styled components
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import styled from '@emotion/styled';
|
|
68
|
+
|
|
69
|
+
// theme is fully typed — autocomplete works, typos fail at compile time
|
|
70
|
+
const MyCard = styled.div(({ theme }) => ({
|
|
71
|
+
backgroundColor: theme.colors.background.surface,
|
|
72
|
+
borderRadius: theme.borders.radius.medium,
|
|
73
|
+
padding: theme.spacing[4],
|
|
74
|
+
boxShadow: theme.shadows.raised,
|
|
75
|
+
}));
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Token Reference
|
|
81
|
+
|
|
82
|
+
### Colors
|
|
83
|
+
|
|
84
|
+
#### Primitive palette
|
|
85
|
+
Raw color values. **Never use these in components directly** — use semantic tokens instead.
|
|
86
|
+
|
|
87
|
+
Families: `warmGrey`, `coolGrey`, `blue`, `orange`, `yellow`, `green`, `pink`, `purple`, `indigo`, `winkle`, `red`
|
|
88
|
+
|
|
89
|
+
#### Semantic colors
|
|
90
|
+
|
|
91
|
+
| Category | Tokens |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `colors.primary` | `primary`, `primaryStrong` |
|
|
94
|
+
| `colors.background` | `background`, `backgroundStrong` |
|
|
95
|
+
| `colors.surface` | `surface`, `surfaceStrong`, `surfaceStronger`, `surfaceStrongest`, `surfaceModal`, `surfaceOnModal` |
|
|
96
|
+
| `colors.overlay` | `overlay60/40/20`, `overlayInverse60`, `overlayLightStatic{80/60/40/20}`, `overlayDarkStatic{80/60/40/20}` |
|
|
97
|
+
| `colors.foreground` | `foreground`, `foregroundWeak`, `foregroundWeaker`, `foregroundWeakest`, `foregroundInverse`, `foregroundLink`, `foregroundLinkStrong`, `foregroundHighlight`, `foregroundCritical`, `foregroundSuccess` |
|
|
98
|
+
| `colors.border` | `border`, `borderStrong`, `borderStronger`, `borderStrongest`, `borderInverse` |
|
|
99
|
+
| `colors.interactive` | `interactive`, `interactiveStrong`, `interactiveStronger`, `interactiveStrongest`, `interactiveInverse`, `interactiveInverseStrong` |
|
|
100
|
+
| `colors.contrast` | `contrastForeground`, `contrastBackground`, `contrastForegroundWeak/Weaker/Weakest`, `contrastBackgroundWeak/Weaker` |
|
|
101
|
+
| `colors.status` | `statusCritical`, `statusSuccess`, `statusWarning`, `statusInfo`, `statusHighlight` (+ `*Strong` variants) |
|
|
102
|
+
|
|
103
|
+
### Typography
|
|
104
|
+
|
|
105
|
+
Font family: **Headspace Apercu** (primary), **Apercu Mono** (utility/code)
|
|
106
|
+
|
|
107
|
+
Type scale categories: `heading` (3xl–s), `body` (l–3xs), `label` (l–3xs), `link` (l–3xs), `utility` (l–xs), `caption`
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
const headingStyle = theme.typography.desktop.heading['2xl'];
|
|
111
|
+
// → { fontFamily, fontSize: '56px', fontWeight: 700, lineHeight: '1.1', letterSpacing: '-3px' }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Spacing
|
|
115
|
+
|
|
116
|
+
16-step scale from `2px` to `128px`. Access via `theme.spacing[16]` → `'16px'`
|
|
117
|
+
|
|
118
|
+
### Border Radius
|
|
119
|
+
|
|
120
|
+
| Token | Value | Figma name |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| `sharp` | 0px | hs-border-radius-sharp |
|
|
123
|
+
| `small2X` | 4px | hs-border-radius-small2X |
|
|
124
|
+
| `smallX` | 8px | hs-border-radius-smallX |
|
|
125
|
+
| `small` | 12px | hs-border-radius-small |
|
|
126
|
+
| `medium` | 16px | hs-border-radius-medium |
|
|
127
|
+
| `large` | 24px | hs-border-radius-large |
|
|
128
|
+
| `largeX` | 32px | hs-border-radius-largeX |
|
|
129
|
+
| `pill` | 999px | hs-border-radius-pill |
|
|
130
|
+
| `circle` | 50% | hs-border-radius-circle |
|
|
131
|
+
|
|
132
|
+
### Shadows
|
|
133
|
+
|
|
134
|
+
`none`, `default`, `navigationTop`, `navigationBottom`, `raised`, `overlay`
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Repository Structure
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
src/
|
|
142
|
+
├── tokens/
|
|
143
|
+
│ ├── primitives/ Raw palette values (internal — do not import in components)
|
|
144
|
+
│ │ ├── colors.ts Warm grey, cool grey, blue, orange, green, red, ...
|
|
145
|
+
│ │ ├── typography.ts Font families, weights, line heights, letter spacing
|
|
146
|
+
│ │ ├── spacing.ts 2px–128px scale
|
|
147
|
+
│ │ ├── borders.ts Border radii and widths
|
|
148
|
+
│ │ └── shadows.ts Elevation shadow strings
|
|
149
|
+
│ └── semantic/ Intent-driven aliases (what components consume)
|
|
150
|
+
│ ├── colors.ts primary, background, surface, foreground, border, ...
|
|
151
|
+
│ └── typography.ts Desktop type scale objects
|
|
152
|
+
├── theme/
|
|
153
|
+
│ ├── types.ts HsdsTheme interface — the stable typed contract
|
|
154
|
+
│ ├── emotion.d.ts Module augmentation (makes theme typed in styled())
|
|
155
|
+
│ ├── theme.ts Assembled HsdsTheme object
|
|
156
|
+
│ └── ThemeProvider.tsx React ThemeProvider wrapper
|
|
157
|
+
└── components/ (Phase 2+)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Roadmap
|
|
163
|
+
|
|
164
|
+
| Phase | Status | Scope |
|
|
165
|
+
|---|---|---|
|
|
166
|
+
| 1 — Foundation | Complete | Token files, HsdsTheme, ThemeProvider |
|
|
167
|
+
| 2 — Core Components | Planned | Button, Text, Stack, Input, Badge, Card, Divider |
|
|
168
|
+
| 3 — Storybook | Planned | Component docs, interactive playground |
|
|
169
|
+
| 4 — Full Library | Planned | Modal, Tooltip, Tabs, Checkbox, Toast, Avatar, + more |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Contributing (for designers)
|
|
174
|
+
|
|
175
|
+
1. Clone this repository and run `npm install`
|
|
176
|
+
2. Edit token files in `src/tokens/` to update values
|
|
177
|
+
3. Run `npm run typecheck` — if it passes, the values are valid
|
|
178
|
+
4. Open a PR
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Tech Stack
|
|
183
|
+
|
|
184
|
+
- **React 18** + **TypeScript 5** + **Emotion 11** + **Vite 5**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAA6B,MAAM,gBAAgB,CAAC;AA8R7E,wBAAgB,MAAM,CAAC,EACrB,OAAmB,EACnB,IAAc,EACd,SAAiB,EACjB,WAAmB,EACnB,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,WAAW,oDAuBb"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'ghost' | 'black' | 'white' | 'critical' | 'success' | 'warning' | 'textPrimary' | 'textSecondary';
|
|
3
|
+
export type ButtonSize = 'large' | 'mediumLarge' | 'medium' | 'small' | 'xSmall';
|
|
4
|
+
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
5
|
+
/** Visual style of the button. @default 'primary' */
|
|
6
|
+
variant?: ButtonVariant;
|
|
7
|
+
/** Height and font size tier. @default 'large' */
|
|
8
|
+
size?: ButtonSize;
|
|
9
|
+
/** Replaces content with a spinner and sets disabled. @default false */
|
|
10
|
+
isLoading?: boolean;
|
|
11
|
+
/** Stretches the button to fill its container. @default false */
|
|
12
|
+
isFullWidth?: boolean;
|
|
13
|
+
/** Icon rendered before the label. */
|
|
14
|
+
leftIcon?: React.ReactNode;
|
|
15
|
+
/** Icon rendered after the label. */
|
|
16
|
+
rightIcon?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=Button.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.types.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,aAAa,GACrB,SAAS,GACT,WAAW,GACX,UAAU,GACV,OAAO,GACP,OAAO,GACP,OAAO,GACP,UAAU,GACV,SAAS,GACT,SAAS,GACT,aAAa,GACb,eAAe,CAAC;AACpB,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEjF,MAAM,WAAW,WAAY,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IAChF,qDAAqD;IACrD,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,kDAAkD;IAClD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iEAAiE;IACjE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qCAAqC;IACrC,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Button/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
|
package/dist/demo.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../src/demo.tsx"],"names":[],"mappings":""}
|