@rokkit/themes 1.1.15 → 1.1.17
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/build.mjs +71 -1
- package/dist/base/alert-list.css +91 -0
- package/dist/base/avatar.css +82 -0
- package/dist/base/badge.css +41 -0
- package/dist/base/breadcrumbs.css +47 -0
- package/dist/base/button.css +254 -0
- package/dist/base/card.css +39 -0
- package/dist/base/carousel.css +128 -0
- package/dist/base/chart.css +94 -0
- package/dist/base/code-block.css +76 -0
- package/dist/base/command-palette.css +35 -0
- package/dist/base/connector.css +92 -0
- package/dist/base/density.css +60 -0
- package/dist/base/display.css +99 -0
- package/dist/base/divider.css +49 -0
- package/dist/base/dropdown.css +167 -0
- package/dist/base/floating-action.css +388 -0
- package/dist/base/floating-navigation.css +405 -0
- package/dist/base/frame.css +36 -0
- package/dist/base/gradient-border.css +32 -0
- package/dist/base/graph-paper.css +83 -0
- package/dist/base/grid.css +93 -0
- package/dist/base/input.css +342 -0
- package/dist/base/item.css +91 -0
- package/dist/base/layout.css +17 -0
- package/dist/base/list.css +188 -0
- package/dist/base/menu.css +277 -0
- package/dist/base/message.css +62 -0
- package/dist/base/nav-content.css +48 -0
- package/dist/base/palette-manager.css +244 -0
- package/dist/base/pill.css +61 -0
- package/dist/base/progress.css +34 -0
- package/dist/base/radius.css +41 -0
- package/dist/base/range.css +122 -0
- package/dist/base/rating.css +42 -0
- package/dist/base/responsive-grid.css +8 -0
- package/dist/base/reveal.css +37 -0
- package/dist/base/search-filter.css +132 -0
- package/dist/base/select.css +413 -0
- package/dist/base/shine.css +14 -0
- package/dist/base/stack.css +76 -0
- package/dist/base/status-list.css +19 -0
- package/dist/base/step-indicator.css +74 -0
- package/dist/base/stepper.css +148 -0
- package/dist/base/swatch.css +85 -0
- package/dist/base/switch.css +168 -0
- package/dist/base/table.css +310 -0
- package/dist/base/tabs.css +184 -0
- package/dist/base/tilt.css +14 -0
- package/dist/base/timeline.css +84 -0
- package/dist/base/toc.css +50 -0
- package/dist/base/toggle.css +185 -0
- package/dist/base/toolbar.css +341 -0
- package/dist/base/tooltip.css +64 -0
- package/dist/base/tree.css +235 -0
- package/dist/base/typography.css +50 -0
- package/dist/base/upload-progress.css +155 -0
- package/dist/base/upload-target.css +77 -0
- package/dist/base.css +7206 -0
- package/dist/frosted/button.css +228 -0
- package/dist/frosted/card.css +128 -0
- package/dist/frosted/chart.css +38 -0
- package/dist/frosted/code-block.css +33 -0
- package/dist/frosted/command-palette.css +43 -0
- package/dist/frosted/dropdown.css +64 -0
- package/dist/frosted/floating-action.css +66 -0
- package/dist/frosted/floating-navigation.css +78 -0
- package/dist/frosted/frame.css +17 -0
- package/dist/frosted/grid.css +26 -0
- package/dist/frosted/input.css +135 -0
- package/dist/frosted/list.css +153 -0
- package/dist/frosted/menu.css +107 -0
- package/dist/frosted/message.css +39 -0
- package/dist/frosted/palette-manager.css +97 -0
- package/dist/frosted/pill.css +17 -0
- package/dist/frosted/progress.css +13 -0
- package/dist/frosted/range.css +64 -0
- package/dist/frosted/rating.css +13 -0
- package/dist/frosted/search-filter.css +53 -0
- package/dist/frosted/select.css +192 -0
- package/dist/frosted/status-list.css +67 -0
- package/dist/frosted/step-indicator.css +43 -0
- package/dist/frosted/swatch.css +21 -0
- package/dist/frosted/switch.css +43 -0
- package/dist/frosted/table.css +122 -0
- package/dist/frosted/tabs.css +61 -0
- package/dist/frosted/timeline.css +46 -0
- package/dist/frosted/toc.css +19 -0
- package/dist/frosted/toggle.css +77 -0
- package/dist/frosted/toolbar.css +92 -0
- package/dist/frosted/tooltip.css +7 -0
- package/dist/frosted/tree.css +115 -0
- package/dist/frosted.css +2357 -0
- package/dist/index.css +19199 -0
- package/dist/material/button.css +178 -0
- package/dist/material/card.css +99 -0
- package/dist/material/chart.css +38 -0
- package/dist/material/code-block.css +33 -0
- package/dist/material/command-palette.css +37 -0
- package/dist/material/dropdown.css +50 -0
- package/dist/material/floating-action.css +64 -0
- package/dist/material/floating-navigation.css +74 -0
- package/dist/material/frame.css +17 -0
- package/dist/material/grid.css +26 -0
- package/dist/material/input.css +164 -0
- package/dist/material/list.css +140 -0
- package/dist/material/menu.css +92 -0
- package/dist/material/message.css +35 -0
- package/dist/material/palette-manager.css +97 -0
- package/dist/material/pill.css +17 -0
- package/dist/material/progress.css +13 -0
- package/dist/material/range.css +62 -0
- package/dist/material/rating.css +13 -0
- package/dist/material/search-filter.css +49 -0
- package/dist/material/select.css +177 -0
- package/dist/material/status-list.css +66 -0
- package/dist/material/step-indicator.css +40 -0
- package/dist/material/swatch.css +21 -0
- package/dist/material/switch.css +28 -0
- package/dist/material/table.css +120 -0
- package/dist/material/tabs.css +88 -0
- package/dist/material/timeline.css +45 -0
- package/dist/material/toc.css +18 -0
- package/dist/material/toggle.css +74 -0
- package/dist/material/toolbar.css +85 -0
- package/dist/material/tooltip.css +7 -0
- package/dist/material/tree.css +134 -0
- package/dist/material.css +2241 -0
- package/dist/minimal/button.css +176 -0
- package/dist/minimal/card.css +99 -0
- package/dist/minimal/chart.css +38 -0
- package/dist/minimal/code-block.css +33 -0
- package/dist/minimal/command-palette.css +37 -0
- package/dist/minimal/dropdown.css +50 -0
- package/dist/minimal/floating-action.css +63 -0
- package/dist/minimal/floating-navigation.css +70 -0
- package/dist/minimal/frame.css +17 -0
- package/dist/minimal/grid.css +26 -0
- package/dist/minimal/input.css +171 -0
- package/dist/minimal/list.css +168 -0
- package/dist/minimal/menu.css +88 -0
- package/dist/minimal/message.css +35 -0
- package/dist/minimal/palette-manager.css +97 -0
- package/dist/minimal/pill.css +17 -0
- package/dist/minimal/progress.css +13 -0
- package/dist/minimal/range.css +61 -0
- package/dist/minimal/rating.css +13 -0
- package/dist/minimal/search-filter.css +49 -0
- package/dist/minimal/select.css +158 -0
- package/dist/minimal/status-list.css +66 -0
- package/dist/minimal/step-indicator.css +40 -0
- package/dist/minimal/swatch.css +21 -0
- package/dist/minimal/switch.css +32 -0
- package/dist/minimal/table.css +118 -0
- package/dist/minimal/tabs.css +151 -0
- package/dist/minimal/timeline.css +45 -0
- package/dist/minimal/toc.css +18 -0
- package/dist/minimal/toggle.css +74 -0
- package/dist/minimal/toolbar.css +85 -0
- package/dist/minimal/tooltip.css +7 -0
- package/dist/minimal/tree.css +141 -0
- package/dist/minimal.css +2317 -0
- package/dist/rokkit/avatar.css +29 -0
- package/dist/rokkit/badge.css +29 -0
- package/dist/rokkit/button.css +308 -0
- package/dist/rokkit/card.css +102 -0
- package/dist/rokkit/chart.css +38 -0
- package/dist/rokkit/code-block.css +33 -0
- package/dist/rokkit/command-palette.css +37 -0
- package/dist/rokkit/connector.css +11 -0
- package/dist/rokkit/divider.css +26 -0
- package/dist/rokkit/dropdown.css +70 -0
- package/dist/rokkit/floating-action.css +65 -0
- package/dist/rokkit/floating-navigation.css +83 -0
- package/dist/rokkit/frame.css +17 -0
- package/dist/rokkit/grid.css +46 -0
- package/dist/rokkit/input.css +134 -0
- package/dist/rokkit/list.css +202 -0
- package/dist/rokkit/menu.css +93 -0
- package/dist/rokkit/message.css +44 -0
- package/dist/rokkit/palette-manager.css +97 -0
- package/dist/rokkit/pill.css +17 -0
- package/dist/rokkit/progress.css +13 -0
- package/dist/rokkit/range.css +62 -0
- package/dist/rokkit/rating.css +13 -0
- package/dist/rokkit/search-filter.css +49 -0
- package/dist/rokkit/select.css +190 -0
- package/dist/rokkit/status-list.css +68 -0
- package/dist/rokkit/step-indicator.css +40 -0
- package/dist/rokkit/swatch.css +20 -0
- package/dist/rokkit/switch.css +29 -0
- package/dist/rokkit/table.css +118 -0
- package/dist/rokkit/tabs.css +114 -0
- package/dist/rokkit/timeline.css +45 -0
- package/dist/rokkit/toc.css +18 -0
- package/dist/rokkit/toggle.css +85 -0
- package/dist/rokkit/toolbar.css +90 -0
- package/dist/rokkit/tooltip.css +7 -0
- package/dist/rokkit/tree.css +149 -0
- package/dist/rokkit/upload-progress.css +102 -0
- package/dist/rokkit/upload-target.css +50 -0
- package/dist/rokkit.css +2789 -0
- package/dist/zen-sumi/button.css +176 -0
- package/dist/zen-sumi/card.css +104 -0
- package/dist/zen-sumi/chart.css +41 -0
- package/dist/zen-sumi/code-block.css +35 -0
- package/dist/zen-sumi/command-palette.css +39 -0
- package/dist/zen-sumi/dropdown.css +53 -0
- package/dist/zen-sumi/floating-action.css +68 -0
- package/dist/zen-sumi/floating-navigation.css +74 -0
- package/dist/zen-sumi/frame.css +20 -0
- package/dist/zen-sumi/grid.css +26 -0
- package/dist/zen-sumi/input.css +171 -0
- package/dist/zen-sumi/list.css +128 -0
- package/dist/zen-sumi/menu.css +91 -0
- package/dist/zen-sumi/message.css +37 -0
- package/dist/zen-sumi/palette-manager.css +97 -0
- package/dist/zen-sumi/pill.css +17 -0
- package/dist/zen-sumi/progress.css +13 -0
- package/dist/zen-sumi/range.css +62 -0
- package/dist/zen-sumi/rating.css +13 -0
- package/dist/zen-sumi/search-filter.css +49 -0
- package/dist/zen-sumi/select.css +160 -0
- package/dist/zen-sumi/status-list.css +66 -0
- package/dist/zen-sumi/step-indicator.css +40 -0
- package/dist/zen-sumi/swatch.css +21 -0
- package/dist/zen-sumi/switch.css +34 -0
- package/dist/zen-sumi/table.css +128 -0
- package/dist/zen-sumi/tabs.css +78 -0
- package/dist/zen-sumi/timeline.css +46 -0
- package/dist/zen-sumi/toc.css +22 -0
- package/dist/zen-sumi/toggle.css +85 -0
- package/dist/zen-sumi/toolbar.css +86 -0
- package/dist/zen-sumi/tooltip.css +7 -0
- package/dist/zen-sumi/tree.css +137 -0
- package/dist/zen-sumi.css +2284 -0
- package/package.json +45 -43
- package/src/frosted/button.css +12 -3
- package/src/frosted/card.css +5 -3
- package/src/frosted/command-palette.css +2 -1
- package/src/frosted/dropdown.css +6 -3
- package/src/frosted/floating-action.css +10 -5
- package/src/frosted/floating-navigation.css +7 -3
- package/src/frosted/input.css +4 -3
- package/src/frosted/list.css +12 -6
- package/src/frosted/menu.css +6 -3
- package/src/frosted/message.css +8 -4
- package/src/frosted/range.css +7 -4
- package/src/frosted/search-filter.css +7 -3
- package/src/frosted/select.css +26 -12
- package/src/frosted/status-list.css +2 -1
- package/src/frosted/step-indicator.css +6 -3
- package/src/frosted/switch.css +2 -1
- package/src/frosted/table.css +12 -6
- package/src/frosted/tabs.css +5 -2
- package/src/frosted/timeline.css +3 -2
- package/src/frosted/toc.css +2 -1
- package/src/frosted/toggle.css +5 -2
- package/src/frosted/toolbar.css +17 -9
- package/src/frosted/tree.css +10 -5
package/build.mjs
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
import { createGenerator, presetWind3, transformerDirectives } from 'unocss'
|
|
21
21
|
import { Theme } from '@rokkit/core'
|
|
22
22
|
import { buildNamedShortcuts } from '@rokkit/unocss'
|
|
23
|
-
import { readFileSync, writeFileSync, mkdirSync } from 'fs'
|
|
23
|
+
import { readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs'
|
|
24
24
|
import { resolve, dirname, join } from 'path'
|
|
25
25
|
import { fileURLToPath } from 'url'
|
|
26
26
|
import MagicString from 'magic-string'
|
|
@@ -178,19 +178,79 @@ function splitTopLevelSelectors(text) {
|
|
|
178
178
|
return parts
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
+
// ─── Regression guard: no @apply may survive into dist ────────────────────────
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Strip /* … */ block comments so the scan matches real CSS, not prose
|
|
185
|
+
* (some files document the @apply pitfall in comments). Mirrors the
|
|
186
|
+
* `stripComments` helper in spec/coverage.spec.js.
|
|
187
|
+
*/
|
|
188
|
+
const stripComments = (s) => s.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Fail the build if any real `@apply` directive survived into a dist file.
|
|
192
|
+
*
|
|
193
|
+
* A leftover `@apply` means a utility didn't resolve (e.g. a named-token
|
|
194
|
+
* `/opacity` shortcut, which UnoCSS can't expand) and would ship raw to
|
|
195
|
+
* consumers — triggering `[lightningcss minify] Unknown at rule: @apply`
|
|
196
|
+
* and rendering nothing. This is the recurrence guard for issue #135.
|
|
197
|
+
*/
|
|
198
|
+
function assertNoApply(outputName) {
|
|
199
|
+
const content = readFileSync(join(distDir, outputName), 'utf-8') // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal — outputName is derived from a hardcoded string array, not user input
|
|
200
|
+
const lines = stripComments(content).split('\n')
|
|
201
|
+
const offending = []
|
|
202
|
+
lines.forEach((line, i) => {
|
|
203
|
+
if (/@apply\b/.test(line)) offending.push(` dist/${outputName}:${i + 1} ${line.trim()}`)
|
|
204
|
+
})
|
|
205
|
+
if (offending.length > 0) {
|
|
206
|
+
throw new Error(
|
|
207
|
+
`Unresolved @apply leaked into dist/${outputName} (issue #135 recurrence).\n` +
|
|
208
|
+
`These utilities did not resolve during build — rewrite them to raw CSS ` +
|
|
209
|
+
`(e.g. color-mix for named-token /opacity):\n${offending.join('\n')}`
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
181
214
|
// ─── Build ────────────────────────────────────────────────────────────────────
|
|
182
215
|
|
|
183
216
|
const srcDir = join(__dirname, 'src')
|
|
184
217
|
const distDir = join(__dirname, 'dist')
|
|
185
218
|
|
|
219
|
+
/** Names of every dist file emitted by this build, scanned by the guard. */
|
|
220
|
+
const emitted = []
|
|
221
|
+
|
|
186
222
|
async function buildFile(inputPath, outputName, label) {
|
|
187
223
|
const fullCSS = resolveImports(inputPath)
|
|
188
224
|
const compiled = await processCSS(fullCSS, outputName)
|
|
189
225
|
const fixed = fixModeSelectors(compiled)
|
|
190
226
|
writeFileSync(join(distDir, outputName), fixed, 'utf-8') // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal — outputName is derived from a hardcoded string array, not user input
|
|
227
|
+
emitted.push(outputName)
|
|
191
228
|
console.log(`✓ dist/${outputName} (${label})`)
|
|
192
229
|
}
|
|
193
230
|
|
|
231
|
+
/**
|
|
232
|
+
* Compile every per-component CSS file (e.g. src/frosted/button.css) into
|
|
233
|
+
* dist/<style>/<component>.css, expanding @apply just like the bundled files.
|
|
234
|
+
*
|
|
235
|
+
* Consumers that import a single component path (e.g.
|
|
236
|
+
* `@rokkit/themes/frosted/button.css`) get resolved CSS, not raw @apply — the
|
|
237
|
+
* `./<style>/*` exports point here. index.css is skipped (it is only an
|
|
238
|
+
* aggregator of @imports, already compiled into dist/<style>.css).
|
|
239
|
+
*/
|
|
240
|
+
async function buildComponentFiles(style) {
|
|
241
|
+
mkdirSync(join(distDir, style), { recursive: true }) // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal — style is from a hardcoded string array, not user input
|
|
242
|
+
const files = readdirSync(join(srcDir, style)) // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal — style is from a hardcoded string array, not user input
|
|
243
|
+
.filter((f) => f.endsWith('.css') && f !== 'index.css')
|
|
244
|
+
.sort()
|
|
245
|
+
for (const file of files) {
|
|
246
|
+
const outputName = `${style}/${file}`
|
|
247
|
+
const compiled = await processCSS(readFileSync(join(srcDir, style, file), 'utf-8'), outputName) // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal — style/file enumerate a hardcoded src dir, not user input
|
|
248
|
+
writeFileSync(join(distDir, outputName), fixModeSelectors(compiled), 'utf-8') // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal — derived from enumerated src files, not user input
|
|
249
|
+
emitted.push(outputName)
|
|
250
|
+
}
|
|
251
|
+
console.log(`✓ dist/${style}/*.css (${files.length} components)`)
|
|
252
|
+
}
|
|
253
|
+
|
|
194
254
|
async function build() {
|
|
195
255
|
mkdirSync(distDir, { recursive: true })
|
|
196
256
|
|
|
@@ -202,6 +262,7 @@ async function build() {
|
|
|
202
262
|
const compiledBase = await processCSS(baseCSS, 'base.css')
|
|
203
263
|
const baseFull = fixModeSelectors(compiledPalette + '\n' + zScaleCSS + '\n' + compiledBase)
|
|
204
264
|
writeFileSync(join(distDir, 'base.css'), baseFull, 'utf-8')
|
|
265
|
+
emitted.push('base.css')
|
|
205
266
|
console.log('✓ dist/base.css (structural styles + palette defaults)')
|
|
206
267
|
|
|
207
268
|
// Per-theme files
|
|
@@ -215,6 +276,11 @@ async function build() {
|
|
|
215
276
|
await buildFile(join(srcDir, name, 'index.css'), `${name}.css`, label)
|
|
216
277
|
}
|
|
217
278
|
|
|
279
|
+
// Per-component files: dist/<style>/<component>.css (for `./<style>/*` exports)
|
|
280
|
+
for (const style of ['base', 'rokkit', 'minimal', 'material', 'frosted', 'zen-sumi']) {
|
|
281
|
+
await buildComponentFiles(style)
|
|
282
|
+
}
|
|
283
|
+
|
|
218
284
|
// Full bundle: base + all themes
|
|
219
285
|
const allThemes = [
|
|
220
286
|
'base',
|
|
@@ -227,8 +293,12 @@ async function build() {
|
|
|
227
293
|
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal — name is from a hardcoded string array, not user input
|
|
228
294
|
const bundleParts = allThemes.map((name) => readFileSync(join(distDir, `${name}.css`), 'utf-8'))
|
|
229
295
|
writeFileSync(join(distDir, 'index.css'), bundleParts.join('\n'), 'utf-8')
|
|
296
|
+
emitted.push('index.css')
|
|
230
297
|
console.log('✓ dist/index.css (full bundle)')
|
|
231
298
|
|
|
299
|
+
// Regression guard (#135): no unresolved @apply may ship in dist.
|
|
300
|
+
for (const outputName of emitted) assertNoApply(outputName)
|
|
301
|
+
|
|
232
302
|
console.log('\n@rokkit/themes build complete.')
|
|
233
303
|
}
|
|
234
304
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* AlertList — base structural styles for the fixed toast container */
|
|
2
|
+
|
|
3
|
+
[data-alert-list] {
|
|
4
|
+
position: fixed;
|
|
5
|
+
z-index: 9999;
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
max-width: 24rem;
|
|
9
|
+
width: calc(100% - 2rem);
|
|
10
|
+
padding: 1rem;
|
|
11
|
+
pointer-events: none;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Each toast wrapper: handles enter animation, spacing, and dismiss collapse */
|
|
15
|
+
[data-alert-list] > * {
|
|
16
|
+
pointer-events: auto;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
max-height: 12rem;
|
|
19
|
+
margin-bottom: 0.5rem;
|
|
20
|
+
transition:
|
|
21
|
+
max-height 0.25s ease-out,
|
|
22
|
+
margin-bottom 0.25s ease-out;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* Collapse height + spacing when dismissing — CSS drives the animation */
|
|
26
|
+
[data-alert-list] > *[data-dismissing] {
|
|
27
|
+
max-height: 0;
|
|
28
|
+
margin-bottom: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Message enter animation */
|
|
32
|
+
@keyframes toast-enter {
|
|
33
|
+
from {
|
|
34
|
+
opacity: 0;
|
|
35
|
+
transform: translateX(2rem);
|
|
36
|
+
}
|
|
37
|
+
to {
|
|
38
|
+
opacity: 1;
|
|
39
|
+
transform: translateX(0);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Message exit transition */
|
|
44
|
+
[data-alert-list] > * > [data-message-root] {
|
|
45
|
+
animation: toast-enter 0.2s ease-out;
|
|
46
|
+
transition:
|
|
47
|
+
opacity 0.2s ease-out,
|
|
48
|
+
transform 0.2s ease-out;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
[data-alert-list] > *[data-dismissing] > [data-message-root] {
|
|
52
|
+
opacity: 0;
|
|
53
|
+
transform: translateX(2rem);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Top positions */
|
|
57
|
+
[data-alert-list][data-position='top-right'] {
|
|
58
|
+
top: 0;
|
|
59
|
+
right: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
[data-alert-list][data-position='top-center'] {
|
|
63
|
+
top: 0;
|
|
64
|
+
left: 50%;
|
|
65
|
+
transform: translateX(-50%);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
[data-alert-list][data-position='top-left'] {
|
|
69
|
+
top: 0;
|
|
70
|
+
left: 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Bottom positions — reverse stack so newest appears at bottom edge */
|
|
74
|
+
[data-alert-list][data-position='bottom-right'] {
|
|
75
|
+
bottom: 0;
|
|
76
|
+
right: 0;
|
|
77
|
+
flex-direction: column-reverse;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
[data-alert-list][data-position='bottom-center'] {
|
|
81
|
+
bottom: 0;
|
|
82
|
+
left: 50%;
|
|
83
|
+
transform: translateX(-50%);
|
|
84
|
+
flex-direction: column-reverse;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[data-alert-list][data-position='bottom-left'] {
|
|
88
|
+
bottom: 0;
|
|
89
|
+
left: 0;
|
|
90
|
+
flex-direction: column-reverse;
|
|
91
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* Avatar — base structural styles */
|
|
2
|
+
|
|
3
|
+
[data-avatar] {
|
|
4
|
+
position: relative;
|
|
5
|
+
display: inline-flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
flex-shrink: 0;
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
user-select: none;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* Shape */
|
|
14
|
+
[data-avatar][data-shape='circle'] {
|
|
15
|
+
border-radius: 9999px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
[data-avatar][data-shape='square'] {
|
|
19
|
+
border-radius: 0.375rem;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Size variants */
|
|
23
|
+
[data-avatar][data-size='xs'] {
|
|
24
|
+
width: 1.5rem;
|
|
25
|
+
height: 1.5rem;
|
|
26
|
+
font-size: 0.5rem;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
[data-avatar][data-size='sm'] {
|
|
30
|
+
width: 2rem;
|
|
31
|
+
height: 2rem;
|
|
32
|
+
font-size: 0.625rem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
[data-avatar][data-size='md'] {
|
|
36
|
+
width: 2.5rem;
|
|
37
|
+
height: 2.5rem;
|
|
38
|
+
font-size: 0.75rem;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
[data-avatar][data-size='lg'] {
|
|
42
|
+
width: 3rem;
|
|
43
|
+
height: 3rem;
|
|
44
|
+
font-size: 0.875rem;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
[data-avatar][data-size='xl'] {
|
|
48
|
+
width: 4rem;
|
|
49
|
+
height: 4rem;
|
|
50
|
+
font-size: 1.125rem;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
[data-avatar-img] {
|
|
54
|
+
width: 100%;
|
|
55
|
+
height: 100%;
|
|
56
|
+
object-fit: cover;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
[data-avatar-initials] {
|
|
60
|
+
font-weight: 600;
|
|
61
|
+
letter-spacing: 0.02em;
|
|
62
|
+
line-height: 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Status indicator dot */
|
|
66
|
+
[data-avatar-status] {
|
|
67
|
+
position: absolute;
|
|
68
|
+
bottom: 0;
|
|
69
|
+
right: 0;
|
|
70
|
+
width: 25%;
|
|
71
|
+
height: 25%;
|
|
72
|
+
min-width: 0.5rem;
|
|
73
|
+
min-height: 0.5rem;
|
|
74
|
+
border-radius: 9999px;
|
|
75
|
+
border: 2px solid transparent;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
[data-avatar][data-shape='square'] [data-avatar-status] {
|
|
79
|
+
border-radius: 9999px;
|
|
80
|
+
bottom: -0.125rem;
|
|
81
|
+
right: -0.125rem;
|
|
82
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/* Badge — base structural styles */
|
|
2
|
+
|
|
3
|
+
[data-badge-wrapper] {
|
|
4
|
+
position: relative;
|
|
5
|
+
display: inline-flex;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
[data-badge] {
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
min-width: 1.25rem;
|
|
13
|
+
height: 1.25rem;
|
|
14
|
+
padding: 0 0.375rem;
|
|
15
|
+
border-radius: 9999px;
|
|
16
|
+
font-size: 0.6875rem;
|
|
17
|
+
font-weight: 600;
|
|
18
|
+
line-height: 1;
|
|
19
|
+
white-space: nowrap;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Dot mode — small circle with no content */
|
|
23
|
+
[data-badge][data-dot] {
|
|
24
|
+
min-width: 0.5rem;
|
|
25
|
+
width: 0.5rem;
|
|
26
|
+
height: 0.5rem;
|
|
27
|
+
padding: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Positioned inside a wrapper */
|
|
31
|
+
[data-badge-wrapper] [data-badge] {
|
|
32
|
+
position: absolute;
|
|
33
|
+
top: -0.375rem;
|
|
34
|
+
right: -0.375rem;
|
|
35
|
+
z-index: 1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
[data-badge-wrapper] [data-badge][data-dot] {
|
|
39
|
+
top: -0.125rem;
|
|
40
|
+
right: -0.125rem;
|
|
41
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* BreadCrumbs — base structural styles */
|
|
2
|
+
|
|
3
|
+
[data-breadcrumbs] {
|
|
4
|
+
display: block;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
[data-breadcrumb-list] {
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
list-style: none;
|
|
11
|
+
padding: 0;
|
|
12
|
+
margin: 0;
|
|
13
|
+
gap: 0.25rem;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
[data-breadcrumb-item] {
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
[data-breadcrumb-separator] {
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
opacity: 0.5;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
[data-breadcrumb-link] {
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
gap: 0.25rem;
|
|
31
|
+
background: none;
|
|
32
|
+
border: none;
|
|
33
|
+
cursor: pointer;
|
|
34
|
+
padding: 0.25rem 0.5rem;
|
|
35
|
+
border-radius: 0.25rem;
|
|
36
|
+
font: inherit;
|
|
37
|
+
color: inherit;
|
|
38
|
+
text-decoration: none;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
[data-breadcrumb-current] {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
gap: 0.25rem;
|
|
45
|
+
padding: 0.25rem 0.5rem;
|
|
46
|
+
font-weight: 600;
|
|
47
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Button - Base Structural Styles
|
|
3
|
+
*
|
|
4
|
+
* These styles provide layout, positioning, and basic structure.
|
|
5
|
+
* No colors, shadows, or visual theming - those belong in theme styles.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/* =============================================================================
|
|
9
|
+
Button
|
|
10
|
+
============================================================================= */
|
|
11
|
+
|
|
12
|
+
[data-button] {
|
|
13
|
+
display: inline-flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
gap: 0.5rem;
|
|
17
|
+
border-radius: 0.5rem;
|
|
18
|
+
font-weight: 500;
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
border: 1px solid transparent;
|
|
21
|
+
white-space: nowrap;
|
|
22
|
+
user-select: none;
|
|
23
|
+
text-decoration: none;
|
|
24
|
+
transition: all 150ms ease;
|
|
25
|
+
background: transparent;
|
|
26
|
+
color: inherit;
|
|
27
|
+
font-family: inherit;
|
|
28
|
+
line-height: 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
[data-button]:focus {
|
|
32
|
+
outline: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
[data-button]:focus-visible {
|
|
36
|
+
outline: 2px solid currentColor;
|
|
37
|
+
outline-offset: 2px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Disabled */
|
|
41
|
+
[data-button][data-disabled],
|
|
42
|
+
[data-button]:disabled {
|
|
43
|
+
pointer-events: none;
|
|
44
|
+
opacity: 0.5;
|
|
45
|
+
cursor: not-allowed;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Loading */
|
|
49
|
+
[data-button][data-loading] {
|
|
50
|
+
pointer-events: none;
|
|
51
|
+
position: relative;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Icon-only */
|
|
55
|
+
[data-button][data-icon-only] {
|
|
56
|
+
aspect-ratio: 1;
|
|
57
|
+
padding: 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
[data-button][data-icon-only] [data-item-text] {
|
|
61
|
+
display: none;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* =============================================================================
|
|
65
|
+
Size Variants
|
|
66
|
+
============================================================================= */
|
|
67
|
+
|
|
68
|
+
/* Small */
|
|
69
|
+
[data-button][data-size='sm'] {
|
|
70
|
+
height: var(--control-h-sm);
|
|
71
|
+
padding-inline: 0.625rem;
|
|
72
|
+
font-size: 0.75rem;
|
|
73
|
+
gap: 0.375rem;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
[data-button][data-size='sm'][data-icon-only] {
|
|
77
|
+
width: var(--control-h-sm);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
[data-button][data-size='sm'] [data-item-icon],
|
|
81
|
+
[data-button][data-size='sm'] [data-button-icon-right] {
|
|
82
|
+
font-size: 1.25rem;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Medium (default) — responds to density */
|
|
86
|
+
[data-button][data-size='md'],
|
|
87
|
+
[data-button]:not([data-size]) {
|
|
88
|
+
height: var(--control-h-md);
|
|
89
|
+
padding-inline: var(--density-spacing-lg);
|
|
90
|
+
font-size: 0.875rem;
|
|
91
|
+
gap: var(--density-spacing-sm);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
[data-button][data-size='md'][data-icon-only],
|
|
95
|
+
[data-button]:not([data-size])[data-icon-only] {
|
|
96
|
+
width: var(--control-h-md);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
[data-button][data-size='md'] [data-item-icon],
|
|
100
|
+
[data-button][data-size='md'] [data-button-icon-right],
|
|
101
|
+
[data-button]:not([data-size]) [data-item-icon],
|
|
102
|
+
[data-button]:not([data-size]) [data-button-icon-right] {
|
|
103
|
+
font-size: var(--density-icon-size);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* Large */
|
|
107
|
+
[data-button][data-size='lg'] {
|
|
108
|
+
height: var(--control-h-lg);
|
|
109
|
+
padding-inline: 1.5rem;
|
|
110
|
+
font-size: 1rem;
|
|
111
|
+
gap: 0.625rem;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
[data-button][data-size='lg'][data-icon-only] {
|
|
115
|
+
width: var(--control-h-lg);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
[data-button][data-size='lg'] [data-item-icon],
|
|
119
|
+
[data-button][data-size='lg'] [data-button-icon-right] {
|
|
120
|
+
font-size: 1.875rem;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* =============================================================================
|
|
124
|
+
Button Elements
|
|
125
|
+
============================================================================= */
|
|
126
|
+
|
|
127
|
+
[data-button] [data-item-icon],
|
|
128
|
+
[data-button] [data-button-icon-right] {
|
|
129
|
+
flex-shrink: 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
[data-button] [data-item-text] {
|
|
133
|
+
display: inline-flex;
|
|
134
|
+
align-items: center;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Hide description and badge inside buttons (ItemContent renders them but we don't need them) */
|
|
138
|
+
[data-button] [data-item-description],
|
|
139
|
+
[data-button] [data-item-badge] {
|
|
140
|
+
display: none;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* =============================================================================
|
|
144
|
+
Gradient Style — Structural
|
|
145
|
+
============================================================================= */
|
|
146
|
+
|
|
147
|
+
[data-button][data-style='gradient'] {
|
|
148
|
+
border: none;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* =============================================================================
|
|
152
|
+
Link Style — Structural
|
|
153
|
+
============================================================================= */
|
|
154
|
+
|
|
155
|
+
[data-button][data-style='link'] {
|
|
156
|
+
background: transparent;
|
|
157
|
+
border: none;
|
|
158
|
+
height: auto;
|
|
159
|
+
padding-inline: 0.25rem;
|
|
160
|
+
border-radius: 0;
|
|
161
|
+
font-weight: inherit;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
[data-button][data-style='link']:hover:not(:disabled):not([data-disabled]) {
|
|
165
|
+
text-decoration: underline;
|
|
166
|
+
text-underline-offset: 2px;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* =============================================================================
|
|
170
|
+
Micro-Animations
|
|
171
|
+
============================================================================= */
|
|
172
|
+
|
|
173
|
+
/* Hover lift — subtle elevation on hover (not on link or ghost style) */
|
|
174
|
+
[data-button]:not([data-style='link']):not([data-style='ghost']):hover:not(:disabled):not(
|
|
175
|
+
[data-disabled]
|
|
176
|
+
) {
|
|
177
|
+
transform: translateY(-1px);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* Press feedback — scale down on active */
|
|
181
|
+
[data-button]:active:not(:disabled):not([data-disabled]) {
|
|
182
|
+
transform: scale(0.97) translateY(0);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* Icon shift — trailing icon moves right on hover */
|
|
186
|
+
[data-button]:hover:not(:disabled):not([data-disabled]) [data-button-icon-right] {
|
|
187
|
+
translate: 0.125rem 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
[data-button] [data-button-icon-right] {
|
|
191
|
+
transition: translate 150ms ease;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* Loading pulse */
|
|
195
|
+
[data-button][data-loading] {
|
|
196
|
+
animation: button-loading-pulse 1.5s ease-in-out infinite;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@keyframes button-loading-pulse {
|
|
200
|
+
0%,
|
|
201
|
+
100% {
|
|
202
|
+
opacity: 1;
|
|
203
|
+
}
|
|
204
|
+
50% {
|
|
205
|
+
opacity: 0.7;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* =============================================================================
|
|
210
|
+
Loading Spinner
|
|
211
|
+
============================================================================= */
|
|
212
|
+
|
|
213
|
+
[data-button-spinner] {
|
|
214
|
+
width: 1em;
|
|
215
|
+
height: 1em;
|
|
216
|
+
border: 2px solid currentColor;
|
|
217
|
+
border-right-color: transparent;
|
|
218
|
+
border-radius: 50%;
|
|
219
|
+
animation: button-spin 0.6s linear infinite;
|
|
220
|
+
flex-shrink: 0;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
@keyframes button-spin {
|
|
224
|
+
to {
|
|
225
|
+
transform: rotate(360deg);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* =============================================================================
|
|
230
|
+
Button Group
|
|
231
|
+
============================================================================= */
|
|
232
|
+
|
|
233
|
+
[data-button-group] {
|
|
234
|
+
display: inline-flex;
|
|
235
|
+
align-items: center;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
[data-button-group] [data-button] {
|
|
239
|
+
border-radius: 0;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
[data-button-group] [data-button]:first-child {
|
|
243
|
+
border-top-left-radius: 0.5rem;
|
|
244
|
+
border-bottom-left-radius: 0.5rem;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
[data-button-group] [data-button]:last-child {
|
|
248
|
+
border-top-right-radius: 0.5rem;
|
|
249
|
+
border-bottom-right-radius: 0.5rem;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
[data-button-group] [data-button]:not(:first-child) {
|
|
253
|
+
margin-left: -1px;
|
|
254
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/* Card — base structural styles */
|
|
2
|
+
|
|
3
|
+
[data-card] {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
border-radius: var(--density-radius-base);
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
text-decoration: none;
|
|
9
|
+
color: inherit;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
button[data-card] {
|
|
13
|
+
background: none;
|
|
14
|
+
border: none;
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
text-align: inherit;
|
|
17
|
+
font: inherit;
|
|
18
|
+
padding: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
a[data-card] {
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
[data-card-header] {
|
|
26
|
+
padding-block: var(--density-spacing-md) var(--density-spacing-sm);
|
|
27
|
+
padding-inline: var(--density-spacing-lg);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[data-card-body] {
|
|
31
|
+
padding-block: var(--density-spacing-sm);
|
|
32
|
+
padding-inline: var(--density-spacing-lg);
|
|
33
|
+
flex: 1;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
[data-card-footer] {
|
|
37
|
+
padding-block: var(--density-spacing-sm) var(--density-spacing-md);
|
|
38
|
+
padding-inline: var(--density-spacing-lg);
|
|
39
|
+
}
|