@codeleap/web 3.24.3 → 4.0.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 (150) hide show
  1. package/package.json +2 -1
  2. package/src/components/ActionIcon/index.tsx +51 -52
  3. package/src/components/ActionIcon/styles.ts +1 -5
  4. package/src/components/ActionIcon/types.ts +15 -0
  5. package/src/components/ActivityIndicator/index.tsx +34 -55
  6. package/src/components/ActivityIndicator/styles.ts +0 -6
  7. package/src/components/ActivityIndicator/types.ts +12 -0
  8. package/src/components/Badge/index.tsx +43 -80
  9. package/src/components/Badge/styles.ts +1 -11
  10. package/src/components/Badge/types.ts +28 -0
  11. package/src/components/Button/index.tsx +46 -89
  12. package/src/components/Button/styles.ts +0 -5
  13. package/src/components/Button/types.ts +25 -0
  14. package/src/components/Checkbox/index.tsx +83 -97
  15. package/src/components/Checkbox/styles.ts +1 -5
  16. package/src/components/Checkbox/types.ts +15 -0
  17. package/src/components/Collapse/index.tsx +41 -83
  18. package/src/components/Collapse/styles.ts +3 -6
  19. package/src/components/Collapse/types.ts +11 -0
  20. package/src/components/ColorPicker/index.tsx +95 -48
  21. package/src/components/ColorPicker/styles.ts +11 -11
  22. package/src/components/ColorPicker/types.ts +26 -12
  23. package/src/components/CropPicker/index.tsx +100 -104
  24. package/src/components/CropPicker/styles.ts +0 -7
  25. package/src/components/CropPicker/types.ts +8 -15
  26. package/src/components/DatePicker/{defaultComponents → components}/Header.tsx +9 -17
  27. package/src/components/DatePicker/{defaultComponents → components}/OuterInput.tsx +6 -7
  28. package/src/components/DatePicker/index.tsx +110 -124
  29. package/src/components/DatePicker/styles.ts +1 -12
  30. package/src/components/DatePicker/types.ts +16 -33
  31. package/src/components/Drawer/index.tsx +133 -125
  32. package/src/components/Drawer/styles.ts +0 -5
  33. package/src/components/Drawer/types.ts +23 -0
  34. package/src/components/Dropzone/index.tsx +87 -63
  35. package/src/components/Dropzone/styles.ts +0 -6
  36. package/src/components/Dropzone/types.ts +29 -37
  37. package/src/components/EmptyPlaceholder/index.tsx +63 -83
  38. package/src/components/EmptyPlaceholder/styles.ts +0 -5
  39. package/src/components/EmptyPlaceholder/types.ts +32 -0
  40. package/src/components/FileInput/index.tsx +72 -0
  41. package/src/components/FileInput/types.ts +14 -0
  42. package/src/components/Grid/index.tsx +40 -41
  43. package/src/components/Grid/styles.ts +2 -9
  44. package/src/components/Grid/types.ts +10 -12
  45. package/src/components/Icon/index.tsx +45 -47
  46. package/src/components/Icon/styles.ts +0 -8
  47. package/src/components/Icon/types.ts +15 -0
  48. package/src/components/InputBase/index.tsx +71 -42
  49. package/src/components/InputBase/styles.ts +37 -47
  50. package/src/components/InputBase/types.ts +19 -7
  51. package/src/components/InputBase/utils.ts +3 -23
  52. package/src/components/List/ListLayout.tsx +20 -37
  53. package/src/components/List/index.tsx +36 -41
  54. package/src/components/List/styles.ts +5 -11
  55. package/src/components/List/types.ts +30 -20
  56. package/src/components/LoadingOverlay/index.tsx +31 -33
  57. package/src/components/LoadingOverlay/styles.ts +3 -8
  58. package/src/components/LoadingOverlay/types.ts +16 -0
  59. package/src/components/Modal/index.tsx +98 -160
  60. package/src/components/Modal/styles.ts +0 -5
  61. package/src/components/Modal/types.ts +55 -0
  62. package/src/components/NumberIncrement/index.tsx +67 -98
  63. package/src/components/NumberIncrement/styles.ts +0 -5
  64. package/src/components/NumberIncrement/types.ts +29 -0
  65. package/src/components/Overlay/index.tsx +37 -35
  66. package/src/components/Overlay/styles.ts +3 -5
  67. package/src/components/Overlay/types.ts +13 -0
  68. package/src/components/Pager/index.tsx +65 -81
  69. package/src/components/Pager/styles.ts +3 -9
  70. package/src/components/Pager/types.ts +35 -0
  71. package/src/components/PaginationButtons/index.tsx +173 -0
  72. package/src/components/PaginationButtons/styles.ts +7 -0
  73. package/src/components/PaginationButtons/types.ts +26 -0
  74. package/src/components/PaginationIndicator/index.tsx +69 -0
  75. package/src/components/PaginationIndicator/styles.ts +3 -0
  76. package/src/components/PaginationIndicator/types.ts +18 -0
  77. package/src/components/Progress/Bar/index.tsx +45 -50
  78. package/src/components/Progress/Bar/styles.ts +10 -0
  79. package/src/components/Progress/Bar/types.ts +26 -0
  80. package/src/components/Progress/Circle/index.tsx +45 -48
  81. package/src/components/Progress/Circle/styles.ts +1 -8
  82. package/src/components/Progress/Circle/types.ts +10 -22
  83. package/src/components/RadioInput/index.tsx +78 -124
  84. package/src/components/RadioInput/styles.ts +0 -6
  85. package/src/components/RadioInput/types.ts +29 -0
  86. package/src/components/SearchInput/index.tsx +10 -10
  87. package/src/components/SectionFilters/index.tsx +47 -36
  88. package/src/components/SectionFilters/styles.ts +1 -5
  89. package/src/components/SectionFilters/types.ts +14 -13
  90. package/src/components/SegmentedControl/index.tsx +111 -89
  91. package/src/components/SegmentedControl/styles.ts +7 -21
  92. package/src/components/SegmentedControl/types.ts +44 -0
  93. package/src/components/Select/index.tsx +92 -56
  94. package/src/components/Select/styles.ts +19 -36
  95. package/src/components/Select/types.ts +15 -10
  96. package/src/components/Slider/index.tsx +85 -93
  97. package/src/components/Slider/styles.ts +13 -6
  98. package/src/components/Slider/types.ts +29 -0
  99. package/src/components/Switch/index.tsx +63 -74
  100. package/src/components/Switch/styles.ts +1 -6
  101. package/src/components/Switch/types.ts +13 -0
  102. package/src/components/Tag/index.tsx +39 -44
  103. package/src/components/Tag/styles.ts +1 -9
  104. package/src/components/Tag/types.ts +10 -10
  105. package/src/components/Text/index.tsx +37 -48
  106. package/src/components/Text/styles.ts +0 -8
  107. package/src/components/Text/types.ts +8 -8
  108. package/src/components/TextEditor/index.tsx +49 -28
  109. package/src/components/TextEditor/styles.ts +1 -8
  110. package/src/components/TextEditor/types.ts +11 -6
  111. package/src/components/TextInput/index.tsx +58 -96
  112. package/src/components/TextInput/mask.tsx +2 -50
  113. package/src/components/TextInput/styles.ts +3 -8
  114. package/src/components/TextInput/types.ts +85 -0
  115. package/src/components/Tooltip/index.tsx +61 -84
  116. package/src/components/Tooltip/styles.ts +3 -10
  117. package/src/components/Tooltip/types.ts +46 -0
  118. package/src/components/Touchable/index.tsx +43 -86
  119. package/src/components/Touchable/styles.ts +0 -6
  120. package/src/components/Touchable/types.ts +22 -0
  121. package/src/components/View/index.tsx +36 -50
  122. package/src/components/View/styles.ts +0 -6
  123. package/src/components/View/types.ts +14 -15
  124. package/src/components/components.ts +2 -3
  125. package/src/index.ts +1 -0
  126. package/src/lib/WebStyleRegistry.ts +51 -0
  127. package/src/lib/hooks/index.ts +5 -0
  128. package/src/lib/hooks/useBreakpointMatch.ts +8 -7
  129. package/src/{components/CropPicker/useCropPicker.tsx → lib/hooks/useCropPicker.ts} +66 -13
  130. package/src/lib/hooks/useFileInput.ts +15 -0
  131. package/src/lib/hooks/useInfiniteScroll.ts +77 -0
  132. package/src/lib/hooks/useMediaQuery.ts +4 -3
  133. package/src/lib/hooks/usePagination.ts +79 -63
  134. package/src/lib/hooks/useRefresh.ts +87 -0
  135. package/src/lib/hooks/useStylesFor.ts +13 -0
  136. package/src/lib/index.ts +1 -0
  137. package/src/lib/utils/cache.ts +9 -0
  138. package/src/lib/utils/index.ts +1 -0
  139. package/src/lib/utils/test.ts +2 -2
  140. package/src/components/CropPicker/utils.ts +0 -51
  141. package/src/components/FileInput.tsx +0 -91
  142. package/src/components/List/PaginationIndicator.tsx +0 -102
  143. package/src/components/List/useInfiniteScroll.ts +0 -159
  144. package/src/components/Progress/Bar/styles.tsx +0 -7
  145. package/src/components/Progress/Bar/types.tsx +0 -30
  146. package/src/components/Scroll/index.tsx +0 -32
  147. package/src/components/Scroll/styles.ts +0 -8
  148. package/src/components/SegmentedControl/SegmentedControlOption.tsx +0 -84
  149. package/src/components/defaultStyles.ts +0 -79
  150. /package/src/components/DatePicker/{defaultComponents → components}/index.tsx +0 -0
@@ -1,27 +1,18 @@
1
- import {
2
- ComponentVariants,
3
- IconPlaceholder,
4
- PropsOf,
5
- StylesOf,
6
- } from '@codeleap/common'
7
- import { DropzoneComposition, DropzonePresets } from './styles'
8
- import { View } from '../View'
9
- import {
10
- DropzoneOptions,
11
- FileRejection,
12
- DropzoneRef as ReactDropzoneRef,
13
- } from 'react-dropzone'
1
+ import { StylesOf } from '@codeleap/common'
2
+ import { DropzoneComposition } from './styles'
3
+ import { DropzoneOptions, FileRejection, DropzoneRef as ReactDropzoneRef } from 'react-dropzone'
14
4
  import { ActionIconComposition } from '../ActionIcon'
5
+ import { AppIcon, StyledProp } from '@codeleap/styles'
15
6
 
16
7
  export type DropzoneFile = File
17
8
 
18
9
  export type DropzoneFileRejection = FileRejection
19
10
 
20
- export type DropzoneProps = ComponentVariants<typeof DropzonePresets> &
21
- DropzoneOptions & {
22
- styles?: StylesOf<DropzoneComposition>
23
- style?: PropsOf<typeof View>['style']
24
- icon?: IconPlaceholder
11
+ export type DropzoneProps =
12
+ Omit<DropzoneOptions, 'style'> &
13
+ {
14
+ style?: StyledProp<DropzoneComposition>
15
+ icon?: AppIcon
25
16
  placeholder?: string
26
17
  acceptedFiles: File[]
27
18
  rejectedFiles?: DropzoneFileRejection[]
@@ -29,30 +20,31 @@ export type DropzoneProps = ComponentVariants<typeof DropzonePresets> &
29
20
  setRejectedFiles?: React.Dispatch<React.SetStateAction<DropzoneFileRejection[]>>
30
21
  onRemove?: (file: DropzoneFile) => void
31
22
  children?: React.ReactNode
32
- fileRightIcon?: IconPlaceholder
33
- fileLeftIcon?: IconPlaceholder
23
+ fileRightIcon?: AppIcon
24
+ fileLeftIcon?: AppIcon
34
25
  withImagePreview?: boolean
35
26
  FilePreviewComponent?: (props: DropzoneInnerFilePreviewProps) => JSX.Element
36
27
  }
37
28
 
38
- export type DropzoneFilePreviewProps = Pick<
39
- DropzoneProps,
40
- 'fileRightIcon' | 'fileLeftIcon' | 'withImagePreview' | 'FilePreviewComponent'
41
- > & {
42
- file: DropzoneFile
43
- errors?: DropzoneFileRejection['errors']
44
- variantStyles: StylesOf<DropzoneComposition>
45
- onRemove?: () => void
46
- fileRightIconStyles?: StylesOf<ActionIconComposition>
47
- index?: number
48
- }
29
+ export type DropzoneFilePreviewProps =
30
+ Pick<DropzoneProps, 'fileRightIcon' | 'fileLeftIcon' | 'withImagePreview' | 'FilePreviewComponent'> &
31
+ {
32
+ file: DropzoneFile
33
+ errors?: DropzoneFileRejection['errors']
34
+ styles: StylesOf<DropzoneComposition>
35
+ onRemove?: () => void
36
+ fileRightIconStyles?: StylesOf<ActionIconComposition>
37
+ index?: number
38
+ }
49
39
 
50
- export type DropzoneInnerFilePreviewProps = DropzoneFilePreviewProps & {
51
- hasErrors: boolean
52
- revokeImageUrl: () => void
53
- imageUrl: string
54
- isPreview: boolean
55
- }
40
+ export type DropzoneInnerFilePreviewProps =
41
+ DropzoneFilePreviewProps &
42
+ {
43
+ hasErrors: boolean
44
+ revokeImageUrl: () => void
45
+ imageUrl: string
46
+ isPreview: boolean
47
+ }
56
48
 
57
49
  export type DropzoneRef = ReactDropzoneRef & {
58
50
  clear: () => void
@@ -2,131 +2,111 @@ import React from 'react'
2
2
  import { Icon } from '../Icon'
3
3
  import { View } from '../View'
4
4
  import { Text } from '../Text'
5
- import { ActivityIndicator, ActivityIndicatorComposition, ActivityIndicatorProps } from '../ActivityIndicator'
6
- import { EmptyPlaceholderComposition, EmptyPlaceholderPresets } from './styles'
7
- import {
8
- ComponentVariants,
9
- getNestedStylesByKey,
10
- IconPlaceholder,
11
- StylesOf,
12
- TypeGuards,
13
- useDefaultComponentStyle,
14
- } from '@codeleap/common'
15
- import { ComponentCommonProps } from '../../types'
5
+ import { ActivityIndicator } from '../ActivityIndicator'
6
+ import { TypeGuards } from '@codeleap/common'
7
+ import { EmptyPlaceholderProps } from './types'
8
+ import { useStylesFor } from '../../lib/hooks/useStylesFor'
9
+ import { WebStyleRegistry } from '../../lib/WebStyleRegistry'
10
+ import { AnyRecord, AppIcon, IJSX, StyledComponentProps, useNestedStylesByKey } from '@codeleap/styles'
16
11
 
17
12
  export * from './styles'
18
-
19
- type RenderEmptyProps = {
20
- emptyText: string | React.ReactElement
21
- emptyIconName?: IconPlaceholder
22
- styles: StylesOf<EmptyPlaceholderComposition> & {
23
- activityIndicatorStyles: StylesOf<ActivityIndicatorComposition>
24
- }
25
- }
26
-
27
- export type EmptyPlaceholderProps = ComponentVariants<typeof EmptyPlaceholderPresets> & {
28
- itemName?: string
29
- title?: React.ReactElement | string
30
- description?: React.ReactElement | string
31
- icon?: IconPlaceholder | ((props: EmptyPlaceholderProps) => JSX.Element) | null
32
- loading?: boolean
33
- styles?: StylesOf<EmptyPlaceholderComposition>
34
- style?: React.CSSProperties
35
- renderEmpty?: (props: RenderEmptyProps) => JSX.Element
36
- wrapperProps?: Partial<typeof View>
37
- imageWrapperProps?: Partial<typeof View>
38
- indicatorProps?: Partial<ActivityIndicatorProps>
39
- } & ComponentCommonProps
40
-
41
- const defaultProps: Partial<EmptyPlaceholderProps> = {}
13
+ export * from './types'
42
14
 
43
15
  export const EmptyPlaceholder = (props: EmptyPlaceholderProps) => {
44
- const allProps = {
45
- ...EmptyPlaceholder.defaultProps,
46
- ...props,
47
- }
48
-
49
16
  const {
50
17
  itemName,
51
18
  title,
52
19
  loading,
53
20
  description,
54
- styles = {},
55
21
  style,
56
- variants = [],
57
- responsiveVariants = {},
58
- icon: IconEmpty = null,
59
- renderEmpty: RenderEmpty = null,
60
- wrapperProps = {},
61
- imageWrapperProps = {},
62
- indicatorProps = {},
22
+ icon: IconEmpty,
23
+ renderEmpty: RenderEmpty,
24
+ image,
25
+ imageProps,
26
+ wrapperProps,
27
+ imageWrapperProps,
28
+ indicatorProps,
63
29
  debugName,
64
- } = allProps
65
-
66
- const emptyText = title || (itemName && `No ${itemName} found.`) || 'No items.'
30
+ } = {
31
+ ...EmptyPlaceholder.defaultProps,
32
+ ...props,
33
+ }
67
34
 
68
- const variantStyles = useDefaultComponentStyle<'u:EmptyPlaceholder', typeof EmptyPlaceholderPresets>('u:EmptyPlaceholder', {
69
- variants,
70
- responsiveVariants,
71
- styles,
72
- })
35
+ const styles = useStylesFor(EmptyPlaceholder.styleRegistryName, style)
73
36
 
74
- const activityIndicatorStyles = React.useMemo(() => {
75
- return getNestedStylesByKey('loader', variantStyles)
76
- }, [variantStyles])
37
+ const emptyText = title || (itemName && `No ${itemName} found.`) || 'No items.'
38
+
39
+ const activityIndicatorStyles = useNestedStylesByKey('loader', styles)
77
40
 
78
41
  const _Image = React.useMemo(() => {
42
+ if (TypeGuards.isString(image)) {
43
+ return <img
44
+ {...imageProps}
45
+ src={image as HTMLImageElement['src']}
46
+ // @ts-expect-error
47
+ css={styles.image}
48
+ />
49
+ }
50
+
79
51
  if (TypeGuards.isNil(IconEmpty)) return null
80
52
 
81
53
  if (TypeGuards.isString(IconEmpty)) {
82
- return <Icon debugName={debugName} name={IconEmpty as IconPlaceholder} forceStyle={variantStyles.icon} />
54
+ return <Icon debugName={debugName} name={IconEmpty as AppIcon} forceStyle={styles.icon} />
83
55
  } else if (React.isValidElement(IconEmpty)) {
84
56
  return <IconEmpty {...props} />
85
57
  }
86
- }, [IconEmpty])
58
+ }, [IconEmpty, image])
87
59
 
88
60
  if (loading) {
89
61
  return (
90
- <View css={[variantStyles.wrapper, variantStyles['wrapper:loading']]}>
91
- <ActivityIndicator debugName={debugName} {...indicatorProps} styles={activityIndicatorStyles}/>
62
+ <View style={[styles.wrapper, styles['wrapper:loading']]}>
63
+ <ActivityIndicator debugName={debugName} {...indicatorProps} style={activityIndicatorStyles} />
92
64
  </View>
93
65
  )
94
66
  }
95
67
 
96
68
  if (!TypeGuards.isNil(RenderEmpty)) {
97
- const _emptyProps = {
98
- emptyText,
99
- emptyIconName: IconEmpty as IconPlaceholder,
100
- styles: {
101
- ...variantStyles,
102
- activityIndicatorStyles,
103
- },
104
- }
105
-
106
69
  return (
107
- <View {...wrapperProps} css={[variantStyles.wrapper, style]}>
108
- <RenderEmpty {..._emptyProps}/>
70
+ <View {...wrapperProps} style={styles.wrapper}>
71
+ <RenderEmpty
72
+ emptyText={emptyText}
73
+ emptyIconName={IconEmpty as AppIcon}
74
+ styles={{
75
+ ...styles,
76
+ activityIndicatorStyles,
77
+ }}
78
+ />
109
79
  </View>
110
80
  )
111
81
  }
112
-
82
+
113
83
  return (
114
- <View {...wrapperProps} css={[variantStyles.wrapper, style]}>
115
- <View {...imageWrapperProps} css={variantStyles.imageWrapper}>
84
+ <View {...wrapperProps} style={styles.wrapper}>
85
+ <View {...imageWrapperProps} style={styles.imageWrapper}>
116
86
  {_Image}
117
87
  </View>
118
88
 
119
- {TypeGuards.isString(emptyText)
120
- ? <Text debugName={debugName} text={emptyText} css={variantStyles.title}/>
89
+ {TypeGuards.isString(emptyText)
90
+ ? <Text debugName={debugName} text={emptyText} style={styles.title} />
121
91
  : React.isValidElement(emptyText) ? emptyText : null
122
92
  }
123
-
124
- {TypeGuards.isString(description)
125
- ? <Text debugName={debugName} text={description} css={variantStyles.description}/>
93
+
94
+ {TypeGuards.isString(description)
95
+ ? <Text debugName={debugName} text={description} style={styles.description} />
126
96
  : React.isValidElement(description) ? description : null
127
97
  }
128
98
  </View>
129
99
  )
130
100
  }
131
101
 
132
- EmptyPlaceholder.defaultProps = defaultProps
102
+ EmptyPlaceholder.styleRegistryName = 'EmptyPlaceholder'
103
+ EmptyPlaceholder.elements = ['wrapper', 'loader', 'title', 'description', 'image', 'imageWrapper', 'icon']
104
+ EmptyPlaceholder.rootElement = 'wrapper'
105
+
106
+ EmptyPlaceholder.withVariantTypes = <S extends AnyRecord>(styles: S) => {
107
+ return EmptyPlaceholder as (props: StyledComponentProps<EmptyPlaceholderProps, typeof styles>) => IJSX
108
+ }
109
+
110
+ EmptyPlaceholder.defaultProps = {} as Partial<EmptyPlaceholderProps>
111
+
112
+ WebStyleRegistry.registerComponent(EmptyPlaceholder)
@@ -1,4 +1,3 @@
1
- import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
2
1
  import { ActivityIndicatorComposition } from '../ActivityIndicator'
3
2
 
4
3
  export type EmptyPlaceholderComposition =
@@ -10,7 +9,3 @@ export type EmptyPlaceholderComposition =
10
9
  | 'image'
11
10
  | 'imageWrapper'
12
11
  | 'icon'
13
-
14
- const createEmptyPlaceholderStyle = createDefaultVariantFactory<EmptyPlaceholderComposition>()
15
-
16
- export const EmptyPlaceholderPresets = includePresets((styles) => createEmptyPlaceholderStyle(() => ({ wrapper: styles })))
@@ -0,0 +1,32 @@
1
+ import React, { ImgHTMLAttributes } from 'react'
2
+ import { ViewProps } from '../View'
3
+ import { ActivityIndicatorComposition, ActivityIndicatorProps } from '../ActivityIndicator'
4
+ import { EmptyPlaceholderComposition } from './styles'
5
+ import { StylesOf } from '@codeleap/common'
6
+ import { ComponentCommonProps } from '../../types'
7
+ import { AppIcon, StyledProp } from '@codeleap/styles'
8
+
9
+ type RenderEmptyProps = {
10
+ emptyText: string | React.ReactElement
11
+ emptyIconName?: AppIcon
12
+ styles: StylesOf<EmptyPlaceholderComposition> & {
13
+ activityIndicatorStyles: StylesOf<ActivityIndicatorComposition>
14
+ }
15
+ }
16
+
17
+ export type EmptyPlaceholderProps =
18
+ ComponentCommonProps &
19
+ {
20
+ itemName?: string
21
+ title?: React.ReactElement | string
22
+ description?: React.ReactElement | string
23
+ icon?: AppIcon | ((props: EmptyPlaceholderProps) => JSX.Element)
24
+ image?: string
25
+ imageProps?: ImgHTMLAttributes<HTMLImageElement>
26
+ loading?: boolean
27
+ style?: StyledProp<EmptyPlaceholderComposition>
28
+ renderEmpty?: (props: RenderEmptyProps) => JSX.Element
29
+ wrapperProps?: ViewProps
30
+ imageWrapperProps?: ViewProps
31
+ indicatorProps?: Partial<ActivityIndicatorProps>
32
+ }
@@ -0,0 +1,72 @@
1
+ import React, { forwardRef, useImperativeHandle, useRef } from 'react'
2
+ import { WebInputFile, useCallback, TypeGuards } from '@codeleap/common'
3
+ import { FileInputProps, FileInputRef } from './types'
4
+
5
+ export * from './types'
6
+
7
+ export const FileInput = forwardRef<FileInputRef, FileInputProps>((props, ref) => {
8
+ const inputRef = useRef<HTMLInputElement>(null)
9
+
10
+ const {
11
+ onFileSelect,
12
+ autoClear,
13
+ onChange,
14
+ ...inputProps
15
+ } = {
16
+ ...FileInput.defaultProps,
17
+ ...props,
18
+ }
19
+
20
+ const resolveWithFile = useRef<(file: WebInputFile[]) => any>()
21
+
22
+ const clearInput = useCallback(() => {
23
+ if (!inputRef.current) return
24
+ inputRef.current.value = null
25
+ }, [])
26
+
27
+ useImperativeHandle(ref, () => ({
28
+ openFilePicker: () => {
29
+ inputRef.current.click()
30
+
31
+ return new Promise<WebInputFile[]>((resolve) => {
32
+ resolveWithFile.current = resolve
33
+ })
34
+ },
35
+ clear: clearInput,
36
+ }))
37
+
38
+ async function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
39
+ if (!e.target.files.length) return
40
+ if (TypeGuards.isFunction(onChange)) onChange(e)
41
+
42
+ const fileArray = Array.from(e.target?.files || []) as File[]
43
+
44
+ const files: WebInputFile[] = fileArray.map((obj) => ({
45
+ file: obj,
46
+ preview: URL.createObjectURL(obj),
47
+ }))
48
+
49
+ onFileSelect && onFileSelect(files)
50
+
51
+ if (resolveWithFile.current) {
52
+ await resolveWithFile.current(files)
53
+ resolveWithFile.current = undefined
54
+ }
55
+
56
+ if (autoClear) clearInput()
57
+ }
58
+
59
+ return (
60
+ <input
61
+ type={'file'}
62
+ style={{ visibility: 'hidden', width: 0, height: 0, opacity: 0, display: 'none' }}
63
+ {...inputProps}
64
+ ref={inputRef}
65
+ onChange={handleChange}
66
+ />
67
+ )
68
+ })
69
+
70
+ FileInput.defaultProps = {
71
+ autoClear: true,
72
+ } as Partial<FileInputProps>
@@ -0,0 +1,14 @@
1
+ import { WebInputFile } from '@codeleap/common'
2
+ import { HTMLProps } from '../../types'
3
+
4
+ export type FileInputRef = {
5
+ openFilePicker: () => Promise<WebInputFile[]>
6
+ clear: () => void
7
+ }
8
+
9
+ export type FileInputProps =
10
+ Omit<HTMLProps<'input'>, 'type' | 'ref'> &
11
+ {
12
+ onFileSelect?: (files: WebInputFile[]) => void
13
+ autoClear?: boolean
14
+ }
@@ -1,49 +1,28 @@
1
1
  import React from 'react'
2
- import { useDefaultComponentStyle } from '@codeleap/common'
3
2
  import { View, ViewProps } from '../View'
4
3
  import { EmptyPlaceholder } from '../EmptyPlaceholder'
5
- import { GridPresets } from './styles'
6
4
  import { GridProps } from './types'
7
- import { ListLayout, useInfiniteScroll } from '../List'
8
- import { ItemMasonryProps, ListMasonry, useMasonryReload } from '../../lib'
5
+ import { ListItem, ListLayout } from '../List'
6
+ import { ItemMasonryProps, ListMasonry, useInfiniteScroll, useMasonryReload } from '../../lib'
7
+ import { useStylesFor } from '../../lib/hooks/useStylesFor'
8
+ import { AnyRecord, IJSX, StyledComponentProps } from '@codeleap/styles'
9
+ import { WebStyleRegistry } from '../../lib/WebStyleRegistry'
9
10
 
10
11
  export * from './styles'
11
12
  export * from './types'
12
13
 
13
- const RenderSeparator = (props: { separatorStyles: ViewProps<'div'>['css'] }) => {
14
- return (
15
- <View css={[props?.separatorStyles]}></View>
16
- )
14
+ const RenderSeparator = (props: { separatorStyles: ViewProps['style'] }) => {
15
+ return <View style={props?.separatorStyles} />
17
16
  }
18
17
 
19
- const defaultProps: Partial<GridProps> = {
20
- ListFooterComponent: null,
21
- ListHeaderComponent: null,
22
- ListLoadingIndicatorComponent: null,
23
- ListEmptyComponent: EmptyPlaceholder,
24
- ListSeparatorComponent: RenderSeparator,
25
- refreshDebounce: 1500,
26
- refreshSize: 40,
27
- refreshThreshold: 0.1,
28
- refreshPosition: 16,
29
- refresh: true,
30
- columnItemsSpacing: 8,
31
- rowItemsSpacing: 8,
32
- overscan: 2,
33
- reloadTimeout: 350,
34
- showFooter: true,
35
- }
36
-
37
- export function Grid<T = any>(props: GridProps<T>) {
18
+ export const Grid = (props: GridProps) => {
38
19
  const allProps = {
39
20
  ...Grid.defaultProps,
40
21
  ...props,
41
- } as GridProps
22
+ }
42
23
 
43
24
  const {
44
- variants = [],
45
- responsiveVariants = {},
46
- styles = {},
25
+ style,
47
26
  renderItem: RenderItem,
48
27
  columnItemsSpacing,
49
28
  rowItemsSpacing,
@@ -51,17 +30,13 @@ export function Grid<T = any>(props: GridProps<T>) {
51
30
  data,
52
31
  overscan,
53
32
  separators,
54
- masonryProps = {},
33
+ masonryProps,
55
34
  numColumns,
56
35
  reloadTimeout,
57
36
  showFooter,
58
37
  } = allProps
59
38
 
60
- const variantStyles = useDefaultComponentStyle<'u:Grid', typeof GridPresets>('u:Grid', {
61
- variants,
62
- responsiveVariants,
63
- styles,
64
- })
39
+ const styles = useStylesFor(Grid.styleRegistryName, style)
65
40
 
66
41
  const { layoutProps, onLoadMore } = useInfiniteScroll(allProps)
67
42
 
@@ -71,7 +46,7 @@ export function Grid<T = any>(props: GridProps<T>) {
71
46
  })
72
47
 
73
48
  const separator = React.useMemo(() => {
74
- return separators ? <ListSeparatorComponent separatorStyles={variantStyles.separator} /> : null
49
+ return separators ? <ListSeparatorComponent separatorStyles={styles.separator} /> : null
75
50
  }, [])
76
51
 
77
52
  const renderItem = React.useCallback((_item: ItemMasonryProps<any>) => {
@@ -97,13 +72,13 @@ export function Grid<T = any>(props: GridProps<T>) {
97
72
  {_item?.index <= numColumns ? null : separator}
98
73
  <RenderItem {..._itemProps} />
99
74
  </>
100
- }, [RenderItem])
75
+ }, [])
101
76
 
102
77
  return (
103
78
  <ListLayout
104
79
  {...allProps}
105
80
  {...layoutProps}
106
- variantStyles={variantStyles}
81
+ styles={styles}
107
82
  showFooter={reloadingLayout ? false : showFooter}
108
83
  >
109
84
  <ListMasonry
@@ -124,4 +99,28 @@ export function Grid<T = any>(props: GridProps<T>) {
124
99
  )
125
100
  }
126
101
 
127
- Grid.defaultProps = defaultProps
102
+ Grid.styleRegistryName = 'Grid'
103
+ Grid.elements = ['wrapper', 'innerWrapper', 'separator', 'refreshControl', 'refreshControlIndicator']
104
+ Grid.rootElement = 'wrapper'
105
+
106
+ Grid.withVariantTypes = <S extends AnyRecord>(styles: S) => {
107
+ return Grid as <T extends ListItem = ListItem>(props: StyledComponentProps<GridProps<T>, typeof styles>) => IJSX
108
+ }
109
+
110
+ Grid.defaultProps = {
111
+ ListEmptyComponent: EmptyPlaceholder,
112
+ ListSeparatorComponent: RenderSeparator,
113
+ refreshDebounce: 1500,
114
+ refreshSize: 40,
115
+ refreshThreshold: 0.1,
116
+ refreshPosition: 16,
117
+ refresh: true,
118
+ columnItemsSpacing: 8,
119
+ rowItemsSpacing: 8,
120
+ overscan: 2,
121
+ reloadTimeout: 350,
122
+ showFooter: true,
123
+ numColumns: 2,
124
+ } as Partial<GridProps>
125
+
126
+ WebStyleRegistry.registerComponent(Grid)
@@ -1,10 +1,3 @@
1
- import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
2
- import { ListComposition, ListParts } from '../List'
1
+ import { ListComposition } from '../List'
3
2
 
4
- export type GridParts = ListParts
5
-
6
- export type GridComposition = ListComposition | GridParts
7
-
8
- const createGridStyle = createDefaultVariantFactory<GridComposition>()
9
-
10
- export const GridPresets = includePresets(style => createGridStyle(() => ({ wrapper: style })))
3
+ export type GridComposition = ListComposition
@@ -1,15 +1,13 @@
1
- import { ComponentVariants, StylesOf } from '@codeleap/common'
1
+ import { StyledProp } from '@codeleap/styles'
2
+ import { GridComposition } from './styles'
2
3
  import { ComponentCommonProps } from '../../types'
3
- import { ListProps } from '../List'
4
- import { GridComposition, GridPresets } from './styles'
4
+ import { ListItem, ListProps } from '../List'
5
5
 
6
- export type GridProps<
7
- T = any[],
8
- Data = T extends Array<infer D> ? D : never
9
- > =
10
- Omit<ListProps<T, Data>, 'variants' | 'styles'> &
11
- ComponentVariants<typeof GridPresets> & {
12
- styles?: StylesOf<GridComposition>
6
+ export type GridProps<T extends ListItem = ListItem> =
7
+ Omit<ListProps<T>, 'style'> &
8
+ ComponentCommonProps &
9
+ {
10
+ style?: StyledProp<GridComposition>
13
11
  columnItemsSpacing?: number
14
- numColumns: number
15
- } & ComponentCommonProps
12
+ numColumns?: number
13
+ }