@scania/tegel-lite 0.0.2 → 0.0.3-rules-beta.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.
- package/.ai/rules/01-design-tokens.mdc +318 -0
- package/.ai/rules/02-components-forms.mdc +396 -0
- package/.ai/rules/03-components-display.mdc +474 -0
- package/.ai/rules/04-components-navigation.mdc +358 -0
- package/.ai/rules/05-guidelines.mdc +144 -0
- package/.ai/rules/06-patterns.mdc +352 -0
- package/.cursor/rules/tegel-lite/01-design-tokens.mdc +317 -0
- package/.cursor/rules/tegel-lite/02-components-forms.mdc +395 -0
- package/.cursor/rules/tegel-lite/03-components-display.mdc +473 -0
- package/.cursor/rules/tegel-lite/04-components-navigation.mdc +357 -0
- package/.cursor/rules/tegel-lite/05-guidelines.mdc +143 -0
- package/.cursor/rules/tegel-lite/06-patterns.mdc +351 -0
- package/.github/copilot-instructions.md +2045 -0
- package/AGENTS.md +2045 -0
- package/CLAUDE.md +2045 -0
- package/README.dev.md +1 -1
- package/README.md +30 -1
- package/bin/setup-ai-rules.js +347 -0
- package/dist/components.css +6 -3
- package/dist/global.css +7 -3
- package/dist/tl-card.css +6 -3
- package/package.json +14 -3
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Navigation and utility components including tabs, breadcrumbs, header, footer, side menu
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Navigation & Utility Components
|
|
7
|
+
|
|
8
|
+
## Breadcrumbs
|
|
9
|
+
|
|
10
|
+
**Classes**: `tl-breadcrumbs`
|
|
11
|
+
|
|
12
|
+
```html
|
|
13
|
+
<nav class="tl-breadcrumbs" aria-label="Breadcrumb">
|
|
14
|
+
<ol>
|
|
15
|
+
<li><a href="/">Home</a></li>
|
|
16
|
+
<li><a href="/products">Products</a></li>
|
|
17
|
+
<li><a href="/products/trucks" aria-current="page">Trucks</a></li>
|
|
18
|
+
</ol>
|
|
19
|
+
</nav>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Chip
|
|
25
|
+
|
|
26
|
+
**Classes**: `tl-chip`
|
|
27
|
+
**Sizes**: `tl-chip--sm` (24px), `tl-chip--lg` (32px)
|
|
28
|
+
**States**: `tl-chip--selected`
|
|
29
|
+
**Modifiers**: `tl-chip--prefix`, `tl-chip--suffix`
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<button class="tl-chip tl-chip--lg">Default</button>
|
|
33
|
+
<button class="tl-chip tl-chip--lg tl-chip--selected">Selected</button>
|
|
34
|
+
<button class="tl-chip tl-chip--sm" disabled>Disabled</button>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Tabs
|
|
40
|
+
|
|
41
|
+
### Inline Tabs
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<div class="tl-inline-tabs" role="tablist">
|
|
45
|
+
<button
|
|
46
|
+
class="tl-inline-tabs__tab tl-inline-tabs__tab--selected"
|
|
47
|
+
role="tab"
|
|
48
|
+
aria-selected="true"
|
|
49
|
+
>
|
|
50
|
+
Tab 1
|
|
51
|
+
</button>
|
|
52
|
+
<button class="tl-inline-tabs__tab" role="tab" aria-selected="false">
|
|
53
|
+
Tab 2
|
|
54
|
+
</button>
|
|
55
|
+
<button
|
|
56
|
+
class="tl-inline-tabs__tab tl-inline-tabs__tab--disabled"
|
|
57
|
+
role="tab"
|
|
58
|
+
aria-disabled="true"
|
|
59
|
+
>
|
|
60
|
+
Disabled
|
|
61
|
+
</button>
|
|
62
|
+
</div>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Folder Tabs
|
|
66
|
+
|
|
67
|
+
```html
|
|
68
|
+
<div class="tl-folder-tabs" role="tablist">
|
|
69
|
+
<button
|
|
70
|
+
class="tl-folder-tabs__tab tl-folder-tabs__tab--selected"
|
|
71
|
+
role="tab"
|
|
72
|
+
aria-selected="true"
|
|
73
|
+
>
|
|
74
|
+
Active
|
|
75
|
+
</button>
|
|
76
|
+
<button class="tl-folder-tabs__tab" role="tab" aria-selected="false">
|
|
77
|
+
Another
|
|
78
|
+
</button>
|
|
79
|
+
</div>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Navigation Tabs
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
<nav class="tl-navigation-tabs" role="tablist">
|
|
86
|
+
<a
|
|
87
|
+
class="tl-navigation-tabs__tab tl-navigation-tabs__tab--selected"
|
|
88
|
+
href="/overview"
|
|
89
|
+
role="tab"
|
|
90
|
+
aria-selected="true"
|
|
91
|
+
>Overview</a
|
|
92
|
+
>
|
|
93
|
+
<a class="tl-navigation-tabs__tab" href="/details" role="tab">Details</a>
|
|
94
|
+
</nav>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Link
|
|
100
|
+
|
|
101
|
+
**Classes**: `tl-link`
|
|
102
|
+
**Modifiers**: `tl-link--underline`, `tl-link--standalone`, `tl-link--disabled`
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<a href="/page" class="tl-link tl-link--underline">
|
|
106
|
+
Learn more
|
|
107
|
+
<span class="tl-link__icon"
|
|
108
|
+
><span class="tl-icon tl-icon--arrow_right"></span
|
|
109
|
+
></span>
|
|
110
|
+
</a>
|
|
111
|
+
|
|
112
|
+
<!-- Standalone link (inherits detail-02 typography) -->
|
|
113
|
+
<a href="/page" class="tl-link tl-link--standalone tl-link--underline"
|
|
114
|
+
>Standalone Link</a
|
|
115
|
+
>
|
|
116
|
+
|
|
117
|
+
<!-- Disabled link -->
|
|
118
|
+
<span class="tl-link tl-link--disabled">Disabled link</span>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Divider
|
|
124
|
+
|
|
125
|
+
**Classes**: `tl-divider`
|
|
126
|
+
**Variants**: `tl-divider--horizontal`, `tl-divider--vertical`, `tl-divider--expressive`, `tl-divider--discrete`
|
|
127
|
+
|
|
128
|
+
```html
|
|
129
|
+
<div class="tl-divider tl-divider--horizontal"></div>
|
|
130
|
+
<div class="tl-divider tl-divider--vertical" style="height: 40px;"></div>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Tooltip
|
|
136
|
+
|
|
137
|
+
**Classes**: `tl-tooltip`
|
|
138
|
+
**Modifiers**: `tl-tooltip--visible`, position variants: `tl-tooltip--top-start`, `tl-tooltip--top-end`, `tl-tooltip--bottom-start`, `tl-tooltip--bottom-end`, `tl-tooltip--left-start`, `tl-tooltip--left-end`, `tl-tooltip--right-start`, `tl-tooltip--right-end`
|
|
139
|
+
|
|
140
|
+
```html
|
|
141
|
+
<div class="tl-tooltip tl-tooltip--visible tl-tooltip--bottom-start">
|
|
142
|
+
Tooltip text here
|
|
143
|
+
</div>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Max width: 204px. Positioning requires JS or CSS `position: fixed`.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Popover Menu
|
|
151
|
+
|
|
152
|
+
**Classes**: `tl-popover-menu`
|
|
153
|
+
**Variants**: `tl-popover-menu--primary`, `tl-popover-menu--secondary`, `tl-popover-menu--visible`, `tl-popover-menu--fluid`
|
|
154
|
+
|
|
155
|
+
```html
|
|
156
|
+
<div
|
|
157
|
+
class="tl-popover-menu tl-popover-menu--visible tl-popover-menu--animation-fade"
|
|
158
|
+
>
|
|
159
|
+
<div class="tl-popover-menu__item-wrapper">
|
|
160
|
+
<button class="tl-popover-menu__item">
|
|
161
|
+
<span class="tl-icon tl-icon--edit"></span>
|
|
162
|
+
Edit
|
|
163
|
+
</button>
|
|
164
|
+
<button class="tl-popover-menu__item">
|
|
165
|
+
<span class="tl-icon tl-icon--copy"></span>
|
|
166
|
+
Duplicate
|
|
167
|
+
</button>
|
|
168
|
+
<div class="tl-divider tl-divider--horizontal"></div>
|
|
169
|
+
<button class="tl-popover-menu__item--disabled">
|
|
170
|
+
<span class="tl-icon tl-icon--trash"></span>
|
|
171
|
+
Delete
|
|
172
|
+
</button>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Slider
|
|
180
|
+
|
|
181
|
+
**Classes**: `tl-slider`
|
|
182
|
+
**Sizes**: default, `tl-slider--small`
|
|
183
|
+
|
|
184
|
+
Slider requires JavaScript for thumb positioning. CSS provides the visual styling only.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Icon
|
|
189
|
+
|
|
190
|
+
**Classes**: `tl-icon tl-icon--{name}`
|
|
191
|
+
**Sizes**: `tl-icon--12` through `tl-icon--96` (even numbers only)
|
|
192
|
+
|
|
193
|
+
Common icons:
|
|
194
|
+
|
|
195
|
+
- Navigation: `arrow_left`, `arrow_right`, `arrow_up`, `arrow_down`, `chevron_down`, `chevron_up`, `chevron_left`, `chevron_right`, `back`
|
|
196
|
+
- Actions: `edit`, `trash`, `copy`, `save`, `download`, `upload`, `export`, `search`, `filters`, `settings`, `plus`, `minus`, `cross`, `tick`
|
|
197
|
+
- Status: `error`, `warning`, `info`, `tick`
|
|
198
|
+
- UI: `burger`, `bento`, `kebab`, `meatballs`, `eye`, `eye_inactive`, `lock`, `unlock`
|
|
199
|
+
- Objects: `calendar`, `clock`, `document`, `folder`, `image`, `profile`, `home`, `notification`
|
|
200
|
+
|
|
201
|
+
```html
|
|
202
|
+
<span class="tl-icon tl-icon--search"></span>
|
|
203
|
+
<span class="tl-icon tl-icon--search tl-icon--24"></span>
|
|
204
|
+
<span class="tl-icon tl-icon--error tl-icon--16"></span>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Icons inherit `color` from parent via `currentcolor`.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Header
|
|
212
|
+
|
|
213
|
+
**Classes**: `tl-header`
|
|
214
|
+
|
|
215
|
+
```html
|
|
216
|
+
<header class="tl-header">
|
|
217
|
+
<nav class="tl-header__nav">
|
|
218
|
+
<ul class="tl-header__list">
|
|
219
|
+
<!-- Brand logo -->
|
|
220
|
+
<li class="tl-header__item">
|
|
221
|
+
<a class="tl-header__item-wrapper" href="/">
|
|
222
|
+
<span class="tl-header__brand"></span>
|
|
223
|
+
</a>
|
|
224
|
+
</li>
|
|
225
|
+
|
|
226
|
+
<!-- Title -->
|
|
227
|
+
<li class="tl-header__item">
|
|
228
|
+
<div class="tl-header__title">
|
|
229
|
+
<span class="tl-header__title-text">Application Name</span>
|
|
230
|
+
</div>
|
|
231
|
+
</li>
|
|
232
|
+
|
|
233
|
+
<!-- Nav items -->
|
|
234
|
+
<li class="tl-header__item">
|
|
235
|
+
<a class="tl-header__item-wrapper" href="/dashboard">Dashboard</a>
|
|
236
|
+
</li>
|
|
237
|
+
|
|
238
|
+
<!-- Spacer -->
|
|
239
|
+
<li class="tl-header__middle-spacer"></li>
|
|
240
|
+
|
|
241
|
+
<!-- Dropdown -->
|
|
242
|
+
<li class="tl-header__dropdown">
|
|
243
|
+
<button class="tl-header__dropdown-wrapper" aria-expanded="false">
|
|
244
|
+
<span class="tl-icon tl-icon--profile"></span>
|
|
245
|
+
</button>
|
|
246
|
+
<ul class="tl-header__dropdown-menu">
|
|
247
|
+
<li class="tl-header__dropdown-menu-item">
|
|
248
|
+
<a href="/settings">Settings</a>
|
|
249
|
+
</li>
|
|
250
|
+
<li class="tl-header__dropdown-menu-item">
|
|
251
|
+
<button>Logout</button>
|
|
252
|
+
</li>
|
|
253
|
+
</ul>
|
|
254
|
+
</li>
|
|
255
|
+
</ul>
|
|
256
|
+
</nav>
|
|
257
|
+
</header>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Footer
|
|
263
|
+
|
|
264
|
+
**Classes**: `tl-footer`
|
|
265
|
+
**Variants**: `tl-footer--primary`, `tl-footer--secondary`
|
|
266
|
+
|
|
267
|
+
```html
|
|
268
|
+
<footer class="tl-footer">
|
|
269
|
+
<!-- Top section with link groups -->
|
|
270
|
+
<div class="tl-footer__top">
|
|
271
|
+
<div class="tl-footer__group">
|
|
272
|
+
<button class="tl-footer__top-title">Resources</button>
|
|
273
|
+
<a class="tl-footer__link" href="#">Documentation</a>
|
|
274
|
+
<a class="tl-footer__link" href="#">API Reference</a>
|
|
275
|
+
</div>
|
|
276
|
+
<div class="tl-footer__group">
|
|
277
|
+
<button class="tl-footer__top-title">Support</button>
|
|
278
|
+
<a class="tl-footer__link" href="#">Contact</a>
|
|
279
|
+
<a class="tl-footer__link" href="#">FAQ</a>
|
|
280
|
+
</div>
|
|
281
|
+
</div>
|
|
282
|
+
|
|
283
|
+
<!-- Main section with brand -->
|
|
284
|
+
<div class="tl-footer__main">
|
|
285
|
+
<div class="tl-footer__main-top">
|
|
286
|
+
<div class="tl-footer__main-top--start">
|
|
287
|
+
<div class="tl-footer__group">
|
|
288
|
+
<a class="tl-footer__link" href="#">Privacy Policy</a>
|
|
289
|
+
<a class="tl-footer__link" href="#">Cookie Policy</a>
|
|
290
|
+
</div>
|
|
291
|
+
</div>
|
|
292
|
+
</div>
|
|
293
|
+
<div class="tl-footer__main-bottom">
|
|
294
|
+
<p class="tl-footer__copyright">© 2025 Scania CV AB</p>
|
|
295
|
+
<span class="tl-footer__brand">Scania</span>
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
</footer>
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Side Menu
|
|
304
|
+
|
|
305
|
+
**Classes**: `tl-side-menu`
|
|
306
|
+
**Modifiers**: `tl-side-menu--persistent`, `tl-side-menu--collapsed`
|
|
307
|
+
|
|
308
|
+
```html
|
|
309
|
+
<nav class="tl-side-menu tl-side-menu--persistent" aria-label="Side navigation">
|
|
310
|
+
<div class="tl-side-menu__wrapper tl-side-menu__wrapper--open">
|
|
311
|
+
<div class="tl-side-menu__overlay"></div>
|
|
312
|
+
<aside class="tl-side-menu__aside">
|
|
313
|
+
<div class="tl-side-menu__navigation">
|
|
314
|
+
<div class="tl-side-menu__list-wrapper">
|
|
315
|
+
<ul class="tl-side-menu__upper-list">
|
|
316
|
+
<li>
|
|
317
|
+
<a
|
|
318
|
+
class="tl-side-menu__item tl-side-menu__item--selected"
|
|
319
|
+
href="/dashboard"
|
|
320
|
+
>
|
|
321
|
+
<span class="tl-icon tl-icon--dashboard"></span>
|
|
322
|
+
Dashboard
|
|
323
|
+
</a>
|
|
324
|
+
</li>
|
|
325
|
+
<li>
|
|
326
|
+
<!-- Dropdown -->
|
|
327
|
+
<div class="tl-side-menu__dropdown">
|
|
328
|
+
<button class="tl-side-menu__item">
|
|
329
|
+
<span class="tl-icon tl-icon--settings"></span>
|
|
330
|
+
Settings
|
|
331
|
+
</button>
|
|
332
|
+
<div class="tl-side-menu__dropdown-menu">
|
|
333
|
+
<ul class="tl-side-menu__dropdown-list">
|
|
334
|
+
<li>
|
|
335
|
+
<a
|
|
336
|
+
class="tl-side-menu__dropdown-item"
|
|
337
|
+
href="/settings/general"
|
|
338
|
+
>General</a
|
|
339
|
+
>
|
|
340
|
+
</li>
|
|
341
|
+
<li>
|
|
342
|
+
<a
|
|
343
|
+
class="tl-side-menu__dropdown-item"
|
|
344
|
+
href="/settings/account"
|
|
345
|
+
>Account</a
|
|
346
|
+
>
|
|
347
|
+
</li>
|
|
348
|
+
</ul>
|
|
349
|
+
</div>
|
|
350
|
+
</div>
|
|
351
|
+
</li>
|
|
352
|
+
</ul>
|
|
353
|
+
</div>
|
|
354
|
+
</div>
|
|
355
|
+
</aside>
|
|
356
|
+
</div>
|
|
357
|
+
</nav>
|
|
358
|
+
```
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Spacing, color usage, responsiveness, accessibility, and code conventions
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Guidelines
|
|
7
|
+
|
|
8
|
+
## Spacing & Sizing Rules
|
|
9
|
+
|
|
10
|
+
### Spacing Custom Properties (available globally)
|
|
11
|
+
|
|
12
|
+
These are used by components internally and can be used for custom layouts:
|
|
13
|
+
|
|
14
|
+
- `--tds-spacing-element-4` (4px)
|
|
15
|
+
- `--tds-spacing-element-8` (8px)
|
|
16
|
+
- `--tds-spacing-element-12` (12px)
|
|
17
|
+
- `--tds-spacing-element-16` (16px)
|
|
18
|
+
- `--tds-spacing-element-20` (20px)
|
|
19
|
+
- `--tds-spacing-element-24` (24px)
|
|
20
|
+
- `--tds-spacing-element-32` (32px)
|
|
21
|
+
- `--tds-spacing-element-48` (48px)
|
|
22
|
+
- `--tds-spacing-layout-64` (64px)
|
|
23
|
+
|
|
24
|
+
### Rules
|
|
25
|
+
|
|
26
|
+
1. Use `var(--dimension-space-small)` (16px) as the base gap between elements.
|
|
27
|
+
2. Use `var(--dimension-space-medium)` (24px) for section padding.
|
|
28
|
+
3. Use `var(--dimension-space-large)` (48px) for major section separators.
|
|
29
|
+
4. Component height follows the sizing convention: sm=40px, md=48px, lg=56px.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Color Usage
|
|
34
|
+
|
|
35
|
+
### Semantic Color Usage
|
|
36
|
+
|
|
37
|
+
| Purpose | Token to Use |
|
|
38
|
+
| ------------------------- | --------------------------------------------- |
|
|
39
|
+
| Page background | `var(--color-background-base)` |
|
|
40
|
+
| Card/section background | `var(--color-background-layer-01)` |
|
|
41
|
+
| Nested section background | `var(--color-background-layer-02)` |
|
|
42
|
+
| Primary heading text | `var(--color-foreground-text-strong)` |
|
|
43
|
+
| Secondary text | `var(--color-foreground-text-defined)` |
|
|
44
|
+
| Subtle/hint text | `var(--color-foreground-text-subtle)` |
|
|
45
|
+
| Link text | `var(--color-foreground-text-accent-default)` |
|
|
46
|
+
| Disabled text | `var(--color-foreground-text-disabled)` |
|
|
47
|
+
| Default border | `var(--color-foreground-border-soft)` |
|
|
48
|
+
| Focus outline | `var(--color-foreground-border-accent-focus)` |
|
|
49
|
+
| Success state | `var(--color-system-success-default)` |
|
|
50
|
+
| Warning state | `var(--color-system-warning-default)` |
|
|
51
|
+
| Error/danger state | `var(--color-system-danger-default)` |
|
|
52
|
+
| Info state | `var(--color-system-info-default)` |
|
|
53
|
+
|
|
54
|
+
### RULE: Never hardcode colors. Always use CSS custom properties.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Responsiveness
|
|
59
|
+
|
|
60
|
+
### Breakpoints
|
|
61
|
+
|
|
62
|
+
| Name | Width | CSS |
|
|
63
|
+
| ------- | -------- | ---------------------------- |
|
|
64
|
+
| Mobile | < 672px | `@media (max-width: 671px)` |
|
|
65
|
+
| Tablet | ≥ 672px | `@media (min-width: 672px)` |
|
|
66
|
+
| Desktop | ≥ 992px | `@media (min-width: 992px)` |
|
|
67
|
+
| Wide | ≥ 1056px | `@media (min-width: 1056px)` |
|
|
68
|
+
| X-Wide | ≥ 1312px | `@media (min-width: 1312px)` |
|
|
69
|
+
| XX-Wide | ≥ 1584px | `@media (min-width: 1584px)` |
|
|
70
|
+
|
|
71
|
+
### Rules
|
|
72
|
+
|
|
73
|
+
1. **Mobile-first**: Write base styles for mobile, add media queries for larger screens.
|
|
74
|
+
2. Header nav items hide below 992px (burger menu shows).
|
|
75
|
+
3. Side menu collapses to overlay below 992px.
|
|
76
|
+
4. Footer top section stacks vertically below 992px.
|
|
77
|
+
5. Modal widths are responsive (100% on mobile, percentage-based on desktop).
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Accessibility (a11y)
|
|
82
|
+
|
|
83
|
+
### Required ARIA Attributes
|
|
84
|
+
|
|
85
|
+
| Component | Required ARIA |
|
|
86
|
+
| ------------- | ----------------------------------------------------------------------------- |
|
|
87
|
+
| Button | `aria-label` for icon-only buttons |
|
|
88
|
+
| Modal | `role="dialog"`, `aria-modal="true"`, `aria-labelledby` |
|
|
89
|
+
| Accordion | `aria-expanded="true/false"` on trigger |
|
|
90
|
+
| Tabs | `role="tablist"`, `role="tab"`, `aria-selected` |
|
|
91
|
+
| Dropdown | `aria-expanded`, `aria-haspopup="listbox"`, `role="listbox"`, `role="option"` |
|
|
92
|
+
| Breadcrumbs | `aria-label="Breadcrumb"`, `aria-current="page"` on last item |
|
|
93
|
+
| Toast/Banner | `role="alert"` |
|
|
94
|
+
| Tooltip | `role="tooltip"`, `aria-describedby` on trigger |
|
|
95
|
+
| Spinner | `aria-label="Loading"`, `role="img"` |
|
|
96
|
+
| Close buttons | `aria-label="Close"` or `aria-label="Dismiss"` |
|
|
97
|
+
| Navigation | `aria-label` on `<nav>` elements |
|
|
98
|
+
|
|
99
|
+
### Focus Management
|
|
100
|
+
|
|
101
|
+
- All interactive elements have `:focus-visible` styles (2px solid blue-400 outline).
|
|
102
|
+
- Focus outline uses `var(--color-foreground-border-accent-focus)`.
|
|
103
|
+
- Modals should trap focus.
|
|
104
|
+
- Side menu overlay closes on Escape.
|
|
105
|
+
|
|
106
|
+
### Contrast
|
|
107
|
+
|
|
108
|
+
- Use semantic tokens (they meet WCAG 2.1 AA contrast requirements).
|
|
109
|
+
- Never override text colors with lighter alternatives.
|
|
110
|
+
- `--color-foreground-text-strong` on `--color-background-base` = ≥4.5:1 ratio.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Code Conventions
|
|
115
|
+
|
|
116
|
+
### BEM Naming Pattern
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
.tl-{block} → Component root
|
|
120
|
+
.tl-{block}__{element} → Sub-part of component
|
|
121
|
+
.tl-{block}--{modifier} → Variant/state
|
|
122
|
+
.tl-{block}__{element}--{mod} → Element variant
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Class Order in HTML
|
|
126
|
+
|
|
127
|
+
1. Base class first: `tl-button`
|
|
128
|
+
2. Variant modifier: `tl-button--primary`
|
|
129
|
+
3. Size modifier: `tl-button--md`
|
|
130
|
+
4. State modifier: `tl-button--full-width`
|
|
131
|
+
|
|
132
|
+
Example: `class="tl-button tl-button--primary tl-button--md tl-button--full-width"`
|
|
133
|
+
|
|
134
|
+
### Rules
|
|
135
|
+
|
|
136
|
+
1. **NEVER write custom CSS** if a Tegel Lite class already exists for the purpose.
|
|
137
|
+
2. **NEVER use inline styles for colors, spacing, or any design properties.** ALWAYS use CSS classes with Tegel tokens.
|
|
138
|
+
- ❌ BAD: `<span style="background-color: var(--color-system-success-discrete);">Active</span>`
|
|
139
|
+
- ✅ GOOD: Create a CSS class `.status-badge--success { background-color: var(--color-system-success-discrete); }`
|
|
140
|
+
3. **NEVER add inline styles to Tegel components.** If a component doesn't have the variant you need, create a custom component.
|
|
141
|
+
4. **ALWAYS use semantic HTML** (`<button>`, `<a>`, `<nav>`, `<header>`, etc.).
|
|
142
|
+
5. **ALWAYS wrap the app** in `<body class="scania tds-mode-light">`.
|
|
143
|
+
6. When building custom components, use Tegel tokens for all colors, spacing, and typography.
|
|
144
|
+
7. Keep custom CSS in separate files, never modify the Tegel Lite CSS files.
|