ui-foundations 0.3.2 → 0.4.1
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 +179 -36
- package/dist/assets/icons/checkmark.svg +1 -0
- package/dist/core/index.css +7 -7
- package/dist/macros/ui.njk +142 -0
- package/dist/main.css +465 -173
- package/dist/react/badge.js +41 -0
- package/dist/react/button.js +15 -6
- package/dist/react/checkbox.js +30 -0
- package/dist/react/icon.js +19 -1
- package/dist/react/index.js +2 -0
- package/dist/react/label.js +1 -1
- package/dist/react/radio.js +62 -0
- package/dist/react/switch.js +18 -0
- package/dist/tokens/css/{appearance-(modes).tokens.mode-dark.css → appearance-modes.tokens.mode-dark.css} +1 -1
- package/dist/tokens/css/{appearance-(modes).tokens.mode-light.css → appearance-modes.tokens.mode-light.css} +1 -1
- package/dist/tokens/css/{components-(ui).tokens.css → components-ui.tokens.css} +46 -3
- package/dist/tokens/css/{core-(primitives).tokens.css → core-primitives.tokens.css} +61 -19
- package/dist/tokens/css/{semantics-(roles).tokens.css → semantics-roles.tokens.css} +1 -1
- package/dist/tokens/css/themes-brands.tokens.brand-a.css +22 -0
- package/dist/tokens/css/{themes-(brands).tokens.brand-b.css → themes-brands.tokens.brand-b.css} +9 -9
- package/dist/tokens/json/appearance-modes.tokens.mode-dark.json +121 -0
- package/dist/tokens/json/appearance-modes.tokens.mode-light.json +121 -0
- package/dist/tokens/json/components-ui.tokens.json +715 -0
- package/dist/tokens/json/{core-(primitives).tokens.json → core-primitives.tokens.json} +227 -413
- package/dist/tokens/json/semantics-roles.tokens.json +141 -0
- package/dist/tokens/json/themes-brands.tokens.brand-a.json +81 -0
- package/dist/tokens/json/themes-brands.tokens.brand-b.json +81 -0
- package/dist/tokens/missing-tokens.json +43 -0
- package/dist/tokens/tokens.yaml +1254 -149
- package/dist/tokens/ts/{appearance-(modes).tokens.mode-dark.ts → appearance-modes.tokens.mode-dark.ts} +1 -1
- package/dist/tokens/ts/{appearance-(modes).tokens.mode-light.ts → appearance-modes.tokens.mode-light.ts} +1 -1
- package/dist/tokens/ts/{components-(ui).tokens.ts → components-ui.tokens.ts} +47 -4
- package/dist/tokens/ts/{core-(primitives).tokens.ts → core-primitives.tokens.ts} +62 -20
- package/dist/tokens/ts/{semantics-(roles).tokens.ts → semantics-roles.tokens.ts} +1 -1
- package/dist/tokens/ts/{themes-(brands).tokens.brand-a.ts → themes-brands.tokens.brand-a.ts} +9 -9
- package/dist/tokens/ts/{themes-(brands).tokens.brand-b.ts → themes-brands.tokens.brand-b.ts} +9 -9
- package/dist/ui/index.css +2 -0
- package/dist/ui/patterns/badge.css +49 -0
- package/dist/ui/patterns/checkbox.css +71 -22
- package/dist/ui/patterns/radio.css +109 -0
- package/docs/README.md +38 -0
- package/docs/agentic/README.md +34 -0
- package/docs/agentic/assistant-behavior-rules.md +48 -0
- package/docs/agentic/skills/ux-writing-coach.md +116 -0
- package/docs/foundations/README.md +31 -0
- package/docs/foundations/foundation-001-token-layering.md +6 -0
- package/docs/foundations/foundation-002-naming-and-grouping.md +6 -0
- package/docs/foundations/foundation-003-color-semantics-and-status.md +6 -0
- package/docs/foundations/foundation-004-typography-scale-and-line-height.md +6 -0
- package/docs/foundations/foundation-005-responsive-breakpoints-and-containers.md +6 -0
- package/docs/foundations/foundation-006-z-index-layering.md +6 -0
- package/docs/foundations/foundation-007-typography-selectors-and-specificity.md +6 -0
- package/docs/foundations/foundation-008-mode-activation-and-consumer-control.md +6 -0
- package/docs/foundations/foundation-009-component-boundaries-and-utility.md +6 -0
- package/docs/foundations/foundation-010-implementation-and-pipeline-workflow.md +6 -0
- package/docs/foundations/foundation-011-branching-and-release-governance.md +6 -0
- package/docs/foundations/foundation-012-minimal-markup-and-composition.md +6 -0
- package/package.json +15 -11
- package/dist/tokens/css/themes-(brands).tokens.brand-a.css +0 -22
- package/dist/tokens/json/appearance-(modes).tokens.mode-dark.json +0 -182
- package/dist/tokens/json/appearance-(modes).tokens.mode-light.json +0 -182
- package/dist/tokens/json/components-(ui).tokens.json +0 -739
- package/dist/tokens/json/semantics-(roles).tokens.json +0 -203
- package/dist/tokens/json/themes-(brands).tokens.brand-a.json +0 -115
- package/dist/tokens/json/themes-(brands).tokens.brand-b.json +0 -115
- package/docs/agentic/skills/README.md +0 -51
- package/docs/agentic/skills/design-ops-specialist/SKILL.md +0 -60
- package/docs/agentic/skills/design-system-architect/SKILL.md +0 -106
- package/docs/agentic/team-ai-playbook.md +0 -226
package/README.md
CHANGED
|
@@ -1,80 +1,210 @@
|
|
|
1
1
|
# UI Foundations
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Keep Figma and code in sync by default — with tokens, not guesswork.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- **Token-first architecture** — every value comes from a token, no hardcoded exceptions
|
|
6
|
+
- **Figma as single source of truth** — variables export directly into production code
|
|
7
|
+
- **Agent-ready workflows** — structured docs that give AI agents deterministic context
|
|
8
|
+
- **Reproducible pipeline** — same input, same output, validated by CI on every change
|
|
9
|
+
|
|
10
|
+
[Documentation](https://ui-foundations.netlify.app/) · [Starter Template](https://github.com/tbielich/ui-foundations-starter) · [npm](https://www.npmjs.com/package/ui-foundations) · [Figma Library](https://www.figma.com/design/uqMsy8fV1fPbQdAzgwlmBA/UI-Foundations)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Why This Exists
|
|
15
|
+
|
|
16
|
+
Design systems break when design and code drift apart.
|
|
17
|
+
Manual syncing is slow, error-prone, and doesn't scale.
|
|
18
|
+
|
|
19
|
+
UI Foundations solves this with a pipeline that turns Figma variables into
|
|
20
|
+
production tokens automatically — and structures everything so AI agents can
|
|
21
|
+
work with the system reliably.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Key Features
|
|
26
|
+
|
|
27
|
+
- **Token-first architecture** — Core → Semantic → Component → Theme, strictly separated
|
|
28
|
+
- **Figma ↔ code alignment** — `codeSyntax.WEB` maps Figma names directly to CSS
|
|
29
|
+
- **Multi-brand and dark mode** — `data-brand` and `data-mode` switch independently
|
|
30
|
+
- **Agent-ready documentation** — deterministic context for AI-assisted workflows
|
|
31
|
+
- **DTCG-compliant output** — 2025.10 format with proper alias syntax and hex colors
|
|
32
|
+
- **CI-enforced integrity** — full validation pipeline in one `npm run ci:check`
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## How It Works
|
|
37
|
+
|
|
38
|
+
### Token Flow
|
|
6
39
|
|
|
7
40
|
```
|
|
8
|
-
Figma Variables
|
|
41
|
+
Figma Variables
|
|
42
|
+
↓
|
|
43
|
+
figma/exports/*.tokens.json
|
|
44
|
+
↓
|
|
45
|
+
extract-tokens.js
|
|
46
|
+
↓
|
|
47
|
+
dist/
|
|
9
48
|
```
|
|
10
49
|
|
|
11
|
-
|
|
50
|
+
The pipeline outputs:
|
|
12
51
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- Figma plugin with Validate + Export tabs (see `figma/plugin/README.md`)
|
|
18
|
-
- CI pipeline: lint, unit tests, build, smoke check, docs build
|
|
19
|
-
- Docs site with Eleventy, auto-generated from token data
|
|
52
|
+
- CSS custom properties (`dist/tokens/css/`)
|
|
53
|
+
- DTCG-compliant JSON (`dist/tokens/json/`)
|
|
54
|
+
- TypeScript constants (`dist/tokens/ts/`)
|
|
55
|
+
- A flat YAML index (`dist/tokens/tokens.yaml`)
|
|
20
56
|
|
|
21
|
-
|
|
57
|
+
### Layering
|
|
58
|
+
|
|
59
|
+
Tokens follow a strict hierarchy:
|
|
60
|
+
|
|
61
|
+
1. **Core** — raw values (spacing, radii, colors, typography)
|
|
62
|
+
2. **Semantic** — intent-based aliases (`--color-text-default`, `--color-fill-brand`)
|
|
63
|
+
3. **Component** — scoped to one component (`--button-solid-container-background-hover`)
|
|
64
|
+
4. **Theme** — brand and mode overrides via `data-brand` / `data-mode`
|
|
65
|
+
|
|
66
|
+
Components reference only Semantic or Core. Never raw values.
|
|
67
|
+
|
|
68
|
+
### Component Integration
|
|
69
|
+
|
|
70
|
+
Every component ships with:
|
|
71
|
+
CSS pattern, React wrapper, Nunjucks macro, playground page, docs page,
|
|
72
|
+
and Code Connect mapping.
|
|
73
|
+
|
|
74
|
+
All surfaces must be present for the component to work predictably across
|
|
75
|
+
docs, playgrounds, and consumer apps.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## For Different Audiences
|
|
80
|
+
|
|
81
|
+
### Designers
|
|
82
|
+
|
|
83
|
+
- Work in Figma variables — they are the source of truth
|
|
84
|
+
- Token names in Figma map directly to CSS variable names
|
|
85
|
+
- Brand and mode switching is built into the variable structure
|
|
86
|
+
|
|
87
|
+
### Developers
|
|
88
|
+
|
|
89
|
+
- Use generated CSS custom properties — `var(--color-text-default)`
|
|
90
|
+
- No hardcoded values — everything comes from tokens
|
|
91
|
+
- Theming via `data-brand` and `data-mode` attributes on the root element
|
|
92
|
+
|
|
93
|
+
### Agents
|
|
94
|
+
|
|
95
|
+
- Start with `AGENTS.md` — it defines context loading order
|
|
96
|
+
- Follow deterministic rules in `docs/agentic/assistant-behavior-rules.md`
|
|
97
|
+
- Select a mode from `docs/agentic/modes/` based on the task
|
|
98
|
+
|
|
99
|
+
---
|
|
22
100
|
|
|
23
|
-
|
|
101
|
+
## Getting Started
|
|
24
102
|
|
|
25
|
-
|
|
103
|
+
### Install
|
|
26
104
|
|
|
27
105
|
```bash
|
|
28
106
|
npm install ui-foundations
|
|
29
107
|
```
|
|
30
108
|
|
|
31
|
-
|
|
109
|
+
### Import
|
|
32
110
|
|
|
33
111
|
```js
|
|
34
112
|
import "ui-foundations/core.css";
|
|
35
113
|
import "ui-foundations/ui.css";
|
|
36
114
|
```
|
|
37
115
|
|
|
38
|
-
|
|
116
|
+
### Apply Theming
|
|
39
117
|
|
|
40
118
|
```js
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
root.dataset.mode = "light"; // "light" | "dark"
|
|
119
|
+
document.documentElement.dataset.brand = "a"; // "a" | "b"
|
|
120
|
+
document.documentElement.dataset.mode = "light"; // "light" | "dark"
|
|
44
121
|
```
|
|
45
122
|
|
|
123
|
+
Explore the [docs site](https://ui-foundations.netlify.app/) or the
|
|
124
|
+
[vanilla starter](https://github.com/tbielich/ui-foundations-starter)
|
|
125
|
+
to see it in action.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Components
|
|
130
|
+
|
|
131
|
+
Label, Button (solid / outline / ghost), ButtonGroup, Input, Icon, Checkbox,
|
|
132
|
+
Radio, RadioGroup, Switch, Slider, Link
|
|
133
|
+
|
|
134
|
+
Each component uses its own token layer and supports theming out of the box.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Agent Integration
|
|
139
|
+
|
|
140
|
+
This repo is structured for agent consumption:
|
|
141
|
+
|
|
142
|
+
| File | Purpose |
|
|
143
|
+
|---|---|
|
|
144
|
+
| `AGENTS.md` | Entry point — behavior rules and context loading order |
|
|
145
|
+
| `docs/playbook.md` | Documentation hierarchy and operating model |
|
|
146
|
+
| `DESIGN.md` | Executive design contract |
|
|
147
|
+
| `docs/working-context.md` | Current priorities |
|
|
148
|
+
| `docs/context-manifest.json` | Machine-readable file index |
|
|
149
|
+
| `docs/agentic/modes/` | Task-specific modes (implementation, audit, pattern discovery, token proposal) |
|
|
150
|
+
|
|
151
|
+
Agents operate in modes:
|
|
152
|
+
|
|
153
|
+
- **Default** → Implementation
|
|
154
|
+
- **Exploratory tasks** → Pattern Discovery or Token Proposal
|
|
155
|
+
- **Review tasks** → Audit
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Documentation Structure
|
|
160
|
+
|
|
161
|
+
| Directory | Content |
|
|
162
|
+
|---|---|
|
|
163
|
+
| `docs/foundations/` | Token layering, naming, theming, parity, and 12 foundation ADRs |
|
|
164
|
+
| `docs/principles/` | Perception laws, heuristics, and accessibility intent |
|
|
165
|
+
| `docs/patterns/` | Pattern-level composition guidance |
|
|
166
|
+
| `docs/components/` | Component entry docs |
|
|
167
|
+
| `docs/agentic/` | Agent behavior rules, modes, workflows, rule pipeline |
|
|
168
|
+
| `docs/validation/` | CI pipeline, token parity, rule pipeline manifest |
|
|
169
|
+
| `docs/token-pipeline.md` | Token generation pipeline and format reference |
|
|
170
|
+
| `site/` | Docs site source (Eleventy) |
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
46
174
|
## Local Development
|
|
47
175
|
|
|
176
|
+
### Build
|
|
177
|
+
|
|
48
178
|
```bash
|
|
49
179
|
npm run build:all # generate tokens + build CSS
|
|
50
180
|
npm run docs:dev # build + serve docs site
|
|
51
181
|
```
|
|
52
182
|
|
|
53
|
-
Figma
|
|
183
|
+
### Figma Sync
|
|
54
184
|
|
|
55
185
|
```bash
|
|
56
|
-
# 1. Export tokens
|
|
186
|
+
# 1. Export tokens from Figma
|
|
57
187
|
# 2. Place JSON files in figma/exports/
|
|
58
|
-
# 3. Build
|
|
59
188
|
npm run build:all
|
|
60
189
|
```
|
|
61
190
|
|
|
62
|
-
Validation
|
|
191
|
+
### Validation
|
|
63
192
|
|
|
64
193
|
```bash
|
|
65
|
-
npm run
|
|
66
|
-
npm run
|
|
67
|
-
npm run
|
|
194
|
+
npm run ci:check # full pipeline
|
|
195
|
+
npm run tokens:validate # token structure
|
|
196
|
+
npm run dtcg:validate # DTCG compliance
|
|
197
|
+
npm run rules:validate # rule pipeline traceability
|
|
68
198
|
```
|
|
69
199
|
|
|
200
|
+
---
|
|
201
|
+
|
|
70
202
|
## MCP Integration
|
|
71
203
|
|
|
72
|
-
|
|
204
|
+
Figma integration via Model Context Protocol:
|
|
73
205
|
|
|
74
206
|
- `figma-developer-mcp` — REST API read access (requires `FIGMA_TOKEN` in `.env`)
|
|
75
|
-
- Figma Desktop MCP — local server via Figma Desktop app
|
|
76
|
-
|
|
77
|
-
Configure these in your agent's MCP config. Example for the REST API server:
|
|
207
|
+
- Figma Desktop MCP — local server via Figma Desktop app
|
|
78
208
|
|
|
79
209
|
```json
|
|
80
210
|
{
|
|
@@ -83,13 +213,16 @@ Configure these in your agent's MCP config. Example for the REST API server:
|
|
|
83
213
|
}
|
|
84
214
|
```
|
|
85
215
|
|
|
86
|
-
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Contributing
|
|
219
|
+
|
|
220
|
+
- Follow token rules — no invented tokens, no hardcoded values
|
|
221
|
+
- Use semantic tokens over primitives
|
|
222
|
+
- Validate before commit: `npm run ci:check`
|
|
223
|
+
- Work on feature branches
|
|
87
224
|
|
|
88
|
-
|
|
89
|
-
- AI playbook: `docs/agentic/team-ai-playbook.md`
|
|
90
|
-
- Figma plugin (Token Foundry): `figma/plugin/README.md`
|
|
91
|
-
- Docs site: `site/`
|
|
92
|
-
- Vanilla starter: `site/examples/vanilla-starter.md`
|
|
225
|
+
---
|
|
93
226
|
|
|
94
227
|
## Release
|
|
95
228
|
|
|
@@ -98,3 +231,13 @@ npm run release:patch # or release:minor / release:major
|
|
|
98
231
|
npm run release:push
|
|
99
232
|
npm run release:publish
|
|
100
233
|
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Tech Stack
|
|
238
|
+
|
|
239
|
+
Vanilla CSS (Custom Properties, `@layer`) · Node.js · Eleventy · React (optional wrappers) · Nunjucks macros · Figma MCP
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
Designed for consistency, built for scale, ready for agents.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 12 10 18 20 6"/></svg>
|
package/dist/core/index.css
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
@import url("./base/fonts.css") layer(base);
|
|
3
3
|
@import url("./base/base.css") layer(base);
|
|
4
4
|
@import url("./base/typography.css") layer(base);
|
|
5
|
-
@import url("../tokens/css/
|
|
6
|
-
@import url("../tokens/css/
|
|
7
|
-
@import url("../tokens/css/
|
|
8
|
-
@import url("../tokens/css/appearance-
|
|
9
|
-
@import url("../tokens/css/
|
|
10
|
-
@import url("../tokens/css/themes-
|
|
11
|
-
@import url("../tokens/css/themes-
|
|
5
|
+
@import url("../tokens/css/core-primitives.tokens.css") layer(tokens);
|
|
6
|
+
@import url("../tokens/css/semantics-roles.tokens.css") layer(tokens);
|
|
7
|
+
@import url("../tokens/css/components-ui.tokens.css") layer(tokens);
|
|
8
|
+
@import url("../tokens/css/appearance-modes.tokens.mode-dark.css") layer(tokens);
|
|
9
|
+
@import url("../tokens/css/appearance-modes.tokens.mode-light.css") layer(tokens);
|
|
10
|
+
@import url("../tokens/css/themes-brands.tokens.brand-a.css") layer(tokens);
|
|
11
|
+
@import url("../tokens/css/themes-brands.tokens.brand-b.css") layer(tokens);
|
|
12
12
|
@import url("./themes/mode.css") layer(themes);
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
{% macro toggleButton(label, dataName, dataValue, variant='outline') -%}
|
|
2
|
+
{%- set classes = "button" -%}
|
|
3
|
+
{%- if variant -%}{%- set classes = classes + " " + variant -%}{%- endif -%}
|
|
4
|
+
<button class="{{ classes }}" type="button"{% if dataName == "mode" %} data-mode="{{ dataValue }}"{% endif %}{% if dataName == "brand" %} data-brand="{{ dataValue }}"{% endif %}{% if dataName == "lang" %} data-lang="{{ dataValue }}"{% endif %} aria-pressed="false">{{ label }}</button>
|
|
5
|
+
{%- endmacro %}
|
|
6
|
+
|
|
7
|
+
{% macro button(label, variant='', disabled=false, type='button') -%}
|
|
8
|
+
{%- set classes = "button" -%}
|
|
9
|
+
{%- if variant -%}{%- set classes = classes + " " + variant -%}{%- endif -%}
|
|
10
|
+
<button type="{{ type }}" class="{{ classes }}"{% if disabled %} disabled{% endif %}>{{ label }}</button>
|
|
11
|
+
{%- endmacro %}
|
|
12
|
+
|
|
13
|
+
{% macro buttonGroup(attached=false, orientation='horizontal', justify='start', ariaLabel='', className='') -%}
|
|
14
|
+
{%- set resolvedOrientation = "vertical" if orientation == "vertical" else "horizontal" -%}
|
|
15
|
+
{%- set resolvedJustify = "stretch" if justify == "stretch" else "start" -%}
|
|
16
|
+
{%- set classes = "button-group" -%}
|
|
17
|
+
{%- if className -%}{%- set classes = classes + " " + className -%}{%- endif -%}
|
|
18
|
+
<div class="{{ classes }}" role="group" data-orientation="{{ resolvedOrientation }}" data-attached="{{ "true" if attached else "false" }}" data-justify="{{ resolvedJustify }}"{% if ariaLabel %} aria-label="{{ ariaLabel }}"{% endif %}>{{ caller() }}</div>
|
|
19
|
+
{%- endmacro %}
|
|
20
|
+
|
|
21
|
+
{% macro input(type='text', placeholder='', value='', state='default', disabled=false, className='', id='', name='', dataPlaygroundControl=false, dataProp='', dataSource='', dataValueType='', dataQueryParam='') -%}
|
|
22
|
+
{%- set classes = "input" -%}
|
|
23
|
+
{%- if state == "hover" -%}{%- set classes = classes + " is-hover" -%}{%- endif -%}
|
|
24
|
+
{%- if state == "active" -%}{%- set classes = classes + " is-active" -%}{%- endif -%}
|
|
25
|
+
{%- if state == "focus" -%}{%- set classes = classes + " is-focus-visible" -%}{%- endif -%}
|
|
26
|
+
{%- if state == "disabled" -%}{%- set classes = classes + " is-disabled" -%}{%- endif -%}
|
|
27
|
+
{%- if className -%}{%- set classes = classes + " " + className -%}{%- endif -%}
|
|
28
|
+
<input class="{{ classes }}" type="{{ type }}"{% if id %} id="{{ id }}"{% endif %}{% if name %} name="{{ name }}"{% endif %}{% if placeholder %} placeholder="{{ placeholder }}"{% endif %}{% if value %} value="{{ value }}"{% endif %}{% if dataPlaygroundControl %} data-playground-control{% endif %}{% if dataProp %} data-prop="{{ dataProp }}"{% endif %}{% if dataSource %} data-source="{{ dataSource }}"{% endif %}{% if dataValueType %} data-value-type="{{ dataValueType }}"{% endif %}{% if dataQueryParam %} data-query-param="{{ dataQueryParam }}"{% endif %}{% if disabled or state == "disabled" %} disabled{% endif %} />
|
|
29
|
+
{%- endmacro %}
|
|
30
|
+
|
|
31
|
+
{% macro checkbox(label='Checkbox', checked=false, disabled=false, state='default', indeterminate=false, className='', wrapperClassName='', id='', name='', value='on') -%}
|
|
32
|
+
{%- set checkboxClasses = "checkbox" -%}
|
|
33
|
+
{%- set fieldClasses = "checkbox-field" -%}
|
|
34
|
+
{%- if checked -%}{%- set checkboxClasses = checkboxClasses + " is-checked" -%}{%- endif -%}
|
|
35
|
+
{%- if indeterminate or state == "indeterminate" -%}{%- set checkboxClasses = checkboxClasses + " is-indeterminate" -%}{%- endif -%}
|
|
36
|
+
{%- if state == "hover" -%}{%- set checkboxClasses = checkboxClasses + " is-hover" -%}{%- endif -%}
|
|
37
|
+
{%- if state == "active" -%}{%- set checkboxClasses = checkboxClasses + " is-active" -%}{%- endif -%}
|
|
38
|
+
{%- if state == "focus" -%}{%- set checkboxClasses = checkboxClasses + " is-focus-visible" -%}{%- endif -%}
|
|
39
|
+
{%- if disabled or state == "disabled" -%}
|
|
40
|
+
{%- set checkboxClasses = checkboxClasses + " is-disabled" -%}
|
|
41
|
+
{%- set fieldClasses = fieldClasses + " is-disabled" -%}
|
|
42
|
+
{%- endif -%}
|
|
43
|
+
{%- if className -%}{%- set checkboxClasses = checkboxClasses + " " + className -%}{%- endif -%}
|
|
44
|
+
{%- if wrapperClassName -%}{%- set fieldClasses = fieldClasses + " " + wrapperClassName -%}{%- endif -%}
|
|
45
|
+
<label class="{{ fieldClasses }}">
|
|
46
|
+
<input class="{{ checkboxClasses }}" type="checkbox"{% if id %} id="{{ id }}"{% endif %}{% if name %} name="{{ name }}"{% endif %}{% if value %} value="{{ value }}"{% endif %}{% if checked %} checked{% endif %}{% if indeterminate or state == "indeterminate" %} aria-checked="mixed"{% endif %}{% if disabled or state == "disabled" %} disabled{% endif %} />
|
|
47
|
+
<span class="checkbox-field__text">{{ label }}</span>
|
|
48
|
+
</label>
|
|
49
|
+
{%- endmacro %}
|
|
50
|
+
|
|
51
|
+
{% macro radio(label='Option', checked=false, disabled=false, state='default', className='', wrapperClassName='', id='', name='', value='') -%}
|
|
52
|
+
{%- set radioClasses = "radio" -%}
|
|
53
|
+
{%- set fieldClasses = "radio-field" -%}
|
|
54
|
+
{%- if checked -%}{%- set radioClasses = radioClasses + " is-checked" -%}{%- endif -%}
|
|
55
|
+
{%- if state == "hover" -%}{%- set radioClasses = radioClasses + " is-hover" -%}{%- endif -%}
|
|
56
|
+
{%- if state == "active" -%}{%- set radioClasses = radioClasses + " is-active" -%}{%- endif -%}
|
|
57
|
+
{%- if state == "focus" -%}{%- set radioClasses = radioClasses + " is-focus-visible" -%}{%- endif -%}
|
|
58
|
+
{%- if disabled or state == "disabled" -%}
|
|
59
|
+
{%- set radioClasses = radioClasses + " is-disabled" -%}
|
|
60
|
+
{%- set fieldClasses = fieldClasses + " is-disabled" -%}
|
|
61
|
+
{%- endif -%}
|
|
62
|
+
{%- if className -%}{%- set radioClasses = radioClasses + " " + className -%}{%- endif -%}
|
|
63
|
+
{%- if wrapperClassName -%}{%- set fieldClasses = fieldClasses + " " + wrapperClassName -%}{%- endif -%}
|
|
64
|
+
<label class="{{ fieldClasses }}">
|
|
65
|
+
<input class="{{ radioClasses }}" type="radio"{% if id %} id="{{ id }}"{% endif %}{% if name %} name="{{ name }}"{% endif %}{% if value %} value="{{ value }}"{% endif %}{% if checked %} checked{% endif %}{% if disabled or state == "disabled" %} disabled{% endif %} />
|
|
66
|
+
<span class="radio-field__text">{{ label }}</span>
|
|
67
|
+
</label>
|
|
68
|
+
{%- endmacro %}
|
|
69
|
+
|
|
70
|
+
{% macro switch(label='Notifications', checked=false, disabled=false, state='default', className='', wrapperClassName='', id='', name='', value='on') -%}
|
|
71
|
+
{%- set switchClasses = "switch" -%}
|
|
72
|
+
{%- set fieldClasses = "switch-field" -%}
|
|
73
|
+
{%- if checked -%}{%- set switchClasses = switchClasses + " is-checked" -%}{%- endif -%}
|
|
74
|
+
{%- if state == "hover" -%}{%- set switchClasses = switchClasses + " is-hover" -%}{%- endif -%}
|
|
75
|
+
{%- if state == "active" -%}{%- set switchClasses = switchClasses + " is-active" -%}{%- endif -%}
|
|
76
|
+
{%- if state == "focus" -%}{%- set switchClasses = switchClasses + " is-focus-visible" -%}{%- endif -%}
|
|
77
|
+
{%- if disabled or state == "disabled" -%}
|
|
78
|
+
{%- set switchClasses = switchClasses + " is-disabled" -%}
|
|
79
|
+
{%- set fieldClasses = fieldClasses + " is-disabled" -%}
|
|
80
|
+
{%- endif -%}
|
|
81
|
+
{%- if className -%}{%- set switchClasses = switchClasses + " " + className -%}{%- endif -%}
|
|
82
|
+
{%- if wrapperClassName -%}{%- set fieldClasses = fieldClasses + " " + wrapperClassName -%}{%- endif -%}
|
|
83
|
+
<label class="{{ fieldClasses }}">
|
|
84
|
+
<input class="{{ switchClasses }}" type="checkbox" role="switch"{% if id %} id="{{ id }}"{% endif %}{% if name %} name="{{ name }}"{% endif %}{% if value %} value="{{ value }}"{% endif %}{% if checked %} checked{% endif %}{% if disabled or state == "disabled" %} disabled{% endif %} />
|
|
85
|
+
<span class="switch-field__text">{{ label }}</span>
|
|
86
|
+
</label>
|
|
87
|
+
{%- endmacro %}
|
|
88
|
+
|
|
89
|
+
{% macro colorChip(token) -%}
|
|
90
|
+
<div class="swatch" style="--swatch-color: var({{ token.cssVar }})">
|
|
91
|
+
<span class="swatch-name">{{ token.name }}</span>
|
|
92
|
+
<span class="swatch-meta">{{ token.value }}</span>
|
|
93
|
+
</div>
|
|
94
|
+
{%- endmacro %}
|
|
95
|
+
|
|
96
|
+
{% macro icon(name, label='', className='') -%}
|
|
97
|
+
{%- set classes = "icon" -%}
|
|
98
|
+
{%- if className -%}{%- set classes = classes + " " + className -%}{%- endif -%}
|
|
99
|
+
<span class="{{ classes }}" style="--icon-src: url('/assets/icons/{{ name }}.svg');"{% if label %} role="img" aria-label="{{ label }}"{% else %} aria-hidden="true"{% endif %}></span>
|
|
100
|
+
{%- endmacro %}
|
|
101
|
+
|
|
102
|
+
{% macro labelContent(text='', startIcon='', endIcon='', iconOnly=false) -%}
|
|
103
|
+
<span class="label-content{% if iconOnly %} is-icon-only{% endif %}">
|
|
104
|
+
{%- if startIcon %}<span class="icon" data-slot="start" style="--icon-src: url('/assets/icons/{{ startIcon }}.svg');" aria-hidden="true"></span>{% endif -%}
|
|
105
|
+
{%- if not iconOnly %}<span class="label-content__text">{{ text }}</span>{% endif -%}
|
|
106
|
+
{%- if endIcon %}<span class="icon" data-slot="end" style="--icon-src: url('/assets/icons/{{ endIcon }}.svg');" aria-hidden="true"></span>{% endif -%}
|
|
107
|
+
</span>
|
|
108
|
+
{%- endmacro %}
|
|
109
|
+
|
|
110
|
+
{% macro fieldLabel(text, htmlFor='', required=false, startIcon='') -%}
|
|
111
|
+
<label class="field-label"{% if htmlFor %} for="{{ htmlFor }}"{% endif %}>
|
|
112
|
+
<span class="label-content">
|
|
113
|
+
{%- if startIcon %}<span class="icon" data-slot="start" style="--icon-src: url('/assets/icons/{{ startIcon }}.svg');" aria-hidden="true"></span>{% endif -%}
|
|
114
|
+
<span class="label-content__text">{{ text }}</span>
|
|
115
|
+
</span>
|
|
116
|
+
{%- if required %}
|
|
117
|
+
<span class="field-label__required" aria-hidden="true">*</span>
|
|
118
|
+
<span class="field-label__required-text"> (required)</span>
|
|
119
|
+
{%- endif %}
|
|
120
|
+
</label>
|
|
121
|
+
{%- endmacro %}
|
|
122
|
+
|
|
123
|
+
{% macro link(text, href='#', startIcon='', endIcon='', state='', disabled=false) -%}
|
|
124
|
+
{%- set classes = "link" -%}
|
|
125
|
+
{%- if state -%}{%- set classes = classes + " is-" + state -%}{%- endif -%}
|
|
126
|
+
{%- if disabled -%}{%- set classes = classes + " is-disabled" -%}{%- endif -%}
|
|
127
|
+
<a class="{{ classes }}" href="{{ href }}"{% if disabled %} aria-disabled="true"{% endif %}>
|
|
128
|
+
{%- if startIcon %}<span class="icon" style="--icon-src: url('/assets/icons/{{ startIcon }}.svg');" aria-hidden="true"></span> {% endif -%}
|
|
129
|
+
{{ text }}
|
|
130
|
+
{%- if endIcon %} <span class="icon" style="--icon-src: url('/assets/icons/{{ endIcon }}.svg');" aria-hidden="true"></span>{% endif -%}
|
|
131
|
+
</a>
|
|
132
|
+
{%- endmacro %}
|
|
133
|
+
|
|
134
|
+
{% macro badge(text, variant='', size='', startIcon='') -%}
|
|
135
|
+
{%- set classes = "badge" -%}
|
|
136
|
+
{%- if variant -%}{%- set classes = classes + " " + variant -%}{%- endif -%}
|
|
137
|
+
{%- if size == "sm" -%}{%- set classes = classes + " sm" -%}{%- endif -%}
|
|
138
|
+
<span class="{{ classes }}">
|
|
139
|
+
{%- if startIcon %}<span class="icon" style="--icon-src: url('/assets/icons/{{ startIcon }}.svg');" aria-hidden="true"></span>{% endif -%}
|
|
140
|
+
<span class="badge__text">{{ text }}</span>
|
|
141
|
+
</span>
|
|
142
|
+
{%- endmacro %}
|