superdesk-ui-framework 4.1.3 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/CODEOWNERS +1 -1
- package/.github/PULL_REQUEST_TEMPLATE.md +17 -0
- package/.mocharc.json +1 -1
- package/README.md +1 -1
- package/app-typescript/components/Lists/LoadMoreIndicator.tsx +105 -0
- package/app-typescript/components/Lists/index.tsx +1 -0
- package/app-typescript/components/TimePicker/TimePickerPopover.spec.ts +163 -0
- package/app-typescript/components/TimePicker/TimePickerPopover.tsx +286 -0
- package/app-typescript/components/TimePicker/TimeValueHolder.tsx +36 -0
- package/app-typescript/components/{TimePicker.tsx → TimePicker/index.tsx} +6 -17
- package/dist/components/Index.tsx +5 -0
- package/dist/components/LoadMoreIndicator.tsx +251 -0
- package/dist/components/TimePicker.tsx +7 -2
- package/dist/components/tsconfig.json +10 -0
- package/dist/examples.bundle.js +1468 -1161
- package/dist/superdesk-ui.bundle.js +853 -688
- package/dist/vendor.bundle.js +15 -15
- package/package.json +4 -2
- package/react/components/Lists/LoadMoreIndicator.d.ts +52 -0
- package/react/components/Lists/LoadMoreIndicator.js +79 -0
- package/react/components/Lists/index.d.ts +1 -0
- package/react/components/Lists/index.js +3 -1
- package/react/components/TimePicker/TimePickerPopover.d.ts +27 -0
- package/react/components/TimePicker/TimePickerPopover.js +231 -0
- package/react/components/TimePicker/TimeValueHolder.d.ts +13 -0
- package/react/components/TimePicker/TimeValueHolder.js +73 -0
- package/react/components/{TimePicker.d.ts → TimePicker/index.d.ts} +1 -1
- package/react/components/{TimePicker.js → TimePicker/index.js} +6 -14
- package/.travis.yml +0 -9
- package/app-typescript/components/TimePickerPopover.tsx +0 -294
- package/react/components/TimePickerPopover.d.ts +0 -19
- package/react/components/TimePickerPopover.js +0 -227
|
@@ -48,6 +48,7 @@ import SimpleListDoc from './SimpleList';
|
|
|
48
48
|
import BoxedListDoc from './BoxedList';
|
|
49
49
|
import TableListDoc from './TableList';
|
|
50
50
|
import ContentListDoc from './ContentList';
|
|
51
|
+
import LoadMoreIndicatorDoc from './LoadMoreIndicator';
|
|
51
52
|
import HeadingDoc from './Heading';
|
|
52
53
|
import TextDoc from './Text';
|
|
53
54
|
import ContainerDoc from './Container';
|
|
@@ -290,6 +291,10 @@ const pages: IPages = {
|
|
|
290
291
|
name: 'Content list',
|
|
291
292
|
component: ContentListDoc,
|
|
292
293
|
},
|
|
294
|
+
'load-more-indicator': {
|
|
295
|
+
name: 'Load more indicator',
|
|
296
|
+
component: LoadMoreIndicatorDoc,
|
|
297
|
+
},
|
|
293
298
|
'with-pagination': {
|
|
294
299
|
name: 'With pagination',
|
|
295
300
|
component: WithPaginationDocs,
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as Markup from '../../js/react';
|
|
3
|
+
import {LoadMoreIndicator, PropsList, Prop} from '../../../app-typescript';
|
|
4
|
+
|
|
5
|
+
interface IState {
|
|
6
|
+
showExample1: boolean;
|
|
7
|
+
showExample2: boolean;
|
|
8
|
+
showExample3: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default class LoadMoreIndicatorDoc extends React.Component<{}, IState> {
|
|
12
|
+
constructor(props: {}) {
|
|
13
|
+
super(props);
|
|
14
|
+
this.state = {
|
|
15
|
+
showExample1: true,
|
|
16
|
+
showExample2: true,
|
|
17
|
+
showExample3: true,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
render() {
|
|
22
|
+
return (
|
|
23
|
+
<section className="docs-page__container">
|
|
24
|
+
<h2 className="docs-page__h2">LoadMoreIndicator</h2>
|
|
25
|
+
<Markup.ReactMarkupCodePreview>
|
|
26
|
+
{`
|
|
27
|
+
<LoadMoreIndicator
|
|
28
|
+
loading={true}
|
|
29
|
+
currentCount={25}
|
|
30
|
+
totalCount={100}
|
|
31
|
+
/>
|
|
32
|
+
`}
|
|
33
|
+
</Markup.ReactMarkupCodePreview>
|
|
34
|
+
<p className="docs-page__paragraph">
|
|
35
|
+
A loading indicator component designed to be appended at the end of scrollable lists during infinite
|
|
36
|
+
scroll/pagination. Shows a spinner with optional progress counter.
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
<Markup.ReactMarkup>
|
|
40
|
+
<Markup.ReactMarkupPreview>
|
|
41
|
+
<p className="docs-page__paragraph">// Default with progress counter</p>
|
|
42
|
+
<div style={{border: '1px solid var(--sd-colour-line--light)', borderRadius: '4px'}}>
|
|
43
|
+
<ul className="sd-list-item-group">
|
|
44
|
+
<li className="sd-list-item">
|
|
45
|
+
<div className="sd-list-item__column">Item 1</div>
|
|
46
|
+
</li>
|
|
47
|
+
<li className="sd-list-item">
|
|
48
|
+
<div className="sd-list-item__column">Item 2</div>
|
|
49
|
+
</li>
|
|
50
|
+
<li className="sd-list-item">
|
|
51
|
+
<div className="sd-list-item__column">Item 3</div>
|
|
52
|
+
</li>
|
|
53
|
+
<LoadMoreIndicator loading={this.state.showExample1} currentCount={3} totalCount={10} />
|
|
54
|
+
</ul>
|
|
55
|
+
</div>
|
|
56
|
+
</Markup.ReactMarkupPreview>
|
|
57
|
+
<Markup.ReactMarkupCode>
|
|
58
|
+
{`
|
|
59
|
+
<ul className="sd-list-item-group">
|
|
60
|
+
<li className="sd-list-item">...</li>
|
|
61
|
+
<li className="sd-list-item">...</li>
|
|
62
|
+
<li className="sd-list-item">...</li>
|
|
63
|
+
<LoadMoreIndicator
|
|
64
|
+
loading={true}
|
|
65
|
+
currentCount={3}
|
|
66
|
+
totalCount={10}
|
|
67
|
+
/>
|
|
68
|
+
</ul>
|
|
69
|
+
`}
|
|
70
|
+
</Markup.ReactMarkupCode>
|
|
71
|
+
</Markup.ReactMarkup>
|
|
72
|
+
|
|
73
|
+
<Markup.ReactMarkup>
|
|
74
|
+
<Markup.ReactMarkupPreview>
|
|
75
|
+
<p className="docs-page__paragraph">// Without progress counter</p>
|
|
76
|
+
<div style={{border: '1px solid var(--sd-colour-line--light)', borderRadius: '4px'}}>
|
|
77
|
+
<ul className="sd-list-item-group">
|
|
78
|
+
<li className="sd-list-item">
|
|
79
|
+
<div className="sd-list-item__column">Item 1</div>
|
|
80
|
+
</li>
|
|
81
|
+
<li className="sd-list-item">
|
|
82
|
+
<div className="sd-list-item__column">Item 2</div>
|
|
83
|
+
</li>
|
|
84
|
+
<LoadMoreIndicator
|
|
85
|
+
loading={this.state.showExample2}
|
|
86
|
+
currentCount={2}
|
|
87
|
+
totalCount={10}
|
|
88
|
+
showProgress={false}
|
|
89
|
+
/>
|
|
90
|
+
</ul>
|
|
91
|
+
</div>
|
|
92
|
+
</Markup.ReactMarkupPreview>
|
|
93
|
+
<Markup.ReactMarkupCode>
|
|
94
|
+
{`
|
|
95
|
+
<LoadMoreIndicator
|
|
96
|
+
loading={true}
|
|
97
|
+
currentCount={2}
|
|
98
|
+
totalCount={10}
|
|
99
|
+
showProgress={false}
|
|
100
|
+
/>
|
|
101
|
+
`}
|
|
102
|
+
</Markup.ReactMarkupCode>
|
|
103
|
+
</Markup.ReactMarkup>
|
|
104
|
+
|
|
105
|
+
<Markup.ReactMarkup>
|
|
106
|
+
<Markup.ReactMarkupPreview>
|
|
107
|
+
<p className="docs-page__paragraph">// Custom text and loader size</p>
|
|
108
|
+
<div style={{border: '1px solid var(--sd-colour-line--light)', borderRadius: '4px'}}>
|
|
109
|
+
<ul className="sd-list-item-group">
|
|
110
|
+
<li className="sd-list-item">
|
|
111
|
+
<div className="sd-list-item__column">Item 1</div>
|
|
112
|
+
</li>
|
|
113
|
+
<LoadMoreIndicator
|
|
114
|
+
loading={this.state.showExample3}
|
|
115
|
+
currentCount={1}
|
|
116
|
+
totalCount={5}
|
|
117
|
+
loadingText="Fetching more items..."
|
|
118
|
+
size="medium"
|
|
119
|
+
/>
|
|
120
|
+
</ul>
|
|
121
|
+
</div>
|
|
122
|
+
</Markup.ReactMarkupPreview>
|
|
123
|
+
<Markup.ReactMarkupCode>
|
|
124
|
+
{`
|
|
125
|
+
<LoadMoreIndicator
|
|
126
|
+
loading={true}
|
|
127
|
+
currentCount={1}
|
|
128
|
+
totalCount={5}
|
|
129
|
+
loadingText="Fetching more items..."
|
|
130
|
+
size="medium"
|
|
131
|
+
/>
|
|
132
|
+
`}
|
|
133
|
+
</Markup.ReactMarkupCode>
|
|
134
|
+
</Markup.ReactMarkup>
|
|
135
|
+
|
|
136
|
+
<h3 className="docs-page__h3">Props</h3>
|
|
137
|
+
<PropsList>
|
|
138
|
+
<Prop
|
|
139
|
+
name="loading"
|
|
140
|
+
isRequired={true}
|
|
141
|
+
type="boolean"
|
|
142
|
+
default="/"
|
|
143
|
+
description="Whether the loading indicator should be visible"
|
|
144
|
+
/>
|
|
145
|
+
<Prop
|
|
146
|
+
name="currentCount"
|
|
147
|
+
isRequired={true}
|
|
148
|
+
type="number"
|
|
149
|
+
default="/"
|
|
150
|
+
description="Current number of loaded items"
|
|
151
|
+
/>
|
|
152
|
+
<Prop
|
|
153
|
+
name="totalCount"
|
|
154
|
+
isRequired={true}
|
|
155
|
+
type="number"
|
|
156
|
+
default="/"
|
|
157
|
+
description="Total number of items available"
|
|
158
|
+
/>
|
|
159
|
+
<Prop
|
|
160
|
+
name="loadingText"
|
|
161
|
+
isRequired={false}
|
|
162
|
+
type="string"
|
|
163
|
+
default="'Loading more...'"
|
|
164
|
+
description="Custom loading text"
|
|
165
|
+
/>
|
|
166
|
+
<Prop
|
|
167
|
+
name="showProgress"
|
|
168
|
+
isRequired={false}
|
|
169
|
+
type="boolean"
|
|
170
|
+
default="true"
|
|
171
|
+
description="Whether to show the progress counter (e.g., '25 of 100')"
|
|
172
|
+
/>
|
|
173
|
+
<Prop
|
|
174
|
+
name="size"
|
|
175
|
+
isRequired={false}
|
|
176
|
+
type="'small' | 'medium' | 'large'"
|
|
177
|
+
default="'small'"
|
|
178
|
+
description="Size of the loader spinner"
|
|
179
|
+
/>
|
|
180
|
+
<Prop
|
|
181
|
+
name="className"
|
|
182
|
+
isRequired={false}
|
|
183
|
+
type="string"
|
|
184
|
+
default="/"
|
|
185
|
+
description="Custom className for the container"
|
|
186
|
+
/>
|
|
187
|
+
<Prop
|
|
188
|
+
name="data-test-id"
|
|
189
|
+
isRequired={false}
|
|
190
|
+
type="string"
|
|
191
|
+
default="'load-more-indicator'"
|
|
192
|
+
description="Test ID for testing purposes"
|
|
193
|
+
/>
|
|
194
|
+
</PropsList>
|
|
195
|
+
|
|
196
|
+
<h3 className="docs-page__h3">Usage with Infinite Scroll</h3>
|
|
197
|
+
<p className="docs-page__paragraph">
|
|
198
|
+
This component is designed to work with infinite scroll patterns. Simply add it at the end of your
|
|
199
|
+
list and control its visibility with a loading state that tracks when you're fetching more items.
|
|
200
|
+
</p>
|
|
201
|
+
<Markup.ReactMarkupCode>
|
|
202
|
+
{`
|
|
203
|
+
class MyListComponent extends React.Component {
|
|
204
|
+
state = { isNextPageLoading: false };
|
|
205
|
+
|
|
206
|
+
handleScroll = (event) => {
|
|
207
|
+
if (this.state.isNextPageLoading) return;
|
|
208
|
+
|
|
209
|
+
const node = event.target;
|
|
210
|
+
if (node.scrollTop + node.offsetHeight + 200 >= node.scrollHeight) {
|
|
211
|
+
this.setState({ isNextPageLoading: true });
|
|
212
|
+
this.props.loadMore()
|
|
213
|
+
.finally(() => this.setState({ isNextPageLoading: false }));
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
render() {
|
|
218
|
+
return (
|
|
219
|
+
<ul onScroll={this.handleScroll}>
|
|
220
|
+
{this.props.items.map(item => <li key={item.id}>{item.name}</li>)}
|
|
221
|
+
<LoadMoreIndicator
|
|
222
|
+
loading={this.state.isNextPageLoading}
|
|
223
|
+
currentCount={this.props.items.length}
|
|
224
|
+
totalCount={this.props.totalCount}
|
|
225
|
+
/>
|
|
226
|
+
</ul>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
`}
|
|
231
|
+
</Markup.ReactMarkupCode>
|
|
232
|
+
|
|
233
|
+
<h3 className="docs-page__h3">Accessibility</h3>
|
|
234
|
+
<p className="docs-page__paragraph">
|
|
235
|
+
The component includes proper ARIA attributes for screen readers:
|
|
236
|
+
</p>
|
|
237
|
+
<ul className="docs-page__ul">
|
|
238
|
+
<li>
|
|
239
|
+
<code>role="status"</code> - Indicates the element is a status message
|
|
240
|
+
</li>
|
|
241
|
+
<li>
|
|
242
|
+
<code>aria-live="polite"</code> - Screen readers will announce updates when convenient
|
|
243
|
+
</li>
|
|
244
|
+
<li>
|
|
245
|
+
<code>aria-busy="true"</code> - Indicates the section is being updated
|
|
246
|
+
</li>
|
|
247
|
+
</ul>
|
|
248
|
+
</section>
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
@@ -36,7 +36,12 @@ class TimePickerExample extends React.PureComponent<{}, {time: string | null}> {
|
|
|
36
36
|
<Button size="small" text="In 30 min" style="hollow" onClick={() => false} />
|
|
37
37
|
<Button size="small" text="In 1 hr" style="hollow" onClick={() => false} />
|
|
38
38
|
<Button size="small" text="In 2 hr" style="hollow" onClick={() => false} />
|
|
39
|
-
<Button
|
|
39
|
+
<Button
|
|
40
|
+
size="small"
|
|
41
|
+
text="16:32"
|
|
42
|
+
style="hollow"
|
|
43
|
+
onClick={() => this.setState({time: '16:32'})}
|
|
44
|
+
/>
|
|
40
45
|
</ButtonGroup>
|
|
41
46
|
}
|
|
42
47
|
footerTemplate={<div>Footer</div>}
|
|
@@ -65,7 +70,7 @@ export default class TimePickerDoc extends React.Component<{}, {time: string}> {
|
|
|
65
70
|
render() {
|
|
66
71
|
return (
|
|
67
72
|
<section className="docs-page__container">
|
|
68
|
-
<h2 className="docs-page__h2">Time picker</h2>
|
|
73
|
+
<h2 className="docs-page__h2">Time picker 1</h2>
|
|
69
74
|
<Markup.ReactMarkupCodePreview>{`
|
|
70
75
|
<TimePicker
|
|
71
76
|
value={this.state.time}
|