@stack-spot/citric-react 0.42.0-beta.0 → 0.42.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 (208) hide show
  1. package/CHANGELOG.md +13 -13
  2. package/dist/citric.css +2849 -3081
  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/Avatar.d.ts +1 -1
  10. package/dist/components/Avatar.js +1 -1
  11. package/dist/components/AvatarGroup.d.ts +1 -1
  12. package/dist/components/AvatarGroup.js +1 -1
  13. package/dist/components/Badge.d.ts +1 -1
  14. package/dist/components/Badge.js +1 -1
  15. package/dist/components/Blockquote.d.ts +1 -1
  16. package/dist/components/Blockquote.js +1 -1
  17. package/dist/components/Breadcrumb.d.ts +1 -1
  18. package/dist/components/Breadcrumb.js +1 -1
  19. package/dist/components/Button.d.ts +1 -1
  20. package/dist/components/Button.js +1 -1
  21. package/dist/components/ButtonLink.d.ts +1 -1
  22. package/dist/components/ButtonLink.js +1 -1
  23. package/dist/components/Card.d.ts +1 -1
  24. package/dist/components/Card.js +1 -1
  25. package/dist/components/Checkbox.d.ts +1 -1
  26. package/dist/components/Checkbox.d.ts.map +1 -1
  27. package/dist/components/Checkbox.js +2 -2
  28. package/dist/components/Checkbox.js.map +1 -1
  29. package/dist/components/CheckboxGroup.d.ts +1 -1
  30. package/dist/components/CheckboxGroup.js +1 -1
  31. package/dist/components/Circle.d.ts +1 -1
  32. package/dist/components/Circle.js +1 -1
  33. package/dist/components/CitricComponent.d.ts +1 -1
  34. package/dist/components/CitricComponent.d.ts.map +1 -1
  35. package/dist/components/Divider.d.ts +1 -1
  36. package/dist/components/Divider.js +1 -1
  37. package/dist/components/ErrorBoundary.d.ts +1 -1
  38. package/dist/components/ErrorBoundary.js +1 -1
  39. package/dist/components/ErrorMessage.d.ts +1 -1
  40. package/dist/components/ErrorMessage.js +1 -1
  41. package/dist/components/FallbackBoundary.d.ts +1 -1
  42. package/dist/components/FallbackBoundary.js +1 -1
  43. package/dist/components/Favorite.d.ts +1 -1
  44. package/dist/components/Favorite.js +1 -1
  45. package/dist/components/FieldGroup.d.ts +1 -1
  46. package/dist/components/FieldGroup.js +1 -1
  47. package/dist/components/Form.d.ts +2 -2
  48. package/dist/components/Form.js +1 -1
  49. package/dist/components/FormGroup.d.ts +1 -1
  50. package/dist/components/FormGroup.js +1 -1
  51. package/dist/components/Icon.d.ts +1 -1
  52. package/dist/components/Icon.js +1 -1
  53. package/dist/components/IconBox.d.ts +3 -3
  54. package/dist/components/IconBox.js +1 -1
  55. package/dist/components/ImageBox.d.ts +3 -3
  56. package/dist/components/ImageBox.js +1 -1
  57. package/dist/components/ImageWithFallback.d.ts +1 -1
  58. package/dist/components/ImageWithFallback.js +1 -1
  59. package/dist/components/Input.d.ts +1 -1
  60. package/dist/components/Input.js +1 -1
  61. package/dist/components/Link.d.ts +1 -1
  62. package/dist/components/Link.js +1 -1
  63. package/dist/components/LoadingPanel.d.ts +1 -1
  64. package/dist/components/LoadingPanel.js +1 -1
  65. package/dist/components/MenuOverlay/Menu.d.ts +1 -1
  66. package/dist/components/MenuOverlay/Menu.js +1 -1
  67. package/dist/components/MenuOverlay/index.d.ts +1 -1
  68. package/dist/components/MenuOverlay/index.js +1 -1
  69. package/dist/components/Overlay/index.d.ts +1 -1
  70. package/dist/components/Overlay/index.js +1 -1
  71. package/dist/components/Pagination.d.ts +1 -1
  72. package/dist/components/Pagination.js +1 -1
  73. package/dist/components/ProgressBar.d.ts +1 -1
  74. package/dist/components/ProgressBar.js +1 -1
  75. package/dist/components/ProgressCircular.d.ts +1 -1
  76. package/dist/components/ProgressCircular.js +1 -1
  77. package/dist/components/RadioGroup.d.ts +1 -1
  78. package/dist/components/RadioGroup.js +1 -1
  79. package/dist/components/Rating.d.ts +1 -1
  80. package/dist/components/Rating.js +1 -1
  81. package/dist/components/Select/MultiSelect.d.ts +1 -1
  82. package/dist/components/Select/MultiSelect.js +1 -1
  83. package/dist/components/Select/RichSelect.d.ts +1 -1
  84. package/dist/components/Select/RichSelect.js +1 -1
  85. package/dist/components/Select/SimpleSelect.d.ts +1 -1
  86. package/dist/components/Select/SimpleSelect.js +1 -1
  87. package/dist/components/Select/index.d.ts +1 -1
  88. package/dist/components/Select/index.js +1 -1
  89. package/dist/components/SelectBox.d.ts +9 -1
  90. package/dist/components/SelectBox.d.ts.map +1 -1
  91. package/dist/components/SelectBox.js +6 -5
  92. package/dist/components/SelectBox.js.map +1 -1
  93. package/dist/components/Skeleton.d.ts +1 -1
  94. package/dist/components/Skeleton.js +1 -1
  95. package/dist/components/Slider.d.ts +1 -1
  96. package/dist/components/Slider.js +1 -1
  97. package/dist/components/SmartTable.d.ts +1 -1
  98. package/dist/components/SmartTable.js +1 -1
  99. package/dist/components/Stepper.d.ts +1 -1
  100. package/dist/components/Stepper.js +1 -1
  101. package/dist/components/Table.d.ts +3 -3
  102. package/dist/components/Table.js +1 -1
  103. package/dist/components/Tabs/index.d.ts +1 -1
  104. package/dist/components/Tabs/index.js +1 -1
  105. package/dist/components/Textarea.d.ts +1 -1
  106. package/dist/components/Textarea.js +1 -1
  107. package/dist/components/Tooltip.d.ts +1 -1
  108. package/dist/components/Tooltip.js +1 -1
  109. package/dist/context/CitricProvider.d.ts +1 -1
  110. package/dist/context/CitricProvider.js +1 -1
  111. package/dist/index.d.ts +1 -1
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +1 -1
  114. package/dist/index.js.map +1 -1
  115. package/dist/overlay.js +1 -1
  116. package/dist/theme.css +415 -415
  117. package/dist/utils/css.js +1 -1
  118. package/dist/utils/css.js.map +1 -1
  119. package/package.json +1 -1
  120. package/scripts/build-css.ts +49 -49
  121. package/src/components/Accordion.tsx +130 -130
  122. package/src/components/Alert.tsx +24 -24
  123. package/src/components/AsyncContent.tsx +75 -75
  124. package/src/components/Avatar.tsx +45 -45
  125. package/src/components/AvatarGroup.tsx +49 -49
  126. package/src/components/Badge.tsx +47 -47
  127. package/src/components/Blockquote.tsx +18 -18
  128. package/src/components/Breadcrumb.tsx +33 -33
  129. package/src/components/Button.tsx +105 -105
  130. package/src/components/ButtonLink.tsx +45 -45
  131. package/src/components/Card.tsx +68 -68
  132. package/src/components/Checkbox.tsx +51 -52
  133. package/src/components/CheckboxGroup.tsx +153 -153
  134. package/src/components/Circle.tsx +43 -43
  135. package/src/components/CitricComponent.ts +47 -47
  136. package/src/components/Divider.tsx +24 -24
  137. package/src/components/ErrorBoundary.tsx +75 -75
  138. package/src/components/ErrorMessage.tsx +11 -11
  139. package/src/components/FallbackBoundary.tsx +40 -40
  140. package/src/components/Favorite.tsx +57 -57
  141. package/src/components/FieldGroup.tsx +46 -46
  142. package/src/components/Form.tsx +36 -36
  143. package/src/components/FormGroup.tsx +57 -57
  144. package/src/components/Icon.tsx +35 -35
  145. package/src/components/IconBox.tsx +134 -134
  146. package/src/components/ImageBox.tsx +125 -125
  147. package/src/components/ImageWithFallback.tsx +65 -65
  148. package/src/components/Input.tsx +49 -49
  149. package/src/components/Link.tsx +55 -55
  150. package/src/components/LoadingPanel.tsx +12 -12
  151. package/src/components/MenuOverlay/Menu.tsx +158 -158
  152. package/src/components/MenuOverlay/context.ts +20 -20
  153. package/src/components/MenuOverlay/index.tsx +55 -55
  154. package/src/components/MenuOverlay/keyboard.ts +60 -60
  155. package/src/components/MenuOverlay/types.ts +171 -171
  156. package/src/components/Overlay/context.ts +10 -10
  157. package/src/components/Overlay/index.tsx +182 -182
  158. package/src/components/Overlay/types.ts +75 -75
  159. package/src/components/Pagination.tsx +133 -133
  160. package/src/components/ProgressBar.tsx +45 -45
  161. package/src/components/ProgressCircular.tsx +45 -45
  162. package/src/components/RadioGroup.tsx +147 -147
  163. package/src/components/Rating.tsx +98 -98
  164. package/src/components/Select/MultiSelect.tsx +217 -217
  165. package/src/components/Select/RichSelect.tsx +128 -128
  166. package/src/components/Select/SimpleSelect.tsx +73 -73
  167. package/src/components/Select/hooks.ts +133 -133
  168. package/src/components/Select/index.tsx +35 -35
  169. package/src/components/Select/types.ts +134 -134
  170. package/src/components/SelectBox.tsx +181 -167
  171. package/src/components/Skeleton.tsx +53 -53
  172. package/src/components/Slider.tsx +89 -89
  173. package/src/components/SmartTable.tsx +227 -227
  174. package/src/components/Stepper.tsx +163 -163
  175. package/src/components/Table.tsx +234 -234
  176. package/src/components/Tabs/TabController.ts +54 -54
  177. package/src/components/Tabs/index.tsx +106 -106
  178. package/src/components/Tabs/types.ts +67 -67
  179. package/src/components/Tabs/utils.ts +6 -6
  180. package/src/components/Text.ts +111 -111
  181. package/src/components/Textarea.tsx +27 -27
  182. package/src/components/Tooltip.tsx +83 -83
  183. package/src/components/layout.tsx +101 -101
  184. package/src/context/CitricContext.tsx +4 -4
  185. package/src/context/CitricProvider.tsx +14 -14
  186. package/src/context/hooks.ts +6 -6
  187. package/src/index.ts +58 -59
  188. package/src/overlay.ts +348 -348
  189. package/src/types.ts +235 -235
  190. package/src/utils/ValueController.ts +28 -28
  191. package/src/utils/acessibility.ts +92 -92
  192. package/src/utils/checkbox.ts +121 -121
  193. package/src/utils/css.ts +119 -119
  194. package/src/utils/options.ts +9 -9
  195. package/src/utils/radio.ts +93 -93
  196. package/src/utils/react.ts +6 -6
  197. package/src/utils/time.ts +5 -5
  198. package/tsconfig.json +10 -10
  199. package/dist/components/Autocomplete/Autocomplete.d.ts +0 -211
  200. package/dist/components/Autocomplete/Autocomplete.d.ts.map +0 -1
  201. package/dist/components/Autocomplete/Autocomplete.js +0 -409
  202. package/dist/components/Autocomplete/Autocomplete.js.map +0 -1
  203. package/dist/components/Autocomplete/index.d.ts +0 -3
  204. package/dist/components/Autocomplete/index.d.ts.map +0 -1
  205. package/dist/components/Autocomplete/index.js +0 -2
  206. package/dist/components/Autocomplete/index.js.map +0 -1
  207. package/src/components/Autocomplete/Autocomplete.tsx +0 -794
  208. 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
+ })