@codeleap/web 3.24.3 → 3.25.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,80 +1,80 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import { View } from '../View'
3
- import { SegmentedControlOption } from './SegmentedControlOption'
4
- import { ComponentVariants, useDefaultComponentStyle, PropsOf, IconPlaceholder, StylesOf, useRef, TypeGuards } from '@codeleap/common'
5
- import { SegmentedControlPresets } from './styles'
3
+ import { useRef, TypeGuards } from '@codeleap/common'
6
4
  import { Text } from '../Text'
7
- import { Touchable } from '../Touchable'
8
- import { SegmentedControlComposition } from './styles'
9
- import { motion, MotionProps, AnimationProps, ForwardRefComponent } from 'framer-motion'
5
+ import { motion, AnimationProps } from 'framer-motion'
10
6
  import { useAnimatedVariantStyles } from '../../lib'
11
- import { IconProps } from '../Icon'
12
-
13
- export type SegmentedControlOptionProps<T = string> = {
14
- label: string
15
- value: T
16
- icon?: IconPlaceholder
17
- }
18
-
19
- export type SegmentedControlProps<T = string> = ComponentVariants<typeof SegmentedControlPresets> & {
20
-
21
- /** options that the segmented control will receive */
22
- options : SegmentedControlOptionProps[]
23
-
24
- /** the value of the segmented control */
25
- value?: T
26
-
27
- /** all styles from the segmented control */
28
- styles?: StylesOf<SegmentedControlComposition>
29
-
30
- /** view style */
31
- style?: PropsOf<typeof View>['style']
32
-
33
- /** prop to control when te value of the segmented control changes */
34
- onValueChange?: (v: any) => void
35
-
36
- /** motion div props */
37
- bubbleProps?: React.HTMLAttributes<HTMLDivElement> & MotionProps
7
+ import { SegmentedControlOptionProps, SegmentedControlProps } from './types'
8
+ import { Touchable } from '../Touchable'
9
+ import { Icon } from '../Icon'
10
+ import { useStylesFor } from '../../lib/hooks/useStylesFor'
11
+ import { WebStyleRegistry } from '../../lib/WebStyleRegistry'
12
+ import { AnyRecord, IJSX, mergeStyles, StyledComponentProps } from '@codeleap/styles'
38
13
 
39
- /** label that will be shown above the segmented control */
40
- label?: string
14
+ export * from './styles'
15
+ export * from './types'
41
16
 
42
- /** * all the touchable props */
43
- touchableProps?: Partial<PropsOf<typeof Touchable>>
17
+ const Option = forwardRef<HTMLButtonElement, SegmentedControlOptionProps>((props, ref) => {
18
+ const {
19
+ selected,
20
+ onPress,
21
+ styles,
22
+ iconProps = {},
23
+ label,
24
+ icon,
25
+ largestWidth,
26
+ textProps,
27
+ disabled,
28
+ ...touchableProps
29
+ } = props
44
30
 
45
- debugName?: string
46
- disabled?: boolean
47
- animationProps?: AnimationProps
48
- transitionDuration?: number
49
- RenderAnimatedView?: ForwardRefComponent<HTMLDivElement, any>
50
- textProps?: Omit<PropsOf<typeof Text>, 'key'>
51
- iconProps?: Partial<IconProps>
52
- debounce?: number
53
- debounceEnabled?: boolean
54
- }
31
+ const iconStyles = mergeStyles([
32
+ styles.icon,
33
+ (selected ? styles['icon:selected'] : null),
34
+ (disabled ? styles['icon:disabled'] : null),
35
+ ])
55
36
 
56
- const defaultProps: Partial<SegmentedControlProps> = {
57
- animationProps: {},
58
- transitionDuration: 0.2,
59
- disabled: false,
60
- RenderAnimatedView: motion.div,
61
- debounce: 1000,
62
- debounceEnabled: true,
63
- }
37
+ return (
38
+ <Touchable
39
+ key={touchableProps.key}
40
+ ref={ref as unknown as React.Ref<HTMLButtonElement>}
41
+ onPress={onPress}
42
+ disabled={disabled}
43
+ {...touchableProps}
44
+ style={{
45
+ ...styles.button,
46
+ ...(selected ? styles['button:selected'] : {}),
47
+ ...(disabled ? styles['button:disabled'] : {}),
48
+ width: largestWidth?.width,
49
+ }}
50
+ >
51
+ {!!icon ? (
52
+ <Icon
53
+ debugName={touchableProps?.debugName}
54
+ name={icon}
55
+ {...iconProps}
56
+ style={iconStyles}
57
+ />
58
+ ) : null}
59
+ <Text
60
+ text={label}
61
+ debugName={touchableProps?.debugName}
62
+ {...textProps}
63
+ style={{
64
+ ...styles.text,
65
+ ...(selected ? styles['text:selected'] : {}),
66
+ ...(disabled ? styles['text:disabled'] : {}),
67
+ }}
68
+ />
69
+ </Touchable>
70
+ )
71
+ })
64
72
 
65
73
  export const SegmentedControl = (props: SegmentedControlProps) => {
66
- const allProps = {
67
- ...SegmentedControl.defaultProps,
68
- ...props,
69
- }
70
-
71
74
  const {
72
75
  label,
73
76
  options,
74
- styles = {},
75
77
  value,
76
- variants = [],
77
- responsiveVariants = {},
78
78
  onValueChange,
79
79
  style,
80
80
  bubbleProps,
@@ -82,22 +82,18 @@ export const SegmentedControl = (props: SegmentedControlProps) => {
82
82
  transitionDuration,
83
83
  disabled,
84
84
  RenderAnimatedView: Bubble,
85
- textProps = {},
86
- iconProps = {},
85
+ textProps,
86
+ iconProps,
87
87
  debugName,
88
88
  debounce,
89
89
  debounceEnabled,
90
90
  ...rest
91
- } = allProps
92
-
93
- const variantStyles = useDefaultComponentStyle<'u:SegmentedControl', typeof SegmentedControlPresets>(
94
- 'u:SegmentedControl',
95
- {
96
- variants,
97
- responsiveVariants,
98
- styles,
99
- },
100
- )
91
+ } = {
92
+ ...SegmentedControl.defaultProps,
93
+ ...props,
94
+ }
95
+
96
+ const styles = useStylesFor(SegmentedControl.styleRegistryName, style)
101
97
 
102
98
  const currentOptionIdx = React.useMemo(() => {
103
99
  return options?.findIndex(o => o?.value === value) || 0
@@ -113,7 +109,7 @@ export const SegmentedControl = (props: SegmentedControlProps) => {
113
109
  }, [maxDivWidthRef.current])
114
110
 
115
111
  const bubbleAnimation = useAnimatedVariantStyles({
116
- variantStyles,
112
+ variantStyles: styles,
117
113
  animatedProperties: [],
118
114
  updater: () => {
119
115
  'worklet'
@@ -130,21 +126,21 @@ export const SegmentedControl = (props: SegmentedControlProps) => {
130
126
  })
131
127
 
132
128
  const selectedBubbleStyles = [
133
- variantStyles.selectedBubble,
134
- disabled && variantStyles['selectedBubble:disabled'],
129
+ styles.selectedBubble,
130
+ disabled && styles['selectedBubble:disabled'],
135
131
  largestWidth,
136
132
  ]
137
133
 
138
134
  const onSelectTab = (option: SegmentedControlOptionProps, e?: React.KeyboardEvent<HTMLButtonElement>) => {
139
135
  if (!e || e?.keyCode === 13 || e?.key === 'Enter') {
140
136
  if (!debounceEnabled || !TypeGuards.isNumber(debounce)) {
141
- onValueChange(option.value)
137
+ onValueChange?.(option?.value)
142
138
  return
143
139
  }
144
140
 
145
141
  if (sectionPressedRef.current !== null) return
146
142
 
147
- onValueChange(option.value)
143
+ onValueChange?.(option?.value)
148
144
  sectionPressedRef.current = setTimeout(() => {
149
145
  clearTimeout(sectionPressedRef.current)
150
146
  sectionPressedRef.current = null
@@ -155,17 +151,18 @@ export const SegmentedControl = (props: SegmentedControlProps) => {
155
151
  }
156
152
 
157
153
  return (
158
- <View css={[variantStyles.wrapper, style]} {...rest}>
159
- {label && <Text text={label} css={[variantStyles.label, disabled && variantStyles['label:disabled']]} />}
160
- <View css={[variantStyles.innerWrapper, disabled && variantStyles['innerWrapper:disabled']]}>
154
+ <View {...rest} style={styles.wrapper}>
155
+ {label ? <Text text={label} style={[styles.label, disabled && styles['label:disabled']]} /> : null}
156
+ <View style={[styles.innerWrapper, disabled && styles['innerWrapper:disabled']]}>
161
157
  <Bubble
158
+ // @ts-expect-error
162
159
  css={selectedBubbleStyles}
163
160
  animate={bubbleAnimation}
164
161
  initial={false}
165
162
  {...bubbleProps}
166
163
  />
167
164
  {options.map((o, idx) => (
168
- <SegmentedControlOption
165
+ <Option
169
166
  ref={(ref) => {
170
167
  if (ref && ref.offsetWidth > maxDivWidthRef.current) {
171
168
  maxDivWidthRef.current = ref.offsetWidth
@@ -179,11 +176,11 @@ export const SegmentedControl = (props: SegmentedControlProps) => {
179
176
  key={idx}
180
177
  icon={o.icon}
181
178
  selected={value === o.value}
182
- variantStyles={variantStyles}
183
- style={largestWidth}
179
+ styles={styles}
184
180
  disabled={disabled}
185
181
  textProps={textProps}
186
182
  iconProps={iconProps}
183
+ largestWidth={largestWidth}
187
184
  tabIndex={0}
188
185
  {...props?.touchableProps}
189
186
  />
@@ -193,6 +190,31 @@ export const SegmentedControl = (props: SegmentedControlProps) => {
193
190
  )
194
191
  }
195
192
 
196
- export * from './styles'
193
+ SegmentedControl.styleRegistryName = 'SegmentedControl'
194
+
195
+ SegmentedControl.elements = [
196
+ 'wrapper',
197
+ 'innerWrapper',
198
+ 'selectedBubble',
199
+ 'text',
200
+ 'icon',
201
+ 'button',
202
+ 'label',
203
+ ]
204
+
205
+ SegmentedControl.rootElement = 'wrapper'
206
+
207
+ SegmentedControl.withVariantTypes = <S extends AnyRecord>(styles: S) => {
208
+ return SegmentedControl as (props: StyledComponentProps<SegmentedControlProps, typeof styles>) => IJSX
209
+ }
210
+
211
+ SegmentedControl.defaultProps = {
212
+ animationProps: {},
213
+ transitionDuration: 0.2,
214
+ disabled: false,
215
+ RenderAnimatedView: motion.div,
216
+ debounce: 1000,
217
+ debounceEnabled: true,
218
+ } as Partial<SegmentedControlProps>
197
219
 
198
- SegmentedControl.defaultProps = defaultProps
220
+ WebStyleRegistry.registerComponent(SegmentedControl)
@@ -1,26 +1,12 @@
1
- import { createDefaultVariantFactory, includePresets, StylesOf } from '@codeleap/common'
2
-
3
1
  export type SegmentedControlStates = 'selected' | 'disabled'
4
2
 
5
3
  type SegmentedControlParts =
6
- 'selectedBubble' |
7
- 'wrapper' |
8
- 'innerWrapper' |
9
- 'text' |
10
- 'icon' |
11
- 'button' |
12
- `label`
4
+ 'wrapper' |
5
+ 'innerWrapper' |
6
+ 'selectedBubble' |
7
+ 'text' |
8
+ 'icon' |
9
+ 'button' |
10
+ `label`
13
11
 
14
12
  export type SegmentedControlComposition = SegmentedControlParts | `${SegmentedControlParts}:${SegmentedControlStates}`
15
-
16
- export type SegmentedControlStylesGen<TCSS = any> =
17
- StylesOf<
18
- Exclude<SegmentedControlComposition, 'buttonFeedback'>
19
- >
20
-
21
- const createSegmentedControlStyle = createDefaultVariantFactory<
22
- SegmentedControlComposition,
23
- SegmentedControlStylesGen
24
- >()
25
-
26
- export const SegmentedControlPresets = includePresets((style) => createSegmentedControlStyle(() => ({ wrapper: style })))
@@ -0,0 +1,44 @@
1
+ import React from 'react'
2
+ import { StylesOf } from '@codeleap/common'
3
+ import { TextProps } from '../Text'
4
+ import { TouchableProps } from '../Touchable'
5
+ import { SegmentedControlComposition } from './styles'
6
+ import { MotionProps, AnimationProps, ForwardRefComponent } from 'framer-motion'
7
+ import { IconProps } from '../Icon'
8
+ import { AppIcon, StyledProp } from '@codeleap/styles'
9
+
10
+ export type SegmentedControlProps<T = string> = {
11
+ options: SegmentedControlOptionProps[]
12
+ value?: T
13
+ style?: StyledProp<SegmentedControlComposition>
14
+ onValueChange?: (v: any) => void
15
+ bubbleProps?: React.HTMLAttributes<HTMLDivElement> & MotionProps
16
+ label?: string
17
+ touchableProps?: Partial<TouchableProps>
18
+ debugName?: string
19
+ disabled?: boolean
20
+ animationProps?: AnimationProps
21
+ transitionDuration?: number
22
+ RenderAnimatedView?: ForwardRefComponent<HTMLDivElement, any>
23
+ textProps?: TextProps
24
+ iconProps?: Partial<IconProps>
25
+ debounce?: number
26
+ debounceEnabled?: boolean
27
+ }
28
+
29
+ export type OptionRef = TouchableProps['ref']
30
+
31
+ export type SegmentedControlOptionProps =
32
+ TouchableProps &
33
+ {
34
+ selected?: boolean
35
+ label: string
36
+ styles?: StylesOf<SegmentedControlComposition>
37
+ value?: any
38
+ textProps?: TextProps
39
+ iconProps?: Partial<IconProps>
40
+ icon?: AppIcon
41
+ largestWidth?: {
42
+ width: number
43
+ }
44
+ }
@@ -1,7 +1,5 @@
1
- /** @jsx jsx */
2
- import { jsx } from '@emotion/react'
3
1
  import React, { useRef, forwardRef, useImperativeHandle } from 'react'
4
- import { FormTypes, useValidate, useState, TypeGuards, onUpdate, IconPlaceholder, useEffect } from '@codeleap/common'
2
+ import { FormTypes, useValidate, useState, TypeGuards, onUpdate, useEffect } from '@codeleap/common'
5
3
  import _Select, { components, MenuListProps, MenuProps, MultiValueProps, NoticeProps } from 'react-select'
6
4
  import Async from 'react-select/async'
7
5
  import { useSelectStyles } from './styles'
@@ -13,14 +11,25 @@ import { View } from '../View'
13
11
  import { ActivityIndicator } from '../ActivityIndicator'
14
12
  import { CSSInterpolation } from '@emotion/css'
15
13
  import { Icon } from '../Icon'
14
+ import { WebStyleRegistry } from '../../lib/WebStyleRegistry'
15
+ import { AnyRecord, AppIcon, IJSX, StyledComponentProps, StyledComponentWithProps } from '@codeleap/styles'
16
16
 
17
17
  export * from './styles'
18
18
  export * from './types'
19
19
 
20
20
  const DefaultOption = (props: TCustomOption & { component: (props: TCustomOption) => JSX.Element }) => {
21
- const { isSelected, optionsStyles, label, selectedIcon, component = null, itemProps = {} as TCustomOption['itemProps'], isFocused, debugName } = props
22
-
23
- const styles = optionsStyles({ isSelected, isFocused, baseStyles: (itemProps?.styles ?? {}) })
21
+ const {
22
+ isSelected,
23
+ optionsStyles,
24
+ label,
25
+ selectedIcon,
26
+ component = null,
27
+ itemProps = {} as TCustomOption['itemProps'],
28
+ isFocused,
29
+ debugName,
30
+ } = props
31
+
32
+ const styles = optionsStyles({ isSelected, isFocused, baseStyles: (itemProps?.style ?? {}) })
24
33
 
25
34
  let _Component = null
26
35
 
@@ -32,7 +41,7 @@ const DefaultOption = (props: TCustomOption & { component: (props: TCustomOption
32
41
  rightIcon={isSelected && selectedIcon}
33
42
  debugName={debugName}
34
43
  {...itemProps}
35
- styles={styles}
44
+ style={styles}
36
45
  />
37
46
  )
38
47
  } else {
@@ -41,14 +50,13 @@ const DefaultOption = (props: TCustomOption & { component: (props: TCustomOption
41
50
 
42
51
  return (
43
52
  <components.Option {...props}>
44
- <_Component {...props} styles={styles} />
53
+ <_Component {...props} style={styles} />
45
54
  </components.Option>
46
55
  )
47
56
  }
48
57
 
49
58
  const CustomMenu = (props: MenuProps & { Footer: () => JSX.Element }) => {
50
59
  const { Footer, children } = props
51
-
52
60
  return <React.Fragment>
53
61
  <components.Menu {...props}>
54
62
  {children}
@@ -59,7 +67,6 @@ const CustomMenu = (props: MenuProps & { Footer: () => JSX.Element }) => {
59
67
 
60
68
  const CustomMenuList = (props: MenuListProps & { defaultStyles: { wrapper: React.CSSProperties } }) => {
61
69
  const { children, defaultStyles } = props
62
-
63
70
  return (
64
71
  <components.MenuList {...props}>
65
72
  <View style={defaultStyles.wrapper}>
@@ -70,13 +77,13 @@ const CustomMenuList = (props: MenuListProps & { defaultStyles: { wrapper: React
70
77
  }
71
78
 
72
79
  const DefaultPlaceholder = (props: PlaceholderProps) => {
73
- const { text: TextPlaceholder, defaultStyles, icon: _IconPlaceholder, debugName } = props
80
+ const { text: TextPlaceholder, defaultStyles, icon: _IconPlaceholder, image, debugName } = props
74
81
 
75
82
  const _Text = () => {
76
83
  if (TypeGuards.isNil(TextPlaceholder)) return null
77
84
 
78
85
  if (TypeGuards.isString(TextPlaceholder)) {
79
- return <Text debugName={debugName} text={TextPlaceholder} css={[defaultStyles.text]} />
86
+ return <Text debugName={debugName} text={TextPlaceholder} style={defaultStyles.text} />
80
87
  } else if (React.isValidElement(TextPlaceholder)) {
81
88
  return TextPlaceholder as JSX.Element
82
89
  } else if (TypeGuards.isFunction(TextPlaceholder)) {
@@ -85,10 +92,14 @@ const DefaultPlaceholder = (props: PlaceholderProps) => {
85
92
  }
86
93
 
87
94
  const _Image = () => {
88
- if (TypeGuards.isNil(_IconPlaceholder)) return null
95
+ if (TypeGuards.isNil(_IconPlaceholder) && TypeGuards.isNil(image)) return null
96
+
97
+ if (TypeGuards.isString(image)) {
98
+ return <img src={image} css={defaultStyles.icon} />
99
+ }
89
100
 
90
101
  if (TypeGuards.isString(_IconPlaceholder)) {
91
- return <Icon debugName={debugName} name={_IconPlaceholder as IconPlaceholder} forceStyle={defaultStyles.icon as React.CSSProperties} />
102
+ return <Icon debugName={debugName} name={_IconPlaceholder as AppIcon} forceStyle={defaultStyles.icon as React.CSSProperties} />
92
103
  } else if (React.isValidElement(_IconPlaceholder)) {
93
104
  // @ts-ignore
94
105
  return <View style={defaultStyles.icon}>
@@ -111,7 +122,7 @@ const LoadingIndicator = (props: LoadingIndicatorProps) => {
111
122
  const { defaultStyles, debugName } = props
112
123
 
113
124
  return (
114
- <View css={[defaultStyles.wrapper]}>
125
+ <View style={defaultStyles.wrapper}>
115
126
  <ActivityIndicator debugName={debugName} />
116
127
  </View>
117
128
  )
@@ -143,38 +154,16 @@ const CustomMultiValue = (props: MultiValueProps & { defaultStyles: { text: CSSI
143
154
  // @ts-ignore
144
155
  const text = getMultiValue(selectProps?.value, separator, { searchable })
145
156
 
146
- return <Text text={text} css={[defaultStyles.text]} />
157
+ return <Text text={text} style={defaultStyles.text} />
147
158
  }
148
159
 
149
160
  const defaultFormatPlaceholderNoItems = (props: PlaceholderProps & { text: string }) => {
150
161
  return props.text + `"${props.selectProps.inputValue}"`
151
162
  }
152
163
 
153
- const defaultProps: Partial<SelectProps> = {
154
- PlaceholderComponent: DefaultPlaceholder,
155
- PlaceholderNoItemsComponent: DefaultPlaceholder,
156
- LoadingIndicatorComponent: LoadingIndicator,
157
- noItemsText: 'No results for ',
158
- noItemsIcon: 'placeholderNoItems-select',
159
- placeholderText: 'Search items',
160
- placeholderIcon: 'placeholder-select',
161
- showDropdownIcon: true,
162
- placeholder: 'Select',
163
- clearable: false,
164
- formatPlaceholderNoItems: defaultFormatPlaceholderNoItems,
165
- selectedIcon: 'check',
166
- searchable: false,
167
- separatorMultiValue: ', ',
168
- itemProps: {} as ButtonProps,
169
- loadingIndicatorSize: 20,
170
- options: [],
171
- loadInitialValue: false,
172
- loadingMessage: 'loading...',
173
- }
174
-
175
164
  export const Select = forwardRef<HTMLInputElement, SelectProps>(
176
- <T extends string | number = string, Multi extends boolean = false>
177
- (props: SelectProps<T, Multi>, inputRef: React.ForwardedRef<HTMLInputElement>) => {
165
+ <T extends string | number = string, Multi extends boolean = false>
166
+ (props: SelectProps<T, Multi>, inputRef: React.ForwardedRef<HTMLInputElement>) => {
178
167
 
179
168
  type Option = FormTypes.Option<T>
180
169
 
@@ -187,9 +176,8 @@ export const Select = forwardRef<HTMLInputElement, SelectProps>(
187
176
  })
188
177
 
189
178
  const {
190
- variants,
191
179
  validate,
192
- styles,
180
+ style,
193
181
  debugName,
194
182
  onValueChange,
195
183
  options,
@@ -207,8 +195,10 @@ export const Select = forwardRef<HTMLInputElement, SelectProps>(
207
195
  LoadingIndicatorComponent,
208
196
  noItemsText,
209
197
  noItemsIcon,
198
+ noItemsImage,
210
199
  placeholderText,
211
200
  placeholderIcon,
201
+ placeholderImage,
212
202
  showDropdownIcon,
213
203
  placeholder,
214
204
  clearable,
@@ -263,13 +253,14 @@ export const Select = forwardRef<HTMLInputElement, SelectProps>(
263
253
 
264
254
  const {
265
255
  reactSelectStyles,
266
- variantStyles,
256
+ styles,
267
257
  optionsStyles,
268
258
  placeholderStyles,
269
259
  loadingStyles,
270
260
  inputMultiValueStyles,
271
261
  menuWrapperStyles,
272
- } = useSelectStyles(props, {
262
+ // @ts-expect-error @verify
263
+ } = useSelectStyles({ ...props, styleRegistryName: Select.styleRegistryName }, {
273
264
  error: !!hasError,
274
265
  focused: isFocused,
275
266
  disabled: isDisabled,
@@ -344,7 +335,7 @@ export const Select = forwardRef<HTMLInputElement, SelectProps>(
344
335
  focused: isFocused,
345
336
  error: !!hasError,
346
337
  disabled: isDisabled,
347
- variantStyles,
338
+ styles,
348
339
  debugName: debugName,
349
340
  }
350
341
 
@@ -352,16 +343,17 @@ export const Select = forwardRef<HTMLInputElement, SelectProps>(
352
343
  const hasInputValue = !!props.selectProps.inputValue
353
344
  const styles = placeholderStyles[hasInputValue ? 'noItems' : 'empty']
354
345
  const icon = hasInputValue ? noItemsIcon : placeholderIcon
346
+ const image = hasInputValue ? noItemsImage : placeholderImage
355
347
 
356
348
  const placeholderProps = {
357
349
  ...props,
358
350
  ...componentProps,
359
351
  icon,
352
+ image,
360
353
  defaultStyles: styles,
361
354
  }
362
355
 
363
356
  if (!hasInputValue) {
364
-
365
357
  return <PlaceholderComponent {...placeholderProps} text={placeholderText} />
366
358
  } else {
367
359
  const _Text = TypeGuards.isString(noItemsText) ? formatPlaceholderNoItems({ ...placeholderProps, text: noItemsText }) : noItemsText
@@ -397,12 +389,12 @@ export const Select = forwardRef<HTMLInputElement, SelectProps>(
397
389
  debugName={debugName}
398
390
  error={hasError ? errorMessage : null}
399
391
  focused={isFocused}
400
- styles={{
401
- ...variantStyles,
402
- innerWrapper: [
403
- variantStyles.innerWrapper,
404
- searchable && variantStyles['innerWrapper:searchable'],
405
- ],
392
+ style={{
393
+ ...styles,
394
+ innerWrapper: {
395
+ ...styles.innerWrapper,
396
+ ...(searchable ? styles['innerWrapper:searchable'] : {}),
397
+ },
406
398
  }}
407
399
  innerWrapperProps={{
408
400
  ...(inputBaseProps.innerWrapperProps || {}),
@@ -418,8 +410,6 @@ export const Select = forwardRef<HTMLInputElement, SelectProps>(
418
410
  tabSelectsValue={false}
419
411
  tabIndex={0}
420
412
  backspaceRemovesValue={true}
421
- // escapeRemoves={true}
422
- // deleteRemoves={true}
423
413
  {...otherProps}
424
414
  {..._props}
425
415
  onKeyDown={isFocused ? handleKeyDown : null}
@@ -477,6 +467,52 @@ export const Select = forwardRef<HTMLInputElement, SelectProps>(
477
467
  />
478
468
  </InputBase>
479
469
  )
480
- })
470
+ }) as StyledComponentWithProps<SelectProps>
471
+
472
+ Select.styleRegistryName = 'Select'
473
+
474
+ Select.elements = [
475
+ ...InputBase.elements,
476
+ 'item',
477
+ 'listPortal',
478
+ 'listHeader',
479
+ 'listWrapper',
480
+ 'list',
481
+ 'inputContainer',
482
+ 'input',
483
+ 'placeholder',
484
+ 'value',
485
+ 'valueMultiple',
486
+ 'valueWrapper',
487
+ 'clearIcon',
488
+ 'dropdownIcon',
489
+ ]
490
+
491
+ Select.rootElement = 'wrapper'
492
+
493
+ Select.withVariantTypes = <S extends AnyRecord>(styles: S) => {
494
+ return Select as (props: StyledComponentProps<SelectProps, typeof styles>) => IJSX
495
+ }
496
+
497
+ Select.defaultProps = {
498
+ PlaceholderComponent: DefaultPlaceholder,
499
+ PlaceholderNoItemsComponent: DefaultPlaceholder,
500
+ LoadingIndicatorComponent: LoadingIndicator,
501
+ noItemsText: 'No results for ',
502
+ placeholderText: 'Search items',
503
+ placeholderIcon: 'search',
504
+ showDropdownIcon: true,
505
+ placeholder: 'Select',
506
+ clearable: false,
507
+ formatPlaceholderNoItems: defaultFormatPlaceholderNoItems,
508
+ selectedIcon: 'check',
509
+ searchable: false,
510
+ separatorMultiValue: ', ',
511
+ itemProps: {} as ButtonProps,
512
+ loadingIndicatorSize: 20,
513
+ options: [],
514
+ loadInitialValue: false,
515
+ loadingMessage: 'loading...',
516
+ } as Partial<SelectProps>
481
517
 
482
- Select.defaultProps = defaultProps
518
+ WebStyleRegistry.registerComponent(Select)