@codeleap/web 3.25.0 → 3.25.3

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