Skip to content

Commit c7c127e

Browse files
committed
feat: create invert() function
1 parent 134aff7 commit c7c127e

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

src/invert.story.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import {Component, createElement as h} from 'react';
2+
import {storiesOf} from '@storybook/react';
3+
import {action} from '@storybook/addon-actions';
4+
import {linkTo} from '@storybook/addon-links';
5+
import {invert} from './invert';
6+
7+
const Audio = invert('audio');
8+
9+
storiesOf('invert()', module)
10+
.add('<audio>', () =>
11+
<Audio
12+
src='https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3'
13+
onTimeUpdate={() => {}}
14+
render={(element, comp) =>
15+
<div>
16+
{element}
17+
<button onClick={() => comp.el.play()}>Play</button>
18+
<button onClick={() => comp.el.pause()}>Pause</button>
19+
<button onClick={() => comp.el.currentTime -= 5}>Seek -</button>
20+
<button onClick={() => comp.el.currentTime += 5}>Seek +</button>
21+
<button onClick={() => comp.el.volume -= 0.05}>Volume -</button>
22+
<button onClick={() => comp.el.volume += 0.05}>Volume +</button>
23+
<button onClick={() => comp.el.muted = true}>Mute</button>
24+
<button onClick={() => comp.el.muted = false}>Unmute</button>
25+
<pre style={{fontFamily: 'monospace'}}>
26+
{JSON.stringify({
27+
duration: comp.el && comp.el.duration,
28+
time: comp.el && comp.el.currentTime,
29+
volume: comp.el && comp.el.volume,
30+
muted: comp.el && comp.el.muted
31+
}, null, 4)}
32+
</pre>
33+
</div>
34+
}
35+
/>
36+
);

src/invert.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import {Component} from 'react';
2+
import {h, noop} from './util';
3+
4+
export interface IInvertedProps {
5+
children?: (...args) => React.ReactElement<any>;
6+
onMounted: (el: HTMLElement, comp: React.Component<any>) => void;
7+
render: (element: React.ReactElement<any>, comp: React.Component<any>) => React.ReactElement<any>;
8+
}
9+
10+
export type TInvert = (tag: string) => React.ComponentClass<any>;
11+
12+
const defaultRenderProp = (element) => element;
13+
14+
export const invert: TInvert = (tag: keyof React.ReactHTML) => {
15+
const Inverted = class Inverted extends Component<IInvertedProps, any> {
16+
static defaultProps = {
17+
render: defaultRenderProp
18+
};
19+
20+
el: HTMLElement = null;
21+
22+
ref = (el) => {
23+
this.el = el;
24+
};
25+
26+
componentDidMount () {
27+
(this.props.onMounted || noop)(this.el, this);
28+
}
29+
30+
compnentWillUnmount () {
31+
this.el = null;
32+
}
33+
34+
event (name: string, handler: (...args) => void) {
35+
return (event) => {
36+
handler(event, this);
37+
this.forceUpdate();
38+
};
39+
}
40+
41+
render () {
42+
const {event} = this;
43+
const {children, render, ...rest} = this.props;
44+
const props = {
45+
ref: this.ref
46+
};
47+
48+
for (const name in rest) {
49+
const value = rest[name];
50+
51+
if ((name[0] === 'o') && (name[1] === 'n') && (typeof value === 'function')) {
52+
props[name] = this.event(name, value);
53+
} else {
54+
props[name] = value;
55+
}
56+
}
57+
58+
const element = h(tag, props, typeof children === 'function' ? children(this) : children);
59+
60+
return render(element, this);
61+
}
62+
}
63+
64+
return Inverted;
65+
};

0 commit comments

Comments
 (0)