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