@aihu/css-engine 0.3.0 → 0.4.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/README.md +11 -11
- package/crates/aihu-css-core/src/apply.rs +314 -0
- package/crates/aihu-css-core/src/bin/main.rs +8 -7
- package/crates/aihu-css-core/src/cache.rs +8 -5
- package/crates/aihu-css-core/src/emit.rs +110 -30
- package/crates/aihu-css-core/src/lib.rs +10 -2
- package/crates/aihu-css-core/src/palette.rs +301 -0
- package/crates/aihu-css-core/src/style_parser.rs +587 -0
- package/crates/aihu-css-core/src/tokens.rs +625 -29
- package/crates/aihu-css-core/src/variants.rs +154 -7
- package/crates/aihu-css-core/tests/apply.rs +203 -0
- package/crates/aihu-css-core/tests/apply_regression.rs +150 -0
- package/crates/aihu-css-core/tests/binary_error.rs +61 -0
- package/crates/aihu-css-core/tests/cache.rs +8 -8
- package/crates/aihu-css-core/tests/emit.rs +95 -36
- package/crates/aihu-css-core/tests/parity.rs +274 -0
- package/crates/aihu-css-core/tests/progressive_snapshot.rs +8 -8
- package/crates/aihu-css-core/tests/scoped_snapshot.rs +49 -11
- package/crates/aihu-css-core/tests/snapshots/apply__apply_inside_nested_rule.snap +11 -0
- package/crates/aihu-css-core/tests/snapshots/apply__arbitrary_value_utility_in_apply.snap +8 -0
- package/crates/aihu-css-core/tests/snapshots/apply__arbitrary_value_variant_in_apply.snap +10 -0
- package/crates/aihu-css-core/tests/snapshots/apply__base_utility_inlines_declarations.snap +9 -0
- package/crates/aihu-css-core/tests/snapshots/apply__dark_variant_cascade_in_apply.snap +10 -0
- package/crates/aihu-css-core/tests/snapshots/apply__data_attribute_variant.snap +10 -0
- package/crates/aihu-css-core/tests/snapshots/apply__multi_token_apply.snap +11 -0
- package/crates/aihu-css-core/tests/snapshots/apply__multiple_apply_directives_per_rule.snap +12 -0
- package/crates/aihu-css-core/tests/snapshots/apply__responsive_variant_wraps_media.snap +12 -0
- package/crates/aihu-css-core/tests/snapshots/apply__single_variant_lifts_to_nested_rule.snap +10 -0
- package/crates/aihu-css-core/tests/snapshots/progressive_snapshot__anchor_snapshot.snap +1 -0
- package/crates/aihu-css-core/tests/snapshots/progressive_snapshot__popover_snapshot.snap +1 -0
- package/crates/aihu-css-core/tests/snapshots/progressive_snapshot__text_balance_snapshot.snap +1 -0
- package/crates/aihu-css-core/tests/snapshots/progressive_snapshot__view_transition_snapshot.snap +1 -0
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_animate_spin_hoists_keyframes.snap +1 -1
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_divide_y_nested_rule.snap +1 -0
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_output_for_sfc.snap +1 -0
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_space_y_nested_rule.snap +1 -0
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_transition_and_transform.snap +1 -1
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_with_authored_style_block.snap +6 -2
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_with_global_style_block.snap +5 -2
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__standard_variants.snap +1 -0
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__theme_default_vs_override.snap +2 -0
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__wc_native_variants.snap +1 -0
- package/crates/aihu-css-core/tests/style_parser.rs +257 -0
- package/crates/aihu-css-core/tests/tokens.rs +52 -0
- package/dist/index.d.ts +0 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -18
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
|
@@ -22,7 +22,7 @@ fn sfc(classes: &str) -> aihu_css_core::SfcAst {
|
|
|
22
22
|
|
|
23
23
|
#[test]
|
|
24
24
|
fn view_transition_is_supports_gated_css_only() {
|
|
25
|
-
let css = compile_sfc_scoped(&sfc("view-transition:hero"));
|
|
25
|
+
let css = compile_sfc_scoped(&sfc("view-transition:hero")).unwrap();
|
|
26
26
|
assert!(
|
|
27
27
|
css.contains("@supports (view-transition-name: none)"),
|
|
28
28
|
"view-transition gated behind @supports: {css}"
|
|
@@ -36,14 +36,14 @@ fn view_transition_is_supports_gated_css_only() {
|
|
|
36
36
|
|
|
37
37
|
#[test]
|
|
38
38
|
fn view_transition_snapshot() {
|
|
39
|
-
insta::assert_snapshot!(compile_sfc_scoped(&sfc("view-transition:hero")));
|
|
39
|
+
insta::assert_snapshot!(compile_sfc_scoped(&sfc("view-transition:hero")).unwrap());
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
// ── Task 6: anchor: (@supports gate + JS fallback marker) ────────────────────
|
|
43
43
|
|
|
44
44
|
#[test]
|
|
45
45
|
fn anchor_is_supports_gated_with_js_marker() {
|
|
46
|
-
let css = compile_sfc_scoped(&sfc("anchor:tooltip"));
|
|
46
|
+
let css = compile_sfc_scoped(&sfc("anchor:tooltip")).unwrap();
|
|
47
47
|
assert!(
|
|
48
48
|
css.contains("@supports (anchor-name: --a)"),
|
|
49
49
|
"anchor gated behind @supports (anchor-name): {css}"
|
|
@@ -57,14 +57,14 @@ fn anchor_is_supports_gated_with_js_marker() {
|
|
|
57
57
|
|
|
58
58
|
#[test]
|
|
59
59
|
fn anchor_snapshot() {
|
|
60
|
-
insta::assert_snapshot!(compile_sfc_scoped(&sfc("anchor:tooltip")));
|
|
60
|
+
insta::assert_snapshot!(compile_sfc_scoped(&sfc("anchor:tooltip")).unwrap());
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
// ── Task 7: popover: (@supports gate + portal JS fallback marker) ────────────
|
|
64
64
|
|
|
65
65
|
#[test]
|
|
66
66
|
fn popover_is_supports_gated_with_js_marker() {
|
|
67
|
-
let css = compile_sfc_scoped(&sfc("popover:menu"));
|
|
67
|
+
let css = compile_sfc_scoped(&sfc("popover:menu")).unwrap();
|
|
68
68
|
assert!(
|
|
69
69
|
css.contains("@supports (selector(:popover-open))"),
|
|
70
70
|
"popover gated behind @supports selector(:popover-open): {css}"
|
|
@@ -77,14 +77,14 @@ fn popover_is_supports_gated_with_js_marker() {
|
|
|
77
77
|
|
|
78
78
|
#[test]
|
|
79
79
|
fn popover_snapshot() {
|
|
80
|
-
insta::assert_snapshot!(compile_sfc_scoped(&sfc("popover:menu")));
|
|
80
|
+
insta::assert_snapshot!(compile_sfc_scoped(&sfc("popover:menu")).unwrap());
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
// ── Task 8: text-balance: (no gate, no JS) ───────────────────────────────────
|
|
84
84
|
|
|
85
85
|
#[test]
|
|
86
86
|
fn text_balance_no_gate_no_js() {
|
|
87
|
-
let css = compile_sfc_scoped(&sfc("text-balance:"));
|
|
87
|
+
let css = compile_sfc_scoped(&sfc("text-balance:")).unwrap();
|
|
88
88
|
assert!(css.contains("text-wrap: balance"), "emits text-wrap: balance: {css}");
|
|
89
89
|
assert!(
|
|
90
90
|
!css.contains("@supports"),
|
|
@@ -98,5 +98,5 @@ fn text_balance_no_gate_no_js() {
|
|
|
98
98
|
|
|
99
99
|
#[test]
|
|
100
100
|
fn text_balance_snapshot() {
|
|
101
|
-
insta::assert_snapshot!(compile_sfc_scoped(&sfc("text-balance:")));
|
|
101
|
+
insta::assert_snapshot!(compile_sfc_scoped(&sfc("text-balance:")).unwrap());
|
|
102
102
|
}
|
|
@@ -25,7 +25,7 @@ fn flat_output_for_class_list() {
|
|
|
25
25
|
|
|
26
26
|
#[test]
|
|
27
27
|
fn scoped_output_for_sfc() {
|
|
28
|
-
insta::assert_snapshot!(compile_sfc_scoped(&sfc("bg-primary p-4 rounded-lg")));
|
|
28
|
+
insta::assert_snapshot!(compile_sfc_scoped(&sfc("bg-primary p-4 rounded-lg")).unwrap());
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
#[test]
|
|
@@ -35,7 +35,7 @@ fn scoped_with_authored_style_block() {
|
|
|
35
35
|
"meta":{"name":"Card"},
|
|
36
36
|
"template":[{"kind":"element","tag":"div","attrs":[
|
|
37
37
|
{"kind":"static","name":"class","value":"p-4 shadow-md"}],"children":[]}]}"#;
|
|
38
|
-
insta::assert_snapshot!(compile_sfc_scoped(&ast(json)));
|
|
38
|
+
insta::assert_snapshot!(compile_sfc_scoped(&ast(json)).unwrap());
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
#[test]
|
|
@@ -43,14 +43,14 @@ fn scoped_with_global_style_block() {
|
|
|
43
43
|
let json = r#"{"tag":"X","astVersion":1,
|
|
44
44
|
"style":{"content":"body { margin: 0; }","scope":"global"},
|
|
45
45
|
"meta":{"name":"X"},"template":null}"#;
|
|
46
|
-
insta::assert_snapshot!(compile_sfc_scoped(&ast(json)));
|
|
46
|
+
insta::assert_snapshot!(compile_sfc_scoped(&ast(json)).unwrap());
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
#[test]
|
|
50
50
|
fn scoped_space_y_nested_rule() {
|
|
51
51
|
// Locks in the nested `& > * + *` sibling-margin shape inside component
|
|
52
52
|
// scope (Round 1: tailwind-support `space-x/y-*` family).
|
|
53
|
-
insta::assert_snapshot!(compile_sfc_scoped(&sfc("space-y-4")));
|
|
53
|
+
insta::assert_snapshot!(compile_sfc_scoped(&sfc("space-y-4")).unwrap());
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
#[test]
|
|
@@ -59,7 +59,7 @@ fn scoped_divide_y_nested_rule() {
|
|
|
59
59
|
// scope (Round 2: tailwind-support `divide-x/y-*` family). Confirms the
|
|
60
60
|
// nested rule survives the scoped CSS-nesting emission path, mirroring
|
|
61
61
|
// `scoped_space_y_nested_rule`.
|
|
62
|
-
insta::assert_snapshot!(compile_sfc_scoped(&sfc("divide-y-2")));
|
|
62
|
+
insta::assert_snapshot!(compile_sfc_scoped(&sfc("divide-y-2")).unwrap());
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
#[test]
|
|
@@ -67,7 +67,7 @@ fn scoped_animate_spin_hoists_keyframes() {
|
|
|
67
67
|
// Locks the `animate-*` emission shape: the scoped `.animate-spin` rule
|
|
68
68
|
// followed by a hoisted top-level `@keyframes spin` sibling (Round 2:
|
|
69
69
|
// tailwind-support `motion` track).
|
|
70
|
-
insta::assert_snapshot!(compile_sfc_scoped(&sfc("animate-spin")));
|
|
70
|
+
insta::assert_snapshot!(compile_sfc_scoped(&sfc("animate-spin")).unwrap());
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
#[test]
|
|
@@ -75,32 +75,70 @@ fn scoped_transition_and_transform() {
|
|
|
75
75
|
// Locks transition shorthand + a transform utility under component scope.
|
|
76
76
|
insta::assert_snapshot!(compile_sfc_scoped(&sfc(
|
|
77
77
|
"transition-transform duration-300 hover:scale-105"
|
|
78
|
-
)));
|
|
78
|
+
)).unwrap());
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
#[test]
|
|
82
82
|
fn wc_native_variants() {
|
|
83
83
|
insta::assert_snapshot!(compile_sfc_scoped(&sfc(
|
|
84
84
|
"host:bg-primary slotted:p-4 slotted-img:rounded-lg part-thumb:bg-accent host-context-dark:bg-surface"
|
|
85
|
-
)));
|
|
85
|
+
)).unwrap());
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
#[test]
|
|
89
89
|
fn standard_variants() {
|
|
90
90
|
insta::assert_snapshot!(compile_sfc_scoped(&sfc(
|
|
91
91
|
"hover:bg-primary focus:text-accent dark:bg-surface md:p-8 [&>div]:text-primary md:hover:bg-primary"
|
|
92
|
-
)));
|
|
92
|
+
)).unwrap());
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
#[test]
|
|
96
|
+
fn style_block_does_not_suppress_scanned_utilities() {
|
|
97
|
+
// Regression for #278: an `@style` block must NOT make the utility-class
|
|
98
|
+
// scanner mutually exclusive. Both the scanned template utilities AND the
|
|
99
|
+
// authored `@style` content must land in the same scoped stylesheet.
|
|
100
|
+
//
|
|
101
|
+
// Repro: `<div class="text-3xl gap-4">` + `@style { .__probe__ { ... } }`.
|
|
102
|
+
// Before the fix the sheet contained ONLY `.__probe__`; the utilities
|
|
103
|
+
// vanished. Assert all three rules coexist (concatenated).
|
|
104
|
+
let json = r#"{"tag":"Probe","astVersion":1,
|
|
105
|
+
"style":{"content":".__probe__ { color: rgb(1,2,3); }","scope":"scoped"},
|
|
106
|
+
"meta":{"name":"Probe"},
|
|
107
|
+
"template":[{"kind":"element","tag":"div","attrs":[
|
|
108
|
+
{"kind":"static","name":"class","value":"text-3xl gap-4"}],"children":[]}]}"#;
|
|
109
|
+
// `.unwrap()` added in the PR-1 merge: compile_sfc_scoped now returns Result.
|
|
110
|
+
let css = compile_sfc_scoped(&ast(json)).unwrap();
|
|
111
|
+
|
|
112
|
+
// Scanned template utilities survive.
|
|
113
|
+
assert!(
|
|
114
|
+
css.contains(".text-3xl"),
|
|
115
|
+
"scanned utility .text-3xl missing when @style present:\n{css}"
|
|
116
|
+
);
|
|
117
|
+
assert!(
|
|
118
|
+
css.contains(".gap-4"),
|
|
119
|
+
"scanned utility .gap-4 missing when @style present:\n{css}"
|
|
120
|
+
);
|
|
121
|
+
// Authored @style content survives. (PR-1 merge: authored @style is now
|
|
122
|
+
// re-rendered through the shared @style parser to enable @apply, so it is
|
|
123
|
+
// whitespace-normalized rather than byte-identical — assert the selector
|
|
124
|
+
// and declaration are present, not the exact single-line form. The #278
|
|
125
|
+
// regression intent (scanned utilities AND authored @style coexist) holds.)
|
|
126
|
+
assert!(css.contains(".__probe__"), "authored @style selector missing:\n{css}");
|
|
127
|
+
assert!(
|
|
128
|
+
css.contains("color: rgb(1,2,3)"),
|
|
129
|
+
"authored @style declaration missing:\n{css}"
|
|
130
|
+
);
|
|
93
131
|
}
|
|
94
132
|
|
|
95
133
|
#[test]
|
|
96
134
|
fn theme_default_vs_override() {
|
|
97
|
-
let default = compile_sfc_scoped(&sfc("bg-primary"));
|
|
135
|
+
let default = compile_sfc_scoped(&sfc("bg-primary")).unwrap();
|
|
98
136
|
let json = r#"{"tag":"X","astVersion":1,
|
|
99
137
|
"style":{"content":"@theme { --color-primary: oklch(0.55 0.18 28); }","scope":"scoped"},
|
|
100
138
|
"meta":{"name":"X"},
|
|
101
139
|
"template":[{"kind":"element","tag":"div","attrs":[
|
|
102
140
|
{"kind":"static","name":"class","value":"bg-primary"}],"children":[]}]}"#;
|
|
103
|
-
let overridden = compile_sfc_scoped(&ast(json));
|
|
141
|
+
let overridden = compile_sfc_scoped(&ast(json)).unwrap();
|
|
104
142
|
insta::assert_snapshot!(format!(
|
|
105
143
|
"--- default ---\n{default}\n--- override ---\n{overridden}"
|
|
106
144
|
));
|
|
@@ -20,6 +20,7 @@ expression: "compile_sfc_scoped(&sfc(\"anchor:tooltip\"))"
|
|
|
20
20
|
--color-surface: #faf8f4;
|
|
21
21
|
--color-surface-foreground: #1a1d24;
|
|
22
22
|
}
|
|
23
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
23
24
|
@supports (anchor-name: --a) {
|
|
24
25
|
.anchor\:tooltip { anchor-name: --tooltip; position-anchor: --tooltip; }
|
|
25
26
|
}
|
|
@@ -20,6 +20,7 @@ expression: "compile_sfc_scoped(&sfc(\"popover:menu\"))"
|
|
|
20
20
|
--color-surface: #faf8f4;
|
|
21
21
|
--color-surface-foreground: #1a1d24;
|
|
22
22
|
}
|
|
23
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
23
24
|
@supports (selector(:popover-open)) {
|
|
24
25
|
.popover\:menu:popover-open { position: fixed; margin: 0; inset: auto; }
|
|
25
26
|
}
|
package/crates/aihu-css-core/tests/snapshots/progressive_snapshot__view_transition_snapshot.snap
CHANGED
|
@@ -20,6 +20,7 @@ expression: "compile_sfc_scoped(&sfc(\"view-transition:hero\"))"
|
|
|
20
20
|
--color-surface: #faf8f4;
|
|
21
21
|
--color-surface-foreground: #1a1d24;
|
|
22
22
|
}
|
|
23
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
23
24
|
@supports (view-transition-name: none) {
|
|
24
25
|
.view-transition\:hero { view-transition-name: hero; }
|
|
25
26
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
---
|
|
2
2
|
source: packages/css-engine/crates/aihu-css-core/tests/scoped_snapshot.rs
|
|
3
|
-
assertion_line: 61
|
|
4
3
|
expression: "compile_sfc_scoped(&sfc(\"animate-spin\"))"
|
|
5
4
|
---
|
|
6
5
|
:host {
|
|
@@ -21,5 +20,6 @@ expression: "compile_sfc_scoped(&sfc(\"animate-spin\"))"
|
|
|
21
20
|
--color-surface: #faf8f4;
|
|
22
21
|
--color-surface-foreground: #1a1d24;
|
|
23
22
|
}
|
|
23
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
24
24
|
.animate-spin { animation: spin 1s linear infinite; }
|
|
25
25
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
@@ -20,6 +20,7 @@ expression: "compile_sfc_scoped(&sfc(\"bg-primary p-4 rounded-lg\"))"
|
|
|
20
20
|
--color-surface: #faf8f4;
|
|
21
21
|
--color-surface-foreground: #1a1d24;
|
|
22
22
|
}
|
|
23
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
23
24
|
.bg-primary { background-color: var(--color-primary); }
|
|
24
25
|
.p-4 { padding: 1rem; }
|
|
25
26
|
.rounded-lg { border-radius: 0.5rem; }
|
package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_transition_and_transform.snap
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
---
|
|
2
2
|
source: packages/css-engine/crates/aihu-css-core/tests/scoped_snapshot.rs
|
|
3
|
-
assertion_line: 67
|
|
4
3
|
expression: "compile_sfc_scoped(&sfc(\"transition-transform duration-300 hover:scale-105\"))"
|
|
5
4
|
---
|
|
6
5
|
:host {
|
|
@@ -21,6 +20,7 @@ expression: "compile_sfc_scoped(&sfc(\"transition-transform duration-300 hover:s
|
|
|
21
20
|
--color-surface: #faf8f4;
|
|
22
21
|
--color-surface-foreground: #1a1d24;
|
|
23
22
|
}
|
|
23
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
24
24
|
.duration-300 { transition-duration: 300ms; }
|
|
25
25
|
.hover\:scale-105:hover { transform: scale(1.05); }
|
|
26
26
|
.transition-transform { transition-property: transform; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
|
package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_with_authored_style_block.snap
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
source: packages/css-engine/crates/aihu-css-core/tests/scoped_snapshot.rs
|
|
3
|
-
expression: compile_sfc_scoped(&ast(json))
|
|
3
|
+
expression: compile_sfc_scoped(&ast(json)).unwrap()
|
|
4
4
|
---
|
|
5
5
|
:host {
|
|
6
6
|
--color-accent: #c8543a;
|
|
@@ -20,7 +20,11 @@ expression: compile_sfc_scoped(&ast(json))
|
|
|
20
20
|
--color-surface: #faf8f4;
|
|
21
21
|
--color-surface-foreground: #1a1d24;
|
|
22
22
|
}
|
|
23
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
23
24
|
.p-4 { padding: 1rem; }
|
|
24
25
|
.shadow-md { box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1); }
|
|
25
26
|
/* authored @style (scoped) */
|
|
26
|
-
.inner {
|
|
27
|
+
.inner {
|
|
28
|
+
display: grid;
|
|
29
|
+
gap: 1rem;
|
|
30
|
+
}
|
package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_with_global_style_block.snap
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
source: packages/css-engine/crates/aihu-css-core/tests/scoped_snapshot.rs
|
|
3
|
-
expression: compile_sfc_scoped(&ast(json))
|
|
3
|
+
expression: compile_sfc_scoped(&ast(json)).unwrap()
|
|
4
4
|
---
|
|
5
5
|
:host {
|
|
6
6
|
--color-accent: #c8543a;
|
|
@@ -20,5 +20,8 @@ expression: compile_sfc_scoped(&ast(json))
|
|
|
20
20
|
--color-surface: #faf8f4;
|
|
21
21
|
--color-surface-foreground: #1a1d24;
|
|
22
22
|
}
|
|
23
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
23
24
|
/* authored @style ($global — unscoped) */
|
|
24
|
-
body {
|
|
25
|
+
body {
|
|
26
|
+
margin: 0;
|
|
27
|
+
}
|
|
@@ -20,6 +20,7 @@ expression: "compile_sfc_scoped(&sfc(\"hover:bg-primary focus:text-accent dark:b
|
|
|
20
20
|
--color-surface: #faf8f4;
|
|
21
21
|
--color-surface-foreground: #1a1d24;
|
|
22
22
|
}
|
|
23
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
23
24
|
.\[&>div\]\:text-primary>div { color: var(--color-primary); }
|
|
24
25
|
/* dark cascade (Firefox-safe; see decision-firefox-host-context-workaround) */
|
|
25
26
|
:host([data-theme="dark"]) .dark\:bg-surface, :root.dark .dark\:bg-surface { background-color: var(--color-surface); }
|
package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__theme_default_vs_override.snap
CHANGED
|
@@ -21,6 +21,7 @@ expression: "format!(\"--- default ---\\n{default}\\n--- override ---\\n{overrid
|
|
|
21
21
|
--color-surface: #faf8f4;
|
|
22
22
|
--color-surface-foreground: #1a1d24;
|
|
23
23
|
}
|
|
24
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
24
25
|
.bg-primary { background-color: var(--color-primary); }
|
|
25
26
|
|
|
26
27
|
--- override ---
|
|
@@ -42,4 +43,5 @@ expression: "format!(\"--- default ---\\n{default}\\n--- override ---\\n{overrid
|
|
|
42
43
|
--color-surface: #faf8f4;
|
|
43
44
|
--color-surface-foreground: #1a1d24;
|
|
44
45
|
}
|
|
46
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
45
47
|
.bg-primary { background-color: var(--color-primary); }
|
|
@@ -20,6 +20,7 @@ expression: "compile_sfc_scoped(&sfc(\"host:bg-primary slotted:p-4 slotted-img:r
|
|
|
20
20
|
--color-surface: #faf8f4;
|
|
21
21
|
--color-surface-foreground: #1a1d24;
|
|
22
22
|
}
|
|
23
|
+
*, ::before, ::after { border-style: solid; border-width: 0; }
|
|
23
24
|
/* dark cascade (Firefox-safe; see decision-firefox-host-context-workaround) */
|
|
24
25
|
:host([data-theme="dark"]) .host-context-dark\:bg-surface, :root.dark .host-context-dark\:bg-surface { background-color: var(--color-surface); }
|
|
25
26
|
:host(.host\:bg-primary) { background-color: var(--color-primary); }
|