@splunk/react-ui 5.7.1 → 5.9.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/Anchor.js +2 -1
- package/Box.js +83 -34
- package/CHANGELOG.md +51 -0
- package/Calendar.js +134 -134
- package/Clickable.js +131 -94
- package/CollapsiblePanel.js +175 -137
- package/ComboBox.js +32 -27
- package/ControlGroup.js +92 -91
- package/DefinitionList.js +9 -9
- package/Drawer.d.ts +2 -0
- package/Drawer.js +679 -0
- package/Dropdown.js +27 -18
- package/DualListbox.js +1 -1
- package/File.js +35 -35
- package/JSONTree.js +73 -72
- package/Link.js +2 -2
- package/MIGRATION.md +10 -0
- package/Menu.js +403 -261
- package/Modal.js +263 -252
- package/Monogram.js +2 -2
- package/Multiselect.js +551 -385
- package/Number.js +2 -1
- package/Paginator.js +14 -12
- package/Popover.js +4 -1
- package/README.md +11 -0
- package/RadioBar.js +1 -1
- package/Search.js +111 -95
- package/Select.js +42 -40
- package/SelectBase.js +819 -715
- package/SidePanel.js +346 -167
- package/SlidingPanels.js +11 -11
- package/StepBar.js +7 -7
- package/Switch.js +5 -5
- package/Table.js +116 -119
- package/Text.js +48 -48
- package/TextArea.js +7 -7
- package/TransitionOpen.js +188 -169
- 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 +292 -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 +939 -0
- package/docs-llm/Notifications.md +46 -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 +591 -0
- package/docs-llm/Typography.md +125 -0
- package/docs-llm/Wait Spinner.md +121 -0
- package/docs-llm/llms.txt +101 -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/Multiselect/Compact.d.ts +8 -3
- package/types/src/Multiselect/Multiselect.d.ts +8 -3
- package/types/src/Multiselect/Normal.d.ts +8 -3
- package/types/src/Multiselect/Option.d.ts +6 -3
- package/types/src/Multiselect/docs/examples/Disabled.d.ts +1 -0
- 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,339 @@
|
|
|
1
|
+
# Slider
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
> Image: Illustration of a Slider component
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## When to use this component
|
|
11
|
+
- To choose a single number within a range with minimum and maximum values
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## When to use another component
|
|
15
|
+
- For precise number input where a range is not defined, consider `Number`
|
|
16
|
+
- For an input that is from a non-continuous range, consider `Select`
|
|
17
|
+
|
|
18
|
+
```mermaid
|
|
19
|
+
graph TD
|
|
20
|
+
accDescr: Decision tree that guides on when to use the Slider component or something else
|
|
21
|
+
A(Is there a defined continuous range with min and max values?) -- Yes --- B(Slider)
|
|
22
|
+
A -- No --- C(Is the input from a small, non-continuous range?)
|
|
23
|
+
C -- Yes --- D(Select)
|
|
24
|
+
C -- No --- E(Number)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Check out
|
|
28
|
+
- [Number][1]
|
|
29
|
+
- [Select][2]
|
|
30
|
+
|
|
31
|
+
## Behaviors
|
|
32
|
+
### Controlled slider
|
|
33
|
+
If the slider use case requires more precision, use the slider along with the Number component. <br />
|
|
34
|
+
[View controlled Slider example](Slider?section=examples#Controlled)
|
|
35
|
+
|
|
36
|
+
### Step marks
|
|
37
|
+
Sliders with step marks allows users to choose from discrete values. The thumb will snap to the ticks. <br />
|
|
38
|
+
[View Slider with step marks example](Slider?section=examples#Step%20marks)
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
### Use descriptive text for custom labels
|
|
42
|
+
Sliders support adding custom labels for the range. Keep these succinct and descriptive so that the user knows what the range is depicting.
|
|
43
|
+
|
|
44
|
+
> Image: The image illustrates two examples of a volume control slider. In the good example, the slider is labeled with descriptive text, showing
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### Avoid selecting ranges instead of values
|
|
48
|
+
Sliders do not support selecting a subset range within the range. Currently, the slider thumb can only select a single value.
|
|
49
|
+
|
|
50
|
+
> Image: The image illustrates two examples of a volume control slider. In the good example, the slider only has one thumb, selecting an exact value. In the bad example, the slider has two thumbs, selecting a subset of a range in the slider.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## Content guidelines
|
|
55
|
+
|
|
56
|
+
### Use parallel terminology
|
|
57
|
+
Slider labels should briefly describe what the range represents. Define the values at the min and max of the range. For non-numerical ranges, use parallel terminology, like min/max and high/low.
|
|
58
|
+
|
|
59
|
+
> Image: The image illustrates two examples of a volume control slider with different value labels. In the good example, the slider labels uses parallel terminology of min and max, while the bad example shows the slider labels going from 0 to max.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
[1]: ./Number
|
|
63
|
+
[2]: ./Select
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Examples
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
### Uncontrolled
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import React from 'react';
|
|
73
|
+
|
|
74
|
+
import Slider from '@splunk/react-ui/Slider';
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
function Basic() {
|
|
78
|
+
return <Slider min={100} max={500} step={25} defaultValue={300} />;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default Basic;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
### Controlled
|
|
87
|
+
|
|
88
|
+
Slider syncing with a Number input.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import React, { Component } from 'react';
|
|
92
|
+
|
|
93
|
+
import ControlGroup from '@splunk/react-ui/ControlGroup';
|
|
94
|
+
import Number, { NumberChangeHandler } from '@splunk/react-ui/Number';
|
|
95
|
+
import Slider, { SliderChangeHandler } from '@splunk/react-ui/Slider';
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class Controlled extends Component<object, { value?: number }> {
|
|
99
|
+
constructor(props: object) {
|
|
100
|
+
super(props);
|
|
101
|
+
this.state = { value: 300 };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
handleSliderChange: SliderChangeHandler = (e, { value }) => {
|
|
105
|
+
this.setState({ value });
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
handleNumberChange: NumberChangeHandler = (e, { value }) => {
|
|
109
|
+
this.setState({ value });
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
render() {
|
|
113
|
+
return (
|
|
114
|
+
<ControlGroup label="Controls">
|
|
115
|
+
<Slider
|
|
116
|
+
inline
|
|
117
|
+
min={100}
|
|
118
|
+
max={500}
|
|
119
|
+
step={25}
|
|
120
|
+
onChange={this.handleSliderChange}
|
|
121
|
+
value={this.state.value}
|
|
122
|
+
/>
|
|
123
|
+
<Number
|
|
124
|
+
inline
|
|
125
|
+
min={100}
|
|
126
|
+
max={500}
|
|
127
|
+
step={25}
|
|
128
|
+
value={this.state.value}
|
|
129
|
+
onChange={this.handleNumberChange}
|
|
130
|
+
style={{ flexBasis: 40 }}
|
|
131
|
+
/>
|
|
132
|
+
</ControlGroup>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default Controlled;
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
### Custom Labels
|
|
143
|
+
|
|
144
|
+
Labels can be modified or removed. Replacing all labels can create very different experiences, such as exponentially increasing values or ordered values (words only).
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import React, { Component } from 'react';
|
|
148
|
+
|
|
149
|
+
import Slider, { SliderChangeHandler } from '@splunk/react-ui/Slider';
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class CustomLabels extends Component<object, { displayValue: string; value: number }> {
|
|
153
|
+
static convertValueToLabel(value: number) {
|
|
154
|
+
const trueValue = 10 ** value;
|
|
155
|
+
const trueValueRounded = Math.round(trueValue * 100) / 100;
|
|
156
|
+
|
|
157
|
+
return `${trueValueRounded}px`;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
constructor(props: object) {
|
|
161
|
+
super(props);
|
|
162
|
+
this.state = {
|
|
163
|
+
displayValue: CustomLabels.convertValueToLabel(1),
|
|
164
|
+
value: 1,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
handleChange: SliderChangeHandler = (e, { value }) => {
|
|
169
|
+
this.setState({
|
|
170
|
+
displayValue: CustomLabels.convertValueToLabel(value),
|
|
171
|
+
value,
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
render() {
|
|
176
|
+
return (
|
|
177
|
+
<Slider
|
|
178
|
+
inline
|
|
179
|
+
displayValue={this.state.displayValue}
|
|
180
|
+
min={0}
|
|
181
|
+
minLabel="sharp"
|
|
182
|
+
max={2}
|
|
183
|
+
maxLabel="blurry"
|
|
184
|
+
step={0.2}
|
|
185
|
+
onChange={this.handleChange}
|
|
186
|
+
value={this.state.value}
|
|
187
|
+
/>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export default CustomLabels;
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
### Disabled
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import React from 'react';
|
|
201
|
+
|
|
202
|
+
import Slider from '@splunk/react-ui/Slider';
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
function Disabled() {
|
|
206
|
+
return <Slider min={1} max={100} step={1} defaultValue={50} inline disabled />;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export default Disabled;
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
### Step Marks
|
|
215
|
+
|
|
216
|
+
stepMarks can be set to always or never. Defaults to show on focus.
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import React from 'react';
|
|
220
|
+
|
|
221
|
+
import Slider from '@splunk/react-ui/Slider';
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
function StepMarks() {
|
|
225
|
+
return (
|
|
226
|
+
<span>
|
|
227
|
+
<Slider min={100} max={200} step={10} defaultValue={150} stepMarks="always" inline />
|
|
228
|
+
<br />
|
|
229
|
+
<Slider min={100} max={200} step={10} defaultValue={150} stepMarks="never" inline />
|
|
230
|
+
</span>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export default StepMarks;
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
### Error
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import React from 'react';
|
|
243
|
+
|
|
244
|
+
import Slider from '@splunk/react-ui/Slider';
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
function Error() {
|
|
248
|
+
return <Slider min={100} max={500} step={25} defaultValue={300} error />;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export default Error;
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
## API
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
### Slider API
|
|
261
|
+
|
|
262
|
+
#### Props
|
|
263
|
+
|
|
264
|
+
| Name | Type | Required | Default | Description |
|
|
265
|
+
|------|------|------|------|------|
|
|
266
|
+
| defaultValue | number | no | | Set this property instead of value to make value uncontrolled. |
|
|
267
|
+
| describedBy | string | no | | The id of the description. When placed in a ControlGroup, this is automatically set to the ControlGroup's help component. |
|
|
268
|
+
| disabled | boolean | no | | Determines whether or not the slider can be moved. |
|
|
269
|
+
| displayValue | string | no | | The label shown in the tooltip. Defaults to the value. |
|
|
270
|
+
| elementRef | React.Ref<HTMLDivElement> | no | | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
|
|
271
|
+
| error | boolean | no | | Highlight the Slider as having an error. The thumb and bar background-color turn to accent negative. |
|
|
272
|
+
| inline | boolean | no | | When false, display as inline-block with the default width. |
|
|
273
|
+
| inputId | string | no | | An id for the input, which may be necessary for accessibility, such as for aria attributes. |
|
|
274
|
+
| labelledBy | string | no | | The id of the label. When placed in a ControlGroup, this is automatically set to the ControlGroup's label. |
|
|
275
|
+
| max | number | no | 5 | The maximum value of the Slider input. |
|
|
276
|
+
| maxLabel | React.ReactNode | no | | The label shown to the right of the slider. Defaults to the max value. Set to null to remove. |
|
|
277
|
+
| min | number | no | 1 | The minimum value of the Slider input. |
|
|
278
|
+
| minLabel | React.ReactNode | no | | The label shown to the left of the slider. Defaults to the min value. Set to null to remove. |
|
|
279
|
+
| 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. |
|
|
280
|
+
| onChange | SliderChangeHandler | no | | Return event and data object with slider value. |
|
|
281
|
+
| step | number | no | 1 | The step value of the Slider input. |
|
|
282
|
+
| stepMarks | 'focus' \| 'always' \| 'never' | no | 'focus' | Determines whether or not the step marks should be shown. Defaults to show on focus. |
|
|
283
|
+
| thumbRef | React.Ref<HTMLButtonElement> | no | | A React ref which is set to the slider thumb when the component mounts and null when it unmounts. |
|
|
284
|
+
| value | number | no | | The value of the slider. Setting this value makes the property controlled. An `onChange` callback is required. |
|
|
285
|
+
|
|
286
|
+
#### Types
|
|
287
|
+
|
|
288
|
+
| Name | Type | Description |
|
|
289
|
+
|------|------|------|
|
|
290
|
+
| SliderChangeHandler | ( event: React.MouseEvent<HTMLDivElement> \| React.KeyboardEvent<HTMLButtonElement> \| MouseEvent, data: { name?: string; value: number; } ) => void | |
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
## Accessibility
|
|
297
|
+
|
|
298
|
+
> NOT supported by design system: multiple thumbs
|
|
299
|
+
|
|
300
|
+
## Visual Design
|
|
301
|
+
- Color contrast ratio **MUST** be:
|
|
302
|
+
- >=4.5:1 [SC 1.4.3][1]
|
|
303
|
+
- Any text to page-background (endpoints, tooltip text)
|
|
304
|
+
- >=3:1 for [SC 1.4.11][2]
|
|
305
|
+
- Selected color to page-background
|
|
306
|
+
- Unselected color to page-background
|
|
307
|
+
- Thumb to page-background
|
|
308
|
+
- Focus State: if the focus ring has a radius of [SC 1.4.11][2]
|
|
309
|
+
- < 3px: >=4.5.1 between thumb <> focus <> background
|
|
310
|
+
- > 3px: >=3.1 between thumb <> focus <> background
|
|
311
|
+
|
|
312
|
+
## States
|
|
313
|
+
- Color contrast does not apply to disabled slider
|
|
314
|
+
|
|
315
|
+
## Interaction Model
|
|
316
|
+
- In the case where two inputs are controlling a single value, such as a slider and number input,
|
|
317
|
+
focus **MUST** be on number input to change the value, as it has an easier interaction model on a keyboard than slider.
|
|
318
|
+
- Focus visible **MUST** be visible on thumb [SC 2.4.7][3]
|
|
319
|
+
- **MUST** have keyboard navigation [SC 2.1][4]
|
|
320
|
+
- <kbd>Tab</kbd> and <kbd>Shift+Tab</kbd>: focus lands on thumb
|
|
321
|
+
- <kbd>Left/Right Arrow</kbd>: moves thumb one step up or down
|
|
322
|
+
- <kbd>Up/Down</kbd>: moves thumb one step up or down
|
|
323
|
+
- <kbd>Home</kbd>: sets the thumb to the first allowed value in its range
|
|
324
|
+
- <kbd>End</kbd>: sets the thumb to the last allowed value in its range
|
|
325
|
+
|
|
326
|
+
## Implementation
|
|
327
|
+
- Implementation **MUST** use either `aria-role="slider"` or HTML `input` with type `range`
|
|
328
|
+
- Slider element **MUST** have the following attributes based on its respective implementation:
|
|
329
|
+
- `aria-valuenow/value` set to a decimal value representing the current value of the slider
|
|
330
|
+
- `aria-valuemin/min` set to a decimal value representing the minimun allowed value of the slider
|
|
331
|
+
- `aria-valuemax/max` set to a decimal value representing the maximum allowed value of the slider
|
|
332
|
+
- For vertical slider, `aria-orientation` **MUST** be set to `vertical`. The default value of `aria-orientation` for slider is `horizontal`.
|
|
333
|
+
|
|
334
|
+
[1]: https://www.w3.org/TR/WCAG21/#contrast-minimum
|
|
335
|
+
[2]: https://www.w3.org/TR/WCAG21/#non-text-contrast
|
|
336
|
+
[3]: https://www.w3.org/TR/WCAG21/#focus-visible
|
|
337
|
+
[4]: https://www.w3.org/TR/WCAG21/#keyboard-accessible
|
|
338
|
+
|
|
339
|
+
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# Sliding Panels
|
|
2
|
+
|
|
3
|
+
## Examples
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Basic
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
import React, { Component } from 'react';
|
|
10
|
+
|
|
11
|
+
import Button from '@splunk/react-ui/Button';
|
|
12
|
+
import ControlGroup from '@splunk/react-ui/ControlGroup';
|
|
13
|
+
import Heading from '@splunk/react-ui/Heading';
|
|
14
|
+
import P from '@splunk/react-ui/Paragraph';
|
|
15
|
+
import SlidingPanels from '@splunk/react-ui/SlidingPanels';
|
|
16
|
+
import Text from '@splunk/react-ui/Text';
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Basic extends Component<
|
|
20
|
+
object,
|
|
21
|
+
{ activePanelId: string; transition: 'forward' | 'backward' }
|
|
22
|
+
> {
|
|
23
|
+
constructor(props: object) {
|
|
24
|
+
super(props);
|
|
25
|
+
this.state = {
|
|
26
|
+
activePanelId: 'one',
|
|
27
|
+
transition: 'forward',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
goBack = () => {
|
|
32
|
+
this.setState((state) => ({
|
|
33
|
+
activePanelId: state.activePanelId === 'one' ? 'two' : 'one',
|
|
34
|
+
transition: 'backward',
|
|
35
|
+
}));
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
goForward = () => {
|
|
39
|
+
this.setState((state) => ({
|
|
40
|
+
activePanelId: state.activePanelId === 'one' ? 'two' : 'one',
|
|
41
|
+
transition: 'forward',
|
|
42
|
+
}));
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
render() {
|
|
46
|
+
const { activePanelId, transition } = this.state;
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div style={{ border: '1px solid #999' }}>
|
|
50
|
+
<SlidingPanels activePanelId={activePanelId} transition={transition}>
|
|
51
|
+
<SlidingPanels.Panel
|
|
52
|
+
key="one"
|
|
53
|
+
panelId="one"
|
|
54
|
+
style={{ width: '100%', padding: 10 }}
|
|
55
|
+
>
|
|
56
|
+
<Heading level={2}>First</Heading>
|
|
57
|
+
<ControlGroup
|
|
58
|
+
label="Field label"
|
|
59
|
+
tooltip="Tooltip helps explain the label."
|
|
60
|
+
help="This is the help text."
|
|
61
|
+
>
|
|
62
|
+
<Text canClear />
|
|
63
|
+
</ControlGroup>
|
|
64
|
+
<Button onClick={this.goBack}>Prev</Button>
|
|
65
|
+
<Button appearance="primary" onClick={this.goForward}>
|
|
66
|
+
Next
|
|
67
|
+
</Button>
|
|
68
|
+
</SlidingPanels.Panel>
|
|
69
|
+
<SlidingPanels.Panel
|
|
70
|
+
key="two"
|
|
71
|
+
panelId="two"
|
|
72
|
+
style={{ width: '100%', padding: 10 }}
|
|
73
|
+
>
|
|
74
|
+
<Heading level={2}>Second</Heading>
|
|
75
|
+
<P>
|
|
76
|
+
This is some content inside the second panel. You can add more details
|
|
77
|
+
here as needed.
|
|
78
|
+
</P>
|
|
79
|
+
<ControlGroup
|
|
80
|
+
label="Field label"
|
|
81
|
+
tooltip="Tooltip helps explain the label."
|
|
82
|
+
help="This is the help text."
|
|
83
|
+
>
|
|
84
|
+
<Text canClear />
|
|
85
|
+
</ControlGroup>
|
|
86
|
+
<Button onClick={this.goBack}>Prev</Button>
|
|
87
|
+
<Button appearance="primary" onClick={this.goForward}>
|
|
88
|
+
Next
|
|
89
|
+
</Button>
|
|
90
|
+
</SlidingPanels.Panel>
|
|
91
|
+
</SlidingPanels>
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export default Basic;
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
### In a Dropdown
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import React, { Component } from 'react';
|
|
106
|
+
|
|
107
|
+
import ChevronLeft from '@splunk/react-icons/ChevronLeft';
|
|
108
|
+
import Button from '@splunk/react-ui/Button';
|
|
109
|
+
import Dropdown, { DropdownPossibleCloseReason } from '@splunk/react-ui/Dropdown';
|
|
110
|
+
import Menu from '@splunk/react-ui/Menu';
|
|
111
|
+
import SlidingPanels from '@splunk/react-ui/SlidingPanels';
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class DropdownExample extends Component<
|
|
115
|
+
object,
|
|
116
|
+
{ activePanelId: string; transition: 'forward' | 'backward' }
|
|
117
|
+
> {
|
|
118
|
+
constructor(props: object) {
|
|
119
|
+
super(props);
|
|
120
|
+
this.state = {
|
|
121
|
+
activePanelId: 'one',
|
|
122
|
+
transition: 'forward',
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
goBack = () => {
|
|
127
|
+
this.setState((state) => ({
|
|
128
|
+
activePanelId: state.activePanelId === 'one' ? 'two' : 'one',
|
|
129
|
+
transition: 'backward',
|
|
130
|
+
}));
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
goForward = () => {
|
|
134
|
+
this.setState((state) => ({
|
|
135
|
+
activePanelId: state.activePanelId === 'one' ? 'two' : 'one',
|
|
136
|
+
transition: 'forward',
|
|
137
|
+
}));
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
render() {
|
|
141
|
+
const { activePanelId, transition } = this.state;
|
|
142
|
+
const toggle = <Button isMenu />;
|
|
143
|
+
const closeReasons: DropdownPossibleCloseReason[] = [
|
|
144
|
+
'clickAway',
|
|
145
|
+
'escapeKey',
|
|
146
|
+
'offScreen',
|
|
147
|
+
'toggleClick',
|
|
148
|
+
];
|
|
149
|
+
return (
|
|
150
|
+
<Dropdown closeReasons={closeReasons} toggle={toggle}>
|
|
151
|
+
<SlidingPanels activePanelId={activePanelId} transition={transition}>
|
|
152
|
+
<SlidingPanels.Panel key="one" panelId="one">
|
|
153
|
+
<Menu style={{ width: 160 }}>
|
|
154
|
+
<Menu.Item hasSubmenu onClick={this.goForward}>
|
|
155
|
+
Category 1
|
|
156
|
+
</Menu.Item>
|
|
157
|
+
<Menu.Item hasSubmenu onClick={this.goForward}>
|
|
158
|
+
Category 2
|
|
159
|
+
</Menu.Item>
|
|
160
|
+
<Menu.Item hasSubmenu onClick={this.goForward}>
|
|
161
|
+
Category 3
|
|
162
|
+
</Menu.Item>
|
|
163
|
+
<Menu.Item hasSubmenu onClick={this.goForward}>
|
|
164
|
+
Category 4
|
|
165
|
+
</Menu.Item>
|
|
166
|
+
<Menu.Item hasSubmenu onClick={this.goForward}>
|
|
167
|
+
Category 5
|
|
168
|
+
</Menu.Item>
|
|
169
|
+
<Menu.Item hasSubmenu onClick={this.goForward}>
|
|
170
|
+
Category 6
|
|
171
|
+
</Menu.Item>
|
|
172
|
+
<Menu.Item hasSubmenu onClick={this.goForward}>
|
|
173
|
+
Category 7
|
|
174
|
+
</Menu.Item>
|
|
175
|
+
<Menu.Item hasSubmenu onClick={this.goForward}>
|
|
176
|
+
Category 8
|
|
177
|
+
</Menu.Item>
|
|
178
|
+
</Menu>
|
|
179
|
+
</SlidingPanels.Panel>
|
|
180
|
+
<SlidingPanels.Panel key="two" panelId="two">
|
|
181
|
+
<Menu style={{ width: 160 }}>
|
|
182
|
+
<Menu.Item startAdornment={<ChevronLeft />} onClick={this.goBack}>
|
|
183
|
+
Back
|
|
184
|
+
</Menu.Item>
|
|
185
|
+
<Menu.Divider />
|
|
186
|
+
<Menu.Item>Option 1</Menu.Item>
|
|
187
|
+
<Menu.Item>Option 2</Menu.Item>
|
|
188
|
+
<Menu.Item>Option 3</Menu.Item>
|
|
189
|
+
<Menu.Item>Option 4</Menu.Item>
|
|
190
|
+
<Menu.Item>Option 5</Menu.Item>
|
|
191
|
+
<Menu.Item>Option 6</Menu.Item>
|
|
192
|
+
<Menu.Item>Option 7</Menu.Item>
|
|
193
|
+
</Menu>
|
|
194
|
+
</SlidingPanels.Panel>
|
|
195
|
+
</SlidingPanels>
|
|
196
|
+
</Dropdown>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export default DropdownExample;
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
### In a Modal
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
import React, { useRef, useState } from 'react';
|
|
210
|
+
|
|
211
|
+
import Button from '@splunk/react-ui/Button';
|
|
212
|
+
import CollapsiblePanel from '@splunk/react-ui/CollapsiblePanel';
|
|
213
|
+
import ControlGroup from '@splunk/react-ui/ControlGroup';
|
|
214
|
+
import Heading from '@splunk/react-ui/Heading';
|
|
215
|
+
import Modal from '@splunk/react-ui/Modal';
|
|
216
|
+
import P from '@splunk/react-ui/Paragraph';
|
|
217
|
+
import SlidingPanels from '@splunk/react-ui/SlidingPanels';
|
|
218
|
+
import Text from '@splunk/react-ui/Text';
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
function ModalExample() {
|
|
222
|
+
const [activePanelId, setActivePanelId] = useState<string>('one');
|
|
223
|
+
const [modalOpen, setModalOpen] = useState<boolean>(false);
|
|
224
|
+
const [transition, setTransition] = useState<'forward' | 'backward'>('forward');
|
|
225
|
+
const modalToggle = useRef<HTMLButtonElement | null>(null);
|
|
226
|
+
|
|
227
|
+
const goBack = () => {
|
|
228
|
+
setActivePanelId(activePanelId === 'one' ? 'two' : 'one');
|
|
229
|
+
setTransition('backward');
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const goForward = () => {
|
|
233
|
+
setActivePanelId(activePanelId === 'one' ? 'two' : 'one');
|
|
234
|
+
setTransition('forward');
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const open = () => {
|
|
238
|
+
setModalOpen(true);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const close = () => {
|
|
242
|
+
setModalOpen(false);
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
return (
|
|
246
|
+
<div>
|
|
247
|
+
<Button elementRef={modalToggle} label="Open modal" onClick={open} />
|
|
248
|
+
<Modal returnFocus={modalToggle} onRequestClose={close} open={modalOpen}>
|
|
249
|
+
<Modal.Header title="SlidingPanels in a Modal" />
|
|
250
|
+
<Modal.Body style={{ padding: 0 }}>
|
|
251
|
+
<SlidingPanels activePanelId={activePanelId} transition={transition}>
|
|
252
|
+
<SlidingPanels.Panel
|
|
253
|
+
key="one"
|
|
254
|
+
panelId="one"
|
|
255
|
+
style={{ padding: 20, width: 350 }}
|
|
256
|
+
>
|
|
257
|
+
<Heading level={2}>First</Heading>
|
|
258
|
+
<ControlGroup
|
|
259
|
+
label="Field Label"
|
|
260
|
+
tooltip="Tooltip helps explain the label."
|
|
261
|
+
help="This is the help text."
|
|
262
|
+
>
|
|
263
|
+
<Text canClear />
|
|
264
|
+
</ControlGroup>
|
|
265
|
+
</SlidingPanels.Panel>
|
|
266
|
+
<SlidingPanels.Panel
|
|
267
|
+
key="two"
|
|
268
|
+
panelId="two"
|
|
269
|
+
style={{ padding: 20, width: 800 }}
|
|
270
|
+
>
|
|
271
|
+
<CollapsiblePanel title="Sub Section">
|
|
272
|
+
<P>This is some content inside the sub section panel.</P>
|
|
273
|
+
<ControlGroup
|
|
274
|
+
label="Field Label"
|
|
275
|
+
tooltip="Tooltip helps explain the label."
|
|
276
|
+
help="This is the help text."
|
|
277
|
+
>
|
|
278
|
+
<Text canClear />
|
|
279
|
+
</ControlGroup>
|
|
280
|
+
</CollapsiblePanel>
|
|
281
|
+
<CollapsiblePanel title="Sub Section">
|
|
282
|
+
<P>Additional content for the second sub section.</P>
|
|
283
|
+
</CollapsiblePanel>
|
|
284
|
+
</SlidingPanels.Panel>
|
|
285
|
+
</SlidingPanels>
|
|
286
|
+
</Modal.Body>
|
|
287
|
+
<Modal.Footer>
|
|
288
|
+
<Button onClick={goBack}>Prev</Button>
|
|
289
|
+
<Button appearance="primary" onClick={goForward}>
|
|
290
|
+
Next
|
|
291
|
+
</Button>
|
|
292
|
+
</Modal.Footer>
|
|
293
|
+
</Modal>
|
|
294
|
+
</div>
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export default ModalExample;
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
## API
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
### SlidingPanels API
|
|
308
|
+
|
|
309
|
+
#### Props
|
|
310
|
+
|
|
311
|
+
| Name | Type | Required | Default | Description |
|
|
312
|
+
|------|------|------|------|------|
|
|
313
|
+
| activePanelId | string \| number | yes | | |
|
|
314
|
+
| children | React.ReactNode | no | | |
|
|
315
|
+
| elementRef | React.Ref<HTMLDivElement> | no | | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
|
|
316
|
+
| innerClassName | string | no | | An additional className to inner container. |
|
|
317
|
+
| innerStyle | React.CSSProperties | no | | |
|
|
318
|
+
| onAnimationEnd | () => void | no | | |
|
|
319
|
+
| outerClassName | string | no | | An additional className to outer container. |
|
|
320
|
+
| outerStyle | React.CSSProperties | no | | |
|
|
321
|
+
| transition | 'forward' \| 'backward' | no | 'forward' | Direction to slide the panel |
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
### SlidingPanels.Panel API
|
|
326
|
+
|
|
327
|
+
Container for arbitrary content.
|
|
328
|
+
|
|
329
|
+
#### Props
|
|
330
|
+
|
|
331
|
+
| Name | Type | Required | Default | Description |
|
|
332
|
+
|------|------|------|------|------|
|
|
333
|
+
| children | React.ReactNode | no | | |
|
|
334
|
+
| elementRef | React.Ref<HTMLDivElement> | no | | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
|
|
335
|
+
| panelId | string \| number | yes | | A unique `id` for this panel and used by the SlidingPanels to keep track of the open panel. |
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|