@cerberus-design/react 0.25.0-rc.7 → 0.25.1-rc.1

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 (165) hide show
  1. package/dist/components/combobox/combobox.cjs +1 -2
  2. package/dist/components/combobox/combobox.d.cts +1 -3
  3. package/dist/components/combobox/combobox.d.ts +1 -3
  4. package/dist/components/combobox/combobox.js +1 -2
  5. package/dist/components/cta-dialog/provider.cjs +3 -1
  6. package/dist/components/cta-dialog/provider.d.cts +2 -1
  7. package/dist/components/cta-dialog/provider.d.ts +2 -1
  8. package/dist/components/cta-dialog/provider.js +3 -1
  9. package/dist/components/date-picker/calendar.cjs +3 -1
  10. package/dist/components/date-picker/calendar.d.cts +4 -8
  11. package/dist/components/date-picker/calendar.d.ts +4 -8
  12. package/dist/components/date-picker/calendar.js +3 -1
  13. package/dist/components/date-picker/content.cjs +1 -3
  14. package/dist/components/date-picker/content.d.cts +1 -2
  15. package/dist/components/date-picker/content.d.ts +1 -2
  16. package/dist/components/date-picker/content.js +1 -3
  17. package/dist/components/date-picker/date-picker.cjs +47 -2
  18. package/dist/components/date-picker/date-picker.d.cts +1 -6
  19. package/dist/components/date-picker/date-picker.d.ts +1 -6
  20. package/dist/components/date-picker/date-picker.js +47 -2
  21. package/dist/components/date-picker/index.cjs +3 -3
  22. package/dist/components/date-picker/index.js +3 -3
  23. package/dist/components/date-picker/input.cjs +1 -1
  24. package/dist/components/date-picker/input.js +1 -1
  25. package/dist/components/date-picker/primitives.cjs +4 -1
  26. package/dist/components/date-picker/primitives.d.cts +1 -4
  27. package/dist/components/date-picker/primitives.d.ts +1 -4
  28. package/dist/components/date-picker/primitives.js +4 -1
  29. package/dist/components/date-picker/range-input.cjs +2 -2
  30. package/dist/components/date-picker/range-input.js +2 -2
  31. package/dist/components/field/status-indicator.cjs +1 -2
  32. package/dist/components/field/status-indicator.d.cts +1 -1
  33. package/dist/components/field/status-indicator.d.ts +1 -1
  34. package/dist/components/field/status-indicator.js +1 -2
  35. package/dist/components/file-upload/file-status.cjs +26 -43
  36. package/dist/components/file-upload/file-status.js +27 -44
  37. package/dist/components/file-upload/file-uploader.cjs +21 -47
  38. package/dist/components/file-upload/file-uploader.d.cts +7 -10
  39. package/dist/components/file-upload/file-uploader.d.ts +7 -10
  40. package/dist/components/file-upload/file-uploader.js +22 -48
  41. package/dist/components/file-upload/helpers.cjs +17 -0
  42. package/dist/components/file-upload/helpers.d.cts +16 -0
  43. package/dist/components/file-upload/helpers.d.ts +16 -0
  44. package/dist/components/file-upload/helpers.js +13 -0
  45. package/dist/components/file-upload/img-preview.cjs +30 -0
  46. package/dist/components/file-upload/img-preview.d.cts +2 -0
  47. package/dist/components/file-upload/img-preview.d.ts +2 -0
  48. package/dist/components/file-upload/img-preview.js +26 -0
  49. package/dist/components/file-upload/index.cjs +24 -0
  50. package/dist/components/file-upload/index.d.cts +4 -0
  51. package/dist/components/file-upload/index.d.ts +4 -0
  52. package/dist/components/file-upload/index.js +4 -0
  53. package/dist/components/file-upload/parts.cjs +28 -0
  54. package/dist/components/file-upload/parts.d.cts +86 -0
  55. package/dist/components/file-upload/parts.d.ts +86 -0
  56. package/dist/components/file-upload/parts.js +24 -0
  57. package/dist/components/file-upload/primitives.cjs +81 -0
  58. package/dist/components/file-upload/primitives.d.cts +45 -0
  59. package/dist/components/file-upload/primitives.d.ts +45 -0
  60. package/dist/components/file-upload/primitives.js +61 -0
  61. package/dist/components/file-upload/utils.cjs +18 -0
  62. package/dist/components/file-upload/utils.d.cts +7 -0
  63. package/dist/components/file-upload/utils.d.ts +7 -0
  64. package/dist/components/file-upload/utils.js +14 -0
  65. package/dist/components/select/select.cjs +6 -3
  66. package/dist/components/select/select.d.cts +1 -3
  67. package/dist/components/select/select.d.ts +1 -3
  68. package/dist/components/select/select.js +6 -3
  69. package/dist/context/confirm-modal.cjs +3 -1
  70. package/dist/context/confirm-modal.d.cts +2 -1
  71. package/dist/context/confirm-modal.d.ts +2 -1
  72. package/dist/context/confirm-modal.js +3 -1
  73. package/dist/context/prompt-modal.cjs +4 -2
  74. package/dist/context/prompt-modal.d.cts +2 -1
  75. package/dist/context/prompt-modal.d.ts +2 -1
  76. package/dist/context/prompt-modal.js +5 -3
  77. package/dist/index.cjs +163 -131
  78. package/dist/index.client.d.cts +1 -1
  79. package/dist/index.client.d.ts +1 -1
  80. package/dist/index.js +8 -4
  81. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-clear-trigger.cjs +19 -0
  82. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-clear-trigger.js +15 -0
  83. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-context.cjs +10 -0
  84. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-context.js +6 -0
  85. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-dropzone.cjs +22 -0
  86. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-dropzone.js +18 -0
  87. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-hidden-input.cjs +21 -0
  88. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-hidden-input.js +17 -0
  89. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-delete-trigger.cjs +23 -0
  90. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-delete-trigger.js +19 -0
  91. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-group.cjs +23 -0
  92. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-group.js +19 -0
  93. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-name.cjs +22 -0
  94. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-name.js +18 -0
  95. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-preview-image.cjs +28 -0
  96. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-preview-image.js +24 -0
  97. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-preview.cjs +22 -0
  98. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-preview.js +18 -0
  99. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-size-text.cjs +22 -0
  100. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item-size-text.js +18 -0
  101. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item.cjs +26 -0
  102. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-item.js +22 -0
  103. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-label.cjs +19 -0
  104. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-label.js +15 -0
  105. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-root.cjs +47 -0
  106. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-root.js +43 -0
  107. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-trigger.cjs +19 -0
  108. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/file-upload-trigger.js +15 -0
  109. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/use-file-upload-context.cjs +15 -0
  110. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/use-file-upload-context.js +10 -0
  111. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/use-file-upload-item-group-props-context.cjs +15 -0
  112. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/use-file-upload-item-group-props-context.js +10 -0
  113. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/use-file-upload-item-props-context.cjs +15 -0
  114. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/use-file-upload-item-props-context.js +10 -0
  115. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/use-file-upload.cjs +36 -0
  116. package/dist/node_modules/.pnpm/@ark-ui_react@5.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@ark-ui/react/dist/components/file-upload/use-file-upload.js +32 -0
  117. package/dist/node_modules/.pnpm/@internationalized_date@3.10.0/node_modules/@internationalized/date/src/CalendarDate.js +3 -3
  118. package/dist/node_modules/.pnpm/@internationalized_date@3.10.0/node_modules/@internationalized/date/src/conversion.js +1 -1
  119. package/dist/node_modules/.pnpm/@internationalized_date@3.10.0/node_modules/@internationalized/date/src/queries.js +1 -1
  120. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/CalendarDate.cjs +218 -0
  121. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/CalendarDate.js +212 -0
  122. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/DateFormatter.cjs +135 -0
  123. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/DateFormatter.js +131 -0
  124. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/calendars/GregorianCalendar.cjs +101 -0
  125. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/calendars/GregorianCalendar.js +93 -0
  126. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/conversion.cjs +200 -0
  127. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/conversion.js +186 -0
  128. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/manipulation.cjs +352 -0
  129. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/manipulation.js +336 -0
  130. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/queries.cjs +39 -0
  131. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/queries.js +30 -0
  132. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/string.cjs +44 -0
  133. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/string.js +37 -0
  134. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/utils.cjs +10 -0
  135. package/dist/node_modules/.pnpm/@internationalized_date@3.10.1/node_modules/@internationalized/date/src/utils.js +6 -0
  136. package/dist/node_modules/.pnpm/@zag-js_file-upload@1.31.1/node_modules/@zag-js/file-upload/dist/index.cjs +649 -0
  137. package/dist/node_modules/.pnpm/@zag-js_file-upload@1.31.1/node_modules/@zag-js/file-upload/dist/index.js +643 -0
  138. package/dist/node_modules/.pnpm/@zag-js_file-utils@1.31.1/node_modules/@zag-js/file-utils/dist/index.cjs +147 -0
  139. package/dist/node_modules/.pnpm/@zag-js_file-utils@1.31.1/node_modules/@zag-js/file-utils/dist/index.js +138 -0
  140. package/dist/node_modules/.pnpm/@zag-js_i18n-utils@1.31.1/node_modules/@zag-js/i18n-utils/dist/index.cjs +53 -0
  141. package/dist/node_modules/.pnpm/@zag-js_i18n-utils@1.31.1/node_modules/@zag-js/i18n-utils/dist/index.js +48 -0
  142. package/dist/node_modules/.pnpm/@zag-js_utils@1.31.1/node_modules/@zag-js/utils/dist/index.cjs +9 -0
  143. package/dist/node_modules/.pnpm/@zag-js_utils@1.31.1/node_modules/@zag-js/utils/dist/index.js +9 -1
  144. package/package.json +7 -7
  145. package/src/components/combobox/combobox.tsx +7 -13
  146. package/src/components/cta-dialog/provider.tsx +8 -3
  147. package/src/components/date-picker/calendar.tsx +10 -9
  148. package/src/components/date-picker/content.tsx +4 -11
  149. package/src/components/date-picker/date-picker.tsx +55 -18
  150. package/src/components/date-picker/input.tsx +1 -1
  151. package/src/components/date-picker/primitives.tsx +4 -1
  152. package/src/components/date-picker/range-input.tsx +2 -2
  153. package/src/components/field/status-indicator.tsx +2 -5
  154. package/src/components/file-upload/file-status.tsx +14 -21
  155. package/src/components/file-upload/file-uploader.tsx +37 -49
  156. package/src/components/file-upload/helpers.ts +28 -0
  157. package/src/components/file-upload/img-preview.tsx +41 -0
  158. package/src/components/file-upload/index.ts +4 -0
  159. package/src/components/file-upload/parts.tsx +126 -0
  160. package/src/components/file-upload/primitives.ts +156 -0
  161. package/src/components/file-upload/utils.ts +20 -0
  162. package/src/components/select/select.tsx +11 -12
  163. package/src/context/confirm-modal.tsx +7 -2
  164. package/src/context/prompt-modal.tsx +9 -4
  165. package/src/index.client.ts +2 -0
@@ -1,35 +1,72 @@
1
+ 'use client'
2
+
3
+ import { DateValue } from '@ark-ui/react/date-picker'
1
4
  import { DatePickerParts } from './parts'
2
5
  import type { DatePickerRootProps } from './primitives'
6
+ import { CalendarDate } from '@internationalized/date'
3
7
 
4
- /**
5
- * This module contains an abstraction of the DatePicker.Root primitive.
6
- * @module 'date-picker/root'
7
- */
8
+ const FULL_DATE_REGEX = /^(\d{1,2})[\s/](\d{1,2})[\s/](\d{4})$/
9
+ const PARTIAL_DATE_REGEX = /^(\d{1,2})[\s/](\d{1,2})$/
10
+ const MONTH_REGEX = /^(\d{1,2})$/
8
11
 
9
12
  /**
10
13
  * DatePicker component is an abstraction of the DatePickerRoot primitive which
11
14
  * is the context provider to the DatePicker.
12
- * @description [Cerberus Docs](https://cerberus.digitalu.design/react/date-picker)
13
- * @description [Ark Docs](https://ark-ui.com/react/docs/components/date-picker)
15
+ * @description [Cerberus Docs](https://cerberus.digitalu.design/docs/components/date-picker)
14
16
  */
15
17
  export function DatePicker(props: DatePickerRootProps) {
16
- // const handleFormat = useCallback((date: DateValue) => {
17
- // const day = date.day.toString().padStart(2, '0')
18
- // const year = date.year.toString()
19
- // const formattedMonth = new DateFormatter('en-US', {
20
- // month: 'short',
21
- // }).format(date.toDate(getLocalTimeZone()))
22
-
23
- // // Format the date as "DD MMM YYYY"
24
- // return `${day} ${formattedMonth} ${year}`
25
- // }, [])
26
-
27
18
  return (
28
19
  <DatePickerParts.Root
29
- {...props}
20
+ format={handleFormat}
21
+ parse={parse}
30
22
  positioning={{
31
23
  placement: 'bottom-start',
32
24
  }}
25
+ {...props}
33
26
  />
34
27
  )
35
28
  }
29
+
30
+ function parse(value: string): DateValue | undefined {
31
+ const fullMatch = value.match(FULL_DATE_REGEX)
32
+ if (fullMatch) {
33
+ const [, month, day, year] = fullMatch.map(Number)
34
+ try {
35
+ return new CalendarDate(year, month, day) as unknown as DateValue
36
+ } catch {
37
+ return undefined
38
+ }
39
+ }
40
+
41
+ const partialMatch = value.match(PARTIAL_DATE_REGEX)
42
+ if (partialMatch) {
43
+ const [, month, day] = partialMatch.map(Number)
44
+ const currentYear = new Date().getFullYear()
45
+ try {
46
+ return new CalendarDate(currentYear, month, day) as unknown as DateValue
47
+ } catch {
48
+ return undefined
49
+ }
50
+ }
51
+
52
+ const monthMatch = value.match(MONTH_REGEX)
53
+ if (monthMatch) {
54
+ const [, month] = monthMatch.map(Number)
55
+ const currentYear = new Date().getFullYear()
56
+ try {
57
+ if (month < 1 || month > 12) return undefined
58
+ return new CalendarDate(currentYear, month, 1) as unknown as DateValue
59
+ } catch {
60
+ return undefined
61
+ }
62
+ }
63
+
64
+ return undefined
65
+ }
66
+
67
+ function handleFormat(date: DateValue): string {
68
+ const day = date.day.toString().padStart(2, '0')
69
+ const month = date.month.toString().padStart(2, '0')
70
+ const year = date.year.toString()
71
+ return `${month} ${day} ${year}`
72
+ }
@@ -19,7 +19,7 @@ export function DatePickerInput(props: DatePickerInputElProps) {
19
19
  <DatePickerParts.Input
20
20
  {...props}
21
21
  maxLength={11}
22
- placeholder={props.placeholder ?? 'DD MMM YYYY'}
22
+ placeholder={props.placeholder ?? 'MM DD YYYY'}
23
23
  />
24
24
  </DatePickerParts.Control>
25
25
  )
@@ -150,7 +150,10 @@ export const DatePickerClearTrigger = withNoRecipe(DatePicker.ClearTrigger)
150
150
  */
151
151
  export type DatePickerPositionerProps =
152
152
  CerberusPrimitiveProps<ArkDatePickerPositionerProps>
153
- export const DatePickerPositioner = withNoRecipe(DatePicker.Positioner)
153
+ export const DatePickerPositioner = withSlotRecipe(
154
+ DatePicker.Positioner,
155
+ 'positioner',
156
+ )
154
157
 
155
158
  /**
156
159
  * The year select input component of the DatePicker. This primitive has no
@@ -21,7 +21,7 @@ export function RangePickerInput(props: RangePickerInputProps) {
21
21
  <DatePickerParts.Input
22
22
  {...props}
23
23
  data-range-input
24
- placeholder={props.placeholder ?? 'DD MMM YYYY'}
24
+ placeholder={props.placeholder ?? 'MM DD YYYY'}
25
25
  maxLength={11}
26
26
  index={0}
27
27
  />
@@ -29,7 +29,7 @@ export function RangePickerInput(props: RangePickerInputProps) {
29
29
  {...props}
30
30
  data-range-input
31
31
  data-range-end-input
32
- placeholder={props.placeholder ?? 'DD MMM YYYY'}
32
+ placeholder={props.placeholder ?? 'MM DD YYYY'}
33
33
  maxLength={11}
34
34
  index={1}
35
35
  />
@@ -6,8 +6,7 @@ import { field } from 'styled-system/recipes'
6
6
  import { useCerberusContext } from '../../context/cerberus'
7
7
  import type { HTMLAttributes, ReactNode } from 'react'
8
8
 
9
- export interface FieldStatusIndicatorProps
10
- extends HTMLAttributes<HTMLSpanElement> {
9
+ export interface FieldStatusIndicatorProps extends HTMLAttributes<HTMLSpanElement> {
11
10
  /**
12
11
  * The fallback content to display when the field is valid.
13
12
  */
@@ -33,9 +32,7 @@ export function FieldStatusIndicator(props: FieldStatusIndicatorProps) {
33
32
  const { icons } = useCerberusContext()
34
33
  const { invalid: InvalidIcon } = icons
35
34
 
36
- if (!fieldContext) return null
37
-
38
- if (fieldContext.invalid) {
35
+ if (fieldContext?.invalid) {
39
36
  return (
40
37
  <span
41
38
  {...nativeProps}
@@ -6,14 +6,16 @@ import {
6
6
  type HTMLAttributes,
7
7
  type MouseEvent,
8
8
  } from 'react'
9
- import { fileStatus, type FileStatusVariantProps } from 'styled-system/recipes'
9
+ import { VStack } from 'styled-system/jsx'
10
10
  import { css, cx } from 'styled-system/css'
11
- import { hstack, vstack } from 'styled-system/patterns'
11
+ import { hstack } from 'styled-system/patterns'
12
+ import { fileStatus, type FileStatusVariantProps } from 'styled-system/recipes'
12
13
  import { useCerberusContext } from '../../context/cerberus'
13
- import { ProgressBar, type ProgressBarProps } from '../progress/index'
14
- import { IconButton } from '../icon-button/index'
15
14
  import { Avatar } from '../avatar/avatar'
16
15
  import { Field, FieldHelperText } from '../field/index'
16
+ import { IconButton } from '../icon-button/index'
17
+ import { ProgressBar, type ProgressBarProps } from '../progress/index'
18
+ import { Text } from '../text/index'
17
19
 
18
20
  /**
19
21
  * This module contains the FileStatus component.
@@ -34,8 +36,10 @@ export type FileStatusKey = (typeof processStatus)[keyof typeof processStatus]
34
36
  * The actions that can be performed on a file.
35
37
  */
36
38
  export type FileStatusActions = 'cancel' | 'retry' | 'delete'
37
- export interface FileBaseStatusProps
38
- extends Omit<HTMLAttributes<HTMLDivElement>, 'onClick'> {
39
+ export interface FileBaseStatusProps extends Omit<
40
+ HTMLAttributes<HTMLDivElement>,
41
+ 'onClick'
42
+ > {
39
43
  /**
40
44
  * A unique identifier for the file status. Required for accessibility.
41
45
  */
@@ -130,21 +134,10 @@ export function FileStatus(props: FileStatusProps) {
130
134
  fallback={<MatchFileStatusIcon size={24} status={status} />}
131
135
  />
132
136
 
133
- <div
134
- className={vstack({
135
- alignItems: 'flex-start',
136
- gap: '0.12rem',
137
- w: 'full',
138
- })}
139
- >
140
- <small
141
- className={css({
142
- color: 'page.text.initial',
143
- textStyle: 'label-sm',
144
- })}
145
- >
137
+ <VStack alignItems="flex-start" gap="0.12rem" w="full">
138
+ <Text as="small" color="page.text.initial" textStyle="label-sm">
146
139
  {file}
147
- </small>
140
+ </Text>
148
141
  <ProgressBar
149
142
  id={props.id}
150
143
  label="File upload status"
@@ -161,7 +154,7 @@ export function FileStatus(props: FileStatusProps) {
161
154
  <MatchFileStatusText status={status} now={now} />
162
155
  </FieldHelperText>
163
156
  </Field>
164
- </div>
157
+ </VStack>
165
158
 
166
159
  <IconButton
167
160
  ariaLabel={actionLabel}
@@ -1,72 +1,60 @@
1
1
  'use client'
2
2
 
3
- import { cx } from 'styled-system/css'
4
- import { vstack } from 'styled-system/patterns'
5
- import { fileUploader } from 'styled-system/recipes'
6
- import { type InputHTMLAttributes } from 'react'
7
- import { Show } from '../show/index'
3
+ import { PropsWithChildren } from 'react'
8
4
  import { useCerberusContext } from '../../context/cerberus'
5
+ import { splitProps } from '../../utils'
6
+ import { Show } from '../show/index'
9
7
  import { Avatar } from '../avatar/avatar'
8
+ import { formatFileTypes } from './utils'
9
+ import { ImgPreview } from './img-preview'
10
+ import { FileUploadParts } from './parts'
11
+ import { FileUploadRootProps } from './primitives'
10
12
 
11
- export interface FileUploaderProps
12
- extends InputHTMLAttributes<HTMLInputElement> {
13
+ export interface FileUploaderProps extends FileUploadRootProps {
13
14
  /**
14
15
  * The optional heading to display in the FileUploader component.
15
16
  */
16
17
  heading?: string
17
18
  /**
18
- * The name of the file input element.
19
- */
20
- name: string
21
- /**
22
- * Disable the FileUploader component. Good for single-use file uploads.
19
+ * Show a preview of the uploaded image.
23
20
  */
24
- disabled?: boolean
21
+ showPreview?: boolean
25
22
  }
26
23
 
27
24
  /**
28
25
  * A component that allows the user to upload files.
29
- * @see https://cerberus.digitalu.design/react/file-uploader
26
+ * @see https://cerberus.digitalu.design/docs/components/file-uploader
30
27
  */
31
- export function FileUploader(props: FileUploaderProps) {
28
+ export function FileUploader(props: PropsWithChildren<FileUploaderProps>) {
29
+ const [elProps, rootProps] = splitProps(props, ['heading', 'showPreview'])
30
+ const { showPreview = true } = elProps
31
+
32
32
  const { icons } = useCerberusContext()
33
- const styles = fileUploader()
34
33
  const { waitingFileUploader: Icon } = icons
35
34
 
36
35
  return (
37
- <div
38
- {...(props.disabled ? { 'aria-disabled': true } : {})}
39
- className={cx(
40
- vstack({
41
- justify: 'center',
42
- }),
43
- styles.container,
44
- )}
45
- >
46
- <div className={styles.icon}>
47
- <Avatar gradient="charon-light" fallback={<Icon />} />
48
- </div>
36
+ <FileUploadParts.Root {...rootProps}>
37
+ <FileUploadParts.Dropzone>
38
+ <FileUploadParts.Icon>
39
+ <Avatar gradient="charon-light" fallback={<Icon />} />
40
+ </FileUploadParts.Icon>
41
+
42
+ <FileUploadParts.Label>
43
+ <Show when={elProps.heading}>
44
+ <FileUploadParts.Heading>{elProps.heading}</FileUploadParts.Heading>
45
+ </Show>
46
+ Import {formatFileTypes(rootProps.accept)} files
47
+ <FileUploadParts.Description>
48
+ Drag and drop files or click to upload
49
+ </FileUploadParts.Description>
50
+ </FileUploadParts.Label>
51
+ </FileUploadParts.Dropzone>
52
+
53
+ <Show when={showPreview} fallback={<>{props.children}</>}>
54
+ {() => <ImgPreview />}
55
+ </Show>
49
56
 
50
- <label
51
- className={cx(
52
- vstack({
53
- justify: 'center',
54
- }),
55
- styles.label,
56
- )}
57
- htmlFor={props.name}
58
- >
59
- <Show when={props.heading}>
60
- <p className={styles.heading}>{props.heading}</p>
61
- </Show>
62
- Import {props.accept?.replace(',', ', ')} files
63
- <p className={styles.description}>Click to select files</p>
64
- <input
65
- {...props}
66
- className={cx(props.className, styles.input)}
67
- type="file"
68
- />
69
- </label>
70
- </div>
57
+ <FileUploadParts.HiddenInput />
58
+ </FileUploadParts.Root>
71
59
  )
72
60
  }
@@ -0,0 +1,28 @@
1
+ import { FileUploadFileError } from '@ark-ui/react/file-upload'
2
+
3
+ type FileErrorTypes = {
4
+ tooMany?: string
5
+ invalidType?: string
6
+ tooLarge?: string
7
+ tooSmall?: string
8
+ invalid?: string
9
+ exists?: string
10
+ }
11
+
12
+ /**
13
+ * Helper function to create error messages for file upload errors. Returns a
14
+ * record of FileUploadFileError codes and their corresponding error messages.
15
+ * @returns Record<FileUploadFileError, string>
16
+ */
17
+ export function createErrorMessages(
18
+ options: FileErrorTypes,
19
+ ): Record<FileUploadFileError, string> {
20
+ return {
21
+ TOO_MANY_FILES: options.tooMany || '📊 Too many files selected',
22
+ FILE_INVALID_TYPE: options.invalidType || '🚫 Invalid file type',
23
+ FILE_TOO_LARGE: options.tooLarge || '📏 File too large',
24
+ FILE_TOO_SMALL: options.tooSmall || '📐 File too small',
25
+ FILE_INVALID: options.invalid || '⚠️ Invalid file',
26
+ FILE_EXISTS: options.exists || '🔄 File already exists',
27
+ }
28
+ }
@@ -0,0 +1,41 @@
1
+ 'use client'
2
+
3
+ import { UseFileUploadContext } from '@ark-ui/react/file-upload'
4
+ import { useCerberusContext } from '../../context/cerberus'
5
+ import { IconButton } from '../icon-button/index'
6
+ import { FileUploadParts } from './parts'
7
+ import { FileUploadContextProps } from './primitives'
8
+
9
+ export function ImgPreview(props: Omit<FileUploadContextProps, 'children'>) {
10
+ const { icons } = useCerberusContext()
11
+ const { close: Icon } = icons
12
+
13
+ return (
14
+ <FileUploadParts.ItemGroup>
15
+ <FileUploadParts.Context {...props}>
16
+ {(ctx: UseFileUploadContext) =>
17
+ ctx.acceptedFiles.map((file) => (
18
+ <FileUploadParts.Item
19
+ key={file.name}
20
+ file={file}
21
+ className="file-item"
22
+ >
23
+ <FileUploadParts.ItemPreview type="image/*">
24
+ <FileUploadParts.ItemPreviewImage />
25
+ </FileUploadParts.ItemPreview>
26
+
27
+ <FileUploadParts.ItemName />
28
+ <FileUploadParts.ItemSizeText />
29
+
30
+ <FileUploadParts.ItemDeleteTrigger asChild>
31
+ <IconButton clipboard size="sm" usage="ghost">
32
+ <Icon />
33
+ </IconButton>
34
+ </FileUploadParts.ItemDeleteTrigger>
35
+ </FileUploadParts.Item>
36
+ ))
37
+ }
38
+ </FileUploadParts.Context>
39
+ </FileUploadParts.ItemGroup>
40
+ )
41
+ }
@@ -1,2 +1,6 @@
1
+ export * from './primitives'
2
+ export * from './parts'
1
3
  export * from './file-status'
2
4
  export * from './file-uploader'
5
+ export * from './img-preview'
6
+ export * from './helpers'
@@ -0,0 +1,126 @@
1
+ import type { ElementType } from 'react'
2
+ import {
3
+ FileUploadContext,
4
+ FileUploadRoot,
5
+ FileUploadDropzone,
6
+ FileUploadLabel,
7
+ FileUploadTrigger,
8
+ FileUploadClearTrigger,
9
+ FileUploadItemGroup,
10
+ FileUploadItem,
11
+ FileUploadItemPreview,
12
+ FileUploadItemPreviewImage,
13
+ FileUploadItemName,
14
+ FileUploadItemSizeText,
15
+ FileUploadItemDeleteTrigger,
16
+ FileUploadIcon,
17
+ FileUploadHiddenInput,
18
+ FileUploadHeading,
19
+ FileUploadDescription,
20
+ } from './primitives'
21
+
22
+ /**
23
+ * This module contains the parts of the FileUploadParts component.
24
+ * @module 'fileUpload/parts'
25
+ */
26
+
27
+ interface FileUploadPartsValue {
28
+ /**
29
+ * The container of the uploader.
30
+ */
31
+ Root: ElementType
32
+ /**
33
+ * The label of the uploader.
34
+ */
35
+ Label: ElementType
36
+ /**
37
+ * The dropzone of the uploader.
38
+ */
39
+ Dropzone: ElementType
40
+ /**
41
+ * The trigger of the uploader.
42
+ */
43
+ Trigger: ElementType
44
+ /**
45
+ * The clear trigger of the uploader.
46
+ */
47
+ ClearTrigger: ElementType
48
+ /**
49
+ * The item group of the uploader.
50
+ */
51
+ ItemGroup: ElementType
52
+ /**
53
+ * The item of the uploader.
54
+ */
55
+ Item: ElementType
56
+ /**
57
+ * The item preview of the uploader.
58
+ */
59
+ ItemPreview: ElementType
60
+ /**
61
+ * The item preview image of the uploader.
62
+ */
63
+ ItemPreviewImage: ElementType
64
+ /**
65
+ * The item name of the uploader.
66
+ */
67
+ ItemName: ElementType
68
+ /**
69
+ * The item size text of the uploader.
70
+ */
71
+ ItemSizeText: ElementType
72
+ /**
73
+ * The item delete trigger of the uploader.
74
+ */
75
+ ItemDeleteTrigger: ElementType
76
+ /**
77
+ * The hidden input of the uploader.
78
+ */
79
+ HiddenInput: ElementType
80
+ /**
81
+ * The context of the uploader.
82
+ */
83
+ Context: ElementType
84
+ /**
85
+ * The icon of the uploader.
86
+ */
87
+ Icon: ElementType
88
+ /**
89
+ * The heading of the uploader.
90
+ */
91
+ Heading: ElementType
92
+ /**
93
+ * The description of the uploader.
94
+ */
95
+ Description: ElementType
96
+ }
97
+
98
+ /**
99
+ * An Object containing the parts of the FileUploader component. For users that
100
+ * prefer Object component syntax.
101
+ *
102
+ * @remarks
103
+ *
104
+ * When using object component syntax, you import the uploaderParts object and
105
+ * the entire family of components vs. only what you use.
106
+ */
107
+ export const FileUploadParts: FileUploadPartsValue = {
108
+ Context: FileUploadContext,
109
+ Root: FileUploadRoot,
110
+ Label: FileUploadLabel,
111
+ Dropzone: FileUploadDropzone,
112
+ Trigger: FileUploadTrigger,
113
+ ClearTrigger: FileUploadClearTrigger,
114
+ ItemGroup: FileUploadItemGroup,
115
+ Item: FileUploadItem,
116
+ ItemPreview: FileUploadItemPreview,
117
+ ItemPreviewImage: FileUploadItemPreviewImage,
118
+ ItemName: FileUploadItemName,
119
+ ItemSizeText: FileUploadItemSizeText,
120
+ ItemDeleteTrigger: FileUploadItemDeleteTrigger,
121
+ HiddenInput: FileUploadHiddenInput,
122
+ // custom cerby primitives
123
+ Icon: FileUploadIcon,
124
+ Heading: FileUploadHeading,
125
+ Description: FileUploadDescription,
126
+ }