@stack-spot/citric-react 0.38.0 → 0.39.1
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/CHANGELOG.md +13 -13
- package/dist/citric.css +2844 -2844
- package/dist/components/Accordion.d.ts +1 -1
- package/dist/components/Accordion.js +1 -1
- package/dist/components/Alert.d.ts +1 -1
- package/dist/components/Alert.js +1 -1
- package/dist/components/AsyncContent.d.ts +1 -1
- package/dist/components/AsyncContent.js +1 -1
- package/dist/components/Avatar.d.ts +1 -1
- package/dist/components/Avatar.js +1 -1
- package/dist/components/AvatarGroup.d.ts +1 -1
- package/dist/components/AvatarGroup.js +1 -1
- package/dist/components/Badge.d.ts +1 -1
- package/dist/components/Badge.js +1 -1
- package/dist/components/Blockquote.d.ts +1 -1
- package/dist/components/Blockquote.js +1 -1
- package/dist/components/Breadcrumb.d.ts +1 -1
- package/dist/components/Breadcrumb.js +1 -1
- package/dist/components/Button.d.ts +1 -1
- package/dist/components/Button.js +1 -1
- package/dist/components/ButtonLink.d.ts +1 -1
- package/dist/components/ButtonLink.js +1 -1
- package/dist/components/Card.d.ts +1 -1
- package/dist/components/Card.js +1 -1
- package/dist/components/Checkbox.d.ts +1 -1
- package/dist/components/Checkbox.js +1 -1
- package/dist/components/CheckboxGroup.d.ts +1 -1
- package/dist/components/CheckboxGroup.d.ts.map +1 -1
- package/dist/components/CheckboxGroup.js +2 -2
- package/dist/components/CheckboxGroup.js.map +1 -1
- package/dist/components/Circle.d.ts +1 -1
- package/dist/components/Circle.js +1 -1
- package/dist/components/Divider.d.ts +1 -1
- package/dist/components/Divider.js +1 -1
- package/dist/components/ErrorBoundary.d.ts +1 -1
- package/dist/components/ErrorBoundary.js +1 -1
- package/dist/components/ErrorMessage.d.ts +1 -1
- package/dist/components/ErrorMessage.js +1 -1
- package/dist/components/FallbackBoundary.d.ts +1 -1
- package/dist/components/FallbackBoundary.js +1 -1
- package/dist/components/Favorite.d.ts +1 -1
- package/dist/components/Favorite.js +1 -1
- package/dist/components/FieldGroup.d.ts +1 -1
- package/dist/components/FieldGroup.js +1 -1
- package/dist/components/Form.d.ts +2 -2
- package/dist/components/Form.js +1 -1
- package/dist/components/FormGroup.d.ts +1 -1
- package/dist/components/FormGroup.js +1 -1
- package/dist/components/Icon.d.ts +1 -1
- package/dist/components/Icon.js +1 -1
- package/dist/components/IconBox.d.ts +3 -3
- package/dist/components/IconBox.js +1 -1
- package/dist/components/ImageBox.d.ts +3 -3
- package/dist/components/ImageBox.js +1 -1
- package/dist/components/ImageWithFallback.d.ts +1 -1
- package/dist/components/ImageWithFallback.js +1 -1
- package/dist/components/Input.d.ts +1 -1
- package/dist/components/Input.js +1 -1
- package/dist/components/Link.d.ts +1 -1
- package/dist/components/Link.js +1 -1
- package/dist/components/LoadingPanel.d.ts +1 -1
- package/dist/components/LoadingPanel.js +1 -1
- package/dist/components/MenuOverlay/Menu.d.ts +1 -1
- package/dist/components/MenuOverlay/Menu.js +1 -1
- package/dist/components/MenuOverlay/index.d.ts +1 -1
- package/dist/components/MenuOverlay/index.js +1 -1
- package/dist/components/Overlay/index.d.ts +4 -1
- package/dist/components/Overlay/index.d.ts.map +1 -1
- package/dist/components/Overlay/index.js +4 -1
- package/dist/components/Overlay/index.js.map +1 -1
- package/dist/components/Pagination.d.ts +1 -1
- package/dist/components/Pagination.js +1 -1
- package/dist/components/ProgressBar.d.ts +1 -1
- package/dist/components/ProgressBar.js +1 -1
- package/dist/components/ProgressCircular.d.ts +1 -1
- package/dist/components/ProgressCircular.js +1 -1
- package/dist/components/RadioGroup.d.ts +1 -1
- package/dist/components/RadioGroup.d.ts.map +1 -1
- package/dist/components/RadioGroup.js +2 -2
- package/dist/components/RadioGroup.js.map +1 -1
- package/dist/components/Rating.d.ts +1 -1
- package/dist/components/Rating.js +1 -1
- package/dist/components/Select/MultiSelect.d.ts +1 -1
- package/dist/components/Select/MultiSelect.js +1 -1
- package/dist/components/Select/RichSelect.d.ts +1 -1
- package/dist/components/Select/RichSelect.js +1 -1
- package/dist/components/Select/SimpleSelect.d.ts +1 -1
- package/dist/components/Select/SimpleSelect.js +1 -1
- package/dist/components/Select/index.d.ts +1 -1
- package/dist/components/Select/index.js +1 -1
- package/dist/components/SelectBox.d.ts +1 -1
- package/dist/components/SelectBox.js +1 -1
- package/dist/components/Skeleton.d.ts +1 -1
- package/dist/components/Skeleton.js +1 -1
- package/dist/components/Slider.d.ts +1 -1
- package/dist/components/Slider.js +1 -1
- package/dist/components/SmartTable.d.ts +1 -1
- package/dist/components/SmartTable.js +1 -1
- package/dist/components/Stepper.d.ts +1 -1
- package/dist/components/Stepper.js +1 -1
- package/dist/components/Table.d.ts +3 -3
- package/dist/components/Table.js +1 -1
- package/dist/components/Tabs/index.d.ts +1 -1
- package/dist/components/Tabs/index.js +1 -1
- package/dist/components/Textarea.d.ts +1 -1
- package/dist/components/Textarea.js +1 -1
- package/dist/components/Tooltip.d.ts +1 -1
- package/dist/components/Tooltip.js +1 -1
- package/dist/context/CitricProvider.d.ts +1 -1
- package/dist/context/CitricProvider.js +1 -1
- package/dist/overlay.js +1 -1
- package/dist/theme.css +415 -415
- package/package.json +1 -1
- package/scripts/build-css.ts +49 -49
- package/src/components/Accordion.tsx +130 -130
- package/src/components/Alert.tsx +24 -24
- package/src/components/AsyncContent.tsx +70 -70
- package/src/components/Avatar.tsx +45 -45
- package/src/components/AvatarGroup.tsx +49 -49
- package/src/components/Badge.tsx +47 -47
- package/src/components/Blockquote.tsx +18 -18
- package/src/components/Breadcrumb.tsx +33 -33
- package/src/components/Button.tsx +105 -105
- package/src/components/ButtonLink.tsx +45 -45
- package/src/components/Card.tsx +68 -68
- package/src/components/Checkbox.tsx +51 -51
- package/src/components/CheckboxGroup.tsx +153 -152
- package/src/components/Circle.tsx +43 -43
- package/src/components/CitricComponent.ts +47 -47
- package/src/components/Divider.tsx +24 -24
- package/src/components/ErrorBoundary.tsx +75 -75
- package/src/components/ErrorMessage.tsx +11 -11
- package/src/components/FallbackBoundary.tsx +40 -40
- package/src/components/Favorite.tsx +57 -57
- package/src/components/FieldGroup.tsx +46 -46
- package/src/components/Form.tsx +36 -36
- package/src/components/FormGroup.tsx +57 -57
- package/src/components/Icon.tsx +35 -35
- package/src/components/IconBox.tsx +134 -134
- package/src/components/ImageBox.tsx +125 -125
- package/src/components/ImageWithFallback.tsx +65 -65
- package/src/components/Input.tsx +49 -49
- package/src/components/Link.tsx +55 -55
- package/src/components/LoadingPanel.tsx +8 -8
- package/src/components/MenuOverlay/Menu.tsx +158 -158
- package/src/components/MenuOverlay/context.ts +20 -20
- package/src/components/MenuOverlay/index.tsx +55 -55
- package/src/components/MenuOverlay/keyboard.ts +60 -60
- package/src/components/MenuOverlay/types.ts +171 -171
- package/src/components/Overlay/context.ts +10 -10
- package/src/components/Overlay/index.tsx +167 -164
- package/src/components/Overlay/types.ts +70 -70
- package/src/components/Pagination.tsx +133 -133
- package/src/components/ProgressBar.tsx +45 -45
- package/src/components/ProgressCircular.tsx +45 -45
- package/src/components/RadioGroup.tsx +147 -146
- package/src/components/Rating.tsx +98 -98
- package/src/components/Select/MultiSelect.tsx +217 -217
- package/src/components/Select/RichSelect.tsx +128 -128
- package/src/components/Select/SimpleSelect.tsx +73 -73
- package/src/components/Select/hooks.ts +133 -133
- package/src/components/Select/index.tsx +35 -35
- package/src/components/Select/types.ts +134 -134
- package/src/components/SelectBox.tsx +167 -167
- package/src/components/Skeleton.tsx +53 -53
- package/src/components/Slider.tsx +89 -89
- package/src/components/SmartTable.tsx +227 -227
- package/src/components/Stepper.tsx +163 -163
- package/src/components/Table.tsx +234 -234
- package/src/components/Tabs/TabController.ts +54 -54
- package/src/components/Tabs/index.tsx +87 -87
- package/src/components/Tabs/types.ts +54 -54
- package/src/components/Tabs/utils.ts +6 -6
- package/src/components/Text.ts +111 -111
- package/src/components/Textarea.tsx +27 -27
- package/src/components/Tooltip.tsx +72 -72
- package/src/components/layout.tsx +101 -101
- package/src/context/CitricContext.tsx +4 -4
- package/src/context/CitricProvider.tsx +14 -14
- package/src/context/hooks.ts +6 -6
- package/src/index.ts +58 -58
- package/src/overlay.ts +341 -341
- package/src/types.ts +216 -216
- package/src/utils/ValueController.ts +28 -28
- package/src/utils/acessibility.ts +92 -92
- package/src/utils/checkbox.ts +121 -121
- package/src/utils/css.ts +119 -119
- package/src/utils/options.ts +9 -9
- package/src/utils/radio.ts +93 -93
- package/src/utils/react.ts +6 -6
- package/tsconfig.json +10 -10
|
@@ -1,163 +1,163 @@
|
|
|
1
|
-
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
-
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
3
|
-
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
4
|
-
import { withRef } from '../utils/react'
|
|
5
|
-
import { Button } from './Button'
|
|
6
|
-
import { Column, Row } from './layout'
|
|
7
|
-
import { Tabs } from './Tabs'
|
|
8
|
-
import { TabController } from './Tabs/TabController'
|
|
9
|
-
import { BaseTabsProps, Tab } from './Tabs/types'
|
|
10
|
-
import { findSelectedIndex } from './Tabs/utils'
|
|
11
|
-
|
|
12
|
-
export interface BaseStepperProps<Key extends string> extends BaseTabsProps<Key> {
|
|
13
|
-
/**
|
|
14
|
-
* Should we show buttons to control the step we are in?
|
|
15
|
-
*
|
|
16
|
-
* Set it to false to not show any buttons, set it to true to show a default set of buttons, set it to an object to customize the buttons.
|
|
17
|
-
*
|
|
18
|
-
* @default true
|
|
19
|
-
*/
|
|
20
|
-
buttons?: boolean | {
|
|
21
|
-
/**
|
|
22
|
-
* The text for the previous button.
|
|
23
|
-
*/
|
|
24
|
-
previous?: string,
|
|
25
|
-
/**
|
|
26
|
-
* The text for the next button.
|
|
27
|
-
*/
|
|
28
|
-
next?: string,
|
|
29
|
-
/**
|
|
30
|
-
* The text for the finish button.
|
|
31
|
-
*/
|
|
32
|
-
finish?: string,
|
|
33
|
-
/**
|
|
34
|
-
* The text for the cancel button.
|
|
35
|
-
*/
|
|
36
|
-
cancel?: string,
|
|
37
|
-
/**
|
|
38
|
-
* When set, instead of not showing a previous button in the first step, it shows a cancel button. This function is run whenever the
|
|
39
|
-
* cancel button is clicked.
|
|
40
|
-
*/
|
|
41
|
-
onCancel?: () => void,
|
|
42
|
-
/**
|
|
43
|
-
* An additional function to run whenever the previous button is clicked. Return false to prevent the default action (going to the
|
|
44
|
-
* previous step).
|
|
45
|
-
*/
|
|
46
|
-
onPrevious?: (tab: Key) => void | boolean,
|
|
47
|
-
/**
|
|
48
|
-
* An additional function to run whenever the next button is clicked. Return false to prevent the default action (going to the
|
|
49
|
-
* next step).
|
|
50
|
-
*/
|
|
51
|
-
onNext?: (tab: Key) => void | boolean,
|
|
52
|
-
/**
|
|
53
|
-
* When set, instead of not showing a next button in the final step, it shows a finish button. This function is run whenever the
|
|
54
|
-
* finish button is clicked.
|
|
55
|
-
*/
|
|
56
|
-
onFinish?: () => void,
|
|
57
|
-
},
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export type StepperProps<Key extends string> = Omit<React.JSX.IntrinsicElements['div'], 'onChange' | 'children'> & BaseStepperProps<Key>
|
|
61
|
-
|
|
62
|
-
function getTabsWithDisabled<Key extends string>(tabs: Tab<Key>[], value: Key | undefined) {
|
|
63
|
-
let index = findSelectedIndex(tabs, value ?? '')
|
|
64
|
-
if (index < 0) index = 0
|
|
65
|
-
return tabs.map((t, i) => ({ ...t, disabled: i > index }))
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* A Stepper is a tab view with a different appearance. To control the current tab (step), retrieve the controller by calling
|
|
70
|
-
* `useTabsController()` from within a tab (step) content.
|
|
71
|
-
*
|
|
72
|
-
* Besides all the properties in "Tabs", the "Stepper" can create a set of "Previous" and "Next" buttons through the property "buttons". By
|
|
73
|
-
* default, the buttons are rendered, to disable them, pass `buttons = false`.
|
|
74
|
-
*
|
|
75
|
-
* @example
|
|
76
|
-
*
|
|
77
|
-
* ```
|
|
78
|
-
* const steps: Tab[] = useMemo(() => [
|
|
79
|
-
* { key: 'step1', label: 'Step 1', content: <><h1>First step</h1><p>Content of the first step</p></> },
|
|
80
|
-
* { key: 'step2', label: 'Step 2', content: <><h1>Second step</h1><p>Content of the second step</p></> },
|
|
81
|
-
* { key: 'step3', label: 'Step 3', content: <><h1>Third step</h1><p>Content of the third step</p></> },
|
|
82
|
-
* ], [])
|
|
83
|
-
*
|
|
84
|
-
* return <Stepper tabs={steps} />
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
export const Stepper = withRef(
|
|
88
|
-
function Stepper<Key extends string>(
|
|
89
|
-
{ tabs: initialTabs, controller: ctrl, value, onChange, buttons = true, className, ...props }: StepperProps<Key>,
|
|
90
|
-
) {
|
|
91
|
-
const controller = useMemo(
|
|
92
|
-
() => ctrl ?? new TabController<Key>(initialTabs.map(t => t.key), value || initialTabs[0]?.key),
|
|
93
|
-
[],
|
|
94
|
-
)
|
|
95
|
-
const [tabs, setTabs] = useState(getTabsWithDisabled(initialTabs, value))
|
|
96
|
-
const [selectedIndex, setSelectedIndex] = useState(findSelectedIndex(tabs, controller.getValue()))
|
|
97
|
-
const t = useTranslate(dictionary)
|
|
98
|
-
|
|
99
|
-
useEffect(() => controller.onChange((v) => {
|
|
100
|
-
setSelectedIndex(findSelectedIndex(tabs, v))
|
|
101
|
-
}), [tabs])
|
|
102
|
-
|
|
103
|
-
useEffect(() => controller.onChange((value) => {
|
|
104
|
-
setTabs(getTabsWithDisabled(initialTabs, value))
|
|
105
|
-
}), [])
|
|
106
|
-
|
|
107
|
-
const onPrevious = useCallback(() => {
|
|
108
|
-
controller.previous()
|
|
109
|
-
if (typeof buttons === 'object') buttons.onPrevious?.(controller.getValue())
|
|
110
|
-
}, [])
|
|
111
|
-
|
|
112
|
-
const onNext = useCallback(() => {
|
|
113
|
-
controller.next()
|
|
114
|
-
if (typeof buttons === 'object') buttons.onNext?.(controller.getValue())
|
|
115
|
-
}, [])
|
|
116
|
-
|
|
117
|
-
return buttons ? (
|
|
118
|
-
<Column {...props} className={className} gap="20px">
|
|
119
|
-
<Tabs tabs={tabs} controller={controller} value={value} onChange={onChange} className="stepper" />
|
|
120
|
-
<Row justifyContent={(typeof buttons !== 'object' || !buttons.onCancel) && selectedIndex === 0 ? 'end' : 'space-between'}>
|
|
121
|
-
{selectedIndex === 0 && typeof buttons === 'object' && buttons.onCancel && (
|
|
122
|
-
<Button onClick={buttons.onCancel} colorScheme="inverse" appearance="outlined">{buttons.cancel || t.cancel}</Button>
|
|
123
|
-
)}
|
|
124
|
-
{selectedIndex > 0 && buttons && (
|
|
125
|
-
<Button onClick={onPrevious} colorScheme="inverse" appearance="outlined">
|
|
126
|
-
{(typeof buttons === 'object' && buttons.previous) || t.previous}
|
|
127
|
-
</Button>
|
|
128
|
-
)}
|
|
129
|
-
{selectedIndex < tabs.length - 1 && buttons && (
|
|
130
|
-
<Button onClick={onNext}>
|
|
131
|
-
{(typeof buttons === 'object' && buttons.next) || t.next}
|
|
132
|
-
</Button>
|
|
133
|
-
)}
|
|
134
|
-
{selectedIndex === tabs.length - 1 && typeof buttons === 'object' && buttons.onFinish && (
|
|
135
|
-
<Button onClick={buttons.onFinish}>{buttons.finish || t.finish}</Button>
|
|
136
|
-
)}
|
|
137
|
-
</Row>
|
|
138
|
-
</Column>
|
|
139
|
-
) : <Tabs
|
|
140
|
-
tabs={tabs}
|
|
141
|
-
controller={controller}
|
|
142
|
-
value={value}
|
|
143
|
-
onChange={onChange}
|
|
144
|
-
className={listToClass([className, 'stepper'])}
|
|
145
|
-
{...props}
|
|
146
|
-
/>
|
|
147
|
-
},
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
const dictionary = {
|
|
151
|
-
en: {
|
|
152
|
-
cancel: 'Cancel',
|
|
153
|
-
previous: 'Previous',
|
|
154
|
-
next: 'Next',
|
|
155
|
-
finish: 'Finish',
|
|
156
|
-
},
|
|
157
|
-
pt: {
|
|
158
|
-
cancel: 'Cancelar',
|
|
159
|
-
previous: 'Anterior',
|
|
160
|
-
next: 'Próximo',
|
|
161
|
-
finish: 'Finalizar',
|
|
162
|
-
},
|
|
163
|
-
} satisfies Dictionary
|
|
1
|
+
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
+
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
3
|
+
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
4
|
+
import { withRef } from '../utils/react'
|
|
5
|
+
import { Button } from './Button'
|
|
6
|
+
import { Column, Row } from './layout'
|
|
7
|
+
import { Tabs } from './Tabs'
|
|
8
|
+
import { TabController } from './Tabs/TabController'
|
|
9
|
+
import { BaseTabsProps, Tab } from './Tabs/types'
|
|
10
|
+
import { findSelectedIndex } from './Tabs/utils'
|
|
11
|
+
|
|
12
|
+
export interface BaseStepperProps<Key extends string> extends BaseTabsProps<Key> {
|
|
13
|
+
/**
|
|
14
|
+
* Should we show buttons to control the step we are in?
|
|
15
|
+
*
|
|
16
|
+
* Set it to false to not show any buttons, set it to true to show a default set of buttons, set it to an object to customize the buttons.
|
|
17
|
+
*
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
buttons?: boolean | {
|
|
21
|
+
/**
|
|
22
|
+
* The text for the previous button.
|
|
23
|
+
*/
|
|
24
|
+
previous?: string,
|
|
25
|
+
/**
|
|
26
|
+
* The text for the next button.
|
|
27
|
+
*/
|
|
28
|
+
next?: string,
|
|
29
|
+
/**
|
|
30
|
+
* The text for the finish button.
|
|
31
|
+
*/
|
|
32
|
+
finish?: string,
|
|
33
|
+
/**
|
|
34
|
+
* The text for the cancel button.
|
|
35
|
+
*/
|
|
36
|
+
cancel?: string,
|
|
37
|
+
/**
|
|
38
|
+
* When set, instead of not showing a previous button in the first step, it shows a cancel button. This function is run whenever the
|
|
39
|
+
* cancel button is clicked.
|
|
40
|
+
*/
|
|
41
|
+
onCancel?: () => void,
|
|
42
|
+
/**
|
|
43
|
+
* An additional function to run whenever the previous button is clicked. Return false to prevent the default action (going to the
|
|
44
|
+
* previous step).
|
|
45
|
+
*/
|
|
46
|
+
onPrevious?: (tab: Key) => void | boolean,
|
|
47
|
+
/**
|
|
48
|
+
* An additional function to run whenever the next button is clicked. Return false to prevent the default action (going to the
|
|
49
|
+
* next step).
|
|
50
|
+
*/
|
|
51
|
+
onNext?: (tab: Key) => void | boolean,
|
|
52
|
+
/**
|
|
53
|
+
* When set, instead of not showing a next button in the final step, it shows a finish button. This function is run whenever the
|
|
54
|
+
* finish button is clicked.
|
|
55
|
+
*/
|
|
56
|
+
onFinish?: () => void,
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type StepperProps<Key extends string> = Omit<React.JSX.IntrinsicElements['div'], 'onChange' | 'children'> & BaseStepperProps<Key>
|
|
61
|
+
|
|
62
|
+
function getTabsWithDisabled<Key extends string>(tabs: Tab<Key>[], value: Key | undefined) {
|
|
63
|
+
let index = findSelectedIndex(tabs, value ?? '')
|
|
64
|
+
if (index < 0) index = 0
|
|
65
|
+
return tabs.map((t, i) => ({ ...t, disabled: i > index }))
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* A Stepper is a tab view with a different appearance. To control the current tab (step), retrieve the controller by calling
|
|
70
|
+
* `useTabsController()` from within a tab (step) content.
|
|
71
|
+
*
|
|
72
|
+
* Besides all the properties in "Tabs", the "Stepper" can create a set of "Previous" and "Next" buttons through the property "buttons". By
|
|
73
|
+
* default, the buttons are rendered, to disable them, pass `buttons = false`.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
*
|
|
77
|
+
* ```
|
|
78
|
+
* const steps: Tab[] = useMemo(() => [
|
|
79
|
+
* { key: 'step1', label: 'Step 1', content: <><h1>First step</h1><p>Content of the first step</p></> },
|
|
80
|
+
* { key: 'step2', label: 'Step 2', content: <><h1>Second step</h1><p>Content of the second step</p></> },
|
|
81
|
+
* { key: 'step3', label: 'Step 3', content: <><h1>Third step</h1><p>Content of the third step</p></> },
|
|
82
|
+
* ], [])
|
|
83
|
+
*
|
|
84
|
+
* return <Stepper tabs={steps} />
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export const Stepper = withRef(
|
|
88
|
+
function Stepper<Key extends string>(
|
|
89
|
+
{ tabs: initialTabs, controller: ctrl, value, onChange, buttons = true, className, ...props }: StepperProps<Key>,
|
|
90
|
+
) {
|
|
91
|
+
const controller = useMemo(
|
|
92
|
+
() => ctrl ?? new TabController<Key>(initialTabs.map(t => t.key), value || initialTabs[0]?.key),
|
|
93
|
+
[],
|
|
94
|
+
)
|
|
95
|
+
const [tabs, setTabs] = useState(getTabsWithDisabled(initialTabs, value))
|
|
96
|
+
const [selectedIndex, setSelectedIndex] = useState(findSelectedIndex(tabs, controller.getValue()))
|
|
97
|
+
const t = useTranslate(dictionary)
|
|
98
|
+
|
|
99
|
+
useEffect(() => controller.onChange((v) => {
|
|
100
|
+
setSelectedIndex(findSelectedIndex(tabs, v))
|
|
101
|
+
}), [tabs])
|
|
102
|
+
|
|
103
|
+
useEffect(() => controller.onChange((value) => {
|
|
104
|
+
setTabs(getTabsWithDisabled(initialTabs, value))
|
|
105
|
+
}), [])
|
|
106
|
+
|
|
107
|
+
const onPrevious = useCallback(() => {
|
|
108
|
+
controller.previous()
|
|
109
|
+
if (typeof buttons === 'object') buttons.onPrevious?.(controller.getValue())
|
|
110
|
+
}, [])
|
|
111
|
+
|
|
112
|
+
const onNext = useCallback(() => {
|
|
113
|
+
controller.next()
|
|
114
|
+
if (typeof buttons === 'object') buttons.onNext?.(controller.getValue())
|
|
115
|
+
}, [])
|
|
116
|
+
|
|
117
|
+
return buttons ? (
|
|
118
|
+
<Column {...props} className={className} gap="20px">
|
|
119
|
+
<Tabs tabs={tabs} controller={controller} value={value} onChange={onChange} className="stepper" />
|
|
120
|
+
<Row justifyContent={(typeof buttons !== 'object' || !buttons.onCancel) && selectedIndex === 0 ? 'end' : 'space-between'}>
|
|
121
|
+
{selectedIndex === 0 && typeof buttons === 'object' && buttons.onCancel && (
|
|
122
|
+
<Button onClick={buttons.onCancel} colorScheme="inverse" appearance="outlined">{buttons.cancel || t.cancel}</Button>
|
|
123
|
+
)}
|
|
124
|
+
{selectedIndex > 0 && buttons && (
|
|
125
|
+
<Button onClick={onPrevious} colorScheme="inverse" appearance="outlined">
|
|
126
|
+
{(typeof buttons === 'object' && buttons.previous) || t.previous}
|
|
127
|
+
</Button>
|
|
128
|
+
)}
|
|
129
|
+
{selectedIndex < tabs.length - 1 && buttons && (
|
|
130
|
+
<Button onClick={onNext}>
|
|
131
|
+
{(typeof buttons === 'object' && buttons.next) || t.next}
|
|
132
|
+
</Button>
|
|
133
|
+
)}
|
|
134
|
+
{selectedIndex === tabs.length - 1 && typeof buttons === 'object' && buttons.onFinish && (
|
|
135
|
+
<Button onClick={buttons.onFinish}>{buttons.finish || t.finish}</Button>
|
|
136
|
+
)}
|
|
137
|
+
</Row>
|
|
138
|
+
</Column>
|
|
139
|
+
) : <Tabs
|
|
140
|
+
tabs={tabs}
|
|
141
|
+
controller={controller}
|
|
142
|
+
value={value}
|
|
143
|
+
onChange={onChange}
|
|
144
|
+
className={listToClass([className, 'stepper'])}
|
|
145
|
+
{...props}
|
|
146
|
+
/>
|
|
147
|
+
},
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
const dictionary = {
|
|
151
|
+
en: {
|
|
152
|
+
cancel: 'Cancel',
|
|
153
|
+
previous: 'Previous',
|
|
154
|
+
next: 'Next',
|
|
155
|
+
finish: 'Finish',
|
|
156
|
+
},
|
|
157
|
+
pt: {
|
|
158
|
+
cancel: 'Cancelar',
|
|
159
|
+
previous: 'Anterior',
|
|
160
|
+
next: 'Próximo',
|
|
161
|
+
finish: 'Finalizar',
|
|
162
|
+
},
|
|
163
|
+
} satisfies Dictionary
|