Skip to content

Commit 1d1987b

Browse files
committed
feat: add support for toggling classes using 'domClass' property
1 parent 47765a3 commit 1d1987b

File tree

4 files changed

+50
-13
lines changed

4 files changed

+50
-13
lines changed

Diff for: cypress/integration/test.spec.js

+6
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,11 @@ context('Page load', () => {
2121
cy.wrap($el[0].foo).should('eq', 3)
2222
})
2323
})
24+
it('Should allow toggling className items based on domClass prop', () => {
25+
cy.get('.clicker')
26+
.then(($el) => {
27+
cy.wrap($el[0].className).should('eq', 'clicker hello')
28+
})
29+
})
2430
})
2531
})

Diff for: example/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function main(sources) {
2222
const vdom$ = count$.map(i =>
2323
h2('div', [
2424
h2('h1', `Hello ${i} times`),
25-
h2('button', {sel: btnSel, className: 'clicker', domProps: {foo: 3}}, 'Reset'),
25+
h2('button', {sel: btnSel, className: 'clicker', domProps: {foo: 3}, domClass: {hello: true, goodbye: false}}, 'Reset'),
2626
]),
2727
);
2828

Diff for: src/h2.ts

+43-12
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,43 @@ import {incorporate} from './incorporate';
1515
export type PropsExtensions = {
1616
sel?: string | symbol;
1717
domProps?: any
18+
domHook?: any
19+
domClass?: any
1820
};
1921

2022
type PropsLike<P> = P & PropsExtensions & Attributes;
2123

2224
type Children = string | Array<ReactNode>;
2325

26+
export function domClassify(Comp: any): ComponentType<any> {
27+
class DomProps extends Component<any, any> {
28+
private ref: any;
29+
private additionalClassname: string;
30+
constructor(props) {
31+
super(props);
32+
this.additionalClassname = this.props.domClass
33+
? (' ' + Object.entries(this.props.domClass).filter(x => x[1]).map(x => x[0]).join(' '))
34+
: ''
35+
this.ref = props.forwardedRef || createRef();
36+
}
37+
38+
render() {
39+
const p: any = {
40+
ref: this.ref,
41+
...this.props,
42+
className: (this.props.className || '') + this.additionalClassname
43+
}
44+
delete p.forwardedRef
45+
delete p.domClass;
46+
return createElement(Comp, p);
47+
}
48+
}
49+
50+
return forwardRef((props, ref) => {
51+
return createElement(DomProps, {...props, forwardedRef: ref});
52+
});
53+
}
54+
2455
export function domPropify(Comp: any): ComponentType<any> {
2556
class DomProps extends Component<any, any> {
2657
private ref: any;
@@ -55,28 +86,28 @@ export function domPropify(Comp: any): ComponentType<any> {
5586
export function domHookify(Comp: any): ComponentType<any> {
5687
class DomHooks extends Component<any, any> {
5788
private ref: any;
58-
private hooks: any;
89+
private hook: any;
5990
constructor(props) {
6091
super(props);
61-
this.hooks = this.props.domHooks;
92+
this.hook = this.props.domHook;
6293
this.ref = props.forwardedRef || createRef();
6394
}
6495

6596
public componentDidMount() {
66-
if (this.hooks && this.hooks.insert && this.ref) {
67-
this.hooks.insert({elm: this.ref.current})
97+
if (this.hook && this.hook.insert && this.ref) {
98+
this.hook.insert({elm: this.ref.current})
6899
}
69100
}
70101

71102
public componentDidUpdate() {
72-
if (this.hooks && this.hooks.update && this.ref) {
73-
this.hooks.update({elm: this.ref.current})
103+
if (this.hook && this.hook.update && this.ref) {
104+
this.hook.update({elm: this.ref.current})
74105
}
75106
}
76107

77108
public componentWillUnmount() {
78-
if (this.hooks && this.hooks.destroy && this.ref) {
79-
this.hooks.destroy({elm: this.ref.current})
109+
if (this.hook && this.hook.destroy && this.ref) {
110+
this.hook.destroy({elm: this.ref.current})
80111
}
81112
}
82113

@@ -109,10 +140,10 @@ function hyperscriptProps<P = any>(
109140
type: ElementType<P> | keyof ReactHTML,
110141
props: PropsLike<P>,
111142
): ReactElement<P> {
112-
if (!props.sel) {
143+
if (!props.sel && !props.domClass && !props.domHook) {
113144
return createElement(type, props);
114145
} else {
115-
return createElement(domHookify(domPropify(incorporate(type))), props);
146+
return createElement(domHookify(domPropify(domClassify(incorporate(type)))), props);
116147
}
117148
}
118149

@@ -128,10 +159,10 @@ function hyperscriptPropsChildren<P = any>(
128159
props: PropsLike<P>,
129160
children: Children,
130161
): ReactElement<P> {
131-
if (!props.sel) {
162+
if (!props.sel && !props.domClass && !props.domHook) {
132163
return createElementSpreading(type, props, children);
133164
} else {
134-
return createElementSpreading(domHookify(domPropify(incorporate(type))), props, children);
165+
return createElementSpreading(domHookify(domPropify(domClassify(incorporate(type)))), props, children);
135166
}
136167
}
137168

0 commit comments

Comments
 (0)