@cerberus-design/react 0.10.4 → 0.11.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 (159) hide show
  1. package/build/legacy/_tsup-dts-rollup.d.cts +244 -2
  2. package/build/legacy/components/Admonition.cjs +419 -0
  3. package/build/legacy/components/Admonition.cjs.map +1 -0
  4. package/build/legacy/components/AnimatingUploadIcon.cjs +124 -0
  5. package/build/legacy/components/AnimatingUploadIcon.cjs.map +1 -0
  6. package/build/legacy/components/Avatar.cjs +110 -13
  7. package/build/legacy/components/Avatar.cjs.map +1 -1
  8. package/build/legacy/components/Checkbox.cjs +107 -10
  9. package/build/legacy/components/Checkbox.cjs.map +1 -1
  10. package/build/legacy/components/CircularProgress.cjs +19 -5
  11. package/build/legacy/components/CircularProgress.cjs.map +1 -1
  12. package/build/legacy/components/Fieldset.cjs +66 -0
  13. package/build/legacy/components/Fieldset.cjs.map +1 -0
  14. package/build/legacy/components/FieldsetLabel.cjs +49 -0
  15. package/build/legacy/components/FieldsetLabel.cjs.map +1 -0
  16. package/build/legacy/components/FileStatus.cjs +138 -39
  17. package/build/legacy/components/FileStatus.cjs.map +1 -1
  18. package/build/legacy/components/FileUploader.cjs +120 -22
  19. package/build/legacy/components/FileUploader.cjs.map +1 -1
  20. package/build/legacy/components/Input.cjs +108 -11
  21. package/build/legacy/components/Input.cjs.map +1 -1
  22. package/build/legacy/components/Label.cjs +1 -1
  23. package/build/legacy/components/Label.cjs.map +1 -1
  24. package/build/legacy/components/Legend.cjs +95 -0
  25. package/build/legacy/components/Legend.cjs.map +1 -0
  26. package/build/legacy/components/ModalHeader.cjs +2 -2
  27. package/build/legacy/components/ModalHeader.cjs.map +1 -1
  28. package/build/legacy/components/Notification.cjs +109 -12
  29. package/build/legacy/components/Notification.cjs.map +1 -1
  30. package/build/legacy/components/Radio.cjs +27 -14
  31. package/build/legacy/components/Radio.cjs.map +1 -1
  32. package/build/legacy/components/Select.cjs +111 -14
  33. package/build/legacy/components/Select.cjs.map +1 -1
  34. package/build/legacy/components/Tag.cjs +106 -9
  35. package/build/legacy/components/Tag.cjs.map +1 -1
  36. package/build/legacy/components/Th.cjs +4 -1
  37. package/build/legacy/components/Th.cjs.map +1 -1
  38. package/build/legacy/components/Toggle.cjs +108 -11
  39. package/build/legacy/components/Toggle.cjs.map +1 -1
  40. package/build/legacy/config/cerbIcons.cjs +102 -5
  41. package/build/legacy/config/cerbIcons.cjs.map +1 -1
  42. package/build/legacy/config/defineIcons.cjs +102 -5
  43. package/build/legacy/config/defineIcons.cjs.map +1 -1
  44. package/build/legacy/context/confirm-modal.cjs +141 -40
  45. package/build/legacy/context/confirm-modal.cjs.map +1 -1
  46. package/build/legacy/context/notification-center.cjs +129 -32
  47. package/build/legacy/context/notification-center.cjs.map +1 -1
  48. package/build/legacy/context/prompt-modal.cjs +178 -66
  49. package/build/legacy/context/prompt-modal.cjs.map +1 -1
  50. package/build/legacy/hooks/useModal.cjs +6 -2
  51. package/build/legacy/hooks/useModal.cjs.map +1 -1
  52. package/build/legacy/index.cjs +793 -442
  53. package/build/legacy/index.cjs.map +1 -1
  54. package/build/modern/_tsup-dts-rollup.d.ts +244 -2
  55. package/build/modern/{chunk-S7XGIQY6.js → chunk-243VUIA6.js} +2 -2
  56. package/build/modern/{chunk-LKFXUM3Z.js → chunk-3NE6C66J.js} +36 -25
  57. package/build/modern/{chunk-LKFXUM3Z.js.map → chunk-3NE6C66J.js.map} +1 -1
  58. package/build/modern/chunk-3ZDFQO25.js +31 -0
  59. package/build/modern/chunk-3ZDFQO25.js.map +1 -0
  60. package/build/modern/{chunk-YLPSE5Z2.js → chunk-6QHOKCV3.js} +11 -6
  61. package/build/modern/chunk-6QHOKCV3.js.map +1 -0
  62. package/build/modern/chunk-6TTN2JMY.js +54 -0
  63. package/build/modern/chunk-6TTN2JMY.js.map +1 -0
  64. package/build/modern/{chunk-OW62FLJ6.js → chunk-7T3JIGM7.js} +8 -4
  65. package/build/modern/chunk-7T3JIGM7.js.map +1 -0
  66. package/build/modern/{chunk-7K6PZBHN.js → chunk-CO4BKT7K.js} +5 -2
  67. package/build/modern/{chunk-7K6PZBHN.js.map → chunk-CO4BKT7K.js.map} +1 -1
  68. package/build/modern/{chunk-NBG2OSYI.js → chunk-FT7DFRHQ.js} +2 -2
  69. package/build/modern/chunk-FTPZHG6J.js +46 -0
  70. package/build/modern/{chunk-LJYCFFX7.js.map → chunk-FTPZHG6J.js.map} +1 -1
  71. package/build/modern/{chunk-JCGWTIR4.js → chunk-HCB5NQ5J.js} +5 -4
  72. package/build/modern/chunk-HCB5NQ5J.js.map +1 -0
  73. package/build/modern/chunk-HVKM54BA.js +100 -0
  74. package/build/modern/chunk-HVKM54BA.js.map +1 -0
  75. package/build/modern/{chunk-CMUFJU4S.js → chunk-KLUBAM4U.js} +2 -2
  76. package/build/modern/{chunk-AUAPBPGW.js → chunk-MDIUFBDX.js} +2 -2
  77. package/build/modern/{chunk-I35HMGJQ.js → chunk-NMF2HYWO.js} +2 -2
  78. package/build/modern/{chunk-I35HMGJQ.js.map → chunk-NMF2HYWO.js.map} +1 -1
  79. package/build/modern/{chunk-O6JYYVO7.js → chunk-PA5EB7EO.js} +2 -2
  80. package/build/modern/chunk-PZAZKQMO.js +25 -0
  81. package/build/modern/chunk-PZAZKQMO.js.map +1 -0
  82. package/build/modern/{chunk-EZNGCXVJ.js → chunk-RDQHHCFR.js} +5 -5
  83. package/build/modern/{chunk-BDCFYW34.js → chunk-TMR7JGMP.js} +12 -9
  84. package/build/modern/chunk-TMR7JGMP.js.map +1 -0
  85. package/build/modern/{chunk-WZOYPFUU.js → chunk-UJKS4DDN.js} +2 -2
  86. package/build/modern/{chunk-WLEX22KS.js → chunk-ULYQLKWA.js} +3 -3
  87. package/build/modern/{chunk-WLEX22KS.js.map → chunk-ULYQLKWA.js.map} +1 -1
  88. package/build/modern/{chunk-6YUB3ITX.js → chunk-X4Y4WTRU.js} +10 -10
  89. package/build/modern/{chunk-UXHAFEBA.js → chunk-YMJMB6OP.js} +5 -3
  90. package/build/modern/chunk-YMJMB6OP.js.map +1 -0
  91. package/build/modern/{chunk-GMG3B34U.js → chunk-YWCTMLLO.js} +2 -2
  92. package/build/modern/chunk-ZW3FFE37.js +138 -0
  93. package/build/modern/chunk-ZW3FFE37.js.map +1 -0
  94. package/build/modern/{chunk-477G5ZEL.js → chunk-ZX6DBC2Z.js} +2 -2
  95. package/build/modern/components/Admonition.js +17 -0
  96. package/build/modern/components/Admonition.js.map +1 -0
  97. package/build/modern/components/AnimatingUploadIcon.js +7 -0
  98. package/build/modern/components/AnimatingUploadIcon.js.map +1 -0
  99. package/build/modern/components/Avatar.js +4 -3
  100. package/build/modern/components/Checkbox.js +4 -3
  101. package/build/modern/components/CircularProgress.js +2 -1
  102. package/build/modern/components/Fieldset.js +9 -0
  103. package/build/modern/components/Fieldset.js.map +1 -0
  104. package/build/modern/components/FieldsetLabel.js +7 -0
  105. package/build/modern/components/FieldsetLabel.js.map +1 -0
  106. package/build/modern/components/FileStatus.js +5 -4
  107. package/build/modern/components/FileUploader.js +5 -4
  108. package/build/modern/components/Input.js +4 -3
  109. package/build/modern/components/Label.js +1 -1
  110. package/build/modern/components/Legend.js +10 -0
  111. package/build/modern/components/Legend.js.map +1 -0
  112. package/build/modern/components/ModalHeader.js +1 -1
  113. package/build/modern/components/Notification.js +4 -3
  114. package/build/modern/components/Radio.js +1 -1
  115. package/build/modern/components/Select.js +4 -3
  116. package/build/modern/components/Tag.js +4 -3
  117. package/build/modern/components/Th.js +1 -1
  118. package/build/modern/components/Toggle.js +4 -3
  119. package/build/modern/config/cerbIcons.js +2 -1
  120. package/build/modern/config/defineIcons.js +3 -2
  121. package/build/modern/context/confirm-modal.js +8 -7
  122. package/build/modern/context/notification-center.js +6 -5
  123. package/build/modern/context/prompt-modal.js +10 -9
  124. package/build/modern/hooks/useModal.js +1 -1
  125. package/build/modern/index.js +86 -65
  126. package/build/modern/index.js.map +1 -1
  127. package/package.json +3 -3
  128. package/src/components/Admonition.tsx +186 -0
  129. package/src/components/AnimatingUploadIcon.tsx +83 -0
  130. package/src/components/CircularProgress.tsx +20 -12
  131. package/src/components/Fieldset.tsx +65 -0
  132. package/src/components/FieldsetLabel.tsx +59 -0
  133. package/src/components/FileStatus.tsx +2 -0
  134. package/src/components/FileUploader.tsx +6 -1
  135. package/src/components/Label.tsx +1 -1
  136. package/src/components/Legend.tsx +87 -0
  137. package/src/components/ModalHeader.tsx +2 -2
  138. package/src/components/Radio.tsx +10 -1
  139. package/src/components/Th.tsx +3 -0
  140. package/src/config/cerbIcons.ts +10 -8
  141. package/src/context/prompt-modal.tsx +8 -1
  142. package/src/hooks/useModal.ts +19 -4
  143. package/src/index.ts +4 -0
  144. package/build/modern/chunk-BDCFYW34.js.map +0 -1
  145. package/build/modern/chunk-JCGWTIR4.js.map +0 -1
  146. package/build/modern/chunk-LJYCFFX7.js +0 -33
  147. package/build/modern/chunk-OW62FLJ6.js.map +0 -1
  148. package/build/modern/chunk-UXHAFEBA.js.map +0 -1
  149. package/build/modern/chunk-YLPSE5Z2.js.map +0 -1
  150. /package/build/modern/{chunk-S7XGIQY6.js.map → chunk-243VUIA6.js.map} +0 -0
  151. /package/build/modern/{chunk-NBG2OSYI.js.map → chunk-FT7DFRHQ.js.map} +0 -0
  152. /package/build/modern/{chunk-CMUFJU4S.js.map → chunk-KLUBAM4U.js.map} +0 -0
  153. /package/build/modern/{chunk-AUAPBPGW.js.map → chunk-MDIUFBDX.js.map} +0 -0
  154. /package/build/modern/{chunk-O6JYYVO7.js.map → chunk-PA5EB7EO.js.map} +0 -0
  155. /package/build/modern/{chunk-EZNGCXVJ.js.map → chunk-RDQHHCFR.js.map} +0 -0
  156. /package/build/modern/{chunk-WZOYPFUU.js.map → chunk-UJKS4DDN.js.map} +0 -0
  157. /package/build/modern/{chunk-6YUB3ITX.js.map → chunk-X4Y4WTRU.js.map} +0 -0
  158. /package/build/modern/{chunk-GMG3B34U.js.map → chunk-YWCTMLLO.js.map} +0 -0
  159. /package/build/modern/{chunk-477G5ZEL.js.map → chunk-ZX6DBC2Z.js.map} +0 -0
@@ -0,0 +1,59 @@
1
+ import { cx } from '@cerberus/styled-system/css'
2
+ import { label, type LabelVariantProps } from '@cerberus/styled-system/recipes'
3
+ import type { LabelProps } from './Label'
4
+
5
+ /**
6
+ * This module contains the FieldsetLabel component.
7
+ * @module FieldsetLabel
8
+ */
9
+
10
+ export type FieldsetLabelProps = LabelProps & LabelVariantProps
11
+
12
+ /**
13
+ * Used for labeling inputs that are children of a Fieldset group.
14
+ * @memberof Fieldset
15
+ * @see https://cerberus.digitalu.design/react/fieldset
16
+ * @definition [ARIA Forms](https://www.a11yproject.com/checklist/#forms)
17
+ * @example
18
+ * ```tsx
19
+ * import { Fieldset, Legend, Field, Radio, Label } from '@cerberus/react'
20
+ * import { Hstack } from '@cerberus/styled-system/jsx'
21
+ *
22
+ * function SomeForm() {
23
+ * return (
24
+ * <form>
25
+ * <Fieldset>
26
+ * <Legend>Do you like cats?</Legend>
27
+ * <Hstack>
28
+ * <Field>
29
+ * <Radio id="yes" name="cats" value="yes" />
30
+ * <FieldsetLabel htmlFor="yes">Yes</FieldsetLabel>
31
+ * </Field>
32
+ * </Hstack>
33
+ * <Hstack>
34
+ * <Field>
35
+ * <Radio id="no" name="cats" value="no" />
36
+ * <FieldsetLabel htmlFor="no">No</FieldsetLabel>
37
+ * </Field>
38
+ * </Hstack>
39
+ * </Fieldset>
40
+ * </form>
41
+ * )
42
+ * }
43
+ * ```
44
+ */
45
+ export function FieldsetLabel(props: FieldsetLabelProps) {
46
+ const { size, usage, ...nativeProps } = props
47
+ return (
48
+ <label
49
+ {...nativeProps}
50
+ className={cx(
51
+ nativeProps.className,
52
+ label({
53
+ size,
54
+ usage,
55
+ }),
56
+ )}
57
+ />
58
+ )
59
+ }
@@ -189,6 +189,7 @@ interface FileStatusElProps {
189
189
 
190
190
  function MatchFileStatusIcon(props: FileStatusElProps) {
191
191
  const {
192
+ waitingFileUploader: TodoIcon,
192
193
  fileUploader: FileUploaderIcon,
193
194
  invalidAlt: InvalidIcon,
194
195
  successNotification: DoneIcon,
@@ -196,6 +197,7 @@ function MatchFileStatusIcon(props: FileStatusElProps) {
196
197
 
197
198
  switch (props.status) {
198
199
  case processStatus.TODO:
200
+ return <TodoIcon size={props.size} />
199
201
  case processStatus.PROCESSING:
200
202
  return <FileUploaderIcon size={props.size} />
201
203
  case processStatus.DONE:
@@ -18,6 +18,10 @@ export interface FileUploaderProps
18
18
  * The name of the file input element.
19
19
  */
20
20
  name: string
21
+ /**
22
+ * Disable the FileUploader component. Good for single-use file uploads.
23
+ */
24
+ disabled?: boolean
21
25
  }
22
26
 
23
27
  /**
@@ -26,10 +30,11 @@ export interface FileUploaderProps
26
30
  */
27
31
  export function FileUploader(props: FileUploaderProps) {
28
32
  const styles = fileUploader()
29
- const Icon = $cerberusIcons.fileUploader
33
+ const { waitingFileUploader: Icon } = $cerberusIcons
30
34
 
31
35
  return (
32
36
  <div
37
+ {...(props.disabled ? { 'aria-disabled': true } : {})}
33
38
  className={cx(
34
39
  vstack({
35
40
  justify: 'center',
@@ -57,7 +57,7 @@ export function Label(props: PropsWithChildren<LabelProps>) {
57
57
  <Show when={required}>
58
58
  <span
59
59
  className={css({
60
- color: 'inherit',
60
+ color: 'page.text.100',
61
61
  fontSize: 'inherit',
62
62
  })}
63
63
  >
@@ -0,0 +1,87 @@
1
+ 'use client'
2
+
3
+ import { css, cx } from '@cerberus/styled-system/css'
4
+ import { type HTMLAttributes } from 'react'
5
+ import { useFieldContext } from '../context/field'
6
+ import { Show } from './Show'
7
+ import {
8
+ label,
9
+ type LabelVariantProps,
10
+ } from '@cerberus-design/styled-system/recipes'
11
+ import { hstack } from '@cerberus-design/styled-system/patterns'
12
+
13
+ /**
14
+ * This module contains the Fieldset component.
15
+ * @module Fieldset
16
+ */
17
+
18
+ export type LegendProps = HTMLAttributes<HTMLLegendElement> & LabelVariantProps
19
+
20
+ /**
21
+ * A component to provide a global label for a group of related elements in a form (for accessibility).
22
+ * @memberof Fieldset
23
+ * @see https://cerberus.digitalu.com/react/fieldset
24
+ * @description [A11y Form Checklist](https://www.a11yproject.com/checklist/#forms)
25
+ * @description [MDN Web Docs: Legend](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend)
26
+ * @example
27
+ * ```tsx
28
+ * import { Fieldset, Legend, Field, Radio, Label } from '@cerberus/react'
29
+ * import { Hstack } from '@cerberus/styled-system/jsx'
30
+ *
31
+ * function SomeForm() {
32
+ * return (
33
+ * <form>
34
+ * <Fieldset>
35
+ * <Legend>Do you like cats?</Legend>
36
+ * <Hstack>
37
+ * <Field>
38
+ * <Radio id="yes" name="cats" value="yes" />
39
+ * <Label htmlFor="yes">Yes</Label>
40
+ * </Field>
41
+ * </Hstack>
42
+ * <Hstack>
43
+ * <Field>
44
+ * <Radio id="no" name="cats" value="no" />
45
+ * <Label htmlFor="no">No</Label>
46
+ * </Field>
47
+ * </Hstack>
48
+ * </Fieldset>
49
+ * </form>
50
+ * )
51
+ * }
52
+ * ```
53
+ */
54
+ export function Legend(props: LegendProps) {
55
+ const { size, ...nativeProps } = props
56
+ const { invalid, ...formState } = useFieldContext()
57
+
58
+ return (
59
+ <legend
60
+ {...nativeProps}
61
+ {...formState}
62
+ {...(invalid && { 'aria-invalid': true })}
63
+ className={cx(
64
+ nativeProps.className,
65
+ hstack({
66
+ justify: 'space-between',
67
+ w: 'full',
68
+ }),
69
+ label({
70
+ size,
71
+ }),
72
+ )}
73
+ >
74
+ {nativeProps.children}
75
+ <Show when={formState.required}>
76
+ <span
77
+ className={css({
78
+ color: 'page.text.100',
79
+ fontSize: 'inherit',
80
+ })}
81
+ >
82
+ (required)
83
+ </span>
84
+ </Show>
85
+ </legend>
86
+ )
87
+ }
@@ -29,8 +29,8 @@ export function ModalHeader(props: ModalHeaderProps) {
29
29
  props.className,
30
30
  vstack({
31
31
  alignItems: 'flex-start',
32
- gap: '4',
33
- mb: '8',
32
+ gap: 'md',
33
+ mb: 'md',
34
34
  }),
35
35
  )}
36
36
  />
@@ -49,7 +49,16 @@ export function Radio(props: PropsWithChildren<RadioProps>) {
49
49
  const styles = radio({ size })
50
50
 
51
51
  return (
52
- <div className={cx('group', hstack(), styles.root)} tabIndex={0}>
52
+ <div
53
+ className={cx(
54
+ 'group',
55
+ hstack({
56
+ gap: 'sm',
57
+ }),
58
+ styles.root,
59
+ )}
60
+ tabIndex={0}
61
+ >
53
62
  <input
54
63
  {...nativeProps}
55
64
  {...state}
@@ -56,6 +56,9 @@ export function Th(props: ThProps) {
56
56
  justifyContent: 'space-between',
57
57
  userSelect: 'none',
58
58
  w: 'full',
59
+ _hover: {
60
+ bgColor: 'page.bg.100',
61
+ },
59
62
  }),
60
63
  )}
61
64
  onClick={onClick}
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  Checkmark,
3
- CheckmarkFilled,
3
+ CheckmarkOutline,
4
4
  ChevronDown,
5
5
  CloseFilled,
6
6
  CloudUpload,
7
- ErrorFilled,
8
7
  Information,
9
- InformationFilled,
10
8
  Restart,
11
9
  TrashCan,
12
10
  UserFilled,
13
11
  Warning,
12
+ WarningAlt,
14
13
  WarningFilled,
15
14
  type CarbonIconType,
16
15
  } from '@cerberus/icons'
17
16
  import type { ElementType } from 'react'
18
17
  import { CheckmarkIcon, IndeterminateIcon } from './icons/checkbox.icons'
18
+ import { AnimatingUploadIcon } from '../components/AnimatingUploadIcon'
19
19
 
20
20
  export type IconType = CarbonIconType | ElementType
21
21
 
@@ -26,6 +26,7 @@ export interface DefinedIcons {
26
26
  confirmModal?: IconType
27
27
  delete?: IconType
28
28
  promptModal?: IconType
29
+ waitingFileUploader?: IconType
29
30
  fileUploader?: IconType
30
31
  indeterminate?: IconType
31
32
  infoNotification?: IconType
@@ -46,12 +47,13 @@ export const defaultIcons: DefinedIcons = {
46
47
  confirmModal: Information,
47
48
  delete: TrashCan,
48
49
  promptModal: Information,
49
- fileUploader: CloudUpload,
50
+ waitingFileUploader: CloudUpload,
51
+ fileUploader: AnimatingUploadIcon,
50
52
  indeterminate: IndeterminateIcon,
51
- infoNotification: InformationFilled,
52
- successNotification: CheckmarkFilled,
53
- warningNotification: WarningFilled,
54
- dangerNotification: ErrorFilled,
53
+ infoNotification: Information,
54
+ successNotification: CheckmarkOutline,
55
+ warningNotification: WarningAlt,
56
+ dangerNotification: WarningFilled,
55
57
  invalid: WarningFilled,
56
58
  invalidAlt: Warning,
57
59
  redo: Restart,
@@ -214,7 +214,14 @@ export function PromptModal(
214
214
  })}
215
215
  >
216
216
  <Field invalid={!isValid}>
217
- <Label htmlFor="confirm" size="md">
217
+ <Label
218
+ className={css({
219
+ gap: 1,
220
+ justifyContent: 'flex-start',
221
+ })}
222
+ htmlFor="confirm"
223
+ size="md"
224
+ >
218
225
  Type
219
226
  <strong
220
227
  className={css({
@@ -1,6 +1,6 @@
1
1
  'use client'
2
2
 
3
- import { useCallback, useMemo, useRef, type RefObject } from 'react'
3
+ import { useCallback, useMemo, useRef, useState, type RefObject } from 'react'
4
4
 
5
5
  /**
6
6
  * This module provides a hook for using a custom modal.
@@ -20,22 +20,36 @@ interface UseModalReturnValue {
20
20
  * Closes the modal.
21
21
  */
22
22
  close: () => void
23
+ /**
24
+ * Whether the modal is open based on the show and close methods.
25
+ */
26
+ isOpen: boolean
23
27
  }
24
28
 
25
29
  /**
26
- * Provides a hook for using a custom modal.
30
+ * Provides a hook for using a custom modal via the native dialog element
31
+ * methods.
32
+ *
33
+ * Cerberus modals use the native dialog element. This hook
34
+ * does not control the modal via React state but rather by calling the
35
+ * native dialog element's `showModal` and `close` methods.
36
+ *
27
37
  * @memberof module:Modal
28
- * @returns The modal hook.
38
+ * @see https://cerberus.digitalu.design/react/modal
39
+ * @description [Moz Dev Dialog Docs](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/showModal)
29
40
  */
30
41
  export function useModal(): UseModalReturnValue {
31
42
  const modalRef = useRef<HTMLDialogElement | null>(null)
43
+ const [isOpen, setIsOpen] = useState<boolean>(false)
32
44
 
33
45
  const show = useCallback(() => {
34
46
  modalRef.current?.showModal()
47
+ setIsOpen(true)
35
48
  }, [])
36
49
 
37
50
  const close = useCallback(() => {
38
51
  modalRef.current?.close()
52
+ setIsOpen(false)
39
53
  }, [])
40
54
 
41
55
  return useMemo(() => {
@@ -43,6 +57,7 @@ export function useModal(): UseModalReturnValue {
43
57
  modalRef,
44
58
  show,
45
59
  close,
60
+ isOpen,
46
61
  }
47
- }, [modalRef, show, close])
62
+ }, [modalRef, show, close, isOpen])
48
63
  }
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  // components
7
7
 
8
+ export * from './components/Admonition'
8
9
  export * from './components/Avatar'
9
10
  export * from './components/Button'
10
11
  export * from './components/Checkbox'
@@ -12,11 +13,14 @@ export * from './components/CircularProgress'
12
13
  export * from './components/Droppable'
13
14
  export * from './components/FieldMessage'
14
15
  export * from './components/FeatureFlag'
16
+ export * from './components/Fieldset'
17
+ export * from './components/FieldsetLabel'
15
18
  export * from './components/FileStatus'
16
19
  export * from './components/FileUploader'
17
20
  export * from './components/IconButton'
18
21
  export * from './components/Input'
19
22
  export * from './components/Label'
23
+ export * from './components/Legend'
20
24
  export * from './components/Modal'
21
25
  export * from './components/ModalHeader'
22
26
  export * from './components/ModalHeading'
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/config/cerbIcons.ts"],"sourcesContent":["import {\n Checkmark,\n CheckmarkFilled,\n ChevronDown,\n CloseFilled,\n CloudUpload,\n ErrorFilled,\n Information,\n InformationFilled,\n Restart,\n TrashCan,\n UserFilled,\n Warning,\n WarningFilled,\n type CarbonIconType,\n} from '@cerberus/icons'\nimport type { ElementType } from 'react'\nimport { CheckmarkIcon, IndeterminateIcon } from './icons/checkbox.icons'\n\nexport type IconType = CarbonIconType | ElementType\n\nexport interface DefinedIcons {\n avatar?: IconType\n checkbox?: IconType\n close?: IconType\n confirmModal?: IconType\n delete?: IconType\n promptModal?: IconType\n fileUploader?: IconType\n indeterminate?: IconType\n infoNotification?: IconType\n successNotification?: IconType\n warningNotification?: IconType\n dangerNotification?: IconType\n invalid: IconType\n invalidAlt?: IconType\n redo?: IconType\n selectArrow?: IconType\n toggleChecked?: IconType\n}\n\nexport const defaultIcons: DefinedIcons = {\n avatar: UserFilled,\n checkbox: CheckmarkIcon,\n close: CloseFilled,\n confirmModal: Information,\n delete: TrashCan,\n promptModal: Information,\n fileUploader: CloudUpload,\n indeterminate: IndeterminateIcon,\n infoNotification: InformationFilled,\n successNotification: CheckmarkFilled,\n warningNotification: WarningFilled,\n dangerNotification: ErrorFilled,\n invalid: WarningFilled,\n invalidAlt: Warning,\n redo: Restart,\n selectArrow: ChevronDown,\n toggleChecked: Checkmark,\n}\n"],"mappings":";;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AA0BA,IAAM,eAA6B;AAAA,EACxC,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,cAAc;AAAA,EACd,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,eAAe;AACjB;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/FileUploader.tsx"],"sourcesContent":["'use client'\n\nimport { cx } from '@cerberus/styled-system/css'\nimport { vstack } from '@cerberus/styled-system/patterns'\nimport { type InputHTMLAttributes } from 'react'\nimport { Show } from './Show'\nimport { fileUploader } from '@cerberus/styled-system/recipes'\nimport { $cerberusIcons } from '../config/defineIcons'\nimport { Avatar } from './Avatar'\n\nexport interface FileUploaderProps\n extends InputHTMLAttributes<HTMLInputElement> {\n /**\n * The optional heading to display in the FileUploader component.\n */\n heading?: string\n /**\n * The name of the file input element.\n */\n name: string\n}\n\n/**\n * A component that allows the user to upload files.\n * @see https://cerberus.digitalu.design/react/file-uploader\n */\nexport function FileUploader(props: FileUploaderProps) {\n const styles = fileUploader()\n const Icon = $cerberusIcons.fileUploader\n\n return (\n <div\n className={cx(\n vstack({\n justify: 'center',\n }),\n styles.container,\n )}\n >\n <div className={styles.icon}>\n <Avatar\n gradient=\"charon-light\"\n ariaLabel=\"\"\n icon={<Icon />}\n size=\"md\"\n src=\"\"\n />\n </div>\n\n <label\n className={cx(\n vstack({\n justify: 'center',\n }),\n styles.label,\n )}\n htmlFor={props.name}\n >\n <Show when={Boolean(props.heading)}>\n <p className={styles.heading}>{props.heading}</p>\n </Show>\n Import {props.accept?.replace(',', ', ')} files\n <p className={styles.description}>Click to select files</p>\n <input\n {...props}\n className={cx(props.className, styles.input)}\n type=\"file\"\n />\n </label>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;AAEA,SAAS,UAAU;AACnB,SAAS,cAAc;AAGvB,SAAS,oBAAoB;AAqCb,cAMV,YANU;AAjBT,SAAS,aAAa,OAA0B;AACrD,QAAM,SAAS,aAAa;AAC5B,QAAM,OAAO,eAAe;AAE5B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT,OAAO;AAAA,UACL,SAAS;AAAA,QACX,CAAC;AAAA,QACD,OAAO;AAAA,MACT;AAAA,MAEA;AAAA,4BAAC,SAAI,WAAW,OAAO,MACrB;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,WAAU;AAAA,YACV,MAAM,oBAAC,QAAK;AAAA,YACZ,MAAK;AAAA,YACL,KAAI;AAAA;AAAA,QACN,GACF;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW;AAAA,cACT,OAAO;AAAA,gBACL,SAAS;AAAA,cACX,CAAC;AAAA,cACD,OAAO;AAAA,YACT;AAAA,YACA,SAAS,MAAM;AAAA,YAEf;AAAA,kCAAC,QAAK,MAAM,QAAQ,MAAM,OAAO,GAC/B,8BAAC,OAAE,WAAW,OAAO,SAAU,gBAAM,SAAQ,GAC/C;AAAA,cAAO;AAAA,cACC,MAAM,QAAQ,QAAQ,KAAK,IAAI;AAAA,cAAE;AAAA,cACzC,oBAAC,OAAE,WAAW,OAAO,aAAa,mCAAqB;AAAA,cACvD;AAAA,gBAAC;AAAA;AAAA,kBACE,GAAG;AAAA,kBACJ,WAAW,GAAG,MAAM,WAAW,OAAO,KAAK;AAAA,kBAC3C,MAAK;AAAA;AAAA,cACP;AAAA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1,33 +0,0 @@
1
- import {
2
- useFieldContext
3
- } from "./chunk-UZDVOIW5.js";
4
-
5
- // src/components/Radio.tsx
6
- import { cx } from "@cerberus/styled-system/css";
7
- import { hstack } from "@cerberus/styled-system/patterns";
8
- import { radio } from "@cerberus/styled-system/recipes";
9
- import { jsx, jsxs } from "react/jsx-runtime";
10
- function Radio(props) {
11
- const { children, size, ...nativeProps } = props;
12
- const { invalid, ...state } = useFieldContext();
13
- const styles = radio({ size });
14
- return /* @__PURE__ */ jsxs("div", { className: cx("group", hstack(), styles.root), tabIndex: 0, children: [
15
- /* @__PURE__ */ jsx(
16
- "input",
17
- {
18
- ...nativeProps,
19
- ...state,
20
- ...invalid && { "aria-invalid": true },
21
- className: cx(nativeProps.className, styles.input),
22
- tabIndex: -1,
23
- type: "radio"
24
- }
25
- ),
26
- children
27
- ] });
28
- }
29
-
30
- export {
31
- Radio
32
- };
33
- //# sourceMappingURL=chunk-LJYCFFX7.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/hooks/useModal.ts"],"sourcesContent":["'use client'\n\nimport { useCallback, useMemo, useRef, type RefObject } from 'react'\n\n/**\n * This module provides a hook for using a custom modal.\n * @module\n */\n\ninterface UseModalReturnValue {\n /**\n * The ref for the modal.\n */\n modalRef: RefObject<HTMLDialogElement>\n /**\n * Shows the modal.\n */\n show: () => void\n /**\n * Closes the modal.\n */\n close: () => void\n}\n\n/**\n * Provides a hook for using a custom modal.\n * @memberof module:Modal\n * @returns The modal hook.\n */\nexport function useModal(): UseModalReturnValue {\n const modalRef = useRef<HTMLDialogElement | null>(null)\n\n const show = useCallback(() => {\n modalRef.current?.showModal()\n }, [])\n\n const close = useCallback(() => {\n modalRef.current?.close()\n }, [])\n\n return useMemo(() => {\n return {\n modalRef,\n show,\n close,\n }\n }, [modalRef, show, close])\n}\n"],"mappings":";AAEA,SAAS,aAAa,SAAS,cAA8B;AA2BtD,SAAS,WAAgC;AAC9C,QAAM,WAAW,OAAiC,IAAI;AAEtD,QAAM,OAAO,YAAY,MAAM;AAC7B,aAAS,SAAS,UAAU;AAAA,EAC9B,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ,YAAY,MAAM;AAC9B,aAAS,SAAS,MAAM;AAAA,EAC1B,GAAG,CAAC,CAAC;AAEL,SAAO,QAAQ,MAAM;AACnB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,UAAU,MAAM,KAAK,CAAC;AAC5B;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/FileStatus.tsx"],"sourcesContent":["'use client'\n\nimport {\n useCallback,\n useMemo,\n type HTMLAttributes,\n type MouseEvent,\n} from 'react'\nimport {\n fileStatus,\n type FileStatusVariantProps,\n} from '@cerberus/styled-system/recipes'\nimport { css, cx } from '@cerberus/styled-system/css'\nimport { hstack, vstack } from '@cerberus/styled-system/patterns'\nimport { $cerberusIcons } from '../config/defineIcons'\nimport { Field } from '../context/field'\nimport { FieldMessage } from './FieldMessage'\nimport { ProgressBar, type ProgressBarProps } from './ProgressBar'\nimport { IconButton } from './IconButton'\nimport { Avatar } from './Avatar'\n\n/**\n * This module contains the FileStatus component.\n * @module\n */\n\n/**\n * The available values of the fileStatus helper Object.\n * @example\n * ```tsx\n * import { fileStatus } from '@cerberus/react'\n * processStatus.TODO // 'todo'\n * ```\n */\nexport type FileStatusKey = (typeof processStatus)[keyof typeof processStatus]\n\n/**\n * The actions that can be performed on a file.\n */\nexport type FileStatusActions = 'cancel' | 'retry' | 'delete'\nexport interface FileBaseStatusProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'onClick'> {\n /**\n * A unique identifier for the file status. Required for accessibility.\n */\n id: string\n /**\n * The name of the file.\n */\n file: string\n /**\n * The percentage of the file that has been processed.\n */\n now: ProgressBarProps['now']\n /**\n * The status of the file.\n */\n status: processStatus\n /**\n * The action to perform on the file when a user clicks the\n * button located at the end of the status card.\n * @param status - The status of the file.\n * @param e - The event object.\n * @example\n * ```tsx\n * <FileStatus file=\"file.txt\" now={0} status={processStatus.TODO} action={(status, e) => console.log(status, e)} />\n * ```\n * @default () => {}\n */\n onClick: (status: FileStatusActions, e: MouseEvent<HTMLButtonElement>) => void\n}\nexport type FileStatusProps = FileBaseStatusProps & FileStatusVariantProps\n\n/**\n * A helper object to represent the status of a file.\n * @example\n * ```tsx\n * import { fileStatus } from '@cerberus/react'\n * processStatus.TODO // 'todo'\n * ```\n */\nexport const enum processStatus {\n TODO = 'todo',\n PROCESSING = 'processing',\n DONE = 'done',\n ERROR = 'error',\n}\n\n/**\n * A component that displays the status of a file during file processing.\n * @see https://cerberus.digitalu.design/react/file-uploader\n * @example\n * ```tsx\n * <FileStatus file=\"file.txt\" now={0} status={processStatus.TODO} action={(status, e) => console.log(status, e)} />\n * ```\n */\nexport function FileStatus(props: FileStatusProps) {\n const { file, now, status, onClick, ...nativeProps } = props\n const actionLabel = useMemo(() => getStatusActionLabel(status), [status])\n const palette = useMemo(() => getPalette(status), [status])\n const modalIconPalette = useMemo(() => getModalIconPalette(status), [status])\n const styles = useMemo(() => {\n switch (status) {\n case processStatus.TODO:\n return fileStatus({ status: 'todo' })\n case processStatus.PROCESSING:\n return fileStatus({ status: 'processing' })\n case processStatus.DONE:\n return fileStatus({ status: 'done' })\n case processStatus.ERROR:\n return fileStatus({ status: 'error' })\n default:\n return fileStatus()\n }\n }, [status])\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n const actionStatus = getStatusActionLabel(\n status,\n ).toLocaleLowerCase() as FileStatusActions\n onClick(actionStatus, e)\n },\n [onClick],\n )\n\n return (\n <div\n {...nativeProps}\n className={cx(nativeProps.className, styles.root, hstack())}\n >\n <Avatar\n ariaLabel=\"\"\n gradient={modalIconPalette}\n icon={<MatchFileStatusIcon size={24} status={status} />}\n src=\"\"\n />\n\n <div\n className={vstack({\n alignItems: 'flex-start',\n gap: '0.12rem',\n w: 'full',\n })}\n >\n <small\n className={css({\n color: 'page.text.initial',\n textStyle: 'label-sm',\n })}\n >\n {file}\n </small>\n <ProgressBar\n id={props.id}\n label=\"File upload status\"\n now={now}\n size=\"sm\"\n />\n <Field invalid={modalIconPalette === 'hades-dark'}>\n <FieldMessage\n className={css({\n color: 'page.text.100',\n })}\n id={`help:${file}`}\n >\n <MatchFileStatusText status={status} now={now} />\n </FieldMessage>\n </Field>\n </div>\n\n <IconButton\n ariaLabel={actionLabel}\n onClick={handleClick}\n palette={palette}\n size=\"sm\"\n >\n <MatchStatusAction status={status} />\n </IconButton>\n </div>\n )\n}\n\ninterface FileStatusElProps {\n status: FileStatusProps['status']\n size?: 16 | 20 | 24 | 32\n now?: number\n}\n\nfunction MatchFileStatusIcon(props: FileStatusElProps) {\n const {\n fileUploader: FileUploaderIcon,\n invalidAlt: InvalidIcon,\n successNotification: DoneIcon,\n } = $cerberusIcons\n\n switch (props.status) {\n case processStatus.TODO:\n case processStatus.PROCESSING:\n return <FileUploaderIcon size={props.size} />\n case processStatus.DONE:\n return <DoneIcon size={props.size} />\n case processStatus.ERROR:\n return <InvalidIcon size={props.size} />\n default:\n throw new Error('Unknown status')\n }\n}\n\nfunction MatchFileStatusText(props: FileStatusElProps) {\n switch (props.status) {\n case processStatus.TODO:\n return 'Waiting to upload'\n case processStatus.PROCESSING:\n return `${props.now}% Complete`\n case processStatus.DONE:\n return 'File uploaded successfully'\n case processStatus.ERROR:\n return 'There was an error uploading the file'\n default:\n throw new Error('Invalid status')\n }\n}\n\nfunction MatchStatusAction(props: FileStatusElProps) {\n const { close: CloseIcon, redo: RedoIcon, delete: TrashIcon } = $cerberusIcons\n switch (props.status) {\n case processStatus.TODO:\n case processStatus.PROCESSING:\n return <CloseIcon />\n case processStatus.ERROR:\n return <RedoIcon />\n case processStatus.DONE:\n return <TrashIcon />\n default:\n throw new Error('Invalid status')\n }\n}\n\nfunction getStatusActionLabel(status: FileStatusKey) {\n switch (status) {\n case processStatus.TODO:\n case processStatus.PROCESSING:\n return 'Cancel'\n case processStatus.ERROR:\n return 'Retry'\n case processStatus.DONE:\n return 'Delete'\n default:\n return ''\n }\n}\n\nfunction getPalette(status: FileStatusKey) {\n switch (status) {\n case processStatus.TODO:\n case processStatus.PROCESSING:\n return 'danger'\n case processStatus.ERROR:\n return 'action'\n case processStatus.DONE:\n return 'danger'\n default:\n return 'action'\n }\n}\n\nfunction getModalIconPalette(status: FileStatusKey) {\n switch (status) {\n case processStatus.TODO:\n case processStatus.PROCESSING:\n return 'charon-light'\n case processStatus.ERROR:\n return 'hades-dark'\n case processStatus.DONE:\n return 'thanatos-light'\n default:\n return 'charon-light'\n }\n}\n"],"mappings":"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","names":["processStatus"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/CircularProgress.tsx"],"sourcesContent":["'use client'\n\nimport { cq } from '@cerberus/styled-system/patterns'\nimport { css } from '@cerberus/styled-system/css'\nimport type { SVGProps } from 'react'\n\n/**\n * This module contains the CircularProgress component.\n * @module\n */\n\nexport interface CircularProgressProps extends SVGProps<SVGSVGElement> {\n /**\n * A unique identifier for the progress bar. Required for accessibility.\n */\n id: string\n /**\n * A description label for the progress bar. Required for accessibility.\n */\n label: string\n /**\n * The current value of the CircularProgress\n */\n now: number\n /**\n * The title of the CircularProgress for a11y\n */\n title: string\n /**\n * What is shown below the now value (default: 'Done')\n */\n syntax?: string\n}\n\n/**\n * The CircularProgress component is used to display a loading indicator.\n * @param props - SVG element attributes\n * @param props.now - The current value of the CircularProgress\n * @param props.title - The title of the CircularProgress for a11y\n * @param props.label - What is shown below the now value (default: 'Done')\n * @see https://cerberus.digitalu.design/react/progress-indicators\n * @example\n * ```tsx\n * <CircularProgress now={24} title=\"Course completion\" label=\"done\" />\n * ```\n */\nexport function CircularProgress(props: CircularProgressProps) {\n const strokeW: number = 14\n const radius = `calc(50% * (1 - ${strokeW}/100))`\n const status: string = props.syntax ?? 'Done'\n const now: number = props.now >= 100 ? 100 : props.now\n\n return (\n <div\n id={props.id}\n aria-label={props.label}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={now}\n className={cq({\n alignSelf: 'stretch',\n flex: 1,\n m: '4px',\n position: 'relative',\n })}\n role=\"progressbar\"\n >\n <svg\n data-complete={now === 100}\n className={css({\n display: 'block',\n rounded: 'full',\n transition: 'all 0.5s ease',\n })}\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeWidth={strokeW}\n viewBox=\"0 0 100 100\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <title>{props.title}</title>\n <desc>{`${now}% ${status}`}</desc>\n <defs>\n <linearGradient id=\"gradient\">\n <stop\n offset=\"0%\"\n stopColor=\"var(--cerberus-colors-action-bg-initial)\"\n />\n <stop\n offset=\"100%\"\n stopColor=\"var(--cerberus-colors-action-bg-active)\"\n />\n </linearGradient>\n </defs>\n\n <circle\n className={css({\n fill: 'page.surface.initial',\n })}\n cx=\"50%\"\n cy=\"50%\"\n r={`calc(50% * (1 - ${strokeW}/100))`}\n pathLength=\"100\"\n />\n <circle\n className={css({\n stroke: 'page.bg.100',\n })}\n cx=\"50%\"\n cy=\"50%\"\n r={radius}\n pathLength=\"100\"\n />\n <circle\n data-complete={now === 100}\n className={css({\n stroke: 'url(#gradient)',\n transition: 'stroke-dashoffset, stroke 0.5s ease',\n '&:is([data-complete=true])': {\n stroke: 'success.bg.initial',\n },\n })}\n cx=\"50%\"\n cy=\"50%\"\n fill=\"none\"\n r={radius}\n pathLength=\"100\"\n strokeDasharray=\"100\"\n strokeDashoffset={100 - now}\n transform=\"rotate(-90 50 50)\"\n />\n\n <g>\n <text\n className={css({\n fill: 'page.text.initial',\n fontFamily: 'mono',\n textStyle: '1.25rem',\n })}\n x=\"50%\"\n y=\"47%\"\n dominantBaseline=\"middle\"\n textAnchor=\"middle\"\n >\n {now}%\n </text>\n <text\n className={css({\n fill: 'page.text.100',\n fontSize: '0.5rem',\n fontWeight: 600,\n })}\n x=\"50%\"\n y=\"59%\"\n dominantBaseline=\"middle\"\n textAnchor=\"middle\"\n >\n {status}\n </text>\n </g>\n </svg>\n </div>\n )\n}\n"],"mappings":";AAEA,SAAS,UAAU;AACnB,SAAS,WAAW;AA6EZ,cAGE,YAHF;AAlCD,SAAS,iBAAiB,OAA8B;AAC7D,QAAM,UAAkB;AACxB,QAAM,SAAS,mBAAmB,OAAO;AACzC,QAAM,SAAiB,MAAM,UAAU;AACvC,QAAM,MAAc,MAAM,OAAO,MAAM,MAAM,MAAM;AAEnD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,IAAI,MAAM;AAAA,MACV,cAAY,MAAM;AAAA,MAClB,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,WAAW,GAAG;AAAA,QACZ,WAAW;AAAA,QACX,MAAM;AAAA,QACN,GAAG;AAAA,QACH,UAAU;AAAA,MACZ,CAAC;AAAA,MACD,MAAK;AAAA,MAEL;AAAA,QAAC;AAAA;AAAA,UACC,iBAAe,QAAQ;AAAA,UACvB,WAAW,IAAI;AAAA,YACb,SAAS;AAAA,YACT,SAAS;AAAA,YACT,YAAY;AAAA,UACd,CAAC;AAAA,UACD,MAAK;AAAA,UACL,eAAc;AAAA,UACd,aAAa;AAAA,UACb,SAAQ;AAAA,UACR,OAAM;AAAA,UAEN;AAAA,gCAAC,WAAO,gBAAM,OAAM;AAAA,YACpB,oBAAC,UAAM,aAAG,GAAG,KAAK,MAAM,IAAG;AAAA,YAC3B,oBAAC,UACC,+BAAC,oBAAe,IAAG,YACjB;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,QAAO;AAAA,kBACP,WAAU;AAAA;AAAA,cACZ;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,QAAO;AAAA,kBACP,WAAU;AAAA;AAAA,cACZ;AAAA,eACF,GACF;AAAA,YAEA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW,IAAI;AAAA,kBACb,MAAM;AAAA,gBACR,CAAC;AAAA,gBACD,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,GAAG,mBAAmB,OAAO;AAAA,gBAC7B,YAAW;AAAA;AAAA,YACb;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW,IAAI;AAAA,kBACb,QAAQ;AAAA,gBACV,CAAC;AAAA,gBACD,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,GAAG;AAAA,gBACH,YAAW;AAAA;AAAA,YACb;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,iBAAe,QAAQ;AAAA,gBACvB,WAAW,IAAI;AAAA,kBACb,QAAQ;AAAA,kBACR,YAAY;AAAA,kBACZ,8BAA8B;AAAA,oBAC5B,QAAQ;AAAA,kBACV;AAAA,gBACF,CAAC;AAAA,gBACD,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,MAAK;AAAA,gBACL,GAAG;AAAA,gBACH,YAAW;AAAA,gBACX,iBAAgB;AAAA,gBAChB,kBAAkB,MAAM;AAAA,gBACxB,WAAU;AAAA;AAAA,YACZ;AAAA,YAEA,qBAAC,OACC;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW,IAAI;AAAA,oBACb,MAAM;AAAA,oBACN,YAAY;AAAA,oBACZ,WAAW;AAAA,kBACb,CAAC;AAAA,kBACD,GAAE;AAAA,kBACF,GAAE;AAAA,kBACF,kBAAiB;AAAA,kBACjB,YAAW;AAAA,kBAEV;AAAA;AAAA,oBAAI;AAAA;AAAA;AAAA,cACP;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW,IAAI;AAAA,oBACb,MAAM;AAAA,oBACN,UAAU;AAAA,oBACV,YAAY;AAAA,kBACd,CAAC;AAAA,kBACD,GAAE;AAAA,kBACF,GAAE;AAAA,kBACF,kBAAiB;AAAA,kBACjB,YAAW;AAAA,kBAEV;AAAA;AAAA,cACH;AAAA,eACF;AAAA;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;","names":[]}