@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.
- 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 +229 -3
- package/dist/global.css +7 -3
- package/dist/tl-card.css +6 -3
- package/package.json +14 -3
package/README.dev.md
CHANGED
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npm install @scania/tegel-lite
|
|
13
|
+
npm install @scania/tegel-lite@0.0.1-beta.10
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
## Quick Start
|
|
@@ -87,6 +87,35 @@ dist/
|
|
|
87
87
|
|
|
88
88
|
All components use the `tl-` prefix.
|
|
89
89
|
|
|
90
|
+
## AI Coding Rules
|
|
91
|
+
|
|
92
|
+
This package ships with AI-aware coding rules that help AI assistants (Cursor, Claude Code, GitHub Copilot, OpenAI Codex) write correct tegel-lite markup.
|
|
93
|
+
|
|
94
|
+
After installing the package, run:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npx tegel-lite-setup-rules
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
An interactive CLI will let you choose which AI tools to configure:
|
|
101
|
+
|
|
102
|
+
| AI Tool | Files installed |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| **Cursor** | `.cursor/rules/tegel-lite/*.mdc` |
|
|
105
|
+
| **Claude Code** | `CLAUDE.md` at project root |
|
|
106
|
+
| **GitHub Copilot** | `.github/copilot-instructions.md` |
|
|
107
|
+
| **OpenAI Codex** | `AGENTS.md` at project root |
|
|
108
|
+
|
|
109
|
+
All options are selected by default. Use arrow keys to navigate, space to toggle, and enter to confirm.
|
|
110
|
+
|
|
111
|
+
To skip the interactive prompt and install all formats at once:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npx tegel-lite-setup-rules --all
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Re-running the command will update existing rules in place (using section markers) without duplicating content.
|
|
118
|
+
|
|
90
119
|
## Documentation
|
|
91
120
|
|
|
92
121
|
Full documentation: **[tegel.scania.com](https://tegel.scania.com)**
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* setup-ai-rules.js
|
|
5
|
+
*
|
|
6
|
+
* Interactive CLI to copy @scania/tegel-lite AI coding rules into a user's project.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* npx tegel-lite-setup-rules # Interactive mode
|
|
10
|
+
* npx tegel-lite-setup-rules --all # Copy all rule formats (skip prompts)
|
|
11
|
+
*
|
|
12
|
+
* Plain Node.js — no external dependencies. Uses built-in readline.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import fs from 'fs';
|
|
16
|
+
import path from 'path';
|
|
17
|
+
import readline from 'readline';
|
|
18
|
+
import { fileURLToPath } from 'url';
|
|
19
|
+
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = path.dirname(__filename);
|
|
22
|
+
const packageRoot = path.resolve(__dirname, '..');
|
|
23
|
+
|
|
24
|
+
// Where files will be copied to
|
|
25
|
+
const projectRoot = process.cwd();
|
|
26
|
+
|
|
27
|
+
// Markers for idempotent updates in aggregated files
|
|
28
|
+
const MARKER_START = '<!-- START @scania/tegel-lite rules -->';
|
|
29
|
+
const MARKER_END = '<!-- END @scania/tegel-lite rules -->';
|
|
30
|
+
|
|
31
|
+
// ── Tool definitions ──────────────────────────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
const TOOLS = [
|
|
34
|
+
{
|
|
35
|
+
id: 'cursor',
|
|
36
|
+
label: 'Cursor',
|
|
37
|
+
description: '.cursor/rules/tegel-lite/*.mdc',
|
|
38
|
+
sourceDir: path.join(packageRoot, '.cursor', 'rules', 'tegel-lite'),
|
|
39
|
+
targetDir: path.join(projectRoot, '.cursor', 'rules', 'tegel-lite'),
|
|
40
|
+
mode: 'directory',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'claude',
|
|
44
|
+
label: 'Claude Code',
|
|
45
|
+
description: 'CLAUDE.md at project root',
|
|
46
|
+
sourceFile: path.join(packageRoot, 'CLAUDE.md'),
|
|
47
|
+
targetFile: path.join(projectRoot, 'CLAUDE.md'),
|
|
48
|
+
mode: 'aggregated',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'copilot',
|
|
52
|
+
label: 'GitHub Copilot',
|
|
53
|
+
description: '.github/copilot-instructions.md',
|
|
54
|
+
sourceFile: path.join(packageRoot, '.github', 'copilot-instructions.md'),
|
|
55
|
+
targetFile: path.join(projectRoot, '.github', 'copilot-instructions.md'),
|
|
56
|
+
mode: 'aggregated',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 'codex',
|
|
60
|
+
label: 'OpenAI Codex',
|
|
61
|
+
description: 'AGENTS.md at project root',
|
|
62
|
+
sourceFile: path.join(packageRoot, 'AGENTS.md'),
|
|
63
|
+
targetFile: path.join(projectRoot, 'AGENTS.md'),
|
|
64
|
+
mode: 'aggregated',
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Wrap content in section markers for idempotent updates.
|
|
72
|
+
*/
|
|
73
|
+
function wrapWithMarkers(content) {
|
|
74
|
+
return `${MARKER_START}\n${content.trim()}\n${MARKER_END}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Replace the marked section in existing file content, or append if not found.
|
|
79
|
+
*/
|
|
80
|
+
function upsertMarkedSection(existingContent, newSection) {
|
|
81
|
+
const pattern = `${escapeRegex(MARKER_START)}[\\s\\S]*?${escapeRegex(MARKER_END)}`;
|
|
82
|
+
const markerRegex = new RegExp(pattern);
|
|
83
|
+
|
|
84
|
+
if (markerRegex.test(existingContent)) {
|
|
85
|
+
// Replace existing section
|
|
86
|
+
return existingContent.replace(new RegExp(pattern), newSection);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Append with spacing
|
|
90
|
+
const separator = existingContent.trim().length > 0 ? '\n\n' : '';
|
|
91
|
+
return existingContent.trimEnd() + separator + newSection + '\n';
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function escapeRegex(str) {
|
|
95
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Ask a yes/no question via readline.
|
|
100
|
+
*/
|
|
101
|
+
function askYesNo(rl, question) {
|
|
102
|
+
return new Promise((resolve) => {
|
|
103
|
+
rl.question(`${question} (y/N): `, (answer) => {
|
|
104
|
+
resolve(answer.trim().toLowerCase() === 'y');
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ── Checkbox UI ───────────────────────────────────────────────────────────────
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Display an interactive checkbox list in the terminal.
|
|
113
|
+
* Arrow keys navigate, space toggles, enter confirms.
|
|
114
|
+
*/
|
|
115
|
+
function showCheckboxList(items) {
|
|
116
|
+
return new Promise((resolve) => {
|
|
117
|
+
const selected = items.map(() => true); // All selected by default
|
|
118
|
+
let cursor = 0;
|
|
119
|
+
|
|
120
|
+
const { stdin, stdout } = process;
|
|
121
|
+
|
|
122
|
+
// Check if we can use raw mode (not available in all environments)
|
|
123
|
+
if (!stdin.isTTY) {
|
|
124
|
+
console.log('Non-interactive terminal detected. Selecting all tools.');
|
|
125
|
+
resolve(items.map((_, i) => i));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function render() {
|
|
130
|
+
// Move cursor up to overwrite previous render (except first time)
|
|
131
|
+
stdout.write('\x1B[?25l'); // Hide cursor
|
|
132
|
+
|
|
133
|
+
const lines = items.map((item, i) => {
|
|
134
|
+
const checkbox = selected[i] ? '\x1B[32m◉\x1B[0m' : '○';
|
|
135
|
+
const pointer = i === cursor ? '\x1B[36m❯\x1B[0m ' : ' ';
|
|
136
|
+
const desc = `\x1B[2m${item.description}\x1B[0m`;
|
|
137
|
+
return `${pointer}${checkbox} ${item.label} ${desc}`;
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
lines.push('');
|
|
141
|
+
lines.push('\x1B[2m↑↓ navigate · space toggle · enter confirm\x1B[0m');
|
|
142
|
+
|
|
143
|
+
return lines.join('\n');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Initial render
|
|
147
|
+
const output = render();
|
|
148
|
+
stdout.write(output);
|
|
149
|
+
|
|
150
|
+
stdin.setRawMode(true);
|
|
151
|
+
stdin.resume();
|
|
152
|
+
stdin.setEncoding('utf-8');
|
|
153
|
+
|
|
154
|
+
function onKeypress(key) {
|
|
155
|
+
// Ctrl+C
|
|
156
|
+
if (key === '\x03') {
|
|
157
|
+
stdin.setRawMode(false);
|
|
158
|
+
stdin.removeListener('data', onKeypress);
|
|
159
|
+
stdout.write('\x1B[?25h\n'); // Show cursor
|
|
160
|
+
process.exit(0);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Enter
|
|
164
|
+
if (key === '\r' || key === '\n') {
|
|
165
|
+
stdin.setRawMode(false);
|
|
166
|
+
stdin.removeListener('data', onKeypress);
|
|
167
|
+
stdout.write('\x1B[?25h\n'); // Show cursor
|
|
168
|
+
resolve(selected.reduce((acc, sel, i) => (sel ? [...acc, i] : acc), []));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Space — toggle
|
|
173
|
+
if (key === ' ') {
|
|
174
|
+
selected[cursor] = !selected[cursor];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Arrow up or k
|
|
178
|
+
if (key === '\x1B[A' || key === 'k') {
|
|
179
|
+
cursor = (cursor - 1 + items.length) % items.length;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Arrow down or j
|
|
183
|
+
if (key === '\x1B[B' || key === 'j') {
|
|
184
|
+
cursor = (cursor + 1) % items.length;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Re-render: move up to overwrite
|
|
188
|
+
const lineCount = items.length + 2;
|
|
189
|
+
stdout.write(`\x1B[${lineCount}A\x1B[0J`);
|
|
190
|
+
stdout.write(render());
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
stdin.on('data', onKeypress);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ── Copy logic ────────────────────────────────────────────────────────────────
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Copy a directory of files (e.g. .cursor/rules/tegel-lite/*.mdc).
|
|
201
|
+
*/
|
|
202
|
+
function copyDirectoryTool(tool, rl, skipPrompt) {
|
|
203
|
+
return copyDirectoryToolAsync(tool, rl, skipPrompt);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async function copyDirectoryToolAsync(tool, rl, skipPrompt) {
|
|
207
|
+
if (!fs.existsSync(tool.sourceDir)) {
|
|
208
|
+
console.log(` ⚠ Source not found: ${path.relative(packageRoot, tool.sourceDir)}`);
|
|
209
|
+
console.log(' Run "npm run generate:ai-rules" in the package first.');
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const files = fs.readdirSync(tool.sourceDir).filter((f) => f.endsWith('.mdc'));
|
|
214
|
+
|
|
215
|
+
if (files.length === 0) {
|
|
216
|
+
console.log(' ⚠ No .mdc files found in source directory.');
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Check if target directory already exists
|
|
221
|
+
if (fs.existsSync(tool.targetDir) && !skipPrompt) {
|
|
222
|
+
const overwrite = await askYesNo(
|
|
223
|
+
rl,
|
|
224
|
+
` Target exists: ${path.relative(projectRoot, tool.targetDir)}. Overwrite?`,
|
|
225
|
+
);
|
|
226
|
+
if (!overwrite) {
|
|
227
|
+
console.log(' Skipped.');
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
fs.mkdirSync(tool.targetDir, { recursive: true });
|
|
233
|
+
|
|
234
|
+
for (const file of files) {
|
|
235
|
+
const src = path.join(tool.sourceDir, file);
|
|
236
|
+
const dest = path.join(tool.targetDir, file);
|
|
237
|
+
fs.copyFileSync(src, dest);
|
|
238
|
+
console.log(` Copied: ${path.relative(projectRoot, dest)}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Copy an aggregated file (CLAUDE.md, AGENTS.md, copilot-instructions.md).
|
|
244
|
+
* Uses markers for idempotent upsert.
|
|
245
|
+
*/
|
|
246
|
+
async function copyAggregatedTool(tool, rl, skipPrompt) {
|
|
247
|
+
if (!fs.existsSync(tool.sourceFile)) {
|
|
248
|
+
console.log(` ⚠ Source not found: ${path.relative(packageRoot, tool.sourceFile)}`);
|
|
249
|
+
console.log(' Run "npm run generate:ai-rules" in the package first.');
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const sourceContent = fs.readFileSync(tool.sourceFile, 'utf-8');
|
|
254
|
+
const wrappedContent = wrapWithMarkers(sourceContent);
|
|
255
|
+
const targetRelative = path.relative(projectRoot, tool.targetFile);
|
|
256
|
+
|
|
257
|
+
if (fs.existsSync(tool.targetFile)) {
|
|
258
|
+
const existingContent = fs.readFileSync(tool.targetFile, 'utf-8');
|
|
259
|
+
|
|
260
|
+
// Check if markers already exist
|
|
261
|
+
if (existingContent.includes(MARKER_START)) {
|
|
262
|
+
// Update in place
|
|
263
|
+
const updatedContent = upsertMarkedSection(existingContent, wrappedContent);
|
|
264
|
+
fs.writeFileSync(tool.targetFile, updatedContent, 'utf-8');
|
|
265
|
+
console.log(` Updated: ${targetRelative} (replaced existing tegel-lite section)`);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// File exists but no markers — ask to append
|
|
270
|
+
if (!skipPrompt) {
|
|
271
|
+
const append = await askYesNo(
|
|
272
|
+
rl,
|
|
273
|
+
` File exists: ${targetRelative}. Append tegel-lite rules?`,
|
|
274
|
+
);
|
|
275
|
+
if (!append) {
|
|
276
|
+
console.log(' Skipped.');
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const updatedContent = upsertMarkedSection(existingContent, wrappedContent);
|
|
282
|
+
fs.writeFileSync(tool.targetFile, updatedContent, 'utf-8');
|
|
283
|
+
console.log(` Updated: ${targetRelative} (appended tegel-lite section)`);
|
|
284
|
+
} else {
|
|
285
|
+
// Create new file
|
|
286
|
+
const dir = path.dirname(tool.targetFile);
|
|
287
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
288
|
+
fs.writeFileSync(tool.targetFile, wrappedContent + '\n', 'utf-8');
|
|
289
|
+
console.log(` Created: ${targetRelative}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// ── Main ──────────────────────────────────────────────────────────────────────
|
|
294
|
+
|
|
295
|
+
async function main() {
|
|
296
|
+
const args = process.argv.slice(2);
|
|
297
|
+
const skipPrompt = args.includes('--all');
|
|
298
|
+
|
|
299
|
+
console.log('');
|
|
300
|
+
console.log('\x1B[1m@scania/tegel-lite — AI Coding Rules Setup\x1B[0m');
|
|
301
|
+
console.log('');
|
|
302
|
+
|
|
303
|
+
let selectedIndices;
|
|
304
|
+
|
|
305
|
+
if (skipPrompt) {
|
|
306
|
+
console.log('Installing all rule formats (--all flag).\n');
|
|
307
|
+
selectedIndices = TOOLS.map((_, i) => i);
|
|
308
|
+
} else {
|
|
309
|
+
console.log('Select which AI tools to configure:\n');
|
|
310
|
+
selectedIndices = await showCheckboxList(TOOLS);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (selectedIndices.length === 0) {
|
|
314
|
+
console.log('No tools selected. Exiting.');
|
|
315
|
+
process.exit(0);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const selectedTools = selectedIndices.map((i) => TOOLS[i]);
|
|
319
|
+
|
|
320
|
+
console.log(`\nInstalling rules for: ${selectedTools.map((t) => t.label).join(', ')}\n`);
|
|
321
|
+
|
|
322
|
+
// Create a readline interface for yes/no prompts
|
|
323
|
+
const rl = readline.createInterface({
|
|
324
|
+
input: process.stdin,
|
|
325
|
+
output: process.stdout,
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
for (const tool of selectedTools) {
|
|
329
|
+
console.log(`\n${tool.label}:`);
|
|
330
|
+
|
|
331
|
+
if (tool.mode === 'directory') {
|
|
332
|
+
await copyDirectoryTool(tool, rl, skipPrompt);
|
|
333
|
+
} else {
|
|
334
|
+
await copyAggregatedTool(tool, rl, skipPrompt);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
rl.close();
|
|
339
|
+
|
|
340
|
+
console.log('\n\x1B[32m✓ Done!\x1B[0m AI coding rules installed successfully.');
|
|
341
|
+
console.log('\nRe-run this command anytime to update rules to the latest version.\n');
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
main().catch((err) => {
|
|
345
|
+
console.error('Error:', err.message);
|
|
346
|
+
process.exit(1);
|
|
347
|
+
});
|
package/dist/components.css
CHANGED
|
@@ -941,11 +941,11 @@
|
|
|
941
941
|
}
|
|
942
942
|
.traton .tl-card--primary {
|
|
943
943
|
--card-box: none;
|
|
944
|
-
--card-background:
|
|
944
|
+
--card-background: transparent;
|
|
945
945
|
}
|
|
946
946
|
.traton .tl-card--secondary {
|
|
947
947
|
--card-box: none;
|
|
948
|
-
--card-background:
|
|
948
|
+
--card-background: transparent;
|
|
949
949
|
}
|
|
950
950
|
|
|
951
951
|
/* Dark mode */
|
|
@@ -966,7 +966,10 @@
|
|
|
966
966
|
}
|
|
967
967
|
|
|
968
968
|
.traton .tds-mode-dark .tl-card--primary {
|
|
969
|
-
--card-background:
|
|
969
|
+
--card-background: transparent;
|
|
970
|
+
}
|
|
971
|
+
.traton .tds-mode-dark .tl-card--secondary {
|
|
972
|
+
--card-background: transparent;
|
|
970
973
|
}
|
|
971
974
|
|
|
972
975
|
.tl-card {
|
|
@@ -8318,6 +8321,69 @@ body {
|
|
|
8318
8321
|
fill: var(--folder-tabs-scroll-button-text);
|
|
8319
8322
|
}
|
|
8320
8323
|
|
|
8324
|
+
/* tl-folder-tabs.scss (overlay buttons, no JS) */
|
|
8325
|
+
.tl-folder-tabs__tab {
|
|
8326
|
+
all: unset;
|
|
8327
|
+
font-family: var(--headline-07-font-family);
|
|
8328
|
+
font-size: var(--headline-07-font-size);
|
|
8329
|
+
line-height: var(--headline-07-line-height);
|
|
8330
|
+
font-weight: var(--headline-07-font-weight);
|
|
8331
|
+
letter-spacing: var(--headline-07-letter-spacing);
|
|
8332
|
+
text-transform: var(--headline-07-text-transform);
|
|
8333
|
+
box-sizing: border-box;
|
|
8334
|
+
position: relative;
|
|
8335
|
+
display: inline-flex;
|
|
8336
|
+
align-items: center;
|
|
8337
|
+
min-inline-size: 142px;
|
|
8338
|
+
inline-size: auto;
|
|
8339
|
+
flex: 0 0 auto;
|
|
8340
|
+
white-space: nowrap;
|
|
8341
|
+
padding: 16px;
|
|
8342
|
+
text-align: left;
|
|
8343
|
+
cursor: pointer;
|
|
8344
|
+
border-left: 1px solid transparent;
|
|
8345
|
+
border-top: 2px solid var(--folder-tab-surface);
|
|
8346
|
+
background-color: var(--folder-tab-surface);
|
|
8347
|
+
color: var(--folder-tab-text);
|
|
8348
|
+
}
|
|
8349
|
+
.tl-folder-tabs__tab + .tl-folder-tabs__tab {
|
|
8350
|
+
border-left-color: var(--folder-tab-divider);
|
|
8351
|
+
}
|
|
8352
|
+
.tl-folder-tabs__tab:focus-visible {
|
|
8353
|
+
outline: 2px solid currentcolor;
|
|
8354
|
+
outline-offset: -4px;
|
|
8355
|
+
box-shadow: none;
|
|
8356
|
+
}
|
|
8357
|
+
.tl-folder-tabs__tab:hover:not(.tl-folder-tabs__tab--disabled):not(.tl-folder-tabs__tab--selected) {
|
|
8358
|
+
background-color: var(--folder-tab-surface-hover);
|
|
8359
|
+
border-top-color: var(--folder-tab-surface-hover);
|
|
8360
|
+
color: var(--folder-tab-text);
|
|
8361
|
+
}
|
|
8362
|
+
.tl-folder-tabs__tab--selected {
|
|
8363
|
+
background-color: var(--folder-tab-surface-selected);
|
|
8364
|
+
border-top-color: var(--folder-tab-border-selected);
|
|
8365
|
+
color: var(--folder-tab-text);
|
|
8366
|
+
}
|
|
8367
|
+
.tl-folder-tabs__tab--selected::after {
|
|
8368
|
+
content: "";
|
|
8369
|
+
position: absolute;
|
|
8370
|
+
top: 0;
|
|
8371
|
+
right: -1px;
|
|
8372
|
+
bottom: 0;
|
|
8373
|
+
width: 1px;
|
|
8374
|
+
background-color: var(--folder-tab-surface-selected);
|
|
8375
|
+
z-index: 1;
|
|
8376
|
+
}
|
|
8377
|
+
.tl-folder-tabs__tab--disabled {
|
|
8378
|
+
color: var(--folder-tab-text-disabled);
|
|
8379
|
+
cursor: not-allowed;
|
|
8380
|
+
user-select: none;
|
|
8381
|
+
}
|
|
8382
|
+
.tl-folder-tabs__tab--disabled:focus-visible {
|
|
8383
|
+
outline: none;
|
|
8384
|
+
box-shadow: none;
|
|
8385
|
+
}
|
|
8386
|
+
|
|
8321
8387
|
.tl-inline-tabs {
|
|
8322
8388
|
/* Horizontal divider */
|
|
8323
8389
|
--inline-tabs-horizontal-divider: var(--color-foreground-icon-discrete);
|
|
@@ -8411,6 +8477,86 @@ body {
|
|
|
8411
8477
|
fill: var(--inline-tabs-scroll-button-text);
|
|
8412
8478
|
}
|
|
8413
8479
|
|
|
8480
|
+
.tl-inline-tabs__tab {
|
|
8481
|
+
all: unset;
|
|
8482
|
+
margin-right: 32px;
|
|
8483
|
+
box-sizing: border-box;
|
|
8484
|
+
}
|
|
8485
|
+
.tl-inline-tabs__tab * {
|
|
8486
|
+
box-sizing: border-box;
|
|
8487
|
+
}
|
|
8488
|
+
.tl-inline-tabs__tab {
|
|
8489
|
+
font-family: var(--headline-07-font-family);
|
|
8490
|
+
font-size: var(--headline-07-font-size);
|
|
8491
|
+
line-height: var(--headline-07-line-height);
|
|
8492
|
+
font-weight: var(--headline-07-font-weight);
|
|
8493
|
+
letter-spacing: var(--headline-07-letter-spacing);
|
|
8494
|
+
text-transform: var(--headline-07-text-transform);
|
|
8495
|
+
color: var(--inline-tabs-tab);
|
|
8496
|
+
text-decoration: none;
|
|
8497
|
+
display: block;
|
|
8498
|
+
position: relative;
|
|
8499
|
+
transition: color 0.15s ease-in-out 0s;
|
|
8500
|
+
white-space: nowrap;
|
|
8501
|
+
background-color: transparent;
|
|
8502
|
+
border: 0;
|
|
8503
|
+
padding: 20px 4px;
|
|
8504
|
+
}
|
|
8505
|
+
.tl-inline-tabs__tab:focus-visible {
|
|
8506
|
+
outline: none;
|
|
8507
|
+
}
|
|
8508
|
+
.tl-inline-tabs__tab:focus-visible::before {
|
|
8509
|
+
content: "";
|
|
8510
|
+
position: absolute;
|
|
8511
|
+
inset: 18px 0;
|
|
8512
|
+
border-radius: 2px;
|
|
8513
|
+
box-shadow: 0 0 0 2px var(--inline-tabs-tab-focus) inset;
|
|
8514
|
+
z-index: 2;
|
|
8515
|
+
pointer-events: none;
|
|
8516
|
+
}
|
|
8517
|
+
.tl-inline-tabs__tab::after {
|
|
8518
|
+
background-color: var(--inline-tabs-tab-indicator-hover);
|
|
8519
|
+
content: " ";
|
|
8520
|
+
position: absolute;
|
|
8521
|
+
bottom: 0;
|
|
8522
|
+
right: 0;
|
|
8523
|
+
left: 0;
|
|
8524
|
+
margin-left: auto;
|
|
8525
|
+
width: 0%;
|
|
8526
|
+
margin-right: auto;
|
|
8527
|
+
height: 2px;
|
|
8528
|
+
z-index: 1;
|
|
8529
|
+
transition: width 0.15s ease-in-out 0s;
|
|
8530
|
+
}
|
|
8531
|
+
.tl-inline-tabs__tab:not(.tl-inline-tabs__tab--selected)::after {
|
|
8532
|
+
width: 0%;
|
|
8533
|
+
}
|
|
8534
|
+
.tl-inline-tabs__tab:hover {
|
|
8535
|
+
cursor: pointer;
|
|
8536
|
+
color: var(--inline-tabs-tab-hover);
|
|
8537
|
+
}
|
|
8538
|
+
.tl-inline-tabs__tab:hover::after {
|
|
8539
|
+
width: 100%;
|
|
8540
|
+
}
|
|
8541
|
+
.tl-inline-tabs__tab--selected {
|
|
8542
|
+
color: var(--inline-tabs-tab-selected);
|
|
8543
|
+
}
|
|
8544
|
+
.tl-inline-tabs__tab--selected::after {
|
|
8545
|
+
background-color: var(--inline-tabs-tab-indicator-active);
|
|
8546
|
+
width: 100%;
|
|
8547
|
+
}
|
|
8548
|
+
.tl-inline-tabs__tab--disabled {
|
|
8549
|
+
color: var(--inline-tabs-tab-disabled);
|
|
8550
|
+
pointer-events: none;
|
|
8551
|
+
cursor: not-allowed;
|
|
8552
|
+
}
|
|
8553
|
+
.tl-inline-tabs__tab--disabled::after {
|
|
8554
|
+
content: none;
|
|
8555
|
+
}
|
|
8556
|
+
.tl-inline-tabs__tab--disabled:focus-visible::before {
|
|
8557
|
+
box-shadow: none;
|
|
8558
|
+
}
|
|
8559
|
+
|
|
8414
8560
|
.tl-navigation-tabs__tab {
|
|
8415
8561
|
/* tds-navigation-tab variables */
|
|
8416
8562
|
--navigation-tabs-tab: var(--color-foreground-text-soft);
|
|
@@ -8502,6 +8648,86 @@ body {
|
|
|
8502
8648
|
fill: var(--navigation-tabs-scroll-button-color);
|
|
8503
8649
|
}
|
|
8504
8650
|
|
|
8651
|
+
.tl-navigation-tabs__tab {
|
|
8652
|
+
all: unset;
|
|
8653
|
+
margin-right: 32px;
|
|
8654
|
+
box-sizing: border-box;
|
|
8655
|
+
}
|
|
8656
|
+
.tl-navigation-tabs__tab * {
|
|
8657
|
+
box-sizing: border-box;
|
|
8658
|
+
}
|
|
8659
|
+
.tl-navigation-tabs__tab {
|
|
8660
|
+
font-family: var(--headline-07-font-family);
|
|
8661
|
+
font-size: var(--headline-07-font-size);
|
|
8662
|
+
line-height: var(--headline-07-line-height);
|
|
8663
|
+
font-weight: var(--headline-07-font-weight);
|
|
8664
|
+
letter-spacing: var(--headline-07-letter-spacing);
|
|
8665
|
+
text-transform: var(--headline-07-text-transform);
|
|
8666
|
+
color: var(--navigation-tabs-tab);
|
|
8667
|
+
text-decoration: none;
|
|
8668
|
+
display: block;
|
|
8669
|
+
position: relative;
|
|
8670
|
+
transition: color 0.15s ease-in-out 0s;
|
|
8671
|
+
white-space: nowrap;
|
|
8672
|
+
background-color: transparent;
|
|
8673
|
+
border: 0;
|
|
8674
|
+
padding: 26px 4px;
|
|
8675
|
+
}
|
|
8676
|
+
.tl-navigation-tabs__tab:focus-visible {
|
|
8677
|
+
outline: none;
|
|
8678
|
+
}
|
|
8679
|
+
.tl-navigation-tabs__tab:focus-visible::before {
|
|
8680
|
+
content: "";
|
|
8681
|
+
position: absolute;
|
|
8682
|
+
inset: 18px 0;
|
|
8683
|
+
border-radius: 2px;
|
|
8684
|
+
box-shadow: 0 0 0 2px var(--navigation-tabs-tab-focus) inset;
|
|
8685
|
+
z-index: 2;
|
|
8686
|
+
pointer-events: none;
|
|
8687
|
+
}
|
|
8688
|
+
.tl-navigation-tabs__tab::after {
|
|
8689
|
+
background-color: var(--navigation-tabs-tab-indicator-hover);
|
|
8690
|
+
content: " ";
|
|
8691
|
+
position: absolute;
|
|
8692
|
+
bottom: 0;
|
|
8693
|
+
right: 0;
|
|
8694
|
+
left: 0;
|
|
8695
|
+
margin-left: auto;
|
|
8696
|
+
width: 0%;
|
|
8697
|
+
margin-right: auto;
|
|
8698
|
+
height: 2px;
|
|
8699
|
+
z-index: 1;
|
|
8700
|
+
transition: width 0.15s ease-in-out 0s;
|
|
8701
|
+
}
|
|
8702
|
+
.tl-navigation-tabs__tab:not(.tl-navigation-tabs__tab--selected)::after {
|
|
8703
|
+
width: 0%;
|
|
8704
|
+
}
|
|
8705
|
+
.tl-navigation-tabs__tab:hover {
|
|
8706
|
+
cursor: pointer;
|
|
8707
|
+
color: var(--navigation-tabs-tab-hover);
|
|
8708
|
+
}
|
|
8709
|
+
.tl-navigation-tabs__tab:hover::after {
|
|
8710
|
+
width: 100%;
|
|
8711
|
+
}
|
|
8712
|
+
.tl-navigation-tabs__tab--selected {
|
|
8713
|
+
color: var(--navigation-tabs-tab-selected);
|
|
8714
|
+
}
|
|
8715
|
+
.tl-navigation-tabs__tab--selected::after {
|
|
8716
|
+
background-color: var(--navigation-tabs-tab-indicator-active);
|
|
8717
|
+
width: 100%;
|
|
8718
|
+
}
|
|
8719
|
+
.tl-navigation-tabs__tab--disabled {
|
|
8720
|
+
color: var(--navigation-tabs-tab-disabled);
|
|
8721
|
+
pointer-events: none;
|
|
8722
|
+
cursor: not-allowed;
|
|
8723
|
+
}
|
|
8724
|
+
.tl-navigation-tabs__tab--disabled::after {
|
|
8725
|
+
content: none;
|
|
8726
|
+
}
|
|
8727
|
+
.tl-navigation-tabs__tab--disabled:focus-visible::before {
|
|
8728
|
+
box-shadow: none;
|
|
8729
|
+
}
|
|
8730
|
+
|
|
8505
8731
|
.tl-textarea {
|
|
8506
8732
|
--textarea-background-primary: var(--color-background-layer-01);
|
|
8507
8733
|
--textarea-background-secondary: var(--color-background-layer-02);
|
package/dist/global.css
CHANGED
|
@@ -4959,13 +4959,13 @@ html {
|
|
|
4959
4959
|
.tds-mode-light .tds-mode-variant-primary {
|
|
4960
4960
|
--tds-table-body-row-background: var(--tds-grey-50);
|
|
4961
4961
|
--tds-table-zebra-mode-backround: var(--tds-white);
|
|
4962
|
-
--tds-table-body-row-background-selected: var(--tds-grey-
|
|
4962
|
+
--tds-table-body-row-background-selected: var(--tds-grey-100);
|
|
4963
4963
|
}
|
|
4964
4964
|
:root .tds-mode-variant-secondary,
|
|
4965
4965
|
.tds-mode-light .tds-mode-variant-secondary {
|
|
4966
4966
|
--tds-table-body-row-background: var(--tds-white);
|
|
4967
4967
|
--tds-table-zebra-mode-backround: var(--tds-grey-50);
|
|
4968
|
-
--tds-table-body-row-background-selected: var(--tds-
|
|
4968
|
+
--tds-table-body-row-background-selected: var(--tds-grey-100);
|
|
4969
4969
|
}
|
|
4970
4970
|
:root,
|
|
4971
4971
|
.tds-mode-light {
|
|
@@ -5017,14 +5017,18 @@ html {
|
|
|
5017
5017
|
.tds-mode-dark .tds-mode-variant-primary {
|
|
5018
5018
|
--tds-table-body-row-background: var(--tds-grey-850);
|
|
5019
5019
|
--tds-table-zebra-mode-backround: var(--tds-grey-900);
|
|
5020
|
+
--tds-table-body-row-background-selected: var(--tds-grey-700);
|
|
5021
|
+
--tds-table-body-row-background-selected-hover: var(--tds-grey-800);
|
|
5020
5022
|
}
|
|
5021
5023
|
.tds-mode-dark .tds-mode-variant-secondary {
|
|
5022
5024
|
--tds-table-body-row-background: var(--tds-grey-900);
|
|
5023
5025
|
--tds-table-zebra-mode-backround: var(--tds-grey-850);
|
|
5026
|
+
--tds-table-body-row-background-selected: var(--tds-grey-700);
|
|
5027
|
+
--tds-table-body-row-background-selected-hover: var(--tds-grey-800);
|
|
5024
5028
|
}
|
|
5025
5029
|
.tds-mode-dark {
|
|
5026
5030
|
--tds-table-body-row-background-selected: var(--tds-grey-700);
|
|
5027
|
-
--tds-table-body-row-background-selected-hover: var(--tds-grey-
|
|
5031
|
+
--tds-table-body-row-background-selected-hover: var(--tds-grey-800);
|
|
5028
5032
|
/* Table input */
|
|
5029
5033
|
--tds-table-input-background-focus: var(--tds-grey-800);
|
|
5030
5034
|
--tds-table-input-background-hover: var(--tds-white-50);
|