Skip to content

Commit 53ac0b7

Browse files
add simple action indicator
1 parent 2090e4a commit 53ac0b7

8 files changed

Lines changed: 127 additions & 7 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface ActionListener {
2+
onAction(label: string): void;
3+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { ActionListener } from './ActionListener';
2+
3+
export class ActionsListener {
4+
private listeners: ActionListener[] = [];
5+
6+
add(listener: ActionListener) {
7+
this.listeners.push(listener);
8+
}
9+
10+
remove(listener: ActionListener) {
11+
this.listeners = this.listeners.filter(l => l !== listener);
12+
}
13+
14+
notify(label: string) {
15+
this.listeners.forEach(l => l.onAction(label));
16+
}
17+
}
18+
19+
export const actionsListener = new ActionsListener();
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.rcv-visualized-actions {
2+
display: flex;
3+
flex-direction: column;
4+
align-items: end;
5+
justify-content: end;
6+
7+
position: fixed;
8+
right: 0;
9+
bottom: 0;
10+
11+
z-index: 1000;
12+
}
13+
14+
.rcv-visualized-action {
15+
font-family: var(--rcv-font-family);
16+
background-color: var(--rcv-attention-text-color);
17+
color: white;
18+
19+
padding: 16px;
20+
border: 1px solid var(--rcv-primary-border-color);
21+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import * as React from 'react';
2+
import { actionsListener } from './ActionsListener';
3+
import { ActionListener } from './ActionListener';
4+
import Timer = NodeJS.Timer;
5+
6+
import './VisualizedActions.css';
7+
8+
export interface State {
9+
actionLabelToShow?: string;
10+
timer?: Timer;
11+
}
12+
13+
export class VisualizedActions extends React.Component<{}, State> {
14+
state: State = {
15+
};
16+
17+
private actionListener: ActionListener;
18+
19+
constructor(props: {}) {
20+
super(props);
21+
this.actionListener = {
22+
onAction: this.onNewAction
23+
};
24+
}
25+
26+
render() {
27+
const {actionLabelToShow} = this.state;
28+
29+
return (
30+
<div className="rcv-visualized-actions">
31+
{actionLabelToShow &&
32+
<div className="rcv-visualized-action">{actionLabelToShow}</div>
33+
}
34+
</div>
35+
);
36+
}
37+
38+
componentDidMount() {
39+
actionsListener.add(this.actionListener);
40+
}
41+
42+
componentWillUnmount() {
43+
actionsListener.remove(this.actionListener);
44+
}
45+
46+
private removeActions = () => {
47+
this.setState({actionLabelToShow: undefined});
48+
}
49+
50+
private onNewAction = (label: string) => {
51+
this.setState(prev => {
52+
if (prev.timer) {
53+
clearTimeout(prev.timer);
54+
}
55+
56+
return {
57+
actionLabelToShow: label,
58+
timer: setTimeout(this.removeActions, 3000)
59+
};
60+
});
61+
}
62+
}

src/components/actions/actions.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { actionsListener } from './ActionsListener';
2+
3+
export function simpleAction(label: string) {
4+
return () => {
5+
actionsListener.notify(label);
6+
console.log('action triggered: ' + label);
7+
};
8+
}

src/components/viewer/ComponentViewer.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import { ComponentViewerDropDown } from './ComponentViewerDropDown';
2424
import { ComponentViewerHelp } from './help/ComponentViewerHelp';
2525
import { globalActionDefaultKeys } from './GlobalActions';
2626

27+
import { VisualizedActions } from '../actions/VisualizedActions';
28+
2729
import './ComponentViewer.css';
2830

2931
export interface Props {
@@ -73,6 +75,7 @@ class ComponentViewer extends Component<Props, ComponentViewerState> {
7375
<React.Fragment>
7476
<GlobalHotKeysHandler keyBoundActions={this.hotKeyBoundActions}/>
7577
{rendered}
78+
<VisualizedActions/>
7679
</React.Fragment>
7780
);
7881
}

src/demo-components/Button.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
padding: 8px;
33
border: 1px solid #ccc;
44
border-radius: 4px;
5+
6+
max-width: 240px;
7+
8+
cursor: pointer;
59
}
610

711
.button.primary {

src/demos/buttons.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import * as React from 'react';
22

33
import { Registry } from '../components';
44
import { Button } from '../demo-components/Button';
5+
import { simpleAction } from '../components/actions/actions';
56

6-
function onClick() {
7-
return 0;
8-
}
7+
const onPrimaryClick = simpleAction('primary clicked');
8+
const onSecondaryClick = simpleAction('secondary clicked');
99

1010
export function buttonsDemo(registry: Registry) {
1111
registry
12-
.add('primary', () => <Button primary label="click me" onClick={onClick}/>,
13-
`long description
14-
multiline markdown`)
15-
.add('secondary', () => <Button label="click me" onClick={onClick}/>);
12+
.add('primary',
13+
() => <Button primary label="click me" onClick={onPrimaryClick}/>)
14+
.add('secondary',
15+
() => <Button label="click me" onClick={onSecondaryClick}/>);
1616
}

0 commit comments

Comments
 (0)