@ibis-design/css 0.7.1 → 0.7.2

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.
Files changed (2) hide show
  1. package/README.md +365 -64
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @ibis-design/css
2
2
 
3
- Design tokens as CSS custom properties, shared component styles, and a Tailwind preset for the IBIS design system. Framework-agnostic; usable from any stack.
3
+ Design tokens, ready-made component styles (`.ibis-*` classes), and a Tailwind preset for the IBIS design system. Use it from **any** frontend stack—vanilla HTML, React, Vue, Svelte, etc.—similar to how you would use Materialize, DaisyUI, or a token-based CSS framework.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,29 +8,35 @@ Design tokens as CSS custom properties, shared component styles, and a Tailwind
8
8
  npm install @ibis-design/css
9
9
  ```
10
10
 
11
- ## Quick start
11
+ ## App setup
12
12
 
13
- 1. Import the token stylesheet once in your app entry (or root layout).
14
- 2. Set `data-theme` on `<html>` (or an ancestor) to pick brand and light/dark mode.
13
+ Every page needs **tokens** once, then **component CSS** only for the components you use.
15
14
 
16
- ```css
17
- @import "@ibis-design/css";
15
+ ```html
16
+ <!DOCTYPE html>
17
+ <html lang="en" data-theme="ib-light">
18
+ <head>
19
+ <link rel="stylesheet" href="/path/to/your/app.css" />
20
+ </head>
21
+ <body>
22
+ <button type="button" class="ibis-button ibis-button--primary ibis-button--md">
23
+ <span class="ibis-button__content">Pay now</span>
24
+ </button>
25
+ </body>
26
+ </html>
18
27
  ```
19
28
 
20
- ```html
21
- <html data-theme="ib-light">
29
+ ```css
30
+ /* app.css */
31
+ @import "@ibis-design/css";
32
+ @import "@ibis-design/css/components/button.css";
22
33
  ```
23
34
 
24
35
  ```js
36
+ // Switch brand or mode at runtime
25
37
  document.documentElement.dataset.theme = "alc-dark";
26
38
  ```
27
39
 
28
- Without the stylesheet and `data-theme`, `var(--color-*)` and other tokens will not resolve.
29
-
30
- ## Theming (`data-theme`)
31
-
32
- All themes expose the **same CSS variable names**; only the values change.
33
-
34
40
  | `data-theme` | Brand | Mode |
35
41
  |--------------|-------|------|
36
42
  | `ib-light` | Ibis | Light (default) |
@@ -38,66 +44,363 @@ All themes expose the **same CSS variable names**; only the values change.
38
44
  | `alc-light` | Alchemy | Light |
39
45
  | `alc-dark` | Alchemy | Dark |
40
46
 
41
- **Cascade:**
42
-
43
- - **Global tokens** (spacing, shadows, motion, border widths, z-index) live on `:root` for every theme.
44
- - **Theme tokens** (colors, font families/sizes, radii, gradients) come from the active `data-theme` block.
45
- - **Ibis light** also applies to `:root` when no theme attribute is set (no-JS fallback).
46
-
47
- Switch themes at runtime:
47
+ **Cascade:** spacing, shadows, and motion tokens live on `:root`. Colors, typography, and radii follow the active `data-theme`. Ibis light also applies when `data-theme` is unset.
48
48
 
49
- ```js
50
- document.documentElement.dataset.theme = "alc-light";
51
- ```
49
+ ---
52
50
 
53
- ## CSS custom properties
51
+ ## Design tokens
54
52
 
55
- ### Naming
56
-
57
- | Category | Example variable |
58
- |----------|------------------|
59
- | Color primitive | `--color-primary-500` |
60
- | Color semantic | `--color-text-primary`, `--color-brand-secondary` |
61
- | Spacing | `--spacing-4` |
62
- | Typography size | `--font-size-body-sm` |
63
- | Border radius | `--border-radius-md` |
64
- | Shadow | `--shadow-elevation-sm`, `--shadow-focus-default` |
65
- | Gradient | `--gradient-button` |
66
-
67
- ### Example
53
+ Use semantic variables in your own CSS:
68
54
 
69
55
  ```css
70
- .card {
56
+ .my-panel {
71
57
  background: var(--color-backgrounds-classic-light);
72
58
  color: var(--color-text-primary);
73
59
  padding: var(--spacing-4);
74
60
  border-radius: var(--border-radius-md);
75
61
  box-shadow: var(--shadow-elevation-sm);
62
+ font-family: var(--font-family-sans);
76
63
  }
77
64
  ```
78
65
 
79
- Semantic brand accents (values differ per theme):
66
+ Common variables: `--color-primary-500`, `--color-brand-secondary`, `--font-size-body-md`, `--shadow-focus-default`, `--gradient-button`.
80
67
 
81
- - `--color-brand-primary`
82
- - `--color-brand-secondary`
83
- - `--color-brand-neutral`
68
+ ---
84
69
 
85
70
  ## Component styles
86
71
 
87
- Optional stylesheets for shared `.ibis-*` classes. Import only what you need:
72
+ Import the stylesheet for each component you render. Class names are stable across themes.
73
+
74
+ | Stylesheet | Root class |
75
+ |------------|------------|
76
+ | `@ibis-design/css/components/button.css` | `.ibis-button` |
77
+ | `@ibis-design/css/components/checkbox.css` | `.ibis-checkbox` |
78
+ | `@ibis-design/css/components/radio.css` | `.ibis-radio` |
79
+ | `@ibis-design/css/components/switch.css` | `.ibis-switch` |
80
+ | `@ibis-design/css/components/textInput.css` | `.ibis-input` |
81
+ | `@ibis-design/css/components/textarea.css` | `.ibis-input` (textarea) |
82
+ | `@ibis-design/css/components/textlink.css` | `.ibis-link` |
83
+ | `@ibis-design/css/components/chips.css` | `.ibis-chips` |
84
+ | `@ibis-design/css/components/banner.css` | `.ibis-banner` |
85
+ | `@ibis-design/css/components/toaster.css` | `.ibis-toaster` |
86
+ | `@ibis-design/css/components/dropdown.css` | `.ibis-dropdown` |
87
+ | `@ibis-design/css/components/dropdownButton.css` | `.ibis-dropdown-button` |
88
+ | `@ibis-design/css/components/pillTab.css` | `.ibis-pill-tab` |
89
+ | `@ibis-design/css/components/tipIndicator.css` | `.ibis-tip-indicator` |
90
+ | `@ibis-design/css/components/tooltip.css` | `.ibis-tooltip` |
91
+
92
+ For **Svelte**, use [@ibis-design/svelte](https://www.npmjs.com/package/@ibis-design/svelte) instead of copying markup by hand.
93
+
94
+ ---
95
+
96
+ ### Button
88
97
 
89
98
  ```css
90
99
  @import "@ibis-design/css/components/button.css";
100
+ ```
101
+
102
+ **Variants:** `ibis-button--primary`, `ibis-button--secondary`
103
+ **Sizes:** `ibis-button--sm`, `ibis-button--md`, `ibis-button--lg`
104
+ **States:** `ibis-button--loading`, `ibis-button--skeleton`, `ibis-button--icon-only`, `disabled` attribute
105
+
106
+ ```html
107
+ <!-- Primary action -->
108
+ <button type="submit" class="ibis-button ibis-button--primary ibis-button--md">
109
+ <span class="ibis-button__content">Submit payment</span>
110
+ </button>
111
+
112
+ <!-- Secondary / cancel -->
113
+ <button type="button" class="ibis-button ibis-button--secondary ibis-button--sm">
114
+ <span class="ibis-button__content">Cancel</span>
115
+ </button>
116
+
117
+ <!-- Loading -->
118
+ <button type="button" class="ibis-button ibis-button--primary ibis-button--md ibis-button--loading" disabled aria-busy="true">
119
+ <span class="ibis-button__content ibis-button__content--hidden">Processing…</span>
120
+ <span class="ibis-button__loader" aria-hidden="true"></span>
121
+ </button>
122
+ ```
123
+
124
+ ---
125
+
126
+ ### Checkbox
127
+
128
+ ```css
91
129
  @import "@ibis-design/css/components/checkbox.css";
92
130
  ```
93
131
 
94
- Available entry points: `banner`, `button`, `checkbox`, `chips`, `dropdown`, `dropdownButton`, `pillTab`, `radio`, `switch`, `textarea`, `textInput`, `textlink`, `tipIndicator`, `toaster`, `tooltip`.
132
+ **Sizes:** `ibis-checkbox--sm`, `ibis-checkbox--md`, `ibis-checkbox--lg`
133
+ **States:** `ibis-checkbox--disabled`, `ibis-checkbox--invalid`
134
+
135
+ ```html
136
+ <div class="ibis-checkbox ibis-checkbox--md">
137
+ <div class="ibis-checkbox__label-wrapper">
138
+ <label class="ibis-checkbox__label" for="terms">Accept terms</label>
139
+ <div class="ibis-checkbox__description">Required to continue.</div>
140
+ </div>
141
+ <div class="ibis-checkbox__wrapper">
142
+ <label class="ibis-checkbox__control">
143
+ <input id="terms" type="checkbox" class="ibis-checkbox__input" />
144
+ <span class="ibis-checkbox__box">
145
+ <span class="ibis-checkbox__icon">✓</span>
146
+ </span>
147
+ </label>
148
+ </div>
149
+ <div class="ibis-checkbox__help">You can change this later in settings.</div>
150
+ </div>
151
+ ```
152
+
153
+ ---
154
+
155
+ ### Radio
156
+
157
+ ```css
158
+ @import "@ibis-design/css/components/radio.css";
159
+ ```
160
+
161
+ Group radios with the same `name`. Use `ibis-radio--invalid` for error styling.
162
+
163
+ ```html
164
+ <div class="ibis-radio ibis-radio--md">
165
+ <div class="ibis-radio__label-wrapper">
166
+ <span class="ibis-radio__label">Account type</span>
167
+ </div>
168
+ <label class="ibis-radio__control">
169
+ <input type="radio" name="account" value="personal" class="ibis-radio__input" />
170
+ <span class="ibis-radio__circle"><span class="ibis-radio__dot"></span></span>
171
+ <span class="ibis-radio__text">Personal</span>
172
+ </label>
173
+ <label class="ibis-radio__control">
174
+ <input type="radio" name="account" value="business" class="ibis-radio__input" checked />
175
+ <span class="ibis-radio__circle"><span class="ibis-radio__dot ibis-radio__dot--active"></span></span>
176
+ <span class="ibis-radio__text">Business</span>
177
+ </label>
178
+ </div>
179
+ ```
180
+
181
+ ---
182
+
183
+ ### Switch
184
+
185
+ ```css
186
+ @import "@ibis-design/css/components/switch.css";
187
+ ```
188
+
189
+ ```html
190
+ <div class="ibis-switch">
191
+ <label class="ibis-switch__control" for="notifications">
192
+ <input id="notifications" type="checkbox" class="ibis-switch__input" checked />
193
+ <span class="ibis-switch__track">
194
+ <span class="ibis-switch__thumb"></span>
195
+ </span>
196
+ <span class="ibis-switch__label">Email notifications</span>
197
+ </label>
198
+ </div>
199
+ ```
200
+
201
+ ---
202
+
203
+ ### Text field
204
+
205
+ ```css
206
+ @import "@ibis-design/css/components/textInput.css";
207
+ ```
208
+
209
+ **Sizes:** `ibis-input--sm`, `ibis-input--md`, `ibis-input--lg`
210
+ **States:** `ibis-input--disabled`, `ibis-input--invalid`, `ibis-input--loading`
211
+
212
+ ```html
213
+ <div class="ibis-input ibis-input--md">
214
+ <label class="ibis-input__label" for="email">Email</label>
215
+ <div class="ibis-input__wrapper">
216
+ <div class="ibis-input__field-wrapper">
217
+ <input id="email" type="email" class="ibis-input__field" placeholder="you@example.com" />
218
+ </div>
219
+ </div>
220
+ <div class="ibis-input__help">We will never share your email.</div>
221
+ </div>
222
+
223
+ <!-- Invalid -->
224
+ <div class="ibis-input ibis-input--md ibis-input--invalid">
225
+ <label class="ibis-input__label" for="amount">Amount</label>
226
+ <div class="ibis-input__wrapper">
227
+ <div class="ibis-input__field-wrapper">
228
+ <input id="amount" type="text" class="ibis-input__field" aria-invalid="true" />
229
+ </div>
230
+ </div>
231
+ <div class="ibis-input__error" role="alert">Enter a valid amount.</div>
232
+ </div>
233
+ ```
234
+
235
+ Textarea uses the same `.ibis-input` structure; import `textarea.css` and use a `<textarea class="ibis-input__field">` inside `.ibis-input__field-wrapper`.
236
+
237
+ ---
238
+
239
+ ### Text link
240
+
241
+ ```css
242
+ @import "@ibis-design/css/components/textlink.css";
243
+ ```
244
+
245
+ **Sizes:** `ibis-link--sm`, `ibis-link--md`, `ibis-link--lg`
246
+ **Underline:** `ibis-link--underline-always`, `ibis-link--underline-hover`, `ibis-link--underline-none`
95
247
 
96
- If you use **@ibis-design/svelte**, components already import the matching stylesheet; you do not need these unless you use the same class names outside Svelte.
248
+ ```html
249
+ <a href="/help" class="ibis-link ibis-link--md ibis-link--underline-hover">
250
+ <span class="ibis-link__content">Learn more</span>
251
+ </a>
252
+ ```
97
253
 
98
- ## Tailwind CSS
254
+ ---
99
255
 
100
- Use the preset in `tailwind.config.js` (Tailwind v3):
256
+ ### Chip
257
+
258
+ ```css
259
+ @import "@ibis-design/css/components/chips.css";
260
+ ```
261
+
262
+ **Sizes:** `ibis-chips--sm`, `ibis-chips--md`, `ibis-chips--lg`
263
+ **States:** `ibis-chips--selected`, `ibis-chips--disabled`, `ibis-chips--loading`, `ibis-chips--skeleton`
264
+
265
+ ```html
266
+ <button type="button" class="ibis-chips ibis-chips--md ibis-chips--selected" aria-pressed="true">
267
+ <span class="ibis-chips__content">Selected filter</span>
268
+ </button>
269
+ ```
270
+
271
+ ---
272
+
273
+ ### Banner
274
+
275
+ ```css
276
+ @import "@ibis-design/css/components/banner.css";
277
+ ```
278
+
279
+ **Types:** `ibis-banner--success`, `ibis-banner--error`, `ibis-banner--default`
280
+
281
+ ```html
282
+ <div class="ibis-banner ibis-banner--success" role="status">
283
+ <div class="ibis-banner__icon">✓</div>
284
+ <div class="ibis-banner__content">
285
+ <div class="ibis-banner__title">Payment received</div>
286
+ <div class="ibis-banner__message">Your transfer completed successfully.</div>
287
+ </div>
288
+ <button type="button" class="ibis-banner__close" aria-label="Close">×</button>
289
+ </div>
290
+ ```
291
+
292
+ ---
293
+
294
+ ### Toaster
295
+
296
+ ```css
297
+ @import "@ibis-design/css/components/toaster.css";
298
+ ```
299
+
300
+ **Types:** `ibis-toaster--success`, `ibis-toaster--error`, `ibis-toaster--accent`, `ibis-toaster--default`
301
+
302
+ ```html
303
+ <div class="ibis-toaster ibis-toaster--accent" role="status">
304
+ <div class="ibis-toaster__icon">!</div>
305
+ <div class="ibis-toaster__content">
306
+ <div class="ibis-toaster__title">Session expiring</div>
307
+ <div class="ibis-toaster__message">Sign in again to continue.</div>
308
+ </div>
309
+ </div>
310
+ ```
311
+
312
+ ---
313
+
314
+ ### Dropdown (custom menu)
315
+
316
+ ```css
317
+ @import "@ibis-design/css/components/dropdown.css";
318
+ ```
319
+
320
+ Pair with your own JS for open/close. Structure:
321
+
322
+ ```html
323
+ <div class="ibis-dropdown">
324
+ <!-- trigger + listbox markup; see Storybook or @ibis-design/svelte Dropdown for a complete pattern -->
325
+ </div>
326
+ ```
327
+
328
+ For a full accessible select experience, prefer **@ibis-design/svelte** `Dropdown` or build menu behavior on `.ibis-dropdown-button` below.
329
+
330
+ ---
331
+
332
+ ### Dropdown button
333
+
334
+ ```css
335
+ @import "@ibis-design/css/components/dropdownButton.css";
336
+ @import "@ibis-design/css/components/button.css";
337
+ ```
338
+
339
+ Wrap a trigger and menu:
340
+
341
+ ```html
342
+ <div class="ibis-dropdown-button">
343
+ <button type="button" class="ibis-button ibis-button--secondary ibis-button--md" aria-haspopup="menu" aria-expanded="false">
344
+ <span class="ibis-button__content">Actions</span>
345
+ </button>
346
+ <div class="ibis-dropdown-menu" role="menu">
347
+ <button type="button" class="ibis-dropdown-menu__item" role="menuitem">Export</button>
348
+ <button type="button" class="ibis-dropdown-menu__item" role="menuitem">Print</button>
349
+ </div>
350
+ </div>
351
+ ```
352
+
353
+ Toggle visibility of `.ibis-dropdown-menu` with your framework or vanilla JS.
354
+
355
+ ---
356
+
357
+ ### Pill tab
358
+
359
+ ```css
360
+ @import "@ibis-design/css/components/pillTab.css";
361
+ ```
362
+
363
+ Radio-based tabs inside a group container:
364
+
365
+ ```html
366
+ <div class="ibis-pill-tabs" style="display:inline-flex;gap:4px;padding:4px;border-radius:9999px;background:var(--color-white);">
367
+ <label class="ibis-pill-tab ibis-pill-tab--active">
368
+ <input type="radio" name="view" value="overview" class="ibis-pill-tab__input" checked />
369
+ <span class="ibis-pill-tab__content">Overview</span>
370
+ </label>
371
+ <label class="ibis-pill-tab">
372
+ <input type="radio" name="view" value="activity" class="ibis-pill-tab__input" />
373
+ <span class="ibis-pill-tab__content">Activity</span>
374
+ </label>
375
+ </div>
376
+ ```
377
+
378
+ Add class `ibis-pill-tab--active` on the selected label (or use Svelte `PillTabs` / `PillTab`).
379
+
380
+ ---
381
+
382
+ ### Tip indicator
383
+
384
+ ```css
385
+ @import "@ibis-design/css/components/tipIndicator.css";
386
+ ```
387
+
388
+ ```html
389
+ <span class="ibis-tip-indicator" tabindex="0" role="button" aria-describedby="fee-tip">
390
+ <!-- icon SVG optional; see @ibis-design/svelte TipIndicator -->
391
+ <span id="fee-tip" class="ibis-tip ibis-tip--top ibis-tip--width-240" role="tooltip">
392
+ <span class="ibis-tip__text">Fees may apply for international transfers.</span>
393
+ <span class="ibis-tip__arrow"></span>
394
+ </span>
395
+ </span>
396
+ ```
397
+
398
+ **Tooltip position:** `ibis-tip--top`, `ibis-tip--bottom`, `ibis-tip--left`, `ibis-tip--right`
399
+ **Width:** `ibis-tip--width-auto`, `ibis-tip--width-240`, `ibis-tip--width-360`
400
+
401
+ ---
402
+
403
+ ## Tailwind CSS (v3)
101
404
 
102
405
  ```js
103
406
  /** @type {import('tailwindcss').Config} */
@@ -107,28 +410,26 @@ module.exports = {
107
410
  };
108
411
  ```
109
412
 
110
- - Utilities map to the same `var(--*)` names as the CSS bundle.
111
- - Dark mode utilities use `[data-theme$="-dark"]` (configured in the preset).
112
- - You must still import `@ibis-design/css` in your app and set `data-theme` on the document.
413
+ ```css
414
+ @import "@ibis-design/css";
415
+ ```
416
+
417
+ Dark-mode utilities respond to `[data-theme$="-dark"]`. You still must set `data-theme` on `<html>`.
418
+
419
+ ---
113
420
 
114
421
  ## Fonts
115
422
 
116
- Font family tokens (Inter, Metrisch, Beyond Infinity, etc.) are **not** bundled. Load the fonts in your application to match the stacks referenced in the tokens.
423
+ Font stacks in tokens (Inter, Metrisch, Beyond Infinity, etc.) are **not** included. Load matching fonts in your app.
424
+
425
+ ---
117
426
 
118
427
  ## Package entry points
119
428
 
120
429
  | Import | Purpose |
121
430
  |--------|---------|
122
- | `@ibis-design/css` | Full design token stylesheet (`design-tokens.css`) |
123
- | `@ibis-design/css/design-tokens.css` | Same as default export |
124
- | `@ibis-design/css/tailwind.preset` | Tailwind preset (includes dark mode selector) |
125
- | `@ibis-design/css/components/<name>.css` | Per-component presentation CSS |
126
-
127
- ### Legacy paths
128
-
129
- These resolve to the same unified token bundle as `@ibis-design/css`:
130
-
131
- - `@ibis-design/css/ibis-design.css`
132
- - `@ibis-design/css/alchemy-design.css`
431
+ | `@ibis-design/css` | Full token stylesheet |
432
+ | `@ibis-design/css/components/<name>.css` | Component presentation |
433
+ | `@ibis-design/css/tailwind.preset` | Tailwind preset |
133
434
 
134
- Prefer `@ibis-design/css` and switch brand/mode with `data-theme` instead of separate brand CSS files.
435
+ Legacy aliases `@ibis-design/css/ibis-design.css` and `@ibis-design/css/alchemy-design.css` point at the same token bundle—use `data-theme` instead.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibis-design/css",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "Design tokens, CSS variables, and Tailwind preset for the IBIS design system.",
5
5
  "type": "module",
6
6
  "exports": {