ripple 0.2.169 → 0.2.170
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/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Ripple is an elegant TypeScript UI framework",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dominic Gannaway",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.170",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"module": "src/runtime/index-client.js",
|
|
9
9
|
"main": "src/runtime/index-client.js",
|
|
@@ -81,6 +81,6 @@
|
|
|
81
81
|
"typescript": "^5.9.2"
|
|
82
82
|
},
|
|
83
83
|
"peerDependencies": {
|
|
84
|
-
"ripple": "0.2.
|
|
84
|
+
"ripple": "0.2.170"
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -845,6 +845,26 @@ function get_parent_rules(rule) {
|
|
|
845
845
|
return rules;
|
|
846
846
|
}
|
|
847
847
|
|
|
848
|
+
/**
|
|
849
|
+
* Check if a CSS rule contains animation or animation-name properties
|
|
850
|
+
* @param {Compiler.AST.CSS.Rule} rule
|
|
851
|
+
* @returns {boolean}
|
|
852
|
+
*/
|
|
853
|
+
function rule_has_animation(rule) {
|
|
854
|
+
if (!rule.block) return false;
|
|
855
|
+
|
|
856
|
+
for (const child of rule.block.children) {
|
|
857
|
+
if (child.type === 'Declaration') {
|
|
858
|
+
const prop = child.property?.toLowerCase();
|
|
859
|
+
if (prop === 'animation' || prop === 'animation-name') {
|
|
860
|
+
return true;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
return false;
|
|
866
|
+
}
|
|
867
|
+
|
|
848
868
|
export function prune_css(css, element) {
|
|
849
869
|
walk(css, null, {
|
|
850
870
|
Rule(node, context) {
|
|
@@ -859,14 +879,9 @@ export function prune_css(css, element) {
|
|
|
859
879
|
|
|
860
880
|
seen.clear();
|
|
861
881
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
/** @type {Compiler.AST.CSS.Rule} */ (node.metadata.rule),
|
|
866
|
-
element,
|
|
867
|
-
BACKWARD,
|
|
868
|
-
)
|
|
869
|
-
) {
|
|
882
|
+
const rule = /** @type {Compiler.AST.CSS.Rule} */ (node.metadata.rule);
|
|
883
|
+
|
|
884
|
+
if (apply_selector(selectors, rule, element, BACKWARD) || rule_has_animation(rule)) {
|
|
870
885
|
node.metadata.used = true;
|
|
871
886
|
}
|
|
872
887
|
|
|
@@ -195,7 +195,7 @@ const visitors = {
|
|
|
195
195
|
const character = state.code.original[index];
|
|
196
196
|
|
|
197
197
|
if (regex_css_name_boundary.test(character)) {
|
|
198
|
-
if (
|
|
198
|
+
if (name) {
|
|
199
199
|
const append_index = index - name.length;
|
|
200
200
|
state.keyframes[name] ??= { indexes: [], local: undefined };
|
|
201
201
|
if (state.keyframes[name].local) {
|
|
@@ -98,4 +98,61 @@ export component Test() {
|
|
|
98
98
|
expect(css).toContain('@keyframes foo');
|
|
99
99
|
expect(css).toContain('@keyframes bar');
|
|
100
100
|
});
|
|
101
|
+
|
|
102
|
+
it('handles animation property referencing keyframes (not marking as unused)', () => {
|
|
103
|
+
const source = `
|
|
104
|
+
export component Parent() {
|
|
105
|
+
<div class="parent">
|
|
106
|
+
<Child />
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<style>
|
|
110
|
+
/* Scoped keyframe - only usable within Parent */
|
|
111
|
+
@keyframes slideIn {
|
|
112
|
+
from { transform: translateX(-100%); }
|
|
113
|
+
to { transform: translateX(0); }
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Global keyframe - usable in any component */
|
|
117
|
+
@keyframes -global-fadeIn {
|
|
118
|
+
0% { opacity: 0; }
|
|
119
|
+
100% { opacity: 1; }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.parent {
|
|
123
|
+
animation: slideIn 1s;
|
|
124
|
+
}
|
|
125
|
+
</style>
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
component Child() {
|
|
129
|
+
<div class="child">{'Child content'}</div>
|
|
130
|
+
|
|
131
|
+
<style>
|
|
132
|
+
.child {
|
|
133
|
+
animation: fadeIn 3s; /* Uses global fadeIn from Parent */
|
|
134
|
+
}
|
|
135
|
+
</style>
|
|
136
|
+
}`;
|
|
137
|
+
const { css } = compile(source, 'test.ripple');
|
|
138
|
+
|
|
139
|
+
// Parent should have scoped slideIn and global fadeIn
|
|
140
|
+
expect(css).toMatch(/@keyframes ripple-[a-z0-9]+-slideIn/);
|
|
141
|
+
expect(css).toContain('@keyframes fadeIn');
|
|
142
|
+
expect(css).not.toContain('-global-fadeIn');
|
|
143
|
+
|
|
144
|
+
// Parent .parent should reference scoped slideIn
|
|
145
|
+
expect(css).toMatch(
|
|
146
|
+
/\.parent\.ripple-[a-z0-9]+\s*{[\s\S]*?animation:\s*ripple-[a-z0-9]+-slideIn 1s/,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// .parent should NOT be marked as unused
|
|
150
|
+
expect(css).not.toContain('(unused) .parent');
|
|
151
|
+
|
|
152
|
+
// Child .child should reference global fadeIn
|
|
153
|
+
expect(css).toMatch(/\.child\.ripple-[a-z0-9]+\s*{[\s\S]*?animation:\s*fadeIn 3s/);
|
|
154
|
+
|
|
155
|
+
// .child should NOT be marked as unused
|
|
156
|
+
expect(css).not.toContain('(unused) .child');
|
|
157
|
+
});
|
|
101
158
|
});
|