@splunk/react-ui 5.7.1 → 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 +29 -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 +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 +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,295 @@
|
|
|
1
|
+
# Split Button
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
> Image: Illustration of a Split Button component
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## When to use this component
|
|
10
|
+
- When you have two or more actions related to the primary action that need to be consolidated and space is limited.
|
|
11
|
+
|
|
12
|
+
## When to use another component
|
|
13
|
+
Use a button instead of a split button in the following cases:
|
|
14
|
+
- When you want to pair a primary and secondary action, for example “Save” and “Cancel”.
|
|
15
|
+
- If you have only one primary action in a workflow, for example “Done”.
|
|
16
|
+
- If you want to use an icon only and no visible label.
|
|
17
|
+
|
|
18
|
+
```mermaid
|
|
19
|
+
graph TD
|
|
20
|
+
accDescr: Decision tree that guides on when to use the SplitButton component or something else
|
|
21
|
+
A(Is there more than one similar action that needs to be consolidated?) -- Yes --- B(Split Button)
|
|
22
|
+
A -- No --- C(Button)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Check out
|
|
26
|
+
- [Button] [1]
|
|
27
|
+
|
|
28
|
+
## Behaviors
|
|
29
|
+
|
|
30
|
+
### Change label
|
|
31
|
+
Labels can be dynamically swapped for actions that might be repeated.
|
|
32
|
+
> Image: Split button labeled
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Primary action
|
|
38
|
+
Place the primary action on the main button to guide the most common user intent.
|
|
39
|
+
> Image: Two split button examples demonstrating primary action placement. The first example, with a heart eyes emoji, shows a Split button labeled
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Secondary actions
|
|
43
|
+
Ensure the secondary actions in the dropdown are contextually related to the primary action.
|
|
44
|
+
> Image: Two split button examples demonstrating secondary actions in the dropdown. The first example, with a heart eyes emoji, shows a Split button labeled
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### Icons
|
|
48
|
+
Always include a text label for the primary action in Split button to ensure clarity and accessibility. Icons can be used as supplementary elements but should never replace the text label.
|
|
49
|
+
> Image: Two split button examples demonstrating icon usage in labels. The first example, with a heart-eyes emoji, shows a Split button labeled
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
### Multiple buttons
|
|
53
|
+
Split buttons work best alone or paired with additional buttons, using more than one can create confusion.
|
|
54
|
+
> Image: Two examples of split button usage. The first example, with a heart-eyes emoji, shows a single split button labeled
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### Avoid disabling part of the component
|
|
58
|
+
Avoid disabling the primary action or secondary menu.
|
|
59
|
+
> Image: Two examples showing split button states. The first example, with a heart-eyes emoji, displays an enabled split button labeled
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
## Content guidelines
|
|
63
|
+
- Start label with a verb when possible.
|
|
64
|
+
- Avoid vague or generic language such as “click here” or “read more”; this is not helpful for screen reader users.
|
|
65
|
+
- Avoid any acronyms or confusing jargon that may leave a user guessing or afraid to click on a button (SC 2.4.4).
|
|
66
|
+
|
|
67
|
+
### Label should not exceed three words
|
|
68
|
+
Write concise button labels: 1 or 2 words.
|
|
69
|
+
> Image: Two examples showing split button label length. The first example, with a heart-eyes emoji, has a concise label,
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
### Use sentence-style capitalization
|
|
73
|
+
> Image: Two examples showing split button label capitalization. The first example, with a heart-eyes emoji, uses sentence-style capitalization with the label
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
### Use precise language
|
|
77
|
+
Describe the action. For example, use “Add” when using an existing object in a new context, and use “Create” when making a new object from scratch.
|
|
78
|
+
> Image: Two examples showing split button label language. The first example, with a heart-eyes emoji, uses the label
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
### Label overflow
|
|
82
|
+
While usage guidelines for content recommend one to two words for buttons, for internationalization there might be instances when text needs to overflow.
|
|
83
|
+
> Image: Two examples demonstrate split button label overflow. The first example, with a heart-eyes emoji, shows a split button labeled
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
[1]: ./Button
|
|
87
|
+
|
|
88
|
+
## Examples
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
### Basic
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import React from 'react';
|
|
95
|
+
|
|
96
|
+
import Layout from '@splunk/react-ui/Layout';
|
|
97
|
+
import SplitButton from '@splunk/react-ui/SplitButton';
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
export default function Basic() {
|
|
101
|
+
return (
|
|
102
|
+
<Layout>
|
|
103
|
+
<SplitButton>
|
|
104
|
+
<SplitButton.Item>Main action</SplitButton.Item>
|
|
105
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
106
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
107
|
+
</SplitButton>
|
|
108
|
+
<SplitButton appearance="primary">
|
|
109
|
+
<SplitButton.Item>Main action</SplitButton.Item>
|
|
110
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
111
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
112
|
+
</SplitButton>
|
|
113
|
+
<SplitButton appearance="destructive">
|
|
114
|
+
<SplitButton.Item>Main action</SplitButton.Item>
|
|
115
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
116
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
117
|
+
</SplitButton>
|
|
118
|
+
<SplitButton appearance="destructiveSecondary">
|
|
119
|
+
<SplitButton.Item>Main action</SplitButton.Item>
|
|
120
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
121
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
122
|
+
</SplitButton>
|
|
123
|
+
</Layout>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
### Disabled
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import React from 'react';
|
|
134
|
+
|
|
135
|
+
import Layout from '@splunk/react-ui/Layout';
|
|
136
|
+
import SplitButton from '@splunk/react-ui/SplitButton';
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
export default function Disabled() {
|
|
140
|
+
return (
|
|
141
|
+
<Layout>
|
|
142
|
+
<SplitButton disabled>
|
|
143
|
+
<SplitButton.Item>Main action</SplitButton.Item>
|
|
144
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
145
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
146
|
+
</SplitButton>
|
|
147
|
+
<SplitButton appearance="primary" disabled>
|
|
148
|
+
<SplitButton.Item>Main action</SplitButton.Item>
|
|
149
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
150
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
151
|
+
</SplitButton>
|
|
152
|
+
<SplitButton appearance="destructive" disabled>
|
|
153
|
+
<SplitButton.Item>Main action</SplitButton.Item>
|
|
154
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
155
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
156
|
+
</SplitButton>
|
|
157
|
+
<SplitButton appearance="destructiveSecondary" disabled>
|
|
158
|
+
<SplitButton.Item>Main action</SplitButton.Item>
|
|
159
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
160
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
161
|
+
</SplitButton>
|
|
162
|
+
</Layout>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
### Block
|
|
170
|
+
|
|
171
|
+
By default, Split Buttons exist in inline blocks. Set inline to false to make the Split Button the full width of the parent container.
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
import React from 'react';
|
|
175
|
+
|
|
176
|
+
import Layout from '@splunk/react-ui/Layout';
|
|
177
|
+
import SplitButton from '@splunk/react-ui/SplitButton';
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
export default function Block() {
|
|
181
|
+
return (
|
|
182
|
+
<Layout style={{ width: '300px', flexDirection: 'column' }}>
|
|
183
|
+
<SplitButton inline={false}>
|
|
184
|
+
<SplitButton.Item>Main action</SplitButton.Item>
|
|
185
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
186
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
187
|
+
</SplitButton>
|
|
188
|
+
|
|
189
|
+
<SplitButton inline={false} appearance="primary">
|
|
190
|
+
<SplitButton.Item>Primary action</SplitButton.Item>
|
|
191
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
192
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
193
|
+
</SplitButton>
|
|
194
|
+
|
|
195
|
+
<SplitButton inline={false} appearance="destructive">
|
|
196
|
+
<SplitButton.Item>Destructive action</SplitButton.Item>
|
|
197
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
198
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
199
|
+
</SplitButton>
|
|
200
|
+
<SplitButton inline={false} appearance="destructiveSecondary">
|
|
201
|
+
<SplitButton.Item>Destructive secondary action</SplitButton.Item>
|
|
202
|
+
<SplitButton.Item>Option</SplitButton.Item>
|
|
203
|
+
<SplitButton.Item>Another option</SplitButton.Item>
|
|
204
|
+
</SplitButton>
|
|
205
|
+
</Layout>
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
### Change Label
|
|
213
|
+
|
|
214
|
+
The isMain prop can be used to change which Item appears as the main button.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import React, { useState } from 'react';
|
|
218
|
+
|
|
219
|
+
import SplitButton from '@splunk/react-ui/SplitButton';
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
export default function ChangeLabel() {
|
|
223
|
+
const options = ['Create a merge commit', 'Squash and merge', 'Rebase and merge'];
|
|
224
|
+
const [selected, setSelected] = useState(0);
|
|
225
|
+
|
|
226
|
+
const handleMenuItemClick = (index: number) => {
|
|
227
|
+
setSelected(index);
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
return (
|
|
231
|
+
<SplitButton aria-label="PR merge actions">
|
|
232
|
+
{options.map((option, index) => {
|
|
233
|
+
return (
|
|
234
|
+
<SplitButton.Item
|
|
235
|
+
aria-label={option}
|
|
236
|
+
key={option}
|
|
237
|
+
isMain={selected === index}
|
|
238
|
+
onClick={() => handleMenuItemClick(index)}
|
|
239
|
+
>
|
|
240
|
+
{option}
|
|
241
|
+
</SplitButton.Item>
|
|
242
|
+
);
|
|
243
|
+
})}
|
|
244
|
+
</SplitButton>
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
## API
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
### SplitButton API
|
|
256
|
+
|
|
257
|
+
#### Props
|
|
258
|
+
|
|
259
|
+
| Name | Type | Required | Default | Description |
|
|
260
|
+
|------|------|------|------|------|
|
|
261
|
+
| appearance | 'default' \| 'secondary' \| 'primary' \| 'destructive' \| 'destructiveSecondary' | no | 'secondary' | **DEPRECATED**: Value 'default' Changes the style of the main button and toggle. The `default` value is deprecated and will be removed in a future major version. |
|
|
262
|
+
| children | React.ReactNode | no | | Must be `SplitButton.Item`. By default the first child becomes the main button. The remaining children become dropdown items. |
|
|
263
|
+
| disabled | boolean | no | | Prevents main button and dropdown toggle from being clicked. |
|
|
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
|
+
| inline | boolean | no | true | Restricts the horizontal size of the button. Set `inline` to `false` to remove the right margin and stretch the button to the full width of its container. |
|
|
266
|
+
| onClick | React.MouseEventHandler<HTMLDivElement> | no | | A callback for when the main button or toggle is clicked. |
|
|
267
|
+
| toggleRef | React.Ref<HTMLButtonElement \| HTMLAnchorElement> | no | | A React ref which is set to the dropdown toggle when the component mounts and null when it unmounts. |
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
### SplitButton.Item API
|
|
272
|
+
|
|
273
|
+
An item within a `SplitButton`.
|
|
274
|
+
|
|
275
|
+
#### Props
|
|
276
|
+
|
|
277
|
+
| Name | Type | Required | Default | Description |
|
|
278
|
+
|------|------|------|------|------|
|
|
279
|
+
| children | React.ReactNode | no | | Becomes the label. |
|
|
280
|
+
| disabled | boolean | no | | Prevents user from clicking the button. |
|
|
281
|
+
| elementRef | React.Ref<HTMLButtonElement \| HTMLAnchorElement> | no | | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
|
|
282
|
+
| icon | React.ReactNode | no | | Applies an icon in front of the label. |
|
|
283
|
+
| isMain | boolean | no | | Becomes the main button. If no `Item`s have this prop, the first `Item` is the main button. |
|
|
284
|
+
| onClick | ItemClickHandler | no | | A callback for when an item is clicked. |
|
|
285
|
+
|
|
286
|
+
#### Types
|
|
287
|
+
|
|
288
|
+
| Name | Type | Description |
|
|
289
|
+
|------|------|------|
|
|
290
|
+
| ItemClickHandler | ( event: React.MouseEvent<HTMLAnchorElement \| HTMLButtonElement>, data: { action?: string; icon?: React.ReactNode; label?: React.ReactNode; value?: any; // eslint-disable-line @typescript-eslint/no-explicit-any } ) => void | |
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Static Content
|
|
2
|
+
|
|
3
|
+
## Examples
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Basic
|
|
7
|
+
|
|
8
|
+
Static Content renders content within a Control Group.
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
import React from 'react';
|
|
12
|
+
|
|
13
|
+
import ControlGroup from '@splunk/react-ui/ControlGroup';
|
|
14
|
+
import StaticContent from '@splunk/react-ui/StaticContent';
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
function Basic() {
|
|
18
|
+
return (
|
|
19
|
+
<ControlGroup label="StaticContent" controlsLayout="fill">
|
|
20
|
+
<StaticContent> This simply renders the child text! </StaticContent>
|
|
21
|
+
</ControlGroup>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default Basic;
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Icons and Other Controls
|
|
31
|
+
|
|
32
|
+
Static Content with other components in a Control Group.
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import React from 'react';
|
|
36
|
+
|
|
37
|
+
import CylinderMulti from '@splunk/react-icons/CylinderMulti';
|
|
38
|
+
import File from '@splunk/react-icons/File';
|
|
39
|
+
import ControlGroup from '@splunk/react-ui/ControlGroup';
|
|
40
|
+
import StaticContent from '@splunk/react-ui/StaticContent';
|
|
41
|
+
import Text from '@splunk/react-ui/Text';
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
function FieldValue() {
|
|
45
|
+
return (
|
|
46
|
+
<div>
|
|
47
|
+
<ControlGroup label="Product">
|
|
48
|
+
<StaticContent inline>
|
|
49
|
+
<File />
|
|
50
|
+
</StaticContent>
|
|
51
|
+
<StaticContent inline>
|
|
52
|
+
<CylinderMulti />
|
|
53
|
+
</StaticContent>
|
|
54
|
+
</ControlGroup>
|
|
55
|
+
|
|
56
|
+
<ControlGroup label="Cost" controlsLayout="none">
|
|
57
|
+
<Text defaultValue="20" inline />
|
|
58
|
+
<StaticContent inline>Dollars or less</StaticContent>
|
|
59
|
+
</ControlGroup>
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export default FieldValue;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## API
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
### StaticContent API
|
|
74
|
+
|
|
75
|
+
This component is intended for use in a control group, either to display a static value or
|
|
76
|
+
between two controls.
|
|
77
|
+
|
|
78
|
+
#### Props
|
|
79
|
+
|
|
80
|
+
| Name | Type | Required | Default | Description |
|
|
81
|
+
|------|------|------|------|------|
|
|
82
|
+
| children | React.ReactNode | no | | |
|
|
83
|
+
| elementRef | React.Ref<HTMLDivElement> | no | | A React ref which is set to the DOM element when the component mounts, and null when it unmounts. |
|
|
84
|
+
| inline | boolean | no | false | When true, display as inline-block with auto width. |
|
|
85
|
+
| labelledBy | string | no | | |
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# Step Bar
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
> Image: Illustration of a Step Bar component.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## When to use this component
|
|
10
|
+
- You need to guide a user through multiple steps.
|
|
11
|
+
- To display a sequence of related tasks that must be completed in a linear order.
|
|
12
|
+
- When users need to track their progress, such as in long forms or troubleshooting steps.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## When to use another component
|
|
16
|
+
- For navigation between pages, use Breadcrumb instead.
|
|
17
|
+
- To represent overall progress outside of a linear flow, use Progress instead.
|
|
18
|
+
|
|
19
|
+
```mermaid
|
|
20
|
+
graph TD
|
|
21
|
+
accDescr: Decision tree that guides on when to use the StepBar component or something else
|
|
22
|
+
A(Is the purpose to navigate between pages or sections?) -- Yes --- B(Breadcrumbs)
|
|
23
|
+
A -- No --- C(Is the task sequential and step-by-step?)
|
|
24
|
+
C -- Yes --- D(Step Bar)
|
|
25
|
+
C -- No --- E(Progress)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Check out
|
|
29
|
+
- [Breadcrumbs][1]
|
|
30
|
+
- [Progress][2]
|
|
31
|
+
|
|
32
|
+
## Behaviors
|
|
33
|
+
|
|
34
|
+
### Interaction
|
|
35
|
+
Use back and next buttons to navigate to the next step. The Step Bar component is not interactive.
|
|
36
|
+
|
|
37
|
+
> Image: Example laying emphasis on the interactivity of the Step Bar component. The first example with the heart eyes emoji displays the mouse navigating the Step Bar component through the back & next buttons, whereas the second example with the grimacing emoji displays the navigating through the Step Bar component by clicking on the Step Bar component itself.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
### Content alignment
|
|
43
|
+
Content in a step should always relate to its corresponding step title.
|
|
44
|
+
|
|
45
|
+
> Image: Example laying emphasis on content within a step being related to the step title. The first example with the heart eyes emoji displays review summary content under the
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### No less than two steps
|
|
49
|
+
|
|
50
|
+
> Image: Example laying emphasis on least number of steps provided. The first example with the heart eyes emoji displays 2 steps, whereas the second example with the grimacing emoji displays 1 step.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
### Step title content
|
|
54
|
+
#### Provide context
|
|
55
|
+
Provide context about the contents of the step with the help of the step title.
|
|
56
|
+
|
|
57
|
+
> Image: Example laying emphasis on providing context within the step title. The first example with the heart eyes emoji displays step titles that provide context to the step, whereas the second example with the grimacing emoji displays no step titles.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
#### Be concise
|
|
61
|
+
Step titles should be kept as descriptive as possible while remaining concise.
|
|
62
|
+
|
|
63
|
+
> Image: Example laying emphasis on giving concise labels to the step title. The first example with the heart eyes emoji displays a concise label for the step title, whereas the second example with the grimacing emoji displays a longer, more complicated one.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Content
|
|
67
|
+
|
|
68
|
+
### Use sentence case, not title case.
|
|
69
|
+
Only the first letter of the word should be capitalized unless it's a proper noun.
|
|
70
|
+
|
|
71
|
+
> Image: Example laying emphasis on the capitalization in the Step Bar. The first example with the heart eyes emoji displays the step title to use sentence case, whereas the second example with the grimacing emoji displays step title to use title case.
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
[1]: ./Breadcrumbs
|
|
75
|
+
[2]: ./Progress
|
|
76
|
+
|
|
77
|
+
## Examples
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
### numSteps
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import React, { useCallback, useState } from 'react';
|
|
84
|
+
|
|
85
|
+
import ChevronLeft from '@splunk/react-icons/ChevronLeft';
|
|
86
|
+
import ChevronRight from '@splunk/react-icons/ChevronRight';
|
|
87
|
+
import Button from '@splunk/react-ui/Button';
|
|
88
|
+
import Layout from '@splunk/react-ui/Layout';
|
|
89
|
+
import StepBar from '@splunk/react-ui/StepBar';
|
|
90
|
+
|
|
91
|
+
const numSteps = 4;
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
function Basic() {
|
|
95
|
+
const [activeStepId, setActiveStepId] = useState(0);
|
|
96
|
+
|
|
97
|
+
const handlePrevious = useCallback(() => {
|
|
98
|
+
setActiveStepId(activeStepId - 1);
|
|
99
|
+
}, [activeStepId]);
|
|
100
|
+
|
|
101
|
+
const handleNext = useCallback(() => {
|
|
102
|
+
setActiveStepId(activeStepId + 1);
|
|
103
|
+
}, [activeStepId]);
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<div>
|
|
107
|
+
<StepBar activeStepId={activeStepId}>
|
|
108
|
+
<StepBar.Step>Select item</StepBar.Step>
|
|
109
|
+
<StepBar.Step>Configure required</StepBar.Step>
|
|
110
|
+
<StepBar.Step>Configure optional</StepBar.Step>
|
|
111
|
+
<StepBar.Step>Review</StepBar.Step>
|
|
112
|
+
</StepBar>
|
|
113
|
+
<br />
|
|
114
|
+
<br />
|
|
115
|
+
<Layout>
|
|
116
|
+
<Button
|
|
117
|
+
icon={<ChevronLeft />}
|
|
118
|
+
label="Back"
|
|
119
|
+
appearance="default"
|
|
120
|
+
disabled={activeStepId === 0}
|
|
121
|
+
onClick={handlePrevious}
|
|
122
|
+
/>
|
|
123
|
+
<Button
|
|
124
|
+
label={activeStepId < numSteps - 1 ? 'Next' : 'Done'}
|
|
125
|
+
appearance="primary"
|
|
126
|
+
onClick={activeStepId < numSteps - 1 ? handleNext : undefined}
|
|
127
|
+
>
|
|
128
|
+
<ChevronRight />
|
|
129
|
+
</Button>
|
|
130
|
+
</Layout>
|
|
131
|
+
</div>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export default Basic;
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
### numSteps
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import React, { useCallback, useState } from 'react';
|
|
144
|
+
|
|
145
|
+
import ChevronLeft from '@splunk/react-icons/ChevronLeft';
|
|
146
|
+
import ChevronRight from '@splunk/react-icons/ChevronRight';
|
|
147
|
+
import Button from '@splunk/react-ui/Button';
|
|
148
|
+
import Layout from '@splunk/react-ui/Layout';
|
|
149
|
+
import StepBar from '@splunk/react-ui/StepBar';
|
|
150
|
+
|
|
151
|
+
const numSteps = 4;
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
function StepBarError() {
|
|
155
|
+
const [activeStepId, setActiveStepId] = useState(1);
|
|
156
|
+
const handlePrevious = useCallback(() => {
|
|
157
|
+
setActiveStepId(activeStepId - 1);
|
|
158
|
+
}, [activeStepId]);
|
|
159
|
+
|
|
160
|
+
const handleNext = useCallback(() => {
|
|
161
|
+
setActiveStepId(activeStepId + 1);
|
|
162
|
+
}, [activeStepId]);
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<div>
|
|
166
|
+
<StepBar activeStepId={activeStepId}>
|
|
167
|
+
<StepBar.Step>Select item</StepBar.Step>
|
|
168
|
+
<StepBar.Step error>Configure required</StepBar.Step>
|
|
169
|
+
<StepBar.Step>Configure optional</StepBar.Step>
|
|
170
|
+
<StepBar.Step>Review</StepBar.Step>
|
|
171
|
+
</StepBar>
|
|
172
|
+
<br />
|
|
173
|
+
<br />
|
|
174
|
+
<Layout>
|
|
175
|
+
<Button
|
|
176
|
+
icon={<ChevronLeft />}
|
|
177
|
+
label="Back"
|
|
178
|
+
appearance="default"
|
|
179
|
+
disabled={activeStepId === 0}
|
|
180
|
+
onClick={handlePrevious}
|
|
181
|
+
/>
|
|
182
|
+
<Button
|
|
183
|
+
label={activeStepId < numSteps - 1 ? 'Next' : 'Done'}
|
|
184
|
+
appearance="primary"
|
|
185
|
+
onClick={activeStepId < numSteps - 1 ? handleNext : undefined}
|
|
186
|
+
disabled={activeStepId === 1}
|
|
187
|
+
>
|
|
188
|
+
<ChevronRight />
|
|
189
|
+
</Button>
|
|
190
|
+
</Layout>
|
|
191
|
+
</div>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export default StepBarError;
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
### numSteps
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import React, { useCallback, useState } from 'react';
|
|
204
|
+
|
|
205
|
+
import ChevronLeft from '@splunk/react-icons/ChevronLeft';
|
|
206
|
+
import ChevronRight from '@splunk/react-icons/ChevronRight';
|
|
207
|
+
import Button from '@splunk/react-ui/Button';
|
|
208
|
+
import Layout from '@splunk/react-ui/Layout';
|
|
209
|
+
import StepBar from '@splunk/react-ui/StepBar';
|
|
210
|
+
|
|
211
|
+
const numSteps = 4;
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
function Vertical() {
|
|
215
|
+
const [activeStepId, setActiveStepId] = useState(0);
|
|
216
|
+
|
|
217
|
+
const handlePrevious = useCallback(() => {
|
|
218
|
+
setActiveStepId(activeStepId - 1);
|
|
219
|
+
}, [activeStepId]);
|
|
220
|
+
|
|
221
|
+
const handleNext = useCallback(() => {
|
|
222
|
+
setActiveStepId(activeStepId + 1);
|
|
223
|
+
}, [activeStepId]);
|
|
224
|
+
|
|
225
|
+
return (
|
|
226
|
+
<div>
|
|
227
|
+
<StepBar activeStepId={activeStepId} orientation="vertical" style={{ width: '250px' }}>
|
|
228
|
+
<StepBar.Step>Select item</StepBar.Step>
|
|
229
|
+
<StepBar.Step>Configure required</StepBar.Step>
|
|
230
|
+
<StepBar.Step>Configure optional</StepBar.Step>
|
|
231
|
+
<StepBar.Step>Review</StepBar.Step>
|
|
232
|
+
</StepBar>
|
|
233
|
+
<br />
|
|
234
|
+
<br />
|
|
235
|
+
<Layout>
|
|
236
|
+
<Button
|
|
237
|
+
icon={<ChevronLeft />}
|
|
238
|
+
label="Back"
|
|
239
|
+
appearance="default"
|
|
240
|
+
disabled={activeStepId === 0}
|
|
241
|
+
onClick={handlePrevious}
|
|
242
|
+
/>
|
|
243
|
+
<Button
|
|
244
|
+
label={activeStepId < numSteps - 1 ? 'Next' : 'Done'}
|
|
245
|
+
appearance="primary"
|
|
246
|
+
onClick={activeStepId < numSteps - 1 ? handleNext : undefined}
|
|
247
|
+
>
|
|
248
|
+
<ChevronRight />
|
|
249
|
+
</Button>
|
|
250
|
+
</Layout>
|
|
251
|
+
</div>
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export default Vertical;
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
## API
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
### StepBar API
|
|
265
|
+
|
|
266
|
+
#### Props
|
|
267
|
+
|
|
268
|
+
| Name | Type | Required | Default | Description |
|
|
269
|
+
|------|------|------|------|------|
|
|
270
|
+
| activeStepId | number | yes | | The `stepId` of the `StepBar.Step` to activate. |
|
|
271
|
+
| children | React.ReactNode | no | | Must be `StepBar.Step`. |
|
|
272
|
+
| elementRef | React.Ref<HTMLUListElement> | no | | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
|
|
273
|
+
| inline | boolean | no | false | Setting inline to true makes the Step Bar an inline element. It assumes its minimum width. |
|
|
274
|
+
| orientation | 'horizontal' \| 'vertical' | no | 'horizontal' | The flow direction of steps. |
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
### StepBar.Step API
|
|
279
|
+
|
|
280
|
+
#### Props
|
|
281
|
+
|
|
282
|
+
| Name | Type | Required | Default | Description |
|
|
283
|
+
|------|------|------|------|------|
|
|
284
|
+
| children | React.ReactNode | no | | |
|
|
285
|
+
| elementRef | React.Ref<HTMLLIElement> | no | | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
|
|
286
|
+
| error | boolean | no | false | Displays active step with alert icon. |
|
|
287
|
+
| stepId | number | no | | A unique `id` for this step and used by the `StepBar` to keep track of the open `Step`. Defaults to a zero-based index matching the component's position in `StepBar`. |
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
|