UNPKG

7.2 kBJavaScriptView Raw
1import React from 'react';
2import {render} from 'react-dom';
3import {connect} from 'react-redux';
4import {createStore} from 'redux';
5import actions from './actions';
6import {reducers} from './reducers';
7
8
9const NoItems = () => {
10
11 return (
12 <div
13 key={null}
14 className="item item-no-results"
15 >No results found</div>
16 );
17};
18
19const Presentation = ({...props}) => {
20 let topBar;
21 const visibleItems = Object.keys(props.visibleItems).map((item) => {
22 return (
23 <div
24 onClick={() => {
25 props.submit({
26 selected: item,
27 selectedItemLabel: props.items[item]
28 });
29 focus();
30 }}
31 key={item}
32 className={
33 (item == props.currentlyHighlighted) ? 'item item-selected' : 'item'
34 }
35 >
36 {props.items[item]}
37 </div>
38 )
39
40 });
41 const focus = () => {
42 if (topBar)
43 topBar.focus();
44 };
45 return (
46 <div
47 className="select-react-redux-container"
48 ref={(input) => {
49 if (props.initialRender && input) {
50 props.initialRenderFalse();
51 document.addEventListener('click', function (event) {
52 if (!input.contains(event.target)) {
53 props.refresh();
54 }
55 });
56
57 }
58
59 }}>
60 <a href="#"
61 tabIndex={props.tabIndex}
62 onClick={props.topBarOnClick}
63 onKeyPress={props.linkOnKeyPress}
64 autoFocus
65 onKeyDown={e => {
66 if (e.key.indexOf('Arrow') == 0) {
67 props.linkOnKeyPress(e)
68 }
69 }}
70 className={props.open ? 'selected selected-open' : 'selected'}
71 ref={function (input) {
72 if (input && props.open) {
73 topBar = input;
74 focus();
75 }
76 }}
77 >
78 <div
79 className={Object.keys(props.items).length == 0 ? 'top-bar top-bar-empty' : 'top-bar'}>
80 { Object.keys(props.items).length == 0 ? 'No options available' :
81 props.selectedItemLabel
82 ? props.selectedItemLabel
83 : 'Please select...'}
84 </div>
85 </a>
86
87 <div className={props.open ? 'results-container open' : 'results-container' }>
88 <div className="input-container">
89 <input
90 type="text"
91 autoCorrect="off"
92 autoCapitalize="off"
93 spellCheck="false"
94 autoComplete="off"
95 ref={(item) => {
96 if (item && props.open) {
97 item.focus()
98 }
99 }}
100 value={props.visibilityFilter}
101 onKeyPress={(e) => {
102 if (e.key === 'Enter' && props.open) {
103 props.submit({
104 selected: props.currentlyHighlighted,
105 selectedItemLabel: props.items[props.currentlyHighlighted]
106 });
107 focus();
108 }
109 }}
110 onChange={props.inputOnChange}
111 onKeyDown={(e) => {
112 props.inputOnKeyDown(e);
113 if (e.key == 'Escape') {
114 focus();
115 }
116 }}
117 />
118 </div>
119 {visibleItems.length > 0 ? visibleItems : <NoItems/>}
120 </div>
121 </div>
122 );
123};
124
125const Stateless = ({items, selected = null, tabIndex = null, onChange}) => {
126
127 const store = createStore(reducers);
128
129 store.dispatch({type: '@@redux/INIT'});
130
131 window.store = store;
132
133 store.dispatch({type: actions.SET_ITEMS, payload: items});
134
135 if (selected) {
136 store.dispatch({
137 type: actions.SET_SELECTED, payload: {
138 selected: selected,
139 selectedItemLabel: items[selected]
140 }
141 });
142 }
143
144 if (tabIndex) {
145 store.dispatch({type: actions.SET_TABINDEX, payload: tabIndex})
146 }
147
148 const mapStateToProps = (state = {}) => {
149 return state;
150 };
151
152 const mapDispatchToProps = (dispatch) => {
153 return {
154 submit: (item) => {
155 if (item.selected) {
156 dispatch({type: actions.SET_SELECTED, payload: item});
157 dispatch({type: actions.SET_OPEN, payload: false});
158 dispatch({type: actions.SET_FILTER, payload: ''});
159 onChange(item.selected);
160 }
161 },
162 linkOnKeyPress: (e) => {
163 if (e.key != 'Escape') {
164 dispatch({type: actions.SET_OPEN, payload: true});
165 dispatch({type: actions.SET_FILTER, payload: ''});
166 }
167 },
168
169 inputOnChange: (e) => {
170 dispatch({type: actions.SET_FILTER, payload: e.target.value})
171 },
172 inputOnKeyDown: (e) => {
173 if (e.key === 'ArrowDown') {
174 dispatch({type: actions.SET_NEXT_HIGHLIGHTED, payload: false})
175 }
176
177 if (e.key === 'ArrowUp') {
178 dispatch({type: actions.SET_PREV_HIGHLIGHTED, payload: false})
179 }
180
181 if (e.key === 'Escape') {
182 dispatch({type: actions.SET_OPEN, payload: false});
183 dispatch({type: actions.SET_FILTER, payload: ''});
184 }
185 },
186 topBarOnClick: () => {
187 dispatch({type: actions.TOGGLE_OPEN});
188 },
189
190 initialRenderFalse: () => {
191 dispatch({type: actions.SET_INITIAL_RENDER_FALSE});
192 },
193 refresh: () => {
194 dispatch({type: actions.SET_OPEN, payload: false});
195 dispatch({type: actions.SET_FILTER, payload: ''});
196 }
197 }
198 };
199
200 const SelectWithStore = connect(
201 mapStateToProps,
202 mapDispatchToProps
203 )(Presentation);
204
205 return (
206 <SelectWithStore store={store}/>
207 )
208};
209
210
211export class Select extends React.Component {
212 constructor(props) {
213 super(props);
214 }
215
216
217 shouldComponentUpdate() {
218 console.log('should component update');
219 return true;
220 }
221
222 componentWillReceiveProps(nextProps) {
223 console.log('fdf');
224 console.log(nextProps);
225 }
226
227 render() {
228 return (
229 <Stateless {...this.props} />
230 )
231 }
232}
\No newline at end of file