@stack-spot/citric-react 0.42.0-beta.0 → 0.43.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.
Files changed (209) hide show
  1. package/CHANGELOG.md +13 -13
  2. package/dist/citric.css +2926 -2920
  3. package/dist/components/Accordion.d.ts +1 -1
  4. package/dist/components/Accordion.js +1 -1
  5. package/dist/components/Alert.d.ts +1 -1
  6. package/dist/components/Alert.js +1 -1
  7. package/dist/components/AsyncContent.d.ts +1 -1
  8. package/dist/components/AsyncContent.js +1 -1
  9. package/dist/components/Autocomplete.d.ts +370 -0
  10. package/dist/components/Autocomplete.d.ts.map +1 -0
  11. package/dist/components/{Autocomplete/Autocomplete.js → Autocomplete.js} +163 -98
  12. package/dist/components/Autocomplete.js.map +1 -0
  13. package/dist/components/Avatar.d.ts +1 -1
  14. package/dist/components/Avatar.js +1 -1
  15. package/dist/components/AvatarGroup.d.ts +1 -1
  16. package/dist/components/AvatarGroup.js +1 -1
  17. package/dist/components/Badge.d.ts +1 -1
  18. package/dist/components/Badge.js +1 -1
  19. package/dist/components/Blockquote.d.ts +1 -1
  20. package/dist/components/Blockquote.js +1 -1
  21. package/dist/components/Breadcrumb.d.ts +1 -1
  22. package/dist/components/Breadcrumb.js +1 -1
  23. package/dist/components/Button.d.ts +1 -1
  24. package/dist/components/Button.js +1 -1
  25. package/dist/components/ButtonLink.d.ts +1 -1
  26. package/dist/components/ButtonLink.js +1 -1
  27. package/dist/components/Card.d.ts +1 -1
  28. package/dist/components/Card.js +1 -1
  29. package/dist/components/Checkbox.d.ts +1 -1
  30. package/dist/components/Checkbox.d.ts.map +1 -1
  31. package/dist/components/Checkbox.js +2 -2
  32. package/dist/components/Checkbox.js.map +1 -1
  33. package/dist/components/CheckboxGroup.d.ts +1 -1
  34. package/dist/components/CheckboxGroup.js +1 -1
  35. package/dist/components/Circle.d.ts +1 -1
  36. package/dist/components/Circle.js +1 -1
  37. package/dist/components/Divider.d.ts +1 -1
  38. package/dist/components/Divider.js +1 -1
  39. package/dist/components/ErrorBoundary.d.ts +1 -1
  40. package/dist/components/ErrorBoundary.js +1 -1
  41. package/dist/components/ErrorMessage.d.ts +1 -1
  42. package/dist/components/ErrorMessage.js +1 -1
  43. package/dist/components/FallbackBoundary.d.ts +1 -1
  44. package/dist/components/FallbackBoundary.js +1 -1
  45. package/dist/components/Favorite.d.ts +1 -1
  46. package/dist/components/Favorite.js +1 -1
  47. package/dist/components/FieldGroup.d.ts +1 -1
  48. package/dist/components/FieldGroup.js +1 -1
  49. package/dist/components/Form.d.ts +2 -2
  50. package/dist/components/Form.js +1 -1
  51. package/dist/components/FormGroup.d.ts +1 -1
  52. package/dist/components/FormGroup.js +1 -1
  53. package/dist/components/Icon.d.ts +1 -1
  54. package/dist/components/Icon.js +1 -1
  55. package/dist/components/IconBox.d.ts +3 -3
  56. package/dist/components/IconBox.js +1 -1
  57. package/dist/components/ImageBox.d.ts +3 -3
  58. package/dist/components/ImageBox.js +1 -1
  59. package/dist/components/ImageWithFallback.d.ts +1 -1
  60. package/dist/components/ImageWithFallback.js +1 -1
  61. package/dist/components/Input.d.ts +1 -1
  62. package/dist/components/Input.js +1 -1
  63. package/dist/components/Link.d.ts +1 -1
  64. package/dist/components/Link.js +1 -1
  65. package/dist/components/LoadingPanel.d.ts +1 -1
  66. package/dist/components/LoadingPanel.js +1 -1
  67. package/dist/components/MenuOverlay/Menu.d.ts +1 -1
  68. package/dist/components/MenuOverlay/Menu.js +1 -1
  69. package/dist/components/MenuOverlay/index.d.ts +1 -1
  70. package/dist/components/MenuOverlay/index.js +1 -1
  71. package/dist/components/Overlay/index.d.ts +1 -1
  72. package/dist/components/Overlay/index.js +1 -1
  73. package/dist/components/Pagination.d.ts +1 -1
  74. package/dist/components/Pagination.js +1 -1
  75. package/dist/components/ProgressBar.d.ts +1 -1
  76. package/dist/components/ProgressBar.js +1 -1
  77. package/dist/components/ProgressCircular.d.ts +1 -1
  78. package/dist/components/ProgressCircular.js +1 -1
  79. package/dist/components/RadioGroup.d.ts +1 -1
  80. package/dist/components/RadioGroup.js +1 -1
  81. package/dist/components/Rating.d.ts +1 -1
  82. package/dist/components/Rating.js +1 -1
  83. package/dist/components/Select/MultiSelect.d.ts +1 -1
  84. package/dist/components/Select/MultiSelect.js +1 -1
  85. package/dist/components/Select/RichSelect.d.ts +1 -1
  86. package/dist/components/Select/RichSelect.js +1 -1
  87. package/dist/components/Select/SimpleSelect.d.ts +1 -1
  88. package/dist/components/Select/SimpleSelect.js +1 -1
  89. package/dist/components/Select/index.d.ts +1 -1
  90. package/dist/components/Select/index.js +1 -1
  91. package/dist/components/SelectBox.d.ts +9 -1
  92. package/dist/components/SelectBox.d.ts.map +1 -1
  93. package/dist/components/SelectBox.js +6 -5
  94. package/dist/components/SelectBox.js.map +1 -1
  95. package/dist/components/Skeleton.d.ts +1 -1
  96. package/dist/components/Skeleton.js +1 -1
  97. package/dist/components/Slider.d.ts +1 -1
  98. package/dist/components/Slider.js +1 -1
  99. package/dist/components/SmartTable.d.ts +1 -1
  100. package/dist/components/SmartTable.js +1 -1
  101. package/dist/components/Stepper.d.ts +1 -1
  102. package/dist/components/Stepper.js +1 -1
  103. package/dist/components/Table.d.ts +3 -3
  104. package/dist/components/Table.js +1 -1
  105. package/dist/components/Tabs/index.d.ts +1 -1
  106. package/dist/components/Tabs/index.js +1 -1
  107. package/dist/components/Textarea.d.ts +1 -1
  108. package/dist/components/Textarea.js +1 -1
  109. package/dist/components/Tooltip.d.ts +1 -1
  110. package/dist/components/Tooltip.js +1 -1
  111. package/dist/context/CitricProvider.d.ts +1 -1
  112. package/dist/context/CitricProvider.js +1 -1
  113. package/dist/index.d.ts +2 -1
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.js +2 -1
  116. package/dist/index.js.map +1 -1
  117. package/dist/overlay.js +1 -1
  118. package/dist/theme.css +415 -415
  119. package/dist/utils/css.js +1 -1
  120. package/dist/utils/css.js.map +1 -1
  121. package/package.json +1 -1
  122. package/scripts/build-css.ts +49 -49
  123. package/src/components/Accordion.tsx +130 -130
  124. package/src/components/Alert.tsx +24 -24
  125. package/src/components/AsyncContent.tsx +75 -75
  126. package/src/components/{Autocomplete/Autocomplete.tsx → Autocomplete.tsx} +403 -159
  127. package/src/components/Avatar.tsx +45 -45
  128. package/src/components/AvatarGroup.tsx +49 -49
  129. package/src/components/Badge.tsx +47 -47
  130. package/src/components/Blockquote.tsx +18 -18
  131. package/src/components/Breadcrumb.tsx +33 -33
  132. package/src/components/Button.tsx +105 -105
  133. package/src/components/ButtonLink.tsx +45 -45
  134. package/src/components/Card.tsx +68 -68
  135. package/src/components/Checkbox.tsx +51 -52
  136. package/src/components/CheckboxGroup.tsx +153 -153
  137. package/src/components/Circle.tsx +43 -43
  138. package/src/components/CitricComponent.ts +47 -47
  139. package/src/components/Divider.tsx +24 -24
  140. package/src/components/ErrorBoundary.tsx +75 -75
  141. package/src/components/ErrorMessage.tsx +11 -11
  142. package/src/components/FallbackBoundary.tsx +40 -40
  143. package/src/components/Favorite.tsx +57 -57
  144. package/src/components/FieldGroup.tsx +46 -46
  145. package/src/components/Form.tsx +36 -36
  146. package/src/components/FormGroup.tsx +57 -57
  147. package/src/components/Icon.tsx +35 -35
  148. package/src/components/IconBox.tsx +134 -134
  149. package/src/components/ImageBox.tsx +125 -125
  150. package/src/components/ImageWithFallback.tsx +65 -65
  151. package/src/components/Input.tsx +49 -49
  152. package/src/components/Link.tsx +55 -55
  153. package/src/components/LoadingPanel.tsx +12 -12
  154. package/src/components/MenuOverlay/Menu.tsx +158 -158
  155. package/src/components/MenuOverlay/context.ts +20 -20
  156. package/src/components/MenuOverlay/index.tsx +55 -55
  157. package/src/components/MenuOverlay/keyboard.ts +60 -60
  158. package/src/components/MenuOverlay/types.ts +171 -171
  159. package/src/components/Overlay/context.ts +10 -10
  160. package/src/components/Overlay/index.tsx +182 -182
  161. package/src/components/Overlay/types.ts +75 -75
  162. package/src/components/Pagination.tsx +133 -133
  163. package/src/components/ProgressBar.tsx +45 -45
  164. package/src/components/ProgressCircular.tsx +45 -45
  165. package/src/components/RadioGroup.tsx +147 -147
  166. package/src/components/Rating.tsx +98 -98
  167. package/src/components/Select/MultiSelect.tsx +217 -217
  168. package/src/components/Select/RichSelect.tsx +128 -128
  169. package/src/components/Select/SimpleSelect.tsx +73 -73
  170. package/src/components/Select/hooks.ts +133 -133
  171. package/src/components/Select/index.tsx +35 -35
  172. package/src/components/Select/types.ts +134 -134
  173. package/src/components/SelectBox.tsx +181 -167
  174. package/src/components/Skeleton.tsx +53 -53
  175. package/src/components/Slider.tsx +89 -89
  176. package/src/components/SmartTable.tsx +227 -227
  177. package/src/components/Stepper.tsx +163 -163
  178. package/src/components/Table.tsx +234 -234
  179. package/src/components/Tabs/TabController.ts +54 -54
  180. package/src/components/Tabs/index.tsx +106 -106
  181. package/src/components/Tabs/types.ts +67 -67
  182. package/src/components/Tabs/utils.ts +6 -6
  183. package/src/components/Text.ts +111 -111
  184. package/src/components/Textarea.tsx +27 -27
  185. package/src/components/Tooltip.tsx +83 -83
  186. package/src/components/layout.tsx +101 -101
  187. package/src/context/CitricContext.tsx +4 -4
  188. package/src/context/CitricProvider.tsx +14 -14
  189. package/src/context/hooks.ts +6 -6
  190. package/src/index.ts +59 -59
  191. package/src/overlay.ts +348 -348
  192. package/src/types.ts +235 -235
  193. package/src/utils/ValueController.ts +28 -28
  194. package/src/utils/acessibility.ts +92 -92
  195. package/src/utils/checkbox.ts +121 -121
  196. package/src/utils/css.ts +119 -119
  197. package/src/utils/options.ts +9 -9
  198. package/src/utils/radio.ts +93 -93
  199. package/src/utils/react.ts +6 -6
  200. package/src/utils/time.ts +5 -5
  201. package/tsconfig.json +10 -10
  202. package/dist/components/Autocomplete/Autocomplete.d.ts +0 -211
  203. package/dist/components/Autocomplete/Autocomplete.d.ts.map +0 -1
  204. package/dist/components/Autocomplete/Autocomplete.js.map +0 -1
  205. package/dist/components/Autocomplete/index.d.ts +0 -3
  206. package/dist/components/Autocomplete/index.d.ts.map +0 -1
  207. package/dist/components/Autocomplete/index.js +0 -2
  208. package/dist/components/Autocomplete/index.js.map +0 -1
  209. package/src/components/Autocomplete/index.ts +0 -3
@@ -1,167 +1,181 @@
1
- import { listToClass } from '@stack-spot/portal-theme'
2
- import { useMemo } from 'react'
3
- import { WithColorPalette, WithColorScheme } from '../types'
4
- import { defaultRenderKey, defaultRenderLabel } from '../utils/options'
5
- import { withRef } from '../utils/react'
6
- import { CitricComponent } from './CitricComponent'
7
- import { layout } from './layout'
8
-
9
- export interface SelectBoxLabel {
10
- icon?: React.ReactElement,
11
- title: string,
12
- description?: string,
13
- }
14
-
15
- export interface CommonSelectBoxProps<T> extends WithColorPalette, WithColorScheme {
16
- /**
17
- * If multiple is true, checkboxes will be rendered instead of radio buttons.
18
- *
19
- * @default false
20
- */
21
- multiple?: boolean,
22
- /**
23
- * The name for all checkboxes or radio buttons.
24
- */
25
- name?: string,
26
- /**
27
- * The options to show as select boxes.
28
- */
29
- options: T[],
30
- /**
31
- * A function that returns the data to render a select box for an option.
32
- *
33
- * @default "extracts the title by converting the option to a string"
34
- */
35
- renderLabel?: (option: T) => SelectBoxLabel,
36
- /**
37
- * A function that returns a unique identifier for an option.
38
- *
39
- * @default "if the option is a string, uses it as the key. Otherwise, the key won't be specified."
40
- */
41
- renderKey?: (option: T) => string | number | undefined,
42
- /**
43
- * A function that receives an option and decides if it's disabled or not.
44
- */
45
- isDisabled?: (option: T) => boolean,
46
- /**
47
- * Whether to render a row (horizontal) or a column (vertical).
48
- *
49
- * @default 'horizontal'
50
- */
51
- direction?: 'horizontal' | 'vertical',
52
- /**
53
- * The background color level.
54
- *
55
- * @default 300
56
- */
57
- bgLevel?: 300 | 400 | 500 | 600 | 700,
58
- }
59
-
60
- interface CheckboxProps<T> extends CommonSelectBoxProps<T> {
61
- multiple: true,
62
- value?: T[],
63
- onChange?: (value: T[]) => void,
64
- }
65
-
66
- interface RadioProps<T> extends CommonSelectBoxProps<T> {
67
- multiple?: false,
68
- value?: T,
69
- onChange?: (value: T) => void,
70
- }
71
-
72
- export type BaseSelectBoxProps<T> = RadioProps<T> | CheckboxProps<T>
73
-
74
- export type SelectBoxProps<T> = Omit<React.JSX.IntrinsicElements['div'], 'onChange' | 'children'> & BaseSelectBoxProps<T>
75
-
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
- )
1
+ import { listToClass } from '@stack-spot/portal-theme'
2
+ import { useMemo } from 'react'
3
+ import { WithColorPalette, WithColorScheme } from '../types'
4
+ import { defaultRenderKey, defaultRenderLabel } from '../utils/options'
5
+ import { withRef } from '../utils/react'
6
+ import { CitricComponent } from './CitricComponent'
7
+ import { layout } from './layout'
8
+
9
+ export interface SelectBoxLabel {
10
+ icon?: React.ReactElement,
11
+ title: string,
12
+ description?: string,
13
+ }
14
+
15
+ export interface CommonSelectBoxProps<T> extends WithColorPalette, WithColorScheme {
16
+ /**
17
+ * If multiple is true, checkboxes will be rendered instead of radio buttons.
18
+ *
19
+ * @default false
20
+ */
21
+ multiple?: boolean,
22
+ /**
23
+ * The name for all checkboxes or radio buttons.
24
+ */
25
+ name?: string,
26
+ /**
27
+ * The options to show as select boxes.
28
+ */
29
+ options: T[],
30
+ /**
31
+ * A function that returns the data to render a select box for an option.
32
+ *
33
+ * @default "extracts the title by converting the option to a string"
34
+ */
35
+ renderLabel?: (option: T) => SelectBoxLabel,
36
+ /**
37
+ * A function that returns a unique identifier for an option.
38
+ *
39
+ * @default "if the option is a string, uses it as the key. Otherwise, the key won't be specified."
40
+ */
41
+ renderKey?: (option: T) => string | number | undefined,
42
+ /**
43
+ * A function that receives an option and decides if it's disabled or not.
44
+ */
45
+ isDisabled?: (option: T) => boolean,
46
+ /**
47
+ * Whether to render a row (horizontal) or a column (vertical).
48
+ *
49
+ * @default 'horizontal'
50
+ */
51
+ direction?: 'horizontal' | 'vertical',
52
+ /**
53
+ * The background color level.
54
+ *
55
+ * @default 300
56
+ */
57
+ bgLevel?: 300 | 400 | 500 | 600 | 700,
58
+ /**
59
+ * The appearance of each option.
60
+ *
61
+ * Attention: the appearance "button" hides the description text.
62
+ *
63
+ * @default 'box'
64
+ */
65
+ appearance?: 'box' | 'button',
66
+ }
67
+
68
+ interface CheckboxProps<T> extends CommonSelectBoxProps<T> {
69
+ multiple: true,
70
+ value?: T[],
71
+ onChange?: (value: T[]) => void,
72
+ }
73
+
74
+ interface RadioProps<T> extends CommonSelectBoxProps<T> {
75
+ multiple?: false,
76
+ value?: T,
77
+ onChange?: (value: T) => void,
78
+ }
79
+
80
+ export type BaseSelectBoxProps<T> = RadioProps<T> | CheckboxProps<T>
81
+
82
+ export type SelectBoxProps<T> = Omit<React.JSX.IntrinsicElements['div'], 'onChange' | 'children'> & BaseSelectBoxProps<T>
83
+
84
+ /**
85
+ * This component does exactly the same thing as "CheckboxGroup" and "RadioGroup", but with different visuals and less customization.
86
+ *
87
+ * Each option is rendered as a selectable card. The user can select a single option (radio buttons) or multiple options (checkboxes),
88
+ * depending on the value of the property "multiple", which is false by default.
89
+ *
90
+ * Use `renderLabel` to determine what to render inside each card. This is not a free react element, it must return an object containing an
91
+ * icon, a title and a description.
92
+ *
93
+ * @example
94
+ *
95
+ * ```
96
+ * const options = useMemo(() => [
97
+ * { id: 1, image: 'https://images.com/1.png', name: 'Basic plan', price: 59 },
98
+ * { id: 2, image: 'https://images.com/2.png', name: 'Gold plan', price: 69 },
99
+ * { id: 3, image: 'https://images.com/3.png', name: 'Safira plan', price: 79' },
100
+ * { id: 4, image: 'https://images.com/4.png', name: 'Diamond plan', price: 99 },
101
+ * ], [])
102
+ *
103
+ * return <SelectBox
104
+ * options={options}
105
+ * renderKey={o => o.id}
106
+ * renderLabel={o => ({
107
+ * icon: <img src={o.image} />,
108
+ * title: o.name,
109
+ * description: `$${price.toFixed(2)}`,
110
+ * })}
111
+ * />
112
+ * ```
113
+ */
114
+ export const SelectBox = withRef(
115
+ function SelectBox<T>({
116
+ multiple,
117
+ name,
118
+ value,
119
+ options,
120
+ onChange,
121
+ renderLabel = o => ({ title: defaultRenderLabel(o) }),
122
+ renderKey = defaultRenderKey,
123
+ isDisabled,
124
+ className,
125
+ style,
126
+ direction,
127
+ bgLevel,
128
+ colorPalette,
129
+ colorScheme,
130
+ appearance,
131
+ ...props
132
+ }: SelectBoxProps<T>) {
133
+ const items = useMemo(() => {
134
+ const valueAsArray = value ? (Array.isArray(value) ? value : [value]) : []
135
+ const valueKeys = valueAsArray.map(renderKey)
136
+ return options.map((o) => {
137
+ const key = renderKey(o)
138
+ const label = renderLabel(o)
139
+ const checked = value ? valueKeys.includes(key) : undefined
140
+ return (
141
+ <CitricComponent key={key} tag="label" component="select-box" className={listToClass([bgLevel && `bg-${bgLevel}`, appearance])}>
142
+ <input
143
+ // Fixes a super weird bug that happens only when rendering this component in an external project (not in Storybook). The bug
144
+ // prevents the initially checked option from ever being unchecked. By attaching this key to the checked attribute, we can
145
+ // guarantee this input will always be destroyed and reconstructed whenever the value changes.
146
+ key={`${key}-${checked}`}
147
+ type={multiple ? 'checkbox' : 'radio'}
148
+ name={name}
149
+ value={key}
150
+ checked={checked}
151
+ disabled={isDisabled?.(o)}
152
+ onChange={onChange ? (e) => {
153
+ if (multiple) {
154
+ onChange(e.target.checked ? [...valueAsArray, o] : valueAsArray.filter(v => renderKey(v) !== key))
155
+ } else {
156
+ onChange(o)
157
+ }
158
+ } : undefined}
159
+ />
160
+ <div className="option">
161
+ {label.icon}
162
+ <p className="title">{label.title}</p>
163
+ {label.description && appearance !== 'button' && <p className="description">{label.description}</p>}
164
+ </div>
165
+ </CitricComponent>
166
+ )
167
+ })
168
+ }, [options, value, name, multiple, bgLevel, appearance])
169
+ return (
170
+ <div
171
+ data-color-palette={colorPalette}
172
+ data-color-scheme={colorScheme}
173
+ className={listToClass([className, direction === 'vertical' ? layout.column : layout.row])}
174
+ style={{ gap: '5px', ...style }}
175
+ {...props}
176
+ >
177
+ {items}
178
+ </div>
179
+ )
180
+ },
181
+ )
@@ -1,53 +1,53 @@
1
- import { listToClass } from '@stack-spot/portal-theme'
2
- import { withRef } from '../utils/react'
3
- import { CitricComponent } from './CitricComponent'
4
-
5
- export interface BaseSkeletonProps {
6
- /**
7
- * The skeleton's appearance.
8
- *
9
- * @default 'square'
10
- */
11
- appearance?: 'square' | 'circle',
12
- /**
13
- * The skeleton's width.
14
- *
15
- * @default "the available width if 'square', 50px if 'circle'".
16
- */
17
- width?: string,
18
- /**
19
- * The skeleton's width.
20
- *
21
- * @default "32px if 'square', 50px if 'circle'".
22
- */
23
- height?: string,
24
- /**
25
- * The background color level.
26
- *
27
- * @default 500
28
- */
29
- bgLevel?: 400 | 500 | 600,
30
- }
31
-
32
- export type SkeletonProps = React.JSX.IntrinsicElements['div'] & BaseSkeletonProps
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
- */
45
- export const Skeleton = withRef(({ appearance, className, style, width, height, bgLevel, ...props }: SkeletonProps) =>
46
- <CitricComponent
47
- tag="div"
48
- component="skeleton"
49
- className={listToClass([appearance, bgLevel && `bg-${bgLevel}`, className])}
50
- style={{ width, height, ...style }}
51
- {...props}
52
- />,
53
- )
1
+ import { listToClass } from '@stack-spot/portal-theme'
2
+ import { withRef } from '../utils/react'
3
+ import { CitricComponent } from './CitricComponent'
4
+
5
+ export interface BaseSkeletonProps {
6
+ /**
7
+ * The skeleton's appearance.
8
+ *
9
+ * @default 'square'
10
+ */
11
+ appearance?: 'square' | 'circle',
12
+ /**
13
+ * The skeleton's width.
14
+ *
15
+ * @default "the available width if 'square', 50px if 'circle'".
16
+ */
17
+ width?: string,
18
+ /**
19
+ * The skeleton's width.
20
+ *
21
+ * @default "32px if 'square', 50px if 'circle'".
22
+ */
23
+ height?: string,
24
+ /**
25
+ * The background color level.
26
+ *
27
+ * @default 500
28
+ */
29
+ bgLevel?: 400 | 500 | 600,
30
+ }
31
+
32
+ export type SkeletonProps = React.JSX.IntrinsicElements['div'] & BaseSkeletonProps
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
+ */
45
+ export const Skeleton = withRef(({ appearance, className, style, width, height, bgLevel, ...props }: SkeletonProps) =>
46
+ <CitricComponent
47
+ tag="div"
48
+ component="skeleton"
49
+ className={listToClass([appearance, bgLevel && `bg-${bgLevel}`, className])}
50
+ style={{ width, height, ...style }}
51
+ {...props}
52
+ />,
53
+ )
@@ -1,89 +1,89 @@
1
- import { listToClass } from '@stack-spot/portal-theme'
2
- import { ControlledInput, WithColorPalette, WithColorScheme } from '../types'
3
- import { applyCSSVariable } from '../utils/css'
4
- import { withRef } from '../utils/react'
5
- import { CitricComponent } from './CitricComponent'
6
-
7
- export interface BaseSliderProps extends WithColorScheme, WithColorPalette {
8
- value: number,
9
- /**
10
- * The minimum value in the numeric range.
11
- *
12
- * @default 0
13
- */
14
- min?: number,
15
- /**
16
- * The maximum value in the numeric range.
17
- *
18
- * @default 100
19
- */
20
- max?: number,
21
- onChange: (value: number) => void,
22
- /**
23
- * When should we render the current value of the input?
24
- *
25
- * @default 'always'
26
- */
27
- showValue?: 'always' | 'hover' | 'never',
28
- /**
29
- * A function to customize how the value of the input is rendered.
30
- *
31
- * @default "{value}% if 'min' and 'max' are not provided. {value} otherwise."
32
- */
33
- renderValue?: (value: number) => string,
34
- }
35
-
36
- export type SliderProps = ControlledInput & BaseSliderProps
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
- */
50
- export const Slider = withRef((
51
- { value, onChange, min, max, style, showValue, renderValue, colorPalette, colorScheme, className, ...props }: SliderProps,
52
- ) => {
53
- const percent = Math.floor((value / ((max ?? 100) - (min ?? 0))) * 100)
54
- style = applyCSSVariable(style, 'percent', percent)
55
- const rangeProps = {
56
- value,
57
- min,
58
- max,
59
- onChange: (e: React.ChangeEvent<HTMLInputElement>) => onChange(parseInt(e.target.value)),
60
- ...props,
61
- }
62
-
63
- return showValue === 'never'
64
- ? <CitricComponent
65
- tag="input"
66
- type="range"
67
- component="slider"
68
- style={style}
69
- className={className}
70
- colorPalette={colorPalette}
71
- colorScheme={colorScheme}
72
- {...rangeProps}
73
- />
74
- : (
75
- <CitricComponent
76
- tag="div"
77
- component="labeled-slider"
78
- style={style}
79
- colorPalette={colorPalette}
80
- colorScheme={colorScheme}
81
- className={listToClass([className, showValue === 'hover' && 'value-on-hover'])}
82
- >
83
- <input type="range" {...rangeProps} />
84
- <div className="value">
85
- {renderValue ? renderValue(value) : `${value}${min === undefined && max === undefined ? '%' : ''}`}
86
- </div>
87
- </CitricComponent>
88
- )
89
- })
1
+ import { listToClass } from '@stack-spot/portal-theme'
2
+ import { ControlledInput, WithColorPalette, WithColorScheme } from '../types'
3
+ import { applyCSSVariable } from '../utils/css'
4
+ import { withRef } from '../utils/react'
5
+ import { CitricComponent } from './CitricComponent'
6
+
7
+ export interface BaseSliderProps extends WithColorScheme, WithColorPalette {
8
+ value: number,
9
+ /**
10
+ * The minimum value in the numeric range.
11
+ *
12
+ * @default 0
13
+ */
14
+ min?: number,
15
+ /**
16
+ * The maximum value in the numeric range.
17
+ *
18
+ * @default 100
19
+ */
20
+ max?: number,
21
+ onChange: (value: number) => void,
22
+ /**
23
+ * When should we render the current value of the input?
24
+ *
25
+ * @default 'always'
26
+ */
27
+ showValue?: 'always' | 'hover' | 'never',
28
+ /**
29
+ * A function to customize how the value of the input is rendered.
30
+ *
31
+ * @default "{value}% if 'min' and 'max' are not provided. {value} otherwise."
32
+ */
33
+ renderValue?: (value: number) => string,
34
+ }
35
+
36
+ export type SliderProps = ControlledInput & BaseSliderProps
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
+ */
50
+ export const Slider = withRef((
51
+ { value, onChange, min, max, style, showValue, renderValue, colorPalette, colorScheme, className, ...props }: SliderProps,
52
+ ) => {
53
+ const percent = Math.floor((value / ((max ?? 100) - (min ?? 0))) * 100)
54
+ style = applyCSSVariable(style, 'percent', percent)
55
+ const rangeProps = {
56
+ value,
57
+ min,
58
+ max,
59
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => onChange(parseInt(e.target.value)),
60
+ ...props,
61
+ }
62
+
63
+ return showValue === 'never'
64
+ ? <CitricComponent
65
+ tag="input"
66
+ type="range"
67
+ component="slider"
68
+ style={style}
69
+ className={className}
70
+ colorPalette={colorPalette}
71
+ colorScheme={colorScheme}
72
+ {...rangeProps}
73
+ />
74
+ : (
75
+ <CitricComponent
76
+ tag="div"
77
+ component="labeled-slider"
78
+ style={style}
79
+ colorPalette={colorPalette}
80
+ colorScheme={colorScheme}
81
+ className={listToClass([className, showValue === 'hover' && 'value-on-hover'])}
82
+ >
83
+ <input type="range" {...rangeProps} />
84
+ <div className="value">
85
+ {renderValue ? renderValue(value) : `${value}${min === undefined && max === undefined ? '%' : ''}`}
86
+ </div>
87
+ </CitricComponent>
88
+ )
89
+ })