@rokkit/themes 1.0.0-next.127 → 1.0.0-next.128
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 +237 -0
- package/package.json +17 -6
- package/src/base/button.css +7 -3
- package/src/base/connector.css +0 -14
- package/src/base/grid.css +93 -0
- package/src/base/index.css +3 -0
- package/src/base/input.css +16 -12
- package/src/base/item.css +26 -0
- package/src/base/list.css +28 -107
- package/src/base/menu.css +28 -76
- package/src/base/toggle.css +4 -0
- package/src/base/tree.css +44 -5
- package/src/base/upload-progress.css +155 -0
- package/src/base/upload-target.css +67 -0
- package/src/glass/list.css +6 -6
- package/src/glass/menu.css +2 -2
- package/src/index.js +2 -2
- package/src/material/list.css +6 -6
- package/src/material/menu.css +2 -2
- package/src/minimal/list.css +6 -6
- package/src/minimal/menu.css +2 -2
- package/src/rokkit/button.css +54 -54
- package/src/rokkit/grid.css +46 -0
- package/src/rokkit/index.css +3 -0
- package/src/rokkit/list.css +6 -20
- package/src/rokkit/menu.css +5 -35
- package/src/rokkit/upload-progress.css +102 -0
- package/src/rokkit/upload-target.css +50 -0
package/build.mjs
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rokkit/themes — CSS Build Script
|
|
3
|
+
*
|
|
4
|
+
* Compiles theme CSS with UnoCSS, expanding @apply directives into real CSS
|
|
5
|
+
* (including correct dark mode sibling rules).
|
|
6
|
+
*
|
|
7
|
+
* Outputs separate files per theme:
|
|
8
|
+
* dist/base.css — structural styles + default CSS variable palette
|
|
9
|
+
* dist/rokkit.css — rokkit theme (gradients, glowing borders)
|
|
10
|
+
* dist/minimal.css — minimal theme (clean, subtle)
|
|
11
|
+
* dist/material.css — material theme (elevation, shadows)
|
|
12
|
+
* dist/glass.css — glass theme (blur, transparency)
|
|
13
|
+
*
|
|
14
|
+
* Post-processing: adds compound selector form so dark mode works when
|
|
15
|
+
* data-mode and data-style are on the SAME element (e.g. body):
|
|
16
|
+
* Generated: [data-mode="dark"] [data-style="rokkit"] [data-toggle]
|
|
17
|
+
* Added also: [data-mode="dark"][data-style="rokkit"] [data-toggle]
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { createGenerator, presetWind3, transformerDirectives } from 'unocss'
|
|
21
|
+
import { Theme } from '@rokkit/core'
|
|
22
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'fs'
|
|
23
|
+
import { resolve, dirname, join } from 'path'
|
|
24
|
+
import { fileURLToPath } from 'url'
|
|
25
|
+
import MagicString from 'magic-string'
|
|
26
|
+
|
|
27
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
28
|
+
|
|
29
|
+
// ─── UnoCSS config ────────────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
const theme = new Theme()
|
|
32
|
+
|
|
33
|
+
const uno = await createGenerator({
|
|
34
|
+
presets: [
|
|
35
|
+
presetWind3({
|
|
36
|
+
dark: {
|
|
37
|
+
light: '[data-mode="light"]',
|
|
38
|
+
dark: '[data-mode="dark"]'
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
],
|
|
42
|
+
shortcuts: [
|
|
43
|
+
['skin-default', theme.getPalette()],
|
|
44
|
+
...theme.getShortcuts('surface'),
|
|
45
|
+
...theme.getShortcuts('primary'),
|
|
46
|
+
...theme.getShortcuts('secondary'),
|
|
47
|
+
...theme.getShortcuts('accent'),
|
|
48
|
+
...theme.getShortcuts('success'),
|
|
49
|
+
...theme.getShortcuts('warning'),
|
|
50
|
+
...theme.getShortcuts('danger'),
|
|
51
|
+
...theme.getShortcuts('error'),
|
|
52
|
+
...theme.getShortcuts('info'),
|
|
53
|
+
['text-on-primary', 'text-surface-50'],
|
|
54
|
+
['text-on-secondary', 'text-surface-50'],
|
|
55
|
+
['text-on-info', 'text-surface-50'],
|
|
56
|
+
['text-on-success', 'text-surface-50'],
|
|
57
|
+
['text-on-warning', 'text-surface-50'],
|
|
58
|
+
['text-on-error', 'text-surface-50'],
|
|
59
|
+
['text-on-surface', 'text-surface-50']
|
|
60
|
+
],
|
|
61
|
+
theme: {
|
|
62
|
+
colors: theme.getColorRules()
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
// ─── CSS @import resolver ─────────────────────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Recursively inlines local @import statements.
|
|
70
|
+
* External imports (http, @, ~) are left unchanged.
|
|
71
|
+
*/
|
|
72
|
+
function resolveImports(filePath, seen = new Set()) {
|
|
73
|
+
if (seen.has(filePath)) return ''
|
|
74
|
+
seen.add(filePath)
|
|
75
|
+
|
|
76
|
+
const content = readFileSync(filePath, 'utf-8')
|
|
77
|
+
return content.replace(/@import\s+['"]([^'"]+)['"]\s*;/g, (match, importPath) => {
|
|
78
|
+
if (importPath.startsWith('http') || importPath.startsWith('@') || importPath.startsWith('~')) {
|
|
79
|
+
return match
|
|
80
|
+
}
|
|
81
|
+
const resolvedPath = resolve(dirname(filePath), importPath)
|
|
82
|
+
return resolveImports(resolvedPath, seen)
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ─── UnoCSS @apply processor ─────────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
const transformer = transformerDirectives()
|
|
89
|
+
|
|
90
|
+
async function processCSS(content, filename) {
|
|
91
|
+
const s = new MagicString(content)
|
|
92
|
+
await transformer.transform(s, filename, {
|
|
93
|
+
uno,
|
|
94
|
+
tokens: new Set(),
|
|
95
|
+
generate: async (tokens) => uno.generate(tokens, { preflights: false })
|
|
96
|
+
})
|
|
97
|
+
return s.toString()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ─── Post-processing: fix dark mode selectors ─────────────────────────────────
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* UnoCSS generates dark mode rules as descendant selectors:
|
|
104
|
+
* [data-mode="dark"] [data-style="rokkit"] [data-component]
|
|
105
|
+
*
|
|
106
|
+
* This doesn't match when both data-mode and data-style are on the SAME element
|
|
107
|
+
* (e.g. <body data-mode="dark" data-style="rokkit">).
|
|
108
|
+
*
|
|
109
|
+
* For each such rule, we also add the compound selector form:
|
|
110
|
+
* [data-mode="dark"][data-style="rokkit"] [data-component]
|
|
111
|
+
*
|
|
112
|
+
* Both forms are emitted so either usage pattern works.
|
|
113
|
+
*/
|
|
114
|
+
function fixModeSelectors(css) {
|
|
115
|
+
const modePattern = /\[data-mode="(?:dark|light)"\] \[data-style="[^"]+"\]/
|
|
116
|
+
|
|
117
|
+
let result = ''
|
|
118
|
+
let i = 0
|
|
119
|
+
|
|
120
|
+
while (i < css.length) {
|
|
121
|
+
// Find next { (opening of a declarations block)
|
|
122
|
+
const braceOpen = css.indexOf('{', i)
|
|
123
|
+
if (braceOpen === -1) {
|
|
124
|
+
result += css.slice(i)
|
|
125
|
+
break
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const selectorText = css.slice(i, braceOpen)
|
|
129
|
+
|
|
130
|
+
// Only expand selectors that contain the problematic pattern
|
|
131
|
+
if (modePattern.test(selectorText)) {
|
|
132
|
+
// Split on comma, but only top-level commas (not inside :not(), :is(), etc.)
|
|
133
|
+
const parts = splitTopLevelSelectors(selectorText)
|
|
134
|
+
const expanded = []
|
|
135
|
+
|
|
136
|
+
for (const part of parts) {
|
|
137
|
+
const m = part.match(/^(\s*)(\[data-mode="(?:dark|light)"\]) (\[data-style="[^"]+"\])(.*)$/)
|
|
138
|
+
if (m) {
|
|
139
|
+
const [, ws, modeSelector, styleSelector, rest] = m
|
|
140
|
+
// Compound form: [data-mode="X"][data-style="Y"]rest (same-element match)
|
|
141
|
+
expanded.push(`${ws}${modeSelector}${styleSelector}${rest}`)
|
|
142
|
+
}
|
|
143
|
+
// Always include original descendant form
|
|
144
|
+
expanded.push(part)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
result += expanded.join(',') + '{'
|
|
148
|
+
} else {
|
|
149
|
+
result += selectorText + '{'
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Find the matching closing brace, handling nesting
|
|
153
|
+
let depth = 1
|
|
154
|
+
let j = braceOpen + 1
|
|
155
|
+
while (j < css.length && depth > 0) {
|
|
156
|
+
if (css[j] === '{') depth++
|
|
157
|
+
else if (css[j] === '}') depth--
|
|
158
|
+
j++
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
result += css.slice(braceOpen + 1, j)
|
|
162
|
+
i = j
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return result
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Split a selector list by top-level commas only (not inside parentheses).
|
|
170
|
+
*/
|
|
171
|
+
function splitTopLevelSelectors(text) {
|
|
172
|
+
const parts = []
|
|
173
|
+
let depth = 0
|
|
174
|
+
let start = 0
|
|
175
|
+
|
|
176
|
+
for (let i = 0; i < text.length; i++) {
|
|
177
|
+
if (text[i] === '(') depth++
|
|
178
|
+
else if (text[i] === ')') depth--
|
|
179
|
+
else if (text[i] === ',' && depth === 0) {
|
|
180
|
+
parts.push(text.slice(start, i))
|
|
181
|
+
start = i + 1
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
parts.push(text.slice(start))
|
|
185
|
+
return parts
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ─── Build ────────────────────────────────────────────────────────────────────
|
|
189
|
+
|
|
190
|
+
const srcDir = join(__dirname, 'src')
|
|
191
|
+
const distDir = join(__dirname, 'dist')
|
|
192
|
+
|
|
193
|
+
async function buildFile(inputPath, outputName, label) {
|
|
194
|
+
const fullCSS = resolveImports(inputPath)
|
|
195
|
+
const compiled = await processCSS(fullCSS, outputName)
|
|
196
|
+
const fixed = fixModeSelectors(compiled)
|
|
197
|
+
writeFileSync(join(distDir, outputName), fixed, 'utf-8')
|
|
198
|
+
console.log(`✓ dist/${outputName} (${label})`)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async function build() {
|
|
202
|
+
mkdirSync(distDir, { recursive: true })
|
|
203
|
+
|
|
204
|
+
// base.css: structural styles + palette CSS variable defaults
|
|
205
|
+
const paletteCSS = readFileSync(join(srcDir, 'palette.css'), 'utf-8')
|
|
206
|
+
const compiledPalette = await processCSS(paletteCSS, 'palette.css')
|
|
207
|
+
const baseCSS = resolveImports(join(srcDir, 'base', 'index.css'))
|
|
208
|
+
const compiledBase = await processCSS(baseCSS, 'base.css')
|
|
209
|
+
const baseFull = fixModeSelectors(compiledPalette + '\n' + compiledBase)
|
|
210
|
+
writeFileSync(join(distDir, 'base.css'), baseFull, 'utf-8')
|
|
211
|
+
console.log('✓ dist/base.css (structural styles + palette defaults)')
|
|
212
|
+
|
|
213
|
+
// Per-theme files
|
|
214
|
+
for (const [name, label] of [
|
|
215
|
+
['rokkit', 'gradients + glowing borders'],
|
|
216
|
+
['minimal', 'clean + subtle'],
|
|
217
|
+
['material', 'elevation + shadows'],
|
|
218
|
+
['glass', 'blur + transparency']
|
|
219
|
+
]) {
|
|
220
|
+
await buildFile(join(srcDir, name, 'index.css'), `${name}.css`, label)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Full bundle: base + all themes
|
|
224
|
+
const allThemes = ['base', 'rokkit', 'minimal', 'material', 'glass']
|
|
225
|
+
const bundleParts = allThemes.map((name) =>
|
|
226
|
+
readFileSync(join(distDir, `${name}.css`), 'utf-8')
|
|
227
|
+
)
|
|
228
|
+
writeFileSync(join(distDir, 'index.css'), bundleParts.join('\n'), 'utf-8')
|
|
229
|
+
console.log('✓ dist/index.css (full bundle)')
|
|
230
|
+
|
|
231
|
+
console.log('\n@rokkit/themes build complete.')
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
build().catch((err) => {
|
|
235
|
+
console.error('Build failed:', err)
|
|
236
|
+
process.exit(1)
|
|
237
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rokkit/themes",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.128",
|
|
4
4
|
"description": "Theme styles for @rokkit/ui components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
"default": "./src/index.js"
|
|
12
12
|
},
|
|
13
13
|
"./styles": "./src/index.css",
|
|
14
|
+
"./dist": "./dist/index.css",
|
|
15
|
+
"./base.css": "./dist/base.css",
|
|
16
|
+
"./rokkit.css": "./dist/rokkit.css",
|
|
17
|
+
"./minimal.css": "./dist/minimal.css",
|
|
18
|
+
"./material.css": "./dist/material.css",
|
|
19
|
+
"./glass.css": "./dist/glass.css",
|
|
14
20
|
"./base": "./src/base/index.css",
|
|
15
21
|
"./base/*": "./src/base/*.css",
|
|
16
22
|
"./rokkit": "./src/rokkit/index.css",
|
|
@@ -20,17 +26,22 @@
|
|
|
20
26
|
"./material": "./src/material/index.css",
|
|
21
27
|
"./material/*": "./src/material/*.css",
|
|
22
28
|
"./glass": "./src/glass/index.css",
|
|
23
|
-
"./glass/*": "./src/glass/*.css"
|
|
24
|
-
"./palette.css": "./src/palette.css"
|
|
29
|
+
"./glass/*": "./src/glass/*.css"
|
|
25
30
|
},
|
|
26
31
|
"files": [
|
|
27
|
-
"src"
|
|
32
|
+
"src",
|
|
33
|
+
"dist",
|
|
34
|
+
"build.mjs"
|
|
28
35
|
],
|
|
29
36
|
"scripts": {
|
|
30
|
-
"build": "
|
|
37
|
+
"build": "bun run build.mjs"
|
|
31
38
|
},
|
|
32
39
|
"dependencies": {
|
|
33
|
-
"@rokkit/core": "1.0.0-next.
|
|
40
|
+
"@rokkit/core": "1.0.0-next.128"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"magic-string": "^0.30.21",
|
|
44
|
+
"unocss": "^66.5.1"
|
|
34
45
|
},
|
|
35
46
|
"keywords": [
|
|
36
47
|
"themes",
|
package/src/base/button.css
CHANGED
|
@@ -57,6 +57,10 @@
|
|
|
57
57
|
padding: 0;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
[data-button][data-icon-only] [data-item-text] {
|
|
61
|
+
display: none;
|
|
62
|
+
}
|
|
63
|
+
|
|
60
64
|
/* =============================================================================
|
|
61
65
|
Size Variants
|
|
62
66
|
============================================================================= */
|
|
@@ -75,7 +79,7 @@
|
|
|
75
79
|
|
|
76
80
|
[data-button][data-size='sm'] [data-item-icon],
|
|
77
81
|
[data-button][data-size='sm'] [data-button-icon-right] {
|
|
78
|
-
font-size:
|
|
82
|
+
font-size: 1.25rem;
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
/* Medium (default) */
|
|
@@ -96,7 +100,7 @@
|
|
|
96
100
|
[data-button][data-size='md'] [data-button-icon-right],
|
|
97
101
|
[data-button]:not([data-size]) [data-item-icon],
|
|
98
102
|
[data-button]:not([data-size]) [data-button-icon-right] {
|
|
99
|
-
font-size:
|
|
103
|
+
font-size: 1.5rem;
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
/* Large */
|
|
@@ -113,7 +117,7 @@
|
|
|
113
117
|
|
|
114
118
|
[data-button][data-size='lg'] [data-item-icon],
|
|
115
119
|
[data-button][data-size='lg'] [data-button-icon-right] {
|
|
116
|
-
font-size: 1.
|
|
120
|
+
font-size: 1.875rem;
|
|
117
121
|
}
|
|
118
122
|
|
|
119
123
|
/* =============================================================================
|
package/src/base/connector.css
CHANGED
|
@@ -48,8 +48,6 @@
|
|
|
48
48
|
[data-connector-v] {
|
|
49
49
|
grid-column: 1;
|
|
50
50
|
grid-row: 1;
|
|
51
|
-
border-right-width: 1px;
|
|
52
|
-
border-right-style: solid;
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
/* Vertical line - full height (for 'child' and 'sibling' connectors) */
|
|
@@ -61,18 +59,12 @@
|
|
|
61
59
|
[data-connector-h] {
|
|
62
60
|
grid-column: 2;
|
|
63
61
|
grid-row: 1;
|
|
64
|
-
border-bottom-width: 1px;
|
|
65
|
-
border-bottom-style: solid;
|
|
66
62
|
}
|
|
67
63
|
|
|
68
64
|
/* Corner connector for RTL - combines vertical and horizontal */
|
|
69
65
|
[data-connector-corner] {
|
|
70
66
|
grid-column: 1;
|
|
71
67
|
grid-row: 1;
|
|
72
|
-
border-bottom-width: 1px;
|
|
73
|
-
border-bottom-style: solid;
|
|
74
|
-
border-right-width: 1px;
|
|
75
|
-
border-right-style: solid;
|
|
76
68
|
}
|
|
77
69
|
|
|
78
70
|
/* =============================================================================
|
|
@@ -81,9 +73,6 @@
|
|
|
81
73
|
|
|
82
74
|
[data-connector][data-connector-rtl] [data-connector-v] {
|
|
83
75
|
grid-column: 2;
|
|
84
|
-
border-right-width: 0;
|
|
85
|
-
border-left-width: 1px;
|
|
86
|
-
border-left-style: solid;
|
|
87
76
|
}
|
|
88
77
|
|
|
89
78
|
[data-connector][data-connector-rtl] [data-connector-h] {
|
|
@@ -92,9 +81,6 @@
|
|
|
92
81
|
|
|
93
82
|
[data-connector][data-connector-rtl] [data-connector-corner] {
|
|
94
83
|
grid-column: 2;
|
|
95
|
-
border-right-width: 0;
|
|
96
|
-
border-left-width: 1px;
|
|
97
|
-
border-left-style: solid;
|
|
98
84
|
}
|
|
99
85
|
|
|
100
86
|
/* =============================================================================
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grid - Base Structural Styles
|
|
3
|
+
*
|
|
4
|
+
* Layout: CSS grid with auto-fill, tile padding/sizing.
|
|
5
|
+
* No colors or visual theming - those belong in theme styles.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/* =============================================================================
|
|
9
|
+
Grid Container
|
|
10
|
+
============================================================================= */
|
|
11
|
+
|
|
12
|
+
[data-grid] {
|
|
13
|
+
display: grid;
|
|
14
|
+
grid-template-columns: repeat(auto-fill, minmax(var(--grid-min-size, 120px), 1fr));
|
|
15
|
+
gap: var(--grid-gap, 1rem);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
[data-grid][data-disabled] {
|
|
19
|
+
pointer-events: none;
|
|
20
|
+
opacity: 0.5;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* =============================================================================
|
|
24
|
+
Grid Tiles
|
|
25
|
+
============================================================================= */
|
|
26
|
+
|
|
27
|
+
[data-grid-item] {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
align-items: center;
|
|
31
|
+
justify-content: center;
|
|
32
|
+
gap: 0.5rem;
|
|
33
|
+
padding: 1rem;
|
|
34
|
+
border: 1px solid transparent;
|
|
35
|
+
border-radius: 0.5rem;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
transition:
|
|
38
|
+
background-color 150ms ease,
|
|
39
|
+
border-color 150ms ease;
|
|
40
|
+
background: transparent;
|
|
41
|
+
text-align: center;
|
|
42
|
+
word-break: break-word;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
[data-grid-item]:focus {
|
|
46
|
+
outline: none;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
[data-grid-item][data-disabled],
|
|
50
|
+
[data-grid-item]:disabled {
|
|
51
|
+
pointer-events: none;
|
|
52
|
+
opacity: 0.5;
|
|
53
|
+
cursor: not-allowed;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* =============================================================================
|
|
57
|
+
Size Variants
|
|
58
|
+
============================================================================= */
|
|
59
|
+
|
|
60
|
+
[data-grid][data-size='sm'] [data-grid-item] {
|
|
61
|
+
padding: 0.5rem;
|
|
62
|
+
gap: 0.25rem;
|
|
63
|
+
font-size: 0.75rem;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
[data-grid][data-size='md'] [data-grid-item],
|
|
67
|
+
[data-grid]:not([data-size]) [data-grid-item] {
|
|
68
|
+
padding: 1rem;
|
|
69
|
+
gap: 0.5rem;
|
|
70
|
+
font-size: 0.875rem;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
[data-grid][data-size='lg'] [data-grid-item] {
|
|
74
|
+
padding: 1.5rem;
|
|
75
|
+
gap: 0.75rem;
|
|
76
|
+
font-size: 1rem;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* =============================================================================
|
|
80
|
+
Item Elements (reuse shared data-item-* from item.css)
|
|
81
|
+
============================================================================= */
|
|
82
|
+
|
|
83
|
+
[data-grid-item] [data-item-icon] {
|
|
84
|
+
font-size: 1.5rem;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[data-grid][data-size='sm'] [data-grid-item] [data-item-icon] {
|
|
88
|
+
font-size: 1.25rem;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
[data-grid][data-size='lg'] [data-grid-item] [data-item-icon] {
|
|
92
|
+
font-size: 2rem;
|
|
93
|
+
}
|
package/src/base/index.css
CHANGED
package/src/base/input.css
CHANGED
|
@@ -12,16 +12,16 @@
|
|
|
12
12
|
|
|
13
13
|
/* Separator between form fields */
|
|
14
14
|
[data-form-separator] {
|
|
15
|
-
@apply border-
|
|
15
|
+
@apply border-surface-z2 my-1 border-t;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/* Form group (fieldset for nested objects) */
|
|
19
19
|
[data-form-group] {
|
|
20
|
-
@apply flex flex-col gap-3 border-
|
|
20
|
+
@apply border-surface-z2 m-0 flex flex-col gap-3 border-l border-none p-0 pl-3;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
[data-form-group-label] {
|
|
24
|
-
@apply text-xs font-semibold
|
|
24
|
+
@apply pb-1 text-xs font-semibold;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/* Validation report */
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
[data-validation-group-header] {
|
|
37
|
-
@apply flex items-center gap-1.5 text-xs font-semibold
|
|
37
|
+
@apply flex items-center gap-1.5 py-1 text-xs font-semibold;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
[data-validation-count] {
|
|
41
|
-
@apply inline-flex items-center justify-center rounded-full text-[10px] font-bold
|
|
41
|
+
@apply inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full px-1 text-[10px] font-bold;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
[data-severity='error'] > [data-validation-group-header] {
|
|
@@ -74,21 +74,21 @@
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
[data-validation-item] {
|
|
77
|
-
@apply
|
|
77
|
+
@apply rounded px-2 py-0.5 text-left text-xs;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
button[data-validation-item] {
|
|
81
|
-
@apply cursor-pointer
|
|
81
|
+
@apply hover:bg-surface-z1 cursor-pointer border-none bg-transparent;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
/* Form actions (submit/reset buttons) */
|
|
85
85
|
[data-form-actions] {
|
|
86
|
-
@apply flex flex-row gap-2
|
|
86
|
+
@apply flex flex-row justify-end gap-2 pt-2;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
button[data-form-submit],
|
|
90
90
|
button[data-form-reset] {
|
|
91
|
-
@apply
|
|
91
|
+
@apply border-surface-z3 bg-surface-z1 hover:bg-surface-z2 cursor-pointer rounded border px-4 py-1.5 text-sm transition-colors;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
button[data-form-submit] {
|
|
@@ -97,12 +97,12 @@ button[data-form-submit] {
|
|
|
97
97
|
|
|
98
98
|
button[data-form-submit]:disabled,
|
|
99
99
|
button[data-form-reset]:disabled {
|
|
100
|
-
@apply
|
|
100
|
+
@apply cursor-not-allowed opacity-50;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
/* Submitting state: reduce interactivity */
|
|
104
104
|
[data-form-submitting] > :not([data-form-actions]) {
|
|
105
|
-
@apply
|
|
105
|
+
@apply pointer-events-none opacity-60;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
/* Field root container */
|
|
@@ -148,7 +148,7 @@ button[data-form-reset]:disabled {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
[data-field-info] {
|
|
151
|
-
@apply text-xs
|
|
151
|
+
@apply font-mono text-xs;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
/* Numeric/date input alignment */
|
|
@@ -219,6 +219,10 @@ input[type='color'] {
|
|
|
219
219
|
@apply p-0;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
[data-input-root] [data-input-icon] {
|
|
223
|
+
@apply mx-2 aspect-square min-h-full flex-shrink-0;
|
|
224
|
+
}
|
|
225
|
+
|
|
222
226
|
/* Responsive adjustments */
|
|
223
227
|
@media (max-width: 640px) {
|
|
224
228
|
[data-field-root] {
|
package/src/base/item.css
CHANGED
|
@@ -13,6 +13,18 @@
|
|
|
13
13
|
flex-shrink: 0;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/* =============================================================================
|
|
17
|
+
Item Avatar
|
|
18
|
+
============================================================================= */
|
|
19
|
+
|
|
20
|
+
[data-item-avatar] {
|
|
21
|
+
flex-shrink: 0;
|
|
22
|
+
width: 1.5em;
|
|
23
|
+
height: 1.5em;
|
|
24
|
+
border-radius: 9999px;
|
|
25
|
+
object-fit: cover;
|
|
26
|
+
}
|
|
27
|
+
|
|
16
28
|
/* =============================================================================
|
|
17
29
|
Item Text Container
|
|
18
30
|
============================================================================= */
|
|
@@ -50,3 +62,17 @@
|
|
|
50
62
|
font-weight: 500;
|
|
51
63
|
border-radius: 9999px;
|
|
52
64
|
}
|
|
65
|
+
|
|
66
|
+
/* =============================================================================
|
|
67
|
+
Item Shortcut
|
|
68
|
+
============================================================================= */
|
|
69
|
+
|
|
70
|
+
[data-item-shortcut] {
|
|
71
|
+
flex-shrink: 0;
|
|
72
|
+
margin-left: auto;
|
|
73
|
+
padding: 0.125rem 0.375rem;
|
|
74
|
+
font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
|
|
75
|
+
font-size: 0.75em;
|
|
76
|
+
font-weight: 500;
|
|
77
|
+
border-radius: 0.25rem;
|
|
78
|
+
}
|