@splunk/react-ui 5.7.0 → 5.8.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/Accordion.js +6 -6
- package/Box.js +83 -34
- package/CHANGELOG.md +34 -0
- package/CollapsiblePanel.js +11 -11
- package/ComboBox.js +31 -27
- package/ControlGroup.js +92 -91
- package/DefinitionList.js +9 -9
- package/Drawer.d.ts +2 -0
- package/Drawer.js +679 -0
- package/DualListbox.js +1 -1
- package/JSONTree.js +73 -72
- package/Link.js +2 -2
- package/MIGRATION.md +10 -0
- package/Menu.js +338 -240
- package/Modal.js +127 -109
- package/Multiselect.js +437 -351
- package/Paginator.js +14 -12
- package/Popover.js +4 -1
- package/README.md +11 -0
- package/RadioBar.js +1 -1
- package/Search.js +103 -88
- package/Select.js +42 -40
- package/SelectBase.js +374 -328
- package/SidePanel.js +346 -167
- package/SlidingPanels.js +11 -11
- package/StepBar.js +7 -7
- package/Switch.js +5 -5
- package/Text.js +24 -24
- package/TextArea.js +7 -7
- package/TransitionOpen.js +204 -185
- package/docs-llm/Accordion.md +267 -0
- package/docs-llm/Anchor Menu.md +115 -0
- package/docs-llm/Anchor.md +54 -0
- package/docs-llm/AnimationToggle.md +254 -0
- package/docs-llm/Avatar.md +298 -0
- package/docs-llm/Badge.md +212 -0
- package/docs-llm/Breadcrumbs.md +306 -0
- package/docs-llm/Button Group.md +53 -0
- package/docs-llm/Button.md +361 -0
- package/docs-llm/Card Layout.md +286 -0
- package/docs-llm/Card.md +619 -0
- package/docs-llm/Checkbox.md +218 -0
- package/docs-llm/Chip.md +291 -0
- package/docs-llm/Clickable.md +160 -0
- package/docs-llm/Code.md +292 -0
- package/docs-llm/Collapsible Panel.md +744 -0
- package/docs-llm/Color.md +253 -0
- package/docs-llm/Column Layout.md +391 -0
- package/docs-llm/Combo Box.md +540 -0
- package/docs-llm/Control Group.md +594 -0
- package/docs-llm/Date.md +270 -0
- package/docs-llm/Definition List.md +278 -0
- package/docs-llm/Divider.md +216 -0
- package/docs-llm/Drawer.md +414 -0
- package/docs-llm/Dropdown.md +472 -0
- package/docs-llm/Dual Listbox.md +325 -0
- package/docs-llm/File.md +653 -0
- package/docs-llm/Form Rows.md +374 -0
- package/docs-llm/Heading.md +179 -0
- package/docs-llm/Image.md +109 -0
- package/docs-llm/JSON Tree.md +260 -0
- package/docs-llm/Layer.md +74 -0
- package/docs-llm/Layout.md +50 -0
- package/docs-llm/Link.md +318 -0
- package/docs-llm/List.md +189 -0
- package/docs-llm/Markdown.md +179 -0
- package/docs-llm/Menu.md +735 -0
- package/docs-llm/Message Bar.md +236 -0
- package/docs-llm/Message.md +248 -0
- package/docs-llm/Modal.md +443 -0
- package/docs-llm/Monogram.md +159 -0
- package/docs-llm/Multiselect.md +937 -0
- package/docs-llm/Number.md +298 -0
- package/docs-llm/Paginator.md +395 -0
- package/docs-llm/Paragraph.md +148 -0
- package/docs-llm/Phone Number.md +254 -0
- package/docs-llm/Popover.md +166 -0
- package/docs-llm/Progress.md +141 -0
- package/docs-llm/Radio Bar.md +303 -0
- package/docs-llm/Radio List.md +350 -0
- package/docs-llm/Resize.md +362 -0
- package/docs-llm/Screen Reader Content.md +73 -0
- package/docs-llm/Scroll Container Context.md +155 -0
- package/docs-llm/Scroll.md +152 -0
- package/docs-llm/Search.md +381 -0
- package/docs-llm/Select.md +985 -0
- package/docs-llm/Side Panel.md +777 -0
- package/docs-llm/Slider.md +339 -0
- package/docs-llm/Sliding Panels.md +340 -0
- package/docs-llm/Split Button.md +295 -0
- package/docs-llm/Static Content.md +90 -0
- package/docs-llm/Step Bar.md +292 -0
- package/docs-llm/Switch.md +268 -0
- package/docs-llm/Tab Bar.md +439 -0
- package/docs-llm/Tab Layout.md +398 -0
- package/docs-llm/Table.md +2642 -0
- package/docs-llm/Text Area.md +253 -0
- package/docs-llm/Text.md +339 -0
- package/docs-llm/Tooltip.md +325 -0
- package/docs-llm/Transition Open.md +406 -0
- package/docs-llm/Tree.md +586 -0
- package/docs-llm/Typography.md +125 -0
- package/docs-llm/Wait Spinner.md +121 -0
- package/docs-llm/llms.txt +97 -0
- package/package.json +6 -5
- package/types/src/Box/Box.d.ts +2 -10
- package/types/src/Drawer/Body.d.ts +17 -0
- package/types/src/Drawer/Drawer.d.ts +114 -0
- package/types/src/Drawer/DrawerContext.d.ts +11 -0
- package/types/src/Drawer/Footer.d.ts +25 -0
- package/types/src/Drawer/Header.d.ts +41 -0
- package/types/src/Drawer/docs/examples/Basic.d.ts +6 -0
- package/types/src/Drawer/docs/examples/ContainerPosition.d.ts +7 -0
- package/types/src/Drawer/docs/examples/InitialFocus.d.ts +9 -0
- package/types/src/Drawer/docs/examples/InlinePosition.d.ts +7 -0
- package/types/src/Drawer/docs/examples/PagePosition.d.ts +7 -0
- package/types/src/Drawer/index.d.ts +2 -0
- package/types/src/JSONTree/JSONTree.d.ts +12 -5
- package/types/src/JSONTree/renderTreeItems.d.ts +2 -1
- package/types/src/Menu/Item.d.ts +2 -1
- package/types/src/Menu/docs/examples/SelectableCheckbox.d.ts +7 -0
- package/types/src/Modal/Modal.d.ts +1 -2
- package/types/src/Select/Option.d.ts +6 -3
- package/types/src/Select/Select.d.ts +8 -5
- package/types/src/Select/docs/examples/Dimmed.d.ts +7 -0
- package/types/src/SelectBase/OptionBase.d.ts +6 -3
- package/types/src/SelectBase/SelectBase.d.ts +8 -3
- package/types/src/SidePanel/SidePanel.d.ts +43 -2
- package/types/src/SidePanel/docs/examples/DockLayout.d.ts +17 -0
- package/types/src/SidePanel/docs/examples/InitialFocus.d.ts +9 -0
- package/types/src/TransitionOpen/TransitionOpen.d.ts +29 -4
- package/types/src/useKeyPress/index.d.ts +9 -2
- package/types/src/useOnClickOutside/index.d.ts +2 -0
- package/types/src/useOnClickOutside/useOnClickOutside.d.ts +4 -0
- package/useKeyPress.js +23 -18
- package/useOnClickOutside.d.ts +2 -0
- package/useOnClickOutside.js +79 -0
- package/types/src/RadioList/docs/examples/Row.d.ts +0 -6
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# Number
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
> Image: Illustration of a number component
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
<Message appearance="fill" type="info">
|
|
11
|
+
<div>All data entry components should be wrapped in a <Link to="ControlGroup">Control Group</Link> to provide a label, error states, and help or error text, ensuring an accessible experience for all users.</div>
|
|
12
|
+
</Message>
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## When to use this component
|
|
17
|
+
- The user only needs to input numeric values.
|
|
18
|
+
- Increasing or decreasing by small values only requires a few clicks.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## When to use another component
|
|
22
|
+
- Large value changes are expected.
|
|
23
|
+
- Exact values need to be specified within a wide range.
|
|
24
|
+
- Consider the `Slider` component for inputs that aren’t precise.
|
|
25
|
+
- Consider `Text` or `Text Area` for inputs that are a mix of numbers and text
|
|
26
|
+
- For a predetermined list of values the user can select from, use `Select`.
|
|
27
|
+
|
|
28
|
+
```mermaid
|
|
29
|
+
graph TD
|
|
30
|
+
accDescr: Decision tree that guides on when to use the Number component or something else
|
|
31
|
+
A(Is the input solely numerical?) -- Yes --- B(Is the number input from a predetermined range?)
|
|
32
|
+
B -- Yes --- C(Slider)
|
|
33
|
+
B -- No --- D(Is the number input from a predetermined list?)
|
|
34
|
+
D -- Yes --- E(Select)
|
|
35
|
+
D -- No --- F(Number)
|
|
36
|
+
A -- No --- G(Text/Text Area)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Check out
|
|
40
|
+
- [Slider][1]
|
|
41
|
+
- [Text][2]
|
|
42
|
+
- [Text Area] [3]
|
|
43
|
+
- [Select][4]
|
|
44
|
+
|
|
45
|
+
## Behaviors
|
|
46
|
+
### Locale
|
|
47
|
+
Number inputs can automatically convert periods to commas for decimal places based on the user's regional settings.
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
### Avoid placeholder text
|
|
51
|
+
Placeholder text presents a number of visual and cognitive issues; it is best to avoid using it. Placeholder does not replace a label. [Splunk Style Guide placeholder guidelines][5]
|
|
52
|
+
|
|
53
|
+
> Image: Image showing a comparison between two number input fields and ways to show placeholders. The correct version on the left shows a number input field with the placeholder text displayed underneath the input field, providing clear contextual information. The incorrect version shows a number input field with the placeholder text inside the input field, which could be mistaken for user input.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
### Adjust width to support longest values
|
|
57
|
+
Adjust the width to accommodate the anticipated input length, ensuring it is sufficiently wide to support the longest expected values. Avoid extending Number across the entire width of large viewports to maintain usability and readability.
|
|
58
|
+
|
|
59
|
+
> Image: Image showing a comparison between two number input fields and widths based on content. The correct version of the left shows a number input field with a reasonable width that accommodates the longest expected values, ensuring a clean and efficient design. The incorrect version shows a number input field that is excessively long, wasting space and making the design look unbalanced.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
## Content guidelines
|
|
64
|
+
|
|
65
|
+
### Use descriptive labels
|
|
66
|
+
The required labels on top of the number input field should be descriptive to ensure users do not type in additional text along with the number. They should still champion brevity and use sentence-case capitalization.
|
|
67
|
+
|
|
68
|
+
> Image: Image showing a comparison between two number input fields for price. The correct example includes the currency denotated in the label, while the incorrect example requires the user to enter the currency symbol inside the number input field.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
[1]: ./Slider
|
|
72
|
+
[2]: ./Text
|
|
73
|
+
[3]: ./TextArea
|
|
74
|
+
[4]: ./Select
|
|
75
|
+
[5]: https://docs.splunk.com/Documentation/StyleGuide/drafts/StyleGuide/UIGuidelines#Placeholder_text
|
|
76
|
+
|
|
77
|
+
## Examples
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
### Controlled
|
|
81
|
+
|
|
82
|
+
Number requires a value prop and an onChange callback to update the value prop for most use cases. Set value to null.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import React, { Component } from 'react';
|
|
86
|
+
|
|
87
|
+
import Number, { NumberChangeHandler } from '@splunk/react-ui/Number';
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class Basic extends Component<object, { value?: number }> {
|
|
91
|
+
constructor(props: object) {
|
|
92
|
+
super(props);
|
|
93
|
+
|
|
94
|
+
this.state = {
|
|
95
|
+
value: undefined, // default empty
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
handleChange: NumberChangeHandler = (e, { value }) => {
|
|
100
|
+
this.setState({ value });
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
render() {
|
|
104
|
+
return <Number value={this.state.value} onChange={this.handleChange} inline />;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export default Basic;
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
### Uncontrolled
|
|
114
|
+
|
|
115
|
+
Alternately, Number can be uncontrolled and optionally provided a defaultValue. The onChange callback still fires. The value prop cannot be set or updated externally.
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import React from 'react';
|
|
119
|
+
|
|
120
|
+
import Number from '@splunk/react-ui/Number';
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
function Uncontrolled() {
|
|
124
|
+
return <Number inline />;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export default Uncontrolled;
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
### Limits
|
|
133
|
+
|
|
134
|
+
Number accepts min, max, step, and roundTo props.
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import React, { Component } from 'react';
|
|
138
|
+
|
|
139
|
+
import Number, { NumberChangeHandler } from '@splunk/react-ui/Number';
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class Limits extends Component<object, { value?: number }> {
|
|
143
|
+
constructor(props: object) {
|
|
144
|
+
super(props);
|
|
145
|
+
|
|
146
|
+
this.state = {
|
|
147
|
+
value: undefined, // default empty
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
handleChange: NumberChangeHandler = (e, { value }) => {
|
|
152
|
+
this.setState({ value });
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
render() {
|
|
156
|
+
return (
|
|
157
|
+
<Number
|
|
158
|
+
value={this.state.value}
|
|
159
|
+
max={10}
|
|
160
|
+
min={-10}
|
|
161
|
+
roundTo={1}
|
|
162
|
+
step={0.1}
|
|
163
|
+
onChange={this.handleChange}
|
|
164
|
+
inline
|
|
165
|
+
/>
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export default Limits;
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
### Locale
|
|
176
|
+
|
|
177
|
+
A locale can be included which may change the decimal separator to a comma.
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import React, { Component } from 'react';
|
|
181
|
+
|
|
182
|
+
import Number, { NumberChangeHandler } from '@splunk/react-ui/Number';
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class Locale extends Component<object, { value?: number }> {
|
|
186
|
+
constructor(props: object) {
|
|
187
|
+
super(props);
|
|
188
|
+
|
|
189
|
+
this.state = {
|
|
190
|
+
value: 2.4,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
handleChange: NumberChangeHandler = (e, { value }) => {
|
|
195
|
+
this.setState({ value });
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
render() {
|
|
199
|
+
return (
|
|
200
|
+
<Number
|
|
201
|
+
locale="fr-FR"
|
|
202
|
+
step={0.15}
|
|
203
|
+
value={this.state.value}
|
|
204
|
+
onChange={this.handleChange}
|
|
205
|
+
inline
|
|
206
|
+
/>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export default Locale;
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
### Error
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import React from 'react';
|
|
220
|
+
|
|
221
|
+
import Number from '@splunk/react-ui/Number';
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
function NumberError() {
|
|
225
|
+
return <Number error defaultValue={2020} inline />;
|
|
226
|
+
}
|
|
227
|
+
export default NumberError;
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
### Disabled
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import React from 'react';
|
|
236
|
+
|
|
237
|
+
import Number from '@splunk/react-ui/Number';
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
function Disabled() {
|
|
241
|
+
return <Number disabled defaultValue={2020} inline />;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export default Disabled;
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
## API
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
### Number API
|
|
254
|
+
|
|
255
|
+
#### Props
|
|
256
|
+
|
|
257
|
+
| Name | Type | Required | Default | Description |
|
|
258
|
+
|------|------|------|------|------|
|
|
259
|
+
| append | boolean | no | | Append removes the rounded borders and the border from the right side and moves the increment and decrement buttons to the left. |
|
|
260
|
+
| children | React.ReactNode | no | | |
|
|
261
|
+
| defaultValue | number | no | | Set this property instead of value to make the value uncontrolled. |
|
|
262
|
+
| describedBy | string | no | | The id of the description. When placed in a ControlGroup, this is automatically set to the ControlGroup's help component. |
|
|
263
|
+
| disabled | boolean | no | | Determines if the input is editable. |
|
|
264
|
+
| elementRef | React.Ref<HTMLDivElement> | no | | A React ref which is set to the DOM element when the component mounts, and null when it unmounts. |
|
|
265
|
+
| error | boolean | no | | Highlight the field as having an error. |
|
|
266
|
+
| hideStepButtons | boolean | no | | Hides the increment and decrement step buttons if true. |
|
|
267
|
+
| inline | boolean | no | | When false, displays as inline-block with the default width. |
|
|
268
|
+
| inputId | string | no | | An id for the input, which may be necessary for accessibility, such as for aria attributes. |
|
|
269
|
+
| inputRef | React.Ref<HTMLInputElement> | no | | A React ref which is set to the text input element when the component mounts, and null when it unmounts. |
|
|
270
|
+
| labelledBy | string | no | | The id of the label. When placed in a ControlGroup, this is automatically set to the ControlGroup's label. |
|
|
271
|
+
| locale | string | no | 'en-US' | The locale determines the decimal separator. Supported locale formats are: `xx`, `xx-XX`, and `xx_XX`. |
|
|
272
|
+
| max | number | no | | The largest allowable value. |
|
|
273
|
+
| min | number | no | | The smallest allowable value. |
|
|
274
|
+
| name | string | no | | The name is returned with onChange events, which can be used to identify the control when multiple controls share an onChange callback. |
|
|
275
|
+
| onBlur | NumberBlurHandler | no | | A callback for when the input loses focus. |
|
|
276
|
+
| onChange | NumberChangeHandler | no | | This is equivalent to onInput which is called on keydown, paste, and so on. If value is set, this callback is required. This must set the value prop to retain the change. |
|
|
277
|
+
| onClick | React.MouseEventHandler<HTMLInputElement> | no | | A callback for when the input is clicked. This will only trigger when the textbox itself is clicked and will not trigger for other parts of the component such as the step buttons. |
|
|
278
|
+
| onFocus | NumberFocusHandler | no | | A callback for when the input takes focus. |
|
|
279
|
+
| onKeyDown | React.KeyboardEventHandler<HTMLInputElement> | no | | A keydown callback can be used to prevent a certain input by utilizing the event argument. |
|
|
280
|
+
| onKeyUp | React.KeyboardEventHandler<HTMLDivElement> | no | | A keyup callback. |
|
|
281
|
+
| onSelect | React.ReactEventHandler<HTMLInputElement> | no | | A callback for when the user selects text. |
|
|
282
|
+
| prepend | boolean | no | | Prepend removes rounded borders from the left side. This cannot be used in combination with append. |
|
|
283
|
+
| roundTo | number | no | 5 | The number of decimal places for rounding. Set to zero to limit input to integers. Negative numbers are supported. For instance, -2 will round to the nearest hundred. |
|
|
284
|
+
| step | number | no | 1 | The amount of increment and decrement applied by the buttons and arrow keys. |
|
|
285
|
+
| value | number | no | | The contents of the input. Setting this value makes the property controlled. A callback is required. |
|
|
286
|
+
|
|
287
|
+
#### Types
|
|
288
|
+
|
|
289
|
+
| Name | Type | Description |
|
|
290
|
+
|------|------|------|
|
|
291
|
+
| NumberBlurHandler | ( event: React.FocusEvent<HTMLInputElement>, data: { name?: string; value: string; } ) => void | |
|
|
292
|
+
| NumberChangeHandler | ( event: \| React.ChangeEvent<HTMLInputElement> \| React.KeyboardEvent<HTMLInputElement> \| React.MouseEvent<HTMLAnchorElement \| HTMLButtonElement \| HTMLSpanElement>, data: { name?: string; value?: number; reason: 'input' \| 'stepButton'; } ) => void | |
|
|
293
|
+
| NumberFocusHandler | ( event: React.FocusEvent<HTMLInputElement>, data: { name?: string; value: string; } ) => void | |
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# Paginator
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
> Image: Illustration of a Paginator component.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## When to use this component
|
|
10
|
+
- When you have a large amount of data or content that needs to be divided into smaller, more manageable chunks for users to view sequentially.
|
|
11
|
+
- When you want to maintain performance and reduce load times by displaying only a subset of data at a time.
|
|
12
|
+
- When users need to navigate a gallery of content, such as videos.
|
|
13
|
+
|
|
14
|
+
## When to use another component
|
|
15
|
+
- If you only have a small amount of data to display, such as single page content.
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
graph TD
|
|
19
|
+
accDescr: Decision tree that guides on when to use the Paginator component or something else
|
|
20
|
+
A(Does the user need to sequentially navigate a large data collection?) -- Yes --- B(Paginator)
|
|
21
|
+
A -- No --- C(Does the user prefer uninterrupted scrolling through data?)
|
|
22
|
+
C -- Yes --- D(Infinite Scroll)
|
|
23
|
+
C -- No --- E(Load More Button)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Appearance
|
|
28
|
+
|
|
29
|
+
#### Grouping variants
|
|
30
|
+
Use a Paginator at the top and bottom of longer tables for improved keyboard navigation.
|
|
31
|
+
|
|
32
|
+
> Image: Illustration of a data table component utilizing both the compact and default paginator. The compact Paginator is at the top of the table, right aligned, and it includes the Page Control. The default Paginator is at the bottom of the table.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## Behaviors
|
|
36
|
+
The paginator automatically indicates when users are on the first or last page by disabling the previous or next buttons as needed.
|
|
37
|
+
|
|
38
|
+
> Image: Examples illustrating the disabled and enabled states as a visual indicator for navigation controls.
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
### Default
|
|
44
|
+
|
|
45
|
+
> Image: Example of Default Paginator, showing the first page as active.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Page Control
|
|
49
|
+
The Page Control is utilized only with the Compact variant of the Paginator component.
|
|
50
|
+
|
|
51
|
+
> Image: Example of Page Control Paginator, with the label displaying the total page number.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
### Page Control without a label
|
|
55
|
+
Use Page Control without a label when there's a need to save space within a page.
|
|
56
|
+
|
|
57
|
+
> Image: Example of Page Control Paginator, without the label.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
### Compact
|
|
61
|
+
|
|
62
|
+
> Image: Example of Compact Paginator, with the label displaying the total page number.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
### Compact without a label
|
|
66
|
+
|
|
67
|
+
> Image: Example of Compact Paginator, without the label.
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
### Loading
|
|
71
|
+
Use [Wait Spinner] [1] when a page change is initiated and will only take a few seconds.
|
|
72
|
+
|
|
73
|
+
> Image: Examples illustrating the Paginator with a table and a wait spinner. The first example, marked with a heart eyes emoji, displays the paginator component with the data table and a wait spinner as the user navigates to a second page. The second example, identified by a grimacing face emoji, presents the paginator component with an empty table and no spinner as the user navigates to the second page.
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
### Paginator with table
|
|
77
|
+
|
|
78
|
+
The Paginator can be paired with other components, such as the [Table][2], enabling users to navigate data sets in a specific order.
|
|
79
|
+
|
|
80
|
+
> Image: An abstract illustration of a data table with a Paginator component.
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
### Navigating galleries
|
|
84
|
+
|
|
85
|
+
The Paginator can be also utilized to navigate [Card] [3] galleries and other sequential content.
|
|
86
|
+
|
|
87
|
+
> Image: An abstract illustration with three cards in preview and a paginator.
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
[1]: ./WaitSpinner
|
|
91
|
+
[2]: ./Table
|
|
92
|
+
[3]: ./Card
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
## Examples
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
### Basic
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import React, { useState } from 'react';
|
|
102
|
+
|
|
103
|
+
import Paginator, { PaginatorChangeHandler } from '@splunk/react-ui/Paginator';
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
function Basic() {
|
|
107
|
+
const [pageNum, setPageNum] = useState(3);
|
|
108
|
+
|
|
109
|
+
const handleChange: PaginatorChangeHandler = (event, { page }) => {
|
|
110
|
+
setPageNum(page);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<Paginator
|
|
115
|
+
onChange={handleChange}
|
|
116
|
+
current={pageNum}
|
|
117
|
+
alwaysShowLastPageLink
|
|
118
|
+
totalPages={30}
|
|
119
|
+
/>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export default Basic;
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
### Labelled
|
|
129
|
+
|
|
130
|
+
When possible, a Paginator should use aria-labelledby or aria-label to provide an accessible label describing the content that is being paginated.
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import React, { useState } from 'react';
|
|
134
|
+
|
|
135
|
+
import Heading from '@splunk/react-ui/Heading';
|
|
136
|
+
import Paginator, { PaginatorChangeHandler } from '@splunk/react-ui/Paginator';
|
|
137
|
+
import { createDOMID } from '@splunk/ui-utils/id';
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
function Labelled() {
|
|
141
|
+
const [pageNum, setPageNum] = useState(3);
|
|
142
|
+
|
|
143
|
+
const handleChange: PaginatorChangeHandler = (event, { page }) => {
|
|
144
|
+
setPageNum(page);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const labelId = createDOMID('labelled');
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<>
|
|
151
|
+
<Heading level={4} id={labelId} style={{ margin: 0 }}>
|
|
152
|
+
Paginated content example
|
|
153
|
+
</Heading>
|
|
154
|
+
<Paginator
|
|
155
|
+
aria-labelledby={labelId}
|
|
156
|
+
onChange={handleChange}
|
|
157
|
+
current={pageNum}
|
|
158
|
+
alwaysShowLastPageLink
|
|
159
|
+
totalPages={30}
|
|
160
|
+
/>
|
|
161
|
+
</>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export default Labelled;
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
### Page control
|
|
171
|
+
|
|
172
|
+
A Paginator control that allows any page to be selected.
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import React, { useState } from 'react';
|
|
176
|
+
|
|
177
|
+
import Paginator, { PaginatorPageControlChangeHandler } from '@splunk/react-ui/Paginator';
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
function PageControl() {
|
|
181
|
+
const [pageNum, setPageNum] = useState(3);
|
|
182
|
+
|
|
183
|
+
const handleChange: PaginatorPageControlChangeHandler = (event, { page }) => {
|
|
184
|
+
setPageNum(page);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
return <Paginator.PageControl onChange={handleChange} current={pageNum} totalPages={30} />;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export default PageControl;
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
### Custom pages
|
|
196
|
+
|
|
197
|
+
Customize Paginator's pages and Prev/Next buttons with generatePageProps.
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import React, { useState } from 'react';
|
|
201
|
+
|
|
202
|
+
import Paginator, {
|
|
203
|
+
PaginatorGeneratePageProps,
|
|
204
|
+
PaginatorChangeHandler,
|
|
205
|
+
} from '@splunk/react-ui/Paginator';
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
function CustomPages() {
|
|
209
|
+
const [currentPage, setCurrentPage] = useState<number>(3);
|
|
210
|
+
|
|
211
|
+
const handleChange: PaginatorChangeHandler = (e, { page }) => {
|
|
212
|
+
e.preventDefault();
|
|
213
|
+
setCurrentPage(page);
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const generatePageProps: PaginatorGeneratePageProps = ({ page }) => {
|
|
217
|
+
return {
|
|
218
|
+
to: `#page-${page}`,
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
return (
|
|
223
|
+
<Paginator
|
|
224
|
+
alwaysShowLastPageLink
|
|
225
|
+
generatePageProps={generatePageProps}
|
|
226
|
+
current={currentPage}
|
|
227
|
+
onChange={handleChange}
|
|
228
|
+
totalPages={30}
|
|
229
|
+
/>
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export default CustomPages;
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
### Compact
|
|
239
|
+
|
|
240
|
+
A Paginator control with buttons only.
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import React, { useState } from 'react';
|
|
244
|
+
|
|
245
|
+
import Paginator, { PaginatorCompactChangeHandler } from '@splunk/react-ui/Paginator';
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
function Compact() {
|
|
249
|
+
const [pageNum, setPageNum] = useState<number | undefined>(3);
|
|
250
|
+
|
|
251
|
+
const handleChange: PaginatorCompactChangeHandler = (event, { page }) => {
|
|
252
|
+
setPageNum(page);
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
return <Paginator.Compact current={pageNum} onChange={handleChange} totalPages={30} />;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export default Compact;
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
### Compact with label
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
import React, { useState } from 'react';
|
|
267
|
+
|
|
268
|
+
import Paginator, { PaginatorCompactChangeHandler } from '@splunk/react-ui/Paginator';
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
function CompactWithLabel() {
|
|
272
|
+
const [pageNum, setPageNum] = useState<number | undefined>(3);
|
|
273
|
+
|
|
274
|
+
const handleChange: PaginatorCompactChangeHandler = (event, { page }) => {
|
|
275
|
+
setPageNum(page);
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
return (
|
|
279
|
+
<Paginator.Compact current={pageNum} onChange={handleChange} renderLabel totalPages={30} />
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export default CompactWithLabel;
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
### Compact with custom label
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
import React, { useState } from 'react';
|
|
292
|
+
|
|
293
|
+
import Paginator, { PaginatorCompactChangeHandler } from '@splunk/react-ui/Paginator';
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
function CompactCustomLabel() {
|
|
297
|
+
const [pageNum, setPageNum] = useState<number | undefined>(1);
|
|
298
|
+
const itemsPerPage = 50;
|
|
299
|
+
const totalItems = 300;
|
|
300
|
+
|
|
301
|
+
const handleChange: PaginatorCompactChangeHandler = (event, { page }) => {
|
|
302
|
+
setPageNum(page);
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
return (
|
|
306
|
+
<Paginator.Compact
|
|
307
|
+
current={pageNum}
|
|
308
|
+
onChange={handleChange}
|
|
309
|
+
renderLabel={({ current }) => {
|
|
310
|
+
if (current) {
|
|
311
|
+
const pageEnd = current * itemsPerPage;
|
|
312
|
+
const pageStart = pageEnd - itemsPerPage + 1;
|
|
313
|
+
return `${pageStart}-${pageEnd} of ${totalItems}`;
|
|
314
|
+
}
|
|
315
|
+
return `0-${itemsPerPage} of ${totalItems}`;
|
|
316
|
+
}}
|
|
317
|
+
totalPages={totalItems / itemsPerPage}
|
|
318
|
+
/>
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export default CompactCustomLabel;
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
## API
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
### Paginator API
|
|
332
|
+
|
|
333
|
+
#### Props
|
|
334
|
+
|
|
335
|
+
| Name | Type | Required | Default | Description |
|
|
336
|
+
|------|------|------|------|------|
|
|
337
|
+
| alwaysShowLastPageLink | boolean | no | false | Displays a link to the last page in a collection. |
|
|
338
|
+
| current | number | no | 1 | Currently selected page. |
|
|
339
|
+
| elementRef | React.Ref<HTMLElement> | no | | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
|
|
340
|
+
| generatePageProps | PaginatorGeneratePageProps | no | | Passes props to Paginator's pages and Prev/Next buttons. Supports [Clickable](./Clickable) props (except for `onClick`) and global HTML attributes. `generatePageProps` will not differentiate between Prev/Next buttons and its corresponding page. For example, if page 5 is passed prop P and current is 6, the Prev button will also be passed prop P. |
|
|
341
|
+
| numPageLinks | number | no | 5 | Number of pages to display. If greater than `totalPages`, `totalPages` is used instead. |
|
|
342
|
+
| onChange | PaginatorChangeHandler | no | | Callback to handle page change. |
|
|
343
|
+
| totalPages | number | yes | | The total number of pages. |
|
|
344
|
+
|
|
345
|
+
#### Types
|
|
346
|
+
|
|
347
|
+
| Name | Type | Description |
|
|
348
|
+
|------|------|------|
|
|
349
|
+
| PaginatorChangeHandler | ( event: React.MouseEvent<HTMLButtonElement>, data: { page: number } ) => void | |
|
|
350
|
+
| PaginatorGeneratePageProps | ({ page, }: { page: number; }) => Partial<React.ComponentProps<typeof Clickable>> & React.ComponentProps<'a'> & React.ComponentProps<'button'> | |
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
### Page Control API
|
|
355
|
+
|
|
356
|
+
#### Props
|
|
357
|
+
|
|
358
|
+
| Name | Type | Required | Default | Description |
|
|
359
|
+
|------|------|------|------|------|
|
|
360
|
+
| current | number | no | 1 | Currently selected page. |
|
|
361
|
+
| elementRef | React.Ref<HTMLElement> | no | | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
|
|
362
|
+
| onChange | PaginatorPageControlChangeHandler | no | | Callback to handle page change. |
|
|
363
|
+
| totalPages | number | yes | | The total number of pages. |
|
|
364
|
+
|
|
365
|
+
#### Types
|
|
366
|
+
|
|
367
|
+
| Name | Type | Description |
|
|
368
|
+
|------|------|------|
|
|
369
|
+
| PaginatorPageControlChangeHandler | ( event: React.MouseEvent<HTMLButtonElement> \| React.KeyboardEvent<HTMLInputElement>, data: { page: number } ) => void | |
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
### Compact API
|
|
374
|
+
|
|
375
|
+
#### Props
|
|
376
|
+
|
|
377
|
+
| Name | Type | Required | Default | Description |
|
|
378
|
+
|------|------|------|------|------|
|
|
379
|
+
| current | number | no | | The current page number. If not provided, the component will not keep track of the page number and will not provide it in the callback. |
|
|
380
|
+
| elementRef | React.Ref<HTMLElement> | no | | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
|
|
381
|
+
| onChange | PaginatorCompactChangeHandler | no | | Callback to handle page change. |
|
|
382
|
+
| renderLabel | boolean \| PaginatorCompactRenderLabelCallback | no | | If true, renders the a label for the current and total pages. Can be passed a function to render a custom label that receives an object with current and totalPages as an argument. |
|
|
383
|
+
| totalPages | number | no | | The total number of pages. If not provided, the component will operate in indeterminate mode and will not prevent the current page number from exceeding any values. |
|
|
384
|
+
|
|
385
|
+
#### Types
|
|
386
|
+
|
|
387
|
+
| Name | Type | Description |
|
|
388
|
+
|------|------|------|
|
|
389
|
+
| PaginatorCompactChangeHandler | ( event: React.MouseEvent<HTMLButtonElement> \| React.KeyboardEvent<HTMLInputElement>, data: { direction: 'prev' \| 'next'; page?: number } ) => void | |
|
|
390
|
+
| PaginatorCompactRenderLabelCallback | (data: { current?: number; totalPages?: number; }) => React.ReactNode | |
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|