Skip to content

Commit 7fc1289

Browse files
committed
fix svg animation
SVGElement::className isn’t a `string`, it’s a `SVGAnimatedString`
1 parent bc1e3c8 commit 7fc1289

File tree

2 files changed

+104
-7
lines changed

2 files changed

+104
-7
lines changed

src/CSSCore.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,24 @@ const RE_CLASS = /[\n\t\r]+/g;
1717
let norm = elemClass => (SPACE + elemClass + SPACE).replace(RE_CLASS, SPACE);
1818

1919
export function addClass(elem, className) {
20-
elem.className += ' ' + className;
20+
if (elem.classList) {
21+
elem.classList.add(className);
22+
} else {
23+
elem.className += ' ' + className;
24+
}
2125
}
2226

2327
export function removeClass(elem, needle) {
24-
let elemClass = elem.className.trim();
25-
let className = norm(elemClass);
2628
needle = needle.trim();
27-
needle = SPACE + needle + SPACE;
28-
while (className.indexOf(needle) >= 0) {
29-
className = className.replace(needle, SPACE);
29+
if (elem.classList) {
30+
elem.classList.remove(needle);
31+
} else {
32+
let elemClass = elem.className.trim();
33+
let className = norm(elemClass);
34+
needle = SPACE + needle + SPACE;
35+
while (className.indexOf(needle) >= 0) {
36+
className = className.replace(needle, SPACE);
37+
}
38+
elem.className = className.trim();
3039
}
31-
elem.className = className.trim();
3240
}

tests/index.js

+89
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,38 @@ class TodoList extends Component {
5151
}
5252
}
5353

54+
class SVGList extends Component {
55+
state = {
56+
items: ['hello', 'world', 'click', 'me']
57+
};
58+
59+
handleAdd(item) {
60+
let { items } = this.state;
61+
items = items.concat(item);
62+
this.setState({ items });
63+
}
64+
65+
handleRemove(i) {
66+
let { items } = this.state;
67+
items.splice(i, 1);
68+
this.setState({ items });
69+
}
70+
71+
render(_, { items }) {
72+
return (
73+
<svg>
74+
<CSSTransitionGroup transitionName="example" component="g">
75+
{ items.map( (item, i) => (
76+
<text key={item} className="item">
77+
{item}
78+
</text>
79+
)) }
80+
</CSSTransitionGroup>
81+
</svg>
82+
);
83+
}
84+
}
85+
5486

5587
const Nothing = () => null;
5688

@@ -115,3 +147,60 @@ describe('CSSTransitionGroup', () => {
115147
}, 1400);
116148
});
117149
});
150+
151+
describe('CSSTransitionGroup: SVG', () => {
152+
let container = document.createElement('div'),
153+
list, root;
154+
document.body.appendChild(container);
155+
156+
let $ = s => [].slice.call(container.querySelectorAll(s));
157+
158+
beforeEach( () => {
159+
root = render(<div><Nothing /></div>, container, root);
160+
root = render(<div><SVGList ref={c => list=c} /></div>, container, root);
161+
});
162+
163+
afterEach( () => {
164+
list = null;
165+
});
166+
167+
it('create works', () => {
168+
expect($('.item')).to.have.length(4);
169+
});
170+
171+
it('transitionLeave works', done => {
172+
list.handleRemove(0);
173+
174+
setTimeout( () => {
175+
expect($('.item')).to.have.length(4);
176+
177+
expect($('.item')[0].classList.contains('example-leave'));
178+
expect($('.item')[0].classList.contains('example-leave-active'));
179+
}, 100);
180+
181+
setTimeout( () => {
182+
expect($('.item')).to.have.length(3);
183+
done();
184+
}, 1400);
185+
});
186+
187+
it('transitionEnter works', done => {
188+
list.handleAdd(Date.now());
189+
190+
setTimeout( () => {
191+
expect($('.item')).to.have.length(5);
192+
193+
expect($('.item')[4].classList.contains('example-enter'));
194+
expect($('.item')[4].classList.contains('example-enter-active'));
195+
}, 500);
196+
197+
setTimeout( () => {
198+
expect($('.item')).to.have.length(5);
199+
200+
expect(!$('.item')[4].classList.contains('example-enter'));
201+
expect(!$('.item')[4].classList.contains('example-enter-active'));
202+
203+
done();
204+
}, 1400);
205+
});
206+
});

0 commit comments

Comments
 (0)