@stack-spot/citric-react 0.35.1 → 0.37.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 (186) hide show
  1. package/dist/citric.css +2844 -2832
  2. package/dist/components/Accordion.d.ts +1 -1
  3. package/dist/components/Accordion.js +1 -1
  4. package/dist/components/Alert.d.ts +1 -1
  5. package/dist/components/Alert.js +1 -1
  6. package/dist/components/AsyncContent.d.ts +1 -1
  7. package/dist/components/AsyncContent.js +1 -1
  8. package/dist/components/Avatar.d.ts +1 -1
  9. package/dist/components/Avatar.js +1 -1
  10. package/dist/components/AvatarGroup.d.ts +1 -1
  11. package/dist/components/AvatarGroup.js +1 -1
  12. package/dist/components/Badge.d.ts +1 -1
  13. package/dist/components/Badge.js +1 -1
  14. package/dist/components/Blockquote.d.ts +1 -1
  15. package/dist/components/Blockquote.js +1 -1
  16. package/dist/components/Breadcrumb.d.ts +1 -1
  17. package/dist/components/Breadcrumb.js +1 -1
  18. package/dist/components/Button.d.ts +1 -1
  19. package/dist/components/Button.js +1 -1
  20. package/dist/components/ButtonLink.d.ts +1 -1
  21. package/dist/components/ButtonLink.js +1 -1
  22. package/dist/components/Card.d.ts +1 -1
  23. package/dist/components/Card.js +1 -1
  24. package/dist/components/Checkbox.d.ts +1 -1
  25. package/dist/components/Checkbox.js +1 -1
  26. package/dist/components/CheckboxGroup.d.ts +1 -1
  27. package/dist/components/CheckboxGroup.js +1 -1
  28. package/dist/components/Circle.d.ts +1 -1
  29. package/dist/components/Circle.js +1 -1
  30. package/dist/components/Divider.d.ts +1 -1
  31. package/dist/components/Divider.js +1 -1
  32. package/dist/components/ErrorBoundary.d.ts +1 -1
  33. package/dist/components/ErrorBoundary.js +1 -1
  34. package/dist/components/ErrorMessage.d.ts +1 -1
  35. package/dist/components/ErrorMessage.js +1 -1
  36. package/dist/components/FallbackBoundary.d.ts +1 -1
  37. package/dist/components/FallbackBoundary.js +1 -1
  38. package/dist/components/Favorite.d.ts +1 -1
  39. package/dist/components/Favorite.js +1 -1
  40. package/dist/components/FieldGroup.d.ts +1 -1
  41. package/dist/components/FieldGroup.js +1 -1
  42. package/dist/components/Form.d.ts +2 -2
  43. package/dist/components/Form.js +1 -1
  44. package/dist/components/FormGroup.d.ts +1 -1
  45. package/dist/components/FormGroup.js +1 -1
  46. package/dist/components/Icon.d.ts +1 -1
  47. package/dist/components/Icon.js +1 -1
  48. package/dist/components/IconBox.d.ts +3 -3
  49. package/dist/components/IconBox.js +1 -1
  50. package/dist/components/ImageBox.d.ts +3 -3
  51. package/dist/components/ImageBox.js +1 -1
  52. package/dist/components/ImageWithFallback.d.ts +1 -1
  53. package/dist/components/ImageWithFallback.js +1 -1
  54. package/dist/components/Input.d.ts +1 -1
  55. package/dist/components/Input.js +1 -1
  56. package/dist/components/Link.d.ts +1 -1
  57. package/dist/components/Link.js +1 -1
  58. package/dist/components/LoadingPanel.d.ts +1 -1
  59. package/dist/components/LoadingPanel.js +1 -1
  60. package/dist/components/MenuOverlay/Menu.d.ts +1 -1
  61. package/dist/components/MenuOverlay/Menu.js +1 -1
  62. package/dist/components/MenuOverlay/index.d.ts +1 -1
  63. package/dist/components/MenuOverlay/index.js +1 -1
  64. package/dist/components/Overlay/index.d.ts +1 -1
  65. package/dist/components/Overlay/index.js +1 -1
  66. package/dist/components/Pagination.d.ts +1 -1
  67. package/dist/components/Pagination.js +1 -1
  68. package/dist/components/ProgressBar.d.ts +1 -1
  69. package/dist/components/ProgressBar.js +1 -1
  70. package/dist/components/ProgressCircular.d.ts +1 -1
  71. package/dist/components/ProgressCircular.js +1 -1
  72. package/dist/components/RadioGroup.d.ts +1 -1
  73. package/dist/components/RadioGroup.js +1 -1
  74. package/dist/components/Rating.d.ts +17 -3
  75. package/dist/components/Rating.d.ts.map +1 -1
  76. package/dist/components/Rating.js +11 -3
  77. package/dist/components/Rating.js.map +1 -1
  78. package/dist/components/Select/MultiSelect.d.ts +1 -1
  79. package/dist/components/Select/MultiSelect.js +1 -1
  80. package/dist/components/Select/RichSelect.d.ts +1 -1
  81. package/dist/components/Select/RichSelect.js +1 -1
  82. package/dist/components/Select/SimpleSelect.d.ts +1 -1
  83. package/dist/components/Select/SimpleSelect.js +1 -1
  84. package/dist/components/Select/index.d.ts +1 -1
  85. package/dist/components/Select/index.js +1 -1
  86. package/dist/components/SelectBox.d.ts +1 -1
  87. package/dist/components/SelectBox.js +1 -1
  88. package/dist/components/Skeleton.d.ts +1 -1
  89. package/dist/components/Skeleton.js +1 -1
  90. package/dist/components/Slider.d.ts +1 -1
  91. package/dist/components/Slider.js +1 -1
  92. package/dist/components/SmartTable.d.ts +1 -1
  93. package/dist/components/SmartTable.js +1 -1
  94. package/dist/components/Stepper.d.ts +1 -1
  95. package/dist/components/Stepper.js +1 -1
  96. package/dist/components/Table.d.ts +3 -3
  97. package/dist/components/Table.js +1 -1
  98. package/dist/components/Tabs/index.d.ts +1 -1
  99. package/dist/components/Tabs/index.js +1 -1
  100. package/dist/components/Textarea.d.ts +1 -1
  101. package/dist/components/Textarea.js +1 -1
  102. package/dist/components/Tooltip.d.ts +1 -1
  103. package/dist/components/Tooltip.js +1 -1
  104. package/dist/context/CitricProvider.d.ts +1 -1
  105. package/dist/context/CitricProvider.js +1 -1
  106. package/dist/overlay.js +1 -1
  107. package/dist/theme.css +415 -415
  108. package/package.json +7 -6
  109. package/scripts/build-css.ts +49 -49
  110. package/src/components/Accordion.tsx +130 -130
  111. package/src/components/Alert.tsx +24 -24
  112. package/src/components/AsyncContent.tsx +70 -70
  113. package/src/components/Avatar.tsx +45 -45
  114. package/src/components/AvatarGroup.tsx +49 -49
  115. package/src/components/Badge.tsx +47 -47
  116. package/src/components/Blockquote.tsx +18 -18
  117. package/src/components/Breadcrumb.tsx +33 -33
  118. package/src/components/Button.tsx +105 -105
  119. package/src/components/ButtonLink.tsx +45 -45
  120. package/src/components/Card.tsx +68 -68
  121. package/src/components/Checkbox.tsx +51 -51
  122. package/src/components/CheckboxGroup.tsx +152 -152
  123. package/src/components/Circle.tsx +43 -43
  124. package/src/components/CitricComponent.ts +47 -47
  125. package/src/components/Divider.tsx +24 -24
  126. package/src/components/ErrorBoundary.tsx +75 -75
  127. package/src/components/ErrorMessage.tsx +11 -11
  128. package/src/components/FallbackBoundary.tsx +40 -40
  129. package/src/components/Favorite.tsx +57 -57
  130. package/src/components/FieldGroup.tsx +46 -46
  131. package/src/components/Form.tsx +36 -36
  132. package/src/components/FormGroup.tsx +57 -57
  133. package/src/components/Icon.tsx +35 -35
  134. package/src/components/IconBox.tsx +134 -134
  135. package/src/components/ImageBox.tsx +125 -125
  136. package/src/components/ImageWithFallback.tsx +65 -65
  137. package/src/components/Input.tsx +49 -49
  138. package/src/components/Link.tsx +55 -55
  139. package/src/components/LoadingPanel.tsx +8 -8
  140. package/src/components/MenuOverlay/Menu.tsx +158 -158
  141. package/src/components/MenuOverlay/context.ts +20 -20
  142. package/src/components/MenuOverlay/index.tsx +55 -55
  143. package/src/components/MenuOverlay/keyboard.ts +60 -60
  144. package/src/components/MenuOverlay/types.ts +171 -171
  145. package/src/components/Overlay/context.ts +10 -10
  146. package/src/components/Overlay/index.tsx +164 -164
  147. package/src/components/Overlay/types.ts +70 -70
  148. package/src/components/Pagination.tsx +113 -113
  149. package/src/components/ProgressBar.tsx +45 -45
  150. package/src/components/ProgressCircular.tsx +45 -45
  151. package/src/components/RadioGroup.tsx +146 -146
  152. package/src/components/Rating.tsx +98 -35
  153. package/src/components/Select/MultiSelect.tsx +217 -217
  154. package/src/components/Select/RichSelect.tsx +128 -128
  155. package/src/components/Select/SimpleSelect.tsx +73 -73
  156. package/src/components/Select/hooks.ts +133 -133
  157. package/src/components/Select/index.tsx +35 -35
  158. package/src/components/Select/types.ts +134 -134
  159. package/src/components/SelectBox.tsx +167 -167
  160. package/src/components/Skeleton.tsx +53 -53
  161. package/src/components/Slider.tsx +89 -89
  162. package/src/components/SmartTable.tsx +227 -227
  163. package/src/components/Stepper.tsx +163 -163
  164. package/src/components/Table.tsx +234 -234
  165. package/src/components/Tabs/TabController.ts +54 -54
  166. package/src/components/Tabs/index.tsx +87 -87
  167. package/src/components/Tabs/types.ts +54 -54
  168. package/src/components/Tabs/utils.ts +6 -6
  169. package/src/components/Text.ts +111 -111
  170. package/src/components/Textarea.tsx +27 -27
  171. package/src/components/Tooltip.tsx +72 -72
  172. package/src/components/layout.tsx +101 -101
  173. package/src/context/CitricContext.tsx +4 -4
  174. package/src/context/CitricProvider.tsx +14 -14
  175. package/src/context/hooks.ts +6 -6
  176. package/src/index.ts +58 -58
  177. package/src/overlay.ts +341 -341
  178. package/src/types.ts +216 -216
  179. package/src/utils/ValueController.ts +28 -28
  180. package/src/utils/acessibility.ts +92 -92
  181. package/src/utils/checkbox.ts +121 -121
  182. package/src/utils/css.ts +119 -119
  183. package/src/utils/options.ts +9 -9
  184. package/src/utils/radio.ts +93 -93
  185. package/src/utils/react.ts +6 -6
  186. package/tsconfig.json +10 -10
@@ -1,46 +1,46 @@
1
- import { listToClass } from '@stack-spot/portal-theme'
2
- import { withRef } from '../utils/react'
3
- import { CitricComponent } from './CitricComponent'
4
-
5
- export interface BaseFieldGroupProps {
6
- /**
7
- * When this is true, the component will automatically mark the addons.
8
- *
9
- * When this is false, you must add the class "addon" manually to each of the addons.
10
- *
11
- * @default true
12
- */
13
- auto?: boolean,
14
- /**
15
- * When this is true, the FieldGroup will occupy all the width available instead of just what its children need.
16
- *
17
- * @default false
18
- */
19
- fullWidth?: boolean,
20
- }
21
-
22
- export type FieldGroupProps = React.JSX.IntrinsicElements['div'] & BaseFieldGroupProps
23
-
24
- /**
25
- * A FieldGroup is used to concatenate an input with other UI elements, like icons and buttons.
26
- *
27
- * @example
28
- * A search field, with a search icon and a button to submit the search.
29
- * ```
30
- * <FieldGroup>
31
- * <Icon icon="Search" />
32
- * <Input type="search" />
33
- * <Button colorScheme="light">Submit</Button>
34
- * </FieldGroup>
35
- * ```
36
- */
37
- export const FieldGroup = withRef(({ auto = true, fullWidth, className, children, ...props }: FieldGroupProps) => (
38
- <CitricComponent
39
- tag="div"
40
- component="field-group"
41
- className={listToClass([className, auto && 'auto', fullWidth && 'full-width'])}
42
- {...props}
43
- >
44
- {children}
45
- </CitricComponent>
46
- ))
1
+ import { listToClass } from '@stack-spot/portal-theme'
2
+ import { withRef } from '../utils/react'
3
+ import { CitricComponent } from './CitricComponent'
4
+
5
+ export interface BaseFieldGroupProps {
6
+ /**
7
+ * When this is true, the component will automatically mark the addons.
8
+ *
9
+ * When this is false, you must add the class "addon" manually to each of the addons.
10
+ *
11
+ * @default true
12
+ */
13
+ auto?: boolean,
14
+ /**
15
+ * When this is true, the FieldGroup will occupy all the width available instead of just what its children need.
16
+ *
17
+ * @default false
18
+ */
19
+ fullWidth?: boolean,
20
+ }
21
+
22
+ export type FieldGroupProps = React.JSX.IntrinsicElements['div'] & BaseFieldGroupProps
23
+
24
+ /**
25
+ * A FieldGroup is used to concatenate an input with other UI elements, like icons and buttons.
26
+ *
27
+ * @example
28
+ * A search field, with a search icon and a button to submit the search.
29
+ * ```
30
+ * <FieldGroup>
31
+ * <Icon icon="Search" />
32
+ * <Input type="search" />
33
+ * <Button colorScheme="light">Submit</Button>
34
+ * </FieldGroup>
35
+ * ```
36
+ */
37
+ export const FieldGroup = withRef(({ auto = true, fullWidth, className, children, ...props }: FieldGroupProps) => (
38
+ <CitricComponent
39
+ tag="div"
40
+ component="field-group"
41
+ className={listToClass([className, auto && 'auto', fullWidth && 'full-width'])}
42
+ {...props}
43
+ >
44
+ {children}
45
+ </CitricComponent>
46
+ ))
@@ -1,36 +1,36 @@
1
- import { listToClass } from '@stack-spot/portal-theme'
2
- import { withRef } from '../utils/react'
3
- import { CitricComponent } from './CitricComponent'
4
-
5
- export type FormProps = JSX.IntrinsicElements['form']
6
- export type ButtonGroupProps = JSX.IntrinsicElements['div']
7
-
8
- /**
9
- * A form, styled to receive rows, form groups and button groups.
10
- *
11
- * This has the exact same interface as the HTML form.
12
- */
13
- export const Form = ({ children, ...props }: FormProps) => (
14
- <CitricComponent tag="form" component="form" {...props}>
15
- {children}
16
- </CitricComponent>
17
- )
18
-
19
- /**
20
- * Renders a group of buttons in a form.
21
- *
22
- * @example
23
- * ```
24
- * <Form>
25
- * <ButtonGroup>
26
- * <Button>Cancel</Button>
27
- * <Button type="submit">Submit</Button>
28
- * </ButtonGroup>
29
- * </Form>
30
- * ```
31
- */
32
- export const ButtonGroup = withRef(({ className, children, ...props }: ButtonGroupProps) => (
33
- <div className={listToClass([className, 'button-group'])} {...props}>
34
- {children}
35
- </div>
36
- ))
1
+ import { listToClass } from '@stack-spot/portal-theme'
2
+ import { withRef } from '../utils/react'
3
+ import { CitricComponent } from './CitricComponent'
4
+
5
+ export type FormProps = JSX.IntrinsicElements['form']
6
+ export type ButtonGroupProps = JSX.IntrinsicElements['div']
7
+
8
+ /**
9
+ * A form, styled to receive rows, form groups and button groups.
10
+ *
11
+ * This has the exact same interface as the HTML form.
12
+ */
13
+ export const Form = ({ children, ...props }: FormProps) => (
14
+ <CitricComponent tag="form" component="form" {...props}>
15
+ {children}
16
+ </CitricComponent>
17
+ )
18
+
19
+ /**
20
+ * Renders a group of buttons in a form.
21
+ *
22
+ * @example
23
+ * ```
24
+ * <Form>
25
+ * <ButtonGroup>
26
+ * <Button>Cancel</Button>
27
+ * <Button type="submit">Submit</Button>
28
+ * </ButtonGroup>
29
+ * </Form>
30
+ * ```
31
+ */
32
+ export const ButtonGroup = withRef(({ className, children, ...props }: ButtonGroupProps) => (
33
+ <div className={listToClass([className, 'button-group'])} {...props}>
34
+ {children}
35
+ </div>
36
+ ))
@@ -1,57 +1,57 @@
1
- import { listToClass } from '@stack-spot/portal-theme'
2
- import { withRef } from '../utils/react'
3
- import { CitricComponent } from './CitricComponent'
4
- import { IconButton } from './IconBox'
5
- import { Text } from './Text'
6
- import { Tooltip } from './Tooltip'
7
-
8
- export interface BaseFormGroupProps {
9
- /**
10
- * The error string to show, if any. The empty string is equivalent to undefined, i.e. no errors.
11
- */
12
- error?: string,
13
- /**
14
- * The input's label.
15
- */
16
- label?: string,
17
- /**
18
- * A help string, to show as a tooltip.
19
- */
20
- help?: string,
21
- /**
22
- * A warning string, to show right below the field, at all times.
23
- */
24
- warning?: string,
25
- }
26
-
27
- export type FormGroupProps = React.JSX.IntrinsicElements['div'] & BaseFormGroupProps
28
-
29
- /**
30
- * A form group renders everything a field in a form needs: the input, its label, a tooltip (help), an error and a remark (warning).
31
- *
32
- * Labels, errors, tooltips and warnings are only rendered when they're strings with at least one character.
33
- *
34
- * @example
35
- * ```
36
- * <FormGroup label="Birth Date" help="The date when you were born" error="The date you typed is invalid!">
37
- * <Input type="date" />
38
- * </FormGroup>
39
- * ```
40
- */
41
- export const FormGroup = withRef(({ error, help, label, warning, className, children, ...props }: FormGroupProps) => (
42
- <CitricComponent tag="div" component="form-group" className={listToClass([className, error && 'error'])} {...props}>
43
- <label>
44
- {help ? (
45
- <div className="row">
46
- <Text>{label}</Text>
47
- <Tooltip content={help}>
48
- <IconButton icon="InfoCircle" size="xs" />
49
- </Tooltip>
50
- </div>
51
- ): label}
52
- {children}
53
- <div className="feedback">{error}</div>
54
- {warning && <div className="warning">{warning}</div>}
55
- </label>
56
- </CitricComponent>
57
- ))
1
+ import { listToClass } from '@stack-spot/portal-theme'
2
+ import { withRef } from '../utils/react'
3
+ import { CitricComponent } from './CitricComponent'
4
+ import { IconButton } from './IconBox'
5
+ import { Text } from './Text'
6
+ import { Tooltip } from './Tooltip'
7
+
8
+ export interface BaseFormGroupProps {
9
+ /**
10
+ * The error string to show, if any. The empty string is equivalent to undefined, i.e. no errors.
11
+ */
12
+ error?: string,
13
+ /**
14
+ * The input's label.
15
+ */
16
+ label?: string,
17
+ /**
18
+ * A help string, to show as a tooltip.
19
+ */
20
+ help?: string,
21
+ /**
22
+ * A warning string, to show right below the field, at all times.
23
+ */
24
+ warning?: string,
25
+ }
26
+
27
+ export type FormGroupProps = React.JSX.IntrinsicElements['div'] & BaseFormGroupProps
28
+
29
+ /**
30
+ * A form group renders everything a field in a form needs: the input, its label, a tooltip (help), an error and a remark (warning).
31
+ *
32
+ * Labels, errors, tooltips and warnings are only rendered when they're strings with at least one character.
33
+ *
34
+ * @example
35
+ * ```
36
+ * <FormGroup label="Birth Date" help="The date when you were born" error="The date you typed is invalid!">
37
+ * <Input type="date" />
38
+ * </FormGroup>
39
+ * ```
40
+ */
41
+ export const FormGroup = withRef(({ error, help, label, warning, className, children, ...props }: FormGroupProps) => (
42
+ <CitricComponent tag="div" component="form-group" className={listToClass([className, error && 'error'])} {...props}>
43
+ <label>
44
+ {help ? (
45
+ <div className="row">
46
+ <Text>{label}</Text>
47
+ <Tooltip content={help}>
48
+ <IconButton icon="InfoCircle" size="xs" />
49
+ </Tooltip>
50
+ </div>
51
+ ): label}
52
+ {children}
53
+ <div className="feedback">{error}</div>
54
+ {warning && <div className="warning">{warning}</div>}
55
+ </label>
56
+ </CitricComponent>
57
+ ))
@@ -1,35 +1,35 @@
1
- import { IconGroup, Icon as OgIcon, IconProps as OgIconProps } from '@stack-spot/citric-icons'
2
- import { ColorKey } from '@stack-spot/portal-theme'
3
- import { colorNameToColorVariable } from '../utils/css'
4
-
5
- export type IconProps<T extends IconGroup> = Omit<OgIconProps<T>, 'color'> & {
6
- /**
7
- * The color for the icon. Can be any color in the theme.
8
- */
9
- color?: ColorKey,
10
- }
11
-
12
- /**
13
- * Renders an icon based on the properties "icon" and "group".
14
- *
15
- * There are three icon groups:
16
- * - outline: most of the icons are in this group. The icons are stroke only.
17
- * - fill: most outline icons have a fill version. Fill icons are filled with solid colors, they're not just strokes.
18
- * - social: icons for brands (logos).
19
- *
20
- * By default, the group is "outline".
21
- *
22
- * The icon size depends on the font-size of the current context. To set a specific size, use the property "size".
23
- *
24
- * Attention: this is the same as using the component Icon from the icons component, the only difference is that this accepts the property
25
- * "color".
26
- *
27
- * @example
28
- *
29
- * ```
30
- * <Icon icon="Search" />
31
- * ```
32
- */
33
- export function Icon<T extends IconGroup>({ color, style, ...props }: IconProps<T>) {
34
- return <OgIcon {...props} style={{ color: color ? colorNameToColorVariable(color) : undefined, ...style }} />
35
- }
1
+ import { IconGroup, Icon as OgIcon, IconProps as OgIconProps } from '@stack-spot/citric-icons'
2
+ import { ColorKey } from '@stack-spot/portal-theme'
3
+ import { colorNameToColorVariable } from '../utils/css'
4
+
5
+ export type IconProps<T extends IconGroup> = Omit<OgIconProps<T>, 'color'> & {
6
+ /**
7
+ * The color for the icon. Can be any color in the theme.
8
+ */
9
+ color?: ColorKey,
10
+ }
11
+
12
+ /**
13
+ * Renders an icon based on the properties "icon" and "group".
14
+ *
15
+ * There are three icon groups:
16
+ * - outline: most of the icons are in this group. The icons are stroke only.
17
+ * - fill: most outline icons have a fill version. Fill icons are filled with solid colors, they're not just strokes.
18
+ * - social: icons for brands (logos).
19
+ *
20
+ * By default, the group is "outline".
21
+ *
22
+ * The icon size depends on the font-size of the current context. To set a specific size, use the property "size".
23
+ *
24
+ * Attention: this is the same as using the component Icon from the icons component, the only difference is that this accepts the property
25
+ * "color".
26
+ *
27
+ * @example
28
+ *
29
+ * ```
30
+ * <Icon icon="Search" />
31
+ * ```
32
+ */
33
+ export function Icon<T extends IconGroup>({ color, style, ...props }: IconProps<T>) {
34
+ return <OgIcon {...props} style={{ color: color ? colorNameToColorVariable(color) : undefined, ...style }} />
35
+ }
@@ -1,134 +1,134 @@
1
- import { BaseIconProps, IconGroup } from '@stack-spot/citric-icons'
2
- import { listToClass } from '@stack-spot/portal-theme'
3
- import { useCitricController } from '../context/hooks'
4
- import { HTMLTag, WithColorPalette, WithColorScheme } from '../types'
5
- import { withRef } from '../utils/react'
6
- import { asCitricProps, CitricComponent } from './CitricComponent'
7
-
8
- type IconBoxTag = 'a' | 'button' | 'i' | 'span' | 'div'
9
-
10
- export interface BaseIconBoxProps<T extends IconBoxTag, G extends IconGroup> extends BaseIconProps<G>, WithColorScheme, WithColorPalette {
11
- /**
12
- * The HTML element to render.
13
- *
14
- * @default 'i'
15
- */
16
- tag?: T,
17
- /**
18
- * The box appearance.
19
- *
20
- * - circle: a circle with a background color. Its size depends on the value of `size`. If this is clickable, the background and
21
- * foreground colors change on hover or focus.
22
- * - square: a square with rounded corners and a background color. Its size depends on the value of `size`. If this is clickable, the
23
- * background and foreground colors change on hover or focus.
24
- * - text: a circle with transparent background. Its size depends on the value of `size`. If this is clickable, the background and
25
- * foreground colors change on hover or focus (it won't be transparent).
26
- * - none: no special styling, its size depends only on the size of the icon (the property `size` is ignored). Even if this is clickable,
27
- * the style doesn't change on hover or focus.
28
- *
29
- * @default 'circle'
30
- */
31
- appearance?: 'circle' | 'square' | 'text' | 'none',
32
- /**
33
- * Size of the box.
34
- *
35
- * - xs: 20px;
36
- * - sm: 24px;
37
- * - md: 32px;
38
- * - lg: 40px.
39
- *
40
- * @default 'sm'
41
- */
42
- size?: 'xs' | 'sm' | 'md' | 'lg',
43
- /**
44
- * Animated text to show on when the button/link is clicked. This is only valid for buttons and anchors.
45
- */
46
- feedback?: string,
47
- /**
48
- * Only valid if `tag` is "button" or "a".
49
- *
50
- * Metadata for the general onClick event, set by the CitricController. Useful for creating analytics data.
51
- *
52
- * This only takes effect if there's a CitricController in React's context. The value of `metadata` is passed to the function
53
- * `onClickButton/onClickLink` of the controller.
54
- *
55
- * @default false
56
- */
57
- metadata?: any,
58
- }
59
-
60
- export type IconBoxProps<T extends IconBoxTag, G extends IconGroup> = Omit<HTMLTag[T], 'children'> & BaseIconBoxProps<T, G>
61
-
62
- /**
63
- * Renders a wrapper for an icon. The icon must specified by the properties "icon" and "group", this component accepts no children.
64
- *
65
- * If you don't need the icon to be rendered within a box, consider using the component "Icon" directly.
66
- *
67
- * Hover and focus effects are applied if the IconBox is focusable.
68
- *
69
- * @example
70
- * ```
71
- * <IconBox icon="Search" colorScheme="primary" />
72
- * ```
73
- */
74
- export const IconBox = withRef(
75
- function IconBox<T extends IconBoxTag = 'i', G extends IconGroup = 'outline'>(
76
- { group, icon, tag, appearance, size, className, metadata, onClick, feedback, ...props }: IconBoxProps<T, G>,
77
- ) {
78
- props['aria-label'] ||= props.title // accessibility
79
- const citric = useCitricController()
80
-
81
- function handleClick(e: React.MouseEvent<any>) {
82
- onClick?.(e)
83
- if (tag === 'button') citric?.onClickButton?.(e, metadata)
84
- else if (tag === 'a') citric?.onClickLink?.(e, metadata)
85
- }
86
-
87
- const componentProps = {
88
- tag: (tag || 'i') as any,
89
- component: 'icon-box',
90
- className: listToClass(['citric-icon', group || 'outline', icon, appearance, size, className]),
91
- 'data-feedback': feedback || undefined,
92
- onClick: ['button', 'a'].includes(tag ?? '') ? handleClick : onClick,
93
- ...props,
94
- } as const
95
-
96
- return tag === 'a' && citric?.renderLink
97
- ? citric.renderLink(asCitricProps(componentProps))
98
- : <CitricComponent {...componentProps} />
99
- },
100
- )
101
-
102
- /**
103
- * A shortcut for `<IconBox tag="button">`.
104
- *
105
- * Whenever a button is clicked, the function `onClickButton` of the nearest CitricController is called with the event and the value of the
106
- * prop `metadata`.
107
- *
108
- * @example
109
- * ```
110
- * <IconButton icon="Search" />
111
- * ```
112
- */
113
- export const IconButton = withRef(
114
- function IconButton<G extends IconGroup = 'outline'>({ type, ...props }: Omit<IconBoxProps<'button', G>, 'tag'>) {
115
- return <IconBox {...props} tag="button" type={type || 'button' } />
116
- },
117
- )
118
-
119
- /**
120
- * A shortcut for `<IconBox tag="a">`.
121
- *
122
- * Whenever a link is clicked, the function `onClickLink` of the nearest CitricController is called with the event and the value of the
123
- * prop `metadata`.
124
- *
125
- * @example
126
- * ```
127
- * <IconLink icon="Search" href="#" />
128
- * ```
129
- */
130
- export const IconLink = withRef(
131
- function IconLink<G extends IconGroup = 'outline'>(props: Omit<IconBoxProps<'a', G>, 'tag'>) {
132
- return <IconBox {...props} tag="a" />
133
- },
134
- )
1
+ import { BaseIconProps, IconGroup } from '@stack-spot/citric-icons'
2
+ import { listToClass } from '@stack-spot/portal-theme'
3
+ import { useCitricController } from '../context/hooks'
4
+ import { HTMLTag, WithColorPalette, WithColorScheme } from '../types'
5
+ import { withRef } from '../utils/react'
6
+ import { asCitricProps, CitricComponent } from './CitricComponent'
7
+
8
+ type IconBoxTag = 'a' | 'button' | 'i' | 'span' | 'div'
9
+
10
+ export interface BaseIconBoxProps<T extends IconBoxTag, G extends IconGroup> extends BaseIconProps<G>, WithColorScheme, WithColorPalette {
11
+ /**
12
+ * The HTML element to render.
13
+ *
14
+ * @default 'i'
15
+ */
16
+ tag?: T,
17
+ /**
18
+ * The box appearance.
19
+ *
20
+ * - circle: a circle with a background color. Its size depends on the value of `size`. If this is clickable, the background and
21
+ * foreground colors change on hover or focus.
22
+ * - square: a square with rounded corners and a background color. Its size depends on the value of `size`. If this is clickable, the
23
+ * background and foreground colors change on hover or focus.
24
+ * - text: a circle with transparent background. Its size depends on the value of `size`. If this is clickable, the background and
25
+ * foreground colors change on hover or focus (it won't be transparent).
26
+ * - none: no special styling, its size depends only on the size of the icon (the property `size` is ignored). Even if this is clickable,
27
+ * the style doesn't change on hover or focus.
28
+ *
29
+ * @default 'circle'
30
+ */
31
+ appearance?: 'circle' | 'square' | 'text' | 'none',
32
+ /**
33
+ * Size of the box.
34
+ *
35
+ * - xs: 20px;
36
+ * - sm: 24px;
37
+ * - md: 32px;
38
+ * - lg: 40px.
39
+ *
40
+ * @default 'sm'
41
+ */
42
+ size?: 'xs' | 'sm' | 'md' | 'lg',
43
+ /**
44
+ * Animated text to show on when the button/link is clicked. This is only valid for buttons and anchors.
45
+ */
46
+ feedback?: string,
47
+ /**
48
+ * Only valid if `tag` is "button" or "a".
49
+ *
50
+ * Metadata for the general onClick event, set by the CitricController. Useful for creating analytics data.
51
+ *
52
+ * This only takes effect if there's a CitricController in React's context. The value of `metadata` is passed to the function
53
+ * `onClickButton/onClickLink` of the controller.
54
+ *
55
+ * @default false
56
+ */
57
+ metadata?: any,
58
+ }
59
+
60
+ export type IconBoxProps<T extends IconBoxTag, G extends IconGroup> = Omit<HTMLTag[T], 'children'> & BaseIconBoxProps<T, G>
61
+
62
+ /**
63
+ * Renders a wrapper for an icon. The icon must specified by the properties "icon" and "group", this component accepts no children.
64
+ *
65
+ * If you don't need the icon to be rendered within a box, consider using the component "Icon" directly.
66
+ *
67
+ * Hover and focus effects are applied if the IconBox is focusable.
68
+ *
69
+ * @example
70
+ * ```
71
+ * <IconBox icon="Search" colorScheme="primary" />
72
+ * ```
73
+ */
74
+ export const IconBox = withRef(
75
+ function IconBox<T extends IconBoxTag = 'i', G extends IconGroup = 'outline'>(
76
+ { group, icon, tag, appearance, size, className, metadata, onClick, feedback, ...props }: IconBoxProps<T, G>,
77
+ ) {
78
+ props['aria-label'] ||= props.title // accessibility
79
+ const citric = useCitricController()
80
+
81
+ function handleClick(e: React.MouseEvent<any>) {
82
+ onClick?.(e)
83
+ if (tag === 'button') citric?.onClickButton?.(e, metadata)
84
+ else if (tag === 'a') citric?.onClickLink?.(e, metadata)
85
+ }
86
+
87
+ const componentProps = {
88
+ tag: (tag || 'i') as any,
89
+ component: 'icon-box',
90
+ className: listToClass(['citric-icon', group || 'outline', icon, appearance, size, className]),
91
+ 'data-feedback': feedback || undefined,
92
+ onClick: ['button', 'a'].includes(tag ?? '') ? handleClick : onClick,
93
+ ...props,
94
+ } as const
95
+
96
+ return tag === 'a' && citric?.renderLink
97
+ ? citric.renderLink(asCitricProps(componentProps))
98
+ : <CitricComponent {...componentProps} />
99
+ },
100
+ )
101
+
102
+ /**
103
+ * A shortcut for `<IconBox tag="button">`.
104
+ *
105
+ * Whenever a button is clicked, the function `onClickButton` of the nearest CitricController is called with the event and the value of the
106
+ * prop `metadata`.
107
+ *
108
+ * @example
109
+ * ```
110
+ * <IconButton icon="Search" />
111
+ * ```
112
+ */
113
+ export const IconButton = withRef(
114
+ function IconButton<G extends IconGroup = 'outline'>({ type, ...props }: Omit<IconBoxProps<'button', G>, 'tag'>) {
115
+ return <IconBox {...props} tag="button" type={type || 'button' } />
116
+ },
117
+ )
118
+
119
+ /**
120
+ * A shortcut for `<IconBox tag="a">`.
121
+ *
122
+ * Whenever a link is clicked, the function `onClickLink` of the nearest CitricController is called with the event and the value of the
123
+ * prop `metadata`.
124
+ *
125
+ * @example
126
+ * ```
127
+ * <IconLink icon="Search" href="#" />
128
+ * ```
129
+ */
130
+ export const IconLink = withRef(
131
+ function IconLink<G extends IconGroup = 'outline'>(props: Omit<IconBoxProps<'a', G>, 'tag'>) {
132
+ return <IconBox {...props} tag="a" />
133
+ },
134
+ )