@stack-spot/citric-react 0.22.0 → 0.23.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/dist/citric.css +17 -4
- package/dist/components/Accordion.d.ts +34 -0
- package/dist/components/Accordion.d.ts.map +1 -1
- package/dist/components/Accordion.js +34 -0
- package/dist/components/Accordion.js.map +1 -1
- package/dist/components/Alert.d.ts +8 -0
- package/dist/components/Alert.d.ts.map +1 -1
- package/dist/components/Alert.js +8 -0
- package/dist/components/Alert.js.map +1 -1
- package/dist/components/AsyncContent.d.ts +18 -4
- package/dist/components/AsyncContent.d.ts.map +1 -1
- package/dist/components/AsyncContent.js +18 -4
- package/dist/components/AsyncContent.js.map +1 -1
- package/dist/components/Avatar.d.ts +9 -0
- package/dist/components/Avatar.d.ts.map +1 -1
- package/dist/components/Avatar.js +11 -1
- package/dist/components/Avatar.js.map +1 -1
- package/dist/components/AvatarGroup.d.ts +8 -0
- package/dist/components/AvatarGroup.d.ts.map +1 -1
- package/dist/components/AvatarGroup.js +8 -0
- package/dist/components/AvatarGroup.js.map +1 -1
- package/dist/components/Badge.d.ts +13 -2
- package/dist/components/Badge.d.ts.map +1 -1
- package/dist/components/Badge.js +14 -3
- package/dist/components/Badge.js.map +1 -1
- package/dist/components/Blockquote.d.ts +8 -0
- package/dist/components/Blockquote.d.ts.map +1 -1
- package/dist/components/Blockquote.js +8 -0
- package/dist/components/Blockquote.js.map +1 -1
- package/dist/components/Breadcrumb.d.ts +8 -0
- package/dist/components/Breadcrumb.d.ts.map +1 -1
- package/dist/components/Breadcrumb.js +10 -1
- package/dist/components/Breadcrumb.js.map +1 -1
- package/dist/components/Button.d.ts +11 -0
- package/dist/components/Button.d.ts.map +1 -1
- package/dist/components/Button.js +14 -2
- package/dist/components/Button.js.map +1 -1
- package/dist/components/Card.d.ts +15 -4
- package/dist/components/Card.d.ts.map +1 -1
- package/dist/components/Card.js +13 -1
- package/dist/components/Card.js.map +1 -1
- package/dist/components/Checkbox.d.ts +14 -0
- package/dist/components/Checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox.js +14 -0
- package/dist/components/Checkbox.js.map +1 -1
- package/dist/components/CheckboxGroup.d.ts +22 -3
- package/dist/components/CheckboxGroup.d.ts.map +1 -1
- package/dist/components/CheckboxGroup.js +23 -3
- package/dist/components/CheckboxGroup.js.map +1 -1
- package/dist/components/Circle.d.ts +16 -0
- package/dist/components/Circle.d.ts.map +1 -1
- package/dist/components/Circle.js +8 -0
- package/dist/components/Circle.js.map +1 -1
- package/dist/components/CitricComponent.d.ts +14 -0
- package/dist/components/CitricComponent.d.ts.map +1 -1
- package/dist/components/CitricComponent.js +14 -0
- package/dist/components/CitricComponent.js.map +1 -1
- package/dist/components/Divider.d.ts +4 -1
- package/dist/components/Divider.d.ts.map +1 -1
- package/dist/components/Divider.js +4 -1
- package/dist/components/Divider.js.map +1 -1
- package/dist/components/ErrorBoundary.d.ts +13 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/ErrorBoundary.js +13 -0
- package/dist/components/ErrorBoundary.js.map +1 -1
- package/dist/components/ErrorMessage.js +1 -1
- package/dist/components/ErrorMessage.js.map +1 -1
- package/dist/components/FallbackBoundary.d.ts +12 -1
- package/dist/components/FallbackBoundary.d.ts.map +1 -1
- package/dist/components/FallbackBoundary.js +12 -1
- package/dist/components/FallbackBoundary.js.map +1 -1
- package/dist/components/Favorite.d.ts +12 -0
- package/dist/components/Favorite.d.ts.map +1 -1
- package/dist/components/Favorite.js +12 -0
- package/dist/components/Favorite.js.map +1 -1
- package/dist/components/FieldGroup.d.ts +13 -0
- package/dist/components/FieldGroup.d.ts.map +1 -1
- package/dist/components/FieldGroup.js +13 -0
- package/dist/components/FieldGroup.js.map +1 -1
- package/dist/components/Form.d.ts +18 -0
- package/dist/components/Form.d.ts.map +1 -1
- package/dist/components/Form.js +18 -0
- package/dist/components/Form.js.map +1 -1
- package/dist/components/FormGroup.d.ts +12 -0
- package/dist/components/FormGroup.d.ts.map +1 -1
- package/dist/components/FormGroup.js +12 -0
- package/dist/components/FormGroup.js.map +1 -1
- package/dist/components/IconBox.d.ts +33 -8
- package/dist/components/IconBox.d.ts.map +1 -1
- package/dist/components/IconBox.js +37 -11
- package/dist/components/IconBox.js.map +1 -1
- package/dist/components/ImageBox.d.ts +32 -8
- package/dist/components/ImageBox.d.ts.map +1 -1
- package/dist/components/ImageBox.js +36 -11
- package/dist/components/ImageBox.js.map +1 -1
- package/dist/components/ImageWithFallback.d.ts +18 -0
- package/dist/components/ImageWithFallback.d.ts.map +1 -1
- package/dist/components/ImageWithFallback.js +11 -0
- package/dist/components/ImageWithFallback.js.map +1 -1
- package/dist/components/Input.d.ts +15 -3
- package/dist/components/Input.d.ts.map +1 -1
- package/dist/components/Input.js +16 -3
- package/dist/components/Input.js.map +1 -1
- package/dist/components/Link.d.ts +6 -0
- package/dist/components/Link.d.ts.map +1 -1
- package/dist/components/Link.js +6 -0
- package/dist/components/Link.js.map +1 -1
- package/dist/components/MenuOverlay/index.d.ts +20 -0
- package/dist/components/MenuOverlay/index.d.ts.map +1 -1
- package/dist/components/MenuOverlay/index.js +20 -0
- package/dist/components/MenuOverlay/index.js.map +1 -1
- package/dist/components/Overlay/index.d.ts +16 -0
- package/dist/components/Overlay/index.d.ts.map +1 -1
- package/dist/components/Overlay/index.js +16 -0
- package/dist/components/Overlay/index.js.map +1 -1
- package/dist/components/Pagination.d.ts +27 -8
- package/dist/components/Pagination.d.ts.map +1 -1
- package/dist/components/Pagination.js +18 -5
- package/dist/components/Pagination.js.map +1 -1
- package/dist/components/ProgressBar.d.ts +14 -0
- package/dist/components/ProgressBar.d.ts.map +1 -1
- package/dist/components/ProgressBar.js +14 -0
- package/dist/components/ProgressBar.js.map +1 -1
- package/dist/components/ProgressCircular.d.ts +14 -0
- package/dist/components/ProgressCircular.d.ts.map +1 -1
- package/dist/components/ProgressCircular.js +14 -0
- package/dist/components/ProgressCircular.js.map +1 -1
- package/dist/components/RadioGroup.d.ts +24 -3
- package/dist/components/RadioGroup.d.ts.map +1 -1
- package/dist/components/RadioGroup.js +25 -3
- package/dist/components/RadioGroup.js.map +1 -1
- package/dist/components/Rating.d.ts +10 -0
- package/dist/components/Rating.d.ts.map +1 -1
- package/dist/components/Rating.js +10 -0
- package/dist/components/Rating.js.map +1 -1
- package/dist/components/Select/RichSelect.d.ts +3 -5
- package/dist/components/Select/RichSelect.d.ts.map +1 -1
- package/dist/components/Select/RichSelect.js +4 -4
- package/dist/components/Select/RichSelect.js.map +1 -1
- package/dist/components/Select/SimpleSelect.d.ts +2 -3
- package/dist/components/Select/SimpleSelect.d.ts.map +1 -1
- package/dist/components/Select/SimpleSelect.js +2 -3
- package/dist/components/Select/SimpleSelect.js.map +1 -1
- package/dist/components/Select/index.d.ts +25 -2
- package/dist/components/Select/index.d.ts.map +1 -1
- package/dist/components/Select/index.js +26 -3
- package/dist/components/Select/index.js.map +1 -1
- package/dist/components/Select/types.d.ts +1 -2
- package/dist/components/Select/types.d.ts.map +1 -1
- package/dist/components/SelectBox.d.ts +31 -2
- package/dist/components/SelectBox.d.ts.map +1 -1
- package/dist/components/SelectBox.js +32 -3
- package/dist/components/SelectBox.js.map +1 -1
- package/dist/components/Skeleton.d.ts +11 -0
- package/dist/components/Skeleton.d.ts.map +1 -1
- package/dist/components/Skeleton.js +11 -0
- package/dist/components/Skeleton.js.map +1 -1
- package/dist/components/Slider.d.ts +12 -0
- package/dist/components/Slider.d.ts.map +1 -1
- package/dist/components/Slider.js +12 -0
- package/dist/components/Slider.js.map +1 -1
- package/dist/components/SmartTable.d.ts +36 -2
- package/dist/components/SmartTable.d.ts.map +1 -1
- package/dist/components/SmartTable.js +37 -3
- package/dist/components/SmartTable.js.map +1 -1
- package/dist/components/Stepper.d.ts +20 -3
- package/dist/components/Stepper.d.ts.map +1 -1
- package/dist/components/Stepper.js +21 -3
- package/dist/components/Stepper.js.map +1 -1
- package/dist/components/Table.d.ts +10 -0
- package/dist/components/Table.d.ts.map +1 -1
- package/dist/components/Table.js +10 -0
- package/dist/components/Table.js.map +1 -1
- package/dist/components/Tabs/TabController.d.ts +14 -0
- package/dist/components/Tabs/TabController.d.ts.map +1 -1
- package/dist/components/Tabs/TabController.js +14 -0
- package/dist/components/Tabs/TabController.js.map +1 -1
- package/dist/components/Tabs/index.d.ts +20 -3
- package/dist/components/Tabs/index.d.ts.map +1 -1
- package/dist/components/Tabs/index.js +21 -3
- package/dist/components/Tabs/index.js.map +1 -1
- package/dist/components/Text.d.ts +16 -2
- package/dist/components/Text.d.ts.map +1 -1
- package/dist/components/Text.js +17 -3
- package/dist/components/Text.js.map +1 -1
- package/dist/components/Textarea.d.ts +11 -1
- package/dist/components/Textarea.d.ts.map +1 -1
- package/dist/components/Textarea.js +12 -2
- package/dist/components/Textarea.js.map +1 -1
- package/dist/components/Tooltip.d.ts +14 -1
- package/dist/components/Tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip.js +13 -0
- package/dist/components/Tooltip.js.map +1 -1
- package/dist/components/layout.d.ts +41 -7
- package/dist/components/layout.d.ts.map +1 -1
- package/dist/components/layout.js +44 -9
- package/dist/components/layout.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Accordion.tsx +34 -0
- package/src/components/Alert.tsx +8 -0
- package/src/components/AsyncContent.tsx +18 -4
- package/src/components/Avatar.tsx +11 -1
- package/src/components/AvatarGroup.tsx +8 -0
- package/src/components/Badge.tsx +24 -8
- package/src/components/Blockquote.tsx +8 -0
- package/src/components/Breadcrumb.tsx +10 -1
- package/src/components/Button.tsx +17 -2
- package/src/components/Card.tsx +34 -14
- package/src/components/Checkbox.tsx +14 -0
- package/src/components/CheckboxGroup.tsx +61 -40
- package/src/components/Circle.tsx +16 -0
- package/src/components/CitricComponent.ts +14 -0
- package/src/components/Divider.tsx +6 -5
- package/src/components/ErrorBoundary.tsx +13 -0
- package/src/components/ErrorMessage.tsx +1 -1
- package/src/components/FallbackBoundary.tsx +12 -1
- package/src/components/Favorite.tsx +12 -0
- package/src/components/FieldGroup.tsx +13 -0
- package/src/components/Form.tsx +18 -0
- package/src/components/FormGroup.tsx +12 -0
- package/src/components/IconBox.tsx +61 -30
- package/src/components/ImageBox.tsx +60 -30
- package/src/components/ImageWithFallback.tsx +18 -0
- package/src/components/Input.tsx +28 -14
- package/src/components/Link.tsx +6 -0
- package/src/components/MenuOverlay/index.tsx +20 -0
- package/src/components/Overlay/index.tsx +17 -0
- package/src/components/Pagination.tsx +40 -17
- package/src/components/ProgressBar.tsx +14 -0
- package/src/components/ProgressCircular.tsx +14 -0
- package/src/components/RadioGroup.tsx +62 -39
- package/src/components/Rating.tsx +10 -0
- package/src/components/Select/RichSelect.tsx +183 -182
- package/src/components/Select/SimpleSelect.tsx +57 -57
- package/src/components/Select/index.tsx +29 -5
- package/src/components/Select/types.ts +1 -1
- package/src/components/SelectBox.tsx +92 -62
- package/src/components/Skeleton.tsx +11 -0
- package/src/components/Slider.tsx +12 -0
- package/src/components/SmartTable.tsx +91 -56
- package/src/components/Stepper.tsx +76 -57
- package/src/components/Table.tsx +10 -0
- package/src/components/Tabs/TabController.ts +14 -0
- package/src/components/Tabs/index.tsx +56 -37
- package/src/components/Text.ts +36 -21
- package/src/components/Textarea.tsx +14 -4
- package/src/components/Tooltip.tsx +14 -1
- package/src/components/layout.tsx +56 -13
- package/src/index.ts +0 -1
- package/dist/components/Switch.d.ts +0 -10
- package/dist/components/Switch.d.ts.map +0 -1
- package/dist/components/Switch.js +0 -8
- package/dist/components/Switch.js.map +0 -1
- package/src/components/Switch.tsx +0 -30
|
@@ -73,65 +73,95 @@ export type BaseSelectBoxProps<T> = RadioProps<T> | CheckboxProps<T>
|
|
|
73
73
|
|
|
74
74
|
export type SelectBoxProps<T> = Omit<React.JSX.IntrinsicElements['div'], 'onChange' | 'children'> & BaseSelectBoxProps<T>
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
76
|
+
/**
|
|
77
|
+
* This component does exactly the same thing as "CheckboxGroup" and "RadioGroup", but with different visuals and less customization.
|
|
78
|
+
*
|
|
79
|
+
* Each option is rendered as a selectable card. The user can select a single option (radio buttons) or multiple options (checkboxes),
|
|
80
|
+
* depending on the value of the property "multiple", which is false by default.
|
|
81
|
+
*
|
|
82
|
+
* Use `renderLabel` to determine what to render inside each card. This is not a free react element, it must return an object containing an
|
|
83
|
+
* icon, a title and a description.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
*
|
|
87
|
+
* ```
|
|
88
|
+
* const options = useMemo(() => [
|
|
89
|
+
* { id: 1, image: 'https://images.com/1.png', name: 'Basic plan', price: 59 },
|
|
90
|
+
* { id: 2, image: 'https://images.com/2.png', name: 'Gold plan', price: 69 },
|
|
91
|
+
* { id: 3, image: 'https://images.com/3.png', name: 'Safira plan', price: 79' },
|
|
92
|
+
* { id: 4, image: 'https://images.com/4.png', name: 'Diamond plan', price: 99 },
|
|
93
|
+
* ], [])
|
|
94
|
+
*
|
|
95
|
+
* return <SelectBox
|
|
96
|
+
* options={options}
|
|
97
|
+
* renderKey={o => o.id}
|
|
98
|
+
* renderLabel={o => ({
|
|
99
|
+
* icon: <img src={o.image} />,
|
|
100
|
+
* title: o.name,
|
|
101
|
+
* description: `$${price.toFixed(2)}`,
|
|
102
|
+
* })}
|
|
103
|
+
* />
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export const SelectBox = withRef(
|
|
107
|
+
function SelectBox<T>({
|
|
108
|
+
multiple,
|
|
109
|
+
name,
|
|
110
|
+
value,
|
|
111
|
+
options,
|
|
112
|
+
onChange,
|
|
113
|
+
renderLabel = o => ({ title: defaultRenderLabel(o) }),
|
|
114
|
+
renderKey = defaultRenderKey,
|
|
115
|
+
isDisabled,
|
|
116
|
+
className,
|
|
117
|
+
style,
|
|
118
|
+
direction,
|
|
119
|
+
bgLevel,
|
|
120
|
+
colorPalette,
|
|
121
|
+
colorScheme,
|
|
122
|
+
...props
|
|
123
|
+
}: SelectBoxProps<T>) {
|
|
124
|
+
const items = useMemo(() => {
|
|
125
|
+
const valueAsArray = value ? (Array.isArray(value) ? value : [value]) : []
|
|
126
|
+
const valueKeys = valueAsArray.map(renderKey)
|
|
127
|
+
return options.map((o) => {
|
|
128
|
+
const key = renderKey(o)
|
|
129
|
+
const label = renderLabel(o)
|
|
130
|
+
return (
|
|
131
|
+
<CitricComponent key={key} tag="label" component="select-box" className={bgLevel ? `bg-${bgLevel}` : undefined}>
|
|
132
|
+
<input
|
|
133
|
+
type={multiple ? 'checkbox' : 'radio'}
|
|
134
|
+
name={name}
|
|
135
|
+
value={key}
|
|
136
|
+
checked={value ? valueKeys.includes(key) : undefined}
|
|
137
|
+
disabled={isDisabled?.(o)}
|
|
138
|
+
onChange={onChange ? (e) => {
|
|
139
|
+
if (multiple) {
|
|
140
|
+
onChange(e.target.checked ? [...valueAsArray, o] : valueAsArray.filter(v => renderKey(v) !== key))
|
|
141
|
+
} else {
|
|
142
|
+
onChange(o)
|
|
143
|
+
}
|
|
144
|
+
} : undefined}
|
|
145
|
+
/>
|
|
146
|
+
<div className="option">
|
|
147
|
+
{label.icon}
|
|
148
|
+
<p className="title">{label.title}</p>
|
|
149
|
+
{label.description && <p className="description">{label.description}</p>}
|
|
150
|
+
</div>
|
|
151
|
+
</CitricComponent>
|
|
152
|
+
)
|
|
153
|
+
})
|
|
154
|
+
}, [options, value, name, multiple, bgLevel])
|
|
155
|
+
return (
|
|
156
|
+
<div
|
|
157
|
+
data-color-palette={colorPalette}
|
|
158
|
+
data-color-scheme={colorScheme}
|
|
159
|
+
className={listToClass([className, direction === 'vertical' ? layout.column : layout.row])}
|
|
160
|
+
style={{ gap: '5px', ...style }}
|
|
161
|
+
{...props}
|
|
162
|
+
>
|
|
163
|
+
{items}
|
|
164
|
+
</div>
|
|
165
|
+
)
|
|
166
|
+
},
|
|
167
|
+
)
|
|
@@ -31,6 +31,17 @@ export interface BaseSkeletonProps {
|
|
|
31
31
|
|
|
32
32
|
export type SkeletonProps = React.JSX.IntrinsicElements['div'] & BaseSkeletonProps
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* A loading feedback with a discrete animation. Use this to replace elements on the page that are still loading and will be replaced by
|
|
36
|
+
* the same shape when the loading ends.
|
|
37
|
+
*
|
|
38
|
+
* Use the property "bgLevel" to manage how light/dark the background is.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```
|
|
42
|
+
* <Skeleton width="100%" height="20px" />
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
34
45
|
export const Skeleton = withRef(({ appearance, className, style, width, height, bgLevel, ...props }: SkeletonProps) =>
|
|
35
46
|
<CitricComponent
|
|
36
47
|
tag="div"
|
|
@@ -35,6 +35,18 @@ export interface BaseSliderProps extends WithColorScheme, WithColorPalette {
|
|
|
35
35
|
|
|
36
36
|
export type SliderProps = ControlledInput & BaseSliderProps
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* A UI element where the user can slide a knob over a bar to select a number. By default, a number between 0 and 100 can be selected, use
|
|
40
|
+
* the properties "min" and "max" to change this.
|
|
41
|
+
*
|
|
42
|
+
* Attention: "onChange" receives the new value (number) instead of the event.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```
|
|
46
|
+
* const [value, setValue] = useState(0)
|
|
47
|
+
* return <Slider value={value} setValue={setValue} />
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
38
50
|
export const Slider = withRef((
|
|
39
51
|
{ value, onChange, min, max, style, showValue, renderValue, colorPalette, colorScheme, className, ...props }: SliderProps,
|
|
40
52
|
) => {
|
|
@@ -89,63 +89,98 @@ export type BaseSmartTableProps<T extends Record<string, any>> = BaseTableProps
|
|
|
89
89
|
|
|
90
90
|
export type SmartTableProps<T extends Record<string, any>> = Omit<TableProps, 'children'> & ExtraSmartTableProps<T>
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Renders a table. Always prefer using this component over the raw Table component.
|
|
94
|
+
*
|
|
95
|
+
* This receives a dataset and renders each item as a row. The columns are determined by the property "columns".
|
|
96
|
+
*
|
|
97
|
+
* To change the overall table style, use the property "appearance".
|
|
98
|
+
*
|
|
99
|
+
* To check more complex table examples, like tables with accordions and sorting, check the storybook.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
*
|
|
103
|
+
* ```
|
|
104
|
+
* const data = useMemo(() => [
|
|
105
|
+
* { id: 1, name: 'Yuri Tyson', phone: '1-801-475-4561', country: 'Poland', age: 21 },
|
|
106
|
+
* { id: 2, name: 'Amal Mcclure', phone: '(695) 948-4102', country: 'Ukraine', age: 32 },
|
|
107
|
+
* { id: 3, name: 'Levi Glass', phone: '1-976-544-4872', country: 'Colombia', age: 45 },
|
|
108
|
+
* ], [])
|
|
109
|
+
* const columns = useMemo(() => [
|
|
110
|
+
* { key: 'name', label: 'Name', render: item => `${item.name} (${item.age})` },
|
|
111
|
+
* { key: 'phone', label: 'Phone' },
|
|
112
|
+
* { key: 'country', label: 'Country' },
|
|
113
|
+
* {
|
|
114
|
+
* key: 'settings',
|
|
115
|
+
* render: item => (
|
|
116
|
+
* <Row gap={2}>
|
|
117
|
+
* <IconButton icon="ExternalLink" title="View" />
|
|
118
|
+
* <IconButton icon="Pencil" title="Edit" />
|
|
119
|
+
* <IconButton icon="Trash" title="Delete" colorScheme="danger" />
|
|
120
|
+
* </Row>
|
|
121
|
+
* ),
|
|
122
|
+
* },
|
|
123
|
+
* ], [])
|
|
124
|
+
* return <SmartTable data={data} columns={columns} />
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export const SmartTable = withRef(
|
|
128
|
+
function SmartTable<T extends Record<string, any>>(
|
|
129
|
+
{ data, keygen, columns, renderAccordion, accordionTrigger, accordionMaxHeight, id, ...props }: SmartTableProps<T>,
|
|
130
|
+
) {
|
|
131
|
+
id = useMemo(() => id || `${Math.random()}`, [id])
|
|
96
132
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
133
|
+
const headers = useMemo(
|
|
134
|
+
() => columns.map((c) => (
|
|
135
|
+
<Th {...c.th} key={c.key} onSort={c.onSort} direction={c.direction} tabIndex={c.onSort ? 0 : undefined}>
|
|
136
|
+
{c.label ?? c.key}
|
|
137
|
+
</Th>
|
|
138
|
+
)),
|
|
139
|
+
[columns],
|
|
140
|
+
)
|
|
105
141
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
</Tr>
|
|
125
|
-
)
|
|
126
|
-
return renderAccordion ? (
|
|
127
|
-
<tbody key={`${key}-group`}>
|
|
128
|
-
{row}
|
|
129
|
-
<Tr id={`${id}-${key}`} accordion accordionMaxHeight={accordionMaxHeight}>
|
|
130
|
-
<td colSpan={columns.length + 1}><div>{accordionContent}</div></td>
|
|
142
|
+
const rows = useMemo(
|
|
143
|
+
() => data.map((item, index) => {
|
|
144
|
+
const key = keygen ? keygen(item) : index
|
|
145
|
+
const accordionContent = renderAccordion?.(item)
|
|
146
|
+
const row = (
|
|
147
|
+
<Tr key={key} accordionTrigger={accordionContent ? accordionTrigger : undefined}>
|
|
148
|
+
{columns.map(c => <td {...c.td} key={c.key}>{c.render ? c.render(item) : (item[c.key] || '')}</td>)}
|
|
149
|
+
{renderAccordion && (
|
|
150
|
+
<td>
|
|
151
|
+
{accordionContent && (
|
|
152
|
+
<input
|
|
153
|
+
type="checkbox"
|
|
154
|
+
aria-controls={`${id}-${key}`}
|
|
155
|
+
onKeyDown={e => e.key === 'Enter' && e.target instanceof HTMLElement && e.target.click()}
|
|
156
|
+
/>
|
|
157
|
+
)}
|
|
158
|
+
</td>
|
|
159
|
+
)}
|
|
131
160
|
</Tr>
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
161
|
+
)
|
|
162
|
+
return renderAccordion ? (
|
|
163
|
+
<tbody key={`${key}-group`}>
|
|
164
|
+
{row}
|
|
165
|
+
<Tr id={`${id}-${key}`} accordion accordionMaxHeight={accordionMaxHeight}>
|
|
166
|
+
<td colSpan={columns.length + 1}><div>{accordionContent}</div></td>
|
|
167
|
+
</Tr>
|
|
168
|
+
</tbody>
|
|
169
|
+
) : row
|
|
170
|
+
}),
|
|
171
|
+
[columns, data, !!renderAccordion, accordionTrigger],
|
|
172
|
+
)
|
|
137
173
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export const SmartTable = withRef(_SmartTable)
|
|
174
|
+
return (
|
|
175
|
+
<Table id={id} accordionRows={!!renderAccordion} {...props}>
|
|
176
|
+
<thead>
|
|
177
|
+
<tr>
|
|
178
|
+
{headers}
|
|
179
|
+
{renderAccordion && <th></th>}
|
|
180
|
+
</tr>
|
|
181
|
+
</thead>
|
|
182
|
+
{renderAccordion ? rows : <tbody>{rows}</tbody>}
|
|
183
|
+
</Table>
|
|
184
|
+
)
|
|
185
|
+
},
|
|
186
|
+
)
|
|
@@ -65,66 +65,87 @@ function getTabsWithDisabled<Key extends string>(tabs: Tab<Key>[], value: Key |
|
|
|
65
65
|
return tabs.map((t, i) => ({ ...t, disabled: i > index }))
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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)
|
|
78
98
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
99
|
+
useEffect(() => controller.onChange((v) => {
|
|
100
|
+
setSelectedIndex(findSelectedIndex(tabs, v))
|
|
101
|
+
}), [tabs])
|
|
82
102
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
103
|
+
useEffect(() => controller.onChange((value) => {
|
|
104
|
+
setTabs(getTabsWithDisabled(initialTabs, value))
|
|
105
|
+
}), [])
|
|
86
106
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
107
|
+
const onPrevious = useCallback(() => {
|
|
108
|
+
controller.previous()
|
|
109
|
+
if (typeof buttons === 'object') buttons.onPrevious?.(controller.getValue())
|
|
110
|
+
}, [])
|
|
91
111
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
112
|
+
const onNext = useCallback(() => {
|
|
113
|
+
controller.next()
|
|
114
|
+
if (typeof buttons === 'object') buttons.onNext?.(controller.getValue())
|
|
115
|
+
}, [])
|
|
96
116
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
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
|
+
)
|
|
128
149
|
|
|
129
150
|
const dictionary = {
|
|
130
151
|
en: {
|
|
@@ -140,5 +161,3 @@ const dictionary = {
|
|
|
140
161
|
finish: 'Finalizar',
|
|
141
162
|
},
|
|
142
163
|
} satisfies Dictionary
|
|
143
|
-
|
|
144
|
-
export const Stepper = withRef(_Stepper)
|
package/src/components/Table.tsx
CHANGED
|
@@ -110,6 +110,16 @@ export type TableProps = React.JSX.IntrinsicElements['table'] & BaseTableProps
|
|
|
110
110
|
export type ThProps = React.JSX.IntrinsicElements['th'] & BaseThProps
|
|
111
111
|
export type TrProps = React.JSX.IntrinsicElements['tr'] & BaseTrProps
|
|
112
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Renders an HTML table. Use its props for customizing the appearance.
|
|
115
|
+
*
|
|
116
|
+
* - If you need to use Accordion rows, use `<Tr>`instead of `<tr>`.
|
|
117
|
+
* - If you need to sort columns, use `<Th>`instead of `<th>`.
|
|
118
|
+
*
|
|
119
|
+
* This works exactly like the HTML tag "table".
|
|
120
|
+
*
|
|
121
|
+
* Attention: prefer using the component "SmartTable". Use this only if you need full control over the table.
|
|
122
|
+
*/
|
|
113
123
|
export const Table = withRef(({
|
|
114
124
|
appearance, stripped, compressed, showBorders, showHeaderBorders, showRowBorders, rounded, roundedRows, uppercaseHeader, className,
|
|
115
125
|
children, accordionRows, ...props
|
|
@@ -12,16 +12,26 @@ export class TabController<Key extends string> extends ValueController<Key> {
|
|
|
12
12
|
return this.tabOrder.findIndex(t => t === this.value)
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* @returns true if there's another tab after the one currently selected. False otherwise.
|
|
17
|
+
*/
|
|
15
18
|
hasNext(): boolean {
|
|
16
19
|
const current = this.getCurrentIndex()
|
|
17
20
|
return current > -1 && current + 1 < this.tabOrder.length
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
/**
|
|
24
|
+
* @returns true if there's a tab before the one currently selected. False otherwise.
|
|
25
|
+
*/
|
|
20
26
|
hasPrevious(): boolean {
|
|
21
27
|
const current = this.getCurrentIndex()
|
|
22
28
|
return current > -1 && current - 1 >= 0
|
|
23
29
|
}
|
|
24
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Selects the tab on the right of the one currently selected. If there's no next tab, nothing happens.
|
|
33
|
+
* @returns true if the tab is changed, false otherwise.
|
|
34
|
+
*/
|
|
25
35
|
next(): boolean {
|
|
26
36
|
if (this.hasNext()) {
|
|
27
37
|
this.setValue(this.tabOrder[this.getCurrentIndex() + 1])
|
|
@@ -30,6 +40,10 @@ export class TabController<Key extends string> extends ValueController<Key> {
|
|
|
30
40
|
return false
|
|
31
41
|
}
|
|
32
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Selects the tab on the left of the one currently selected. If there's no previous tab, nothing happens.
|
|
45
|
+
* @returns true if the tab is changed, false otherwise.
|
|
46
|
+
*/
|
|
33
47
|
previous(): boolean {
|
|
34
48
|
if (this.hasPrevious()) {
|
|
35
49
|
this.setValue(this.tabOrder[this.getCurrentIndex() - 1])
|