@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.
- package/package.json +2 -1
- package/src/components/ActionIcon/index.tsx +51 -52
- package/src/components/ActionIcon/styles.ts +1 -5
- package/src/components/ActionIcon/types.ts +15 -0
- package/src/components/ActivityIndicator/index.tsx +34 -55
- package/src/components/ActivityIndicator/styles.ts +0 -6
- package/src/components/ActivityIndicator/types.ts +12 -0
- package/src/components/Badge/index.tsx +43 -80
- package/src/components/Badge/styles.ts +1 -11
- package/src/components/Badge/types.ts +28 -0
- package/src/components/Button/index.tsx +46 -89
- package/src/components/Button/styles.ts +0 -5
- package/src/components/Button/types.ts +25 -0
- package/src/components/Checkbox/index.tsx +83 -97
- package/src/components/Checkbox/styles.ts +1 -5
- package/src/components/Checkbox/types.ts +15 -0
- package/src/components/Collapse/index.tsx +41 -83
- package/src/components/Collapse/styles.ts +3 -6
- package/src/components/Collapse/types.ts +11 -0
- package/src/components/ColorPicker/index.tsx +95 -48
- package/src/components/ColorPicker/styles.ts +11 -11
- package/src/components/ColorPicker/types.ts +26 -12
- package/src/components/CropPicker/index.tsx +100 -104
- package/src/components/CropPicker/styles.ts +0 -7
- package/src/components/CropPicker/types.ts +8 -15
- package/src/components/DatePicker/{defaultComponents → components}/Header.tsx +9 -17
- package/src/components/DatePicker/{defaultComponents → components}/OuterInput.tsx +6 -7
- package/src/components/DatePicker/index.tsx +110 -124
- package/src/components/DatePicker/styles.ts +1 -12
- package/src/components/DatePicker/types.ts +16 -33
- package/src/components/Drawer/index.tsx +133 -125
- package/src/components/Drawer/styles.ts +0 -5
- package/src/components/Drawer/types.ts +23 -0
- package/src/components/Dropzone/index.tsx +87 -63
- package/src/components/Dropzone/styles.ts +0 -6
- package/src/components/Dropzone/types.ts +29 -37
- package/src/components/EmptyPlaceholder/index.tsx +63 -83
- package/src/components/EmptyPlaceholder/styles.ts +0 -5
- package/src/components/EmptyPlaceholder/types.ts +32 -0
- package/src/components/FileInput/index.tsx +72 -0
- package/src/components/FileInput/types.ts +14 -0
- package/src/components/Grid/index.tsx +40 -41
- package/src/components/Grid/styles.ts +2 -9
- package/src/components/Grid/types.ts +10 -12
- package/src/components/Icon/index.tsx +45 -47
- package/src/components/Icon/styles.ts +0 -8
- package/src/components/Icon/types.ts +15 -0
- package/src/components/InputBase/index.tsx +71 -42
- package/src/components/InputBase/styles.ts +37 -47
- package/src/components/InputBase/types.ts +19 -7
- package/src/components/InputBase/utils.ts +3 -23
- package/src/components/List/ListLayout.tsx +20 -37
- package/src/components/List/index.tsx +36 -41
- package/src/components/List/styles.ts +5 -11
- package/src/components/List/types.ts +30 -20
- package/src/components/LoadingOverlay/index.tsx +31 -33
- package/src/components/LoadingOverlay/styles.ts +3 -8
- package/src/components/LoadingOverlay/types.ts +16 -0
- package/src/components/Modal/index.tsx +98 -160
- package/src/components/Modal/styles.ts +0 -5
- package/src/components/Modal/types.ts +55 -0
- package/src/components/NumberIncrement/index.tsx +67 -98
- package/src/components/NumberIncrement/styles.ts +0 -5
- package/src/components/NumberIncrement/types.ts +29 -0
- package/src/components/Overlay/index.tsx +37 -35
- package/src/components/Overlay/styles.ts +3 -5
- package/src/components/Overlay/types.ts +13 -0
- package/src/components/Pager/index.tsx +65 -81
- package/src/components/Pager/styles.ts +3 -9
- package/src/components/Pager/types.ts +35 -0
- package/src/components/PaginationButtons/index.tsx +173 -0
- package/src/components/PaginationButtons/styles.ts +7 -0
- package/src/components/PaginationButtons/types.ts +26 -0
- package/src/components/PaginationIndicator/index.tsx +69 -0
- package/src/components/PaginationIndicator/styles.ts +3 -0
- package/src/components/PaginationIndicator/types.ts +18 -0
- package/src/components/Progress/Bar/index.tsx +45 -50
- package/src/components/Progress/Bar/styles.ts +10 -0
- package/src/components/Progress/Bar/types.ts +26 -0
- package/src/components/Progress/Circle/index.tsx +45 -48
- package/src/components/Progress/Circle/styles.ts +1 -8
- package/src/components/Progress/Circle/types.ts +10 -22
- package/src/components/RadioInput/index.tsx +78 -124
- package/src/components/RadioInput/styles.ts +0 -6
- package/src/components/RadioInput/types.ts +29 -0
- package/src/components/SearchInput/index.tsx +10 -10
- package/src/components/SectionFilters/index.tsx +47 -36
- package/src/components/SectionFilters/styles.ts +1 -5
- package/src/components/SectionFilters/types.ts +14 -13
- package/src/components/SegmentedControl/index.tsx +111 -89
- package/src/components/SegmentedControl/styles.ts +7 -21
- package/src/components/SegmentedControl/types.ts +44 -0
- package/src/components/Select/index.tsx +92 -56
- package/src/components/Select/styles.ts +19 -36
- package/src/components/Select/types.ts +15 -10
- package/src/components/Slider/index.tsx +85 -93
- package/src/components/Slider/styles.ts +13 -6
- package/src/components/Slider/types.ts +29 -0
- package/src/components/Switch/index.tsx +63 -74
- package/src/components/Switch/styles.ts +1 -6
- package/src/components/Switch/types.ts +13 -0
- package/src/components/Tag/index.tsx +39 -44
- package/src/components/Tag/styles.ts +1 -9
- package/src/components/Tag/types.ts +10 -10
- package/src/components/Text/index.tsx +37 -48
- package/src/components/Text/styles.ts +0 -8
- package/src/components/Text/types.ts +8 -8
- package/src/components/TextEditor/index.tsx +49 -28
- package/src/components/TextEditor/styles.ts +1 -8
- package/src/components/TextEditor/types.ts +11 -6
- package/src/components/TextInput/index.tsx +58 -96
- package/src/components/TextInput/mask.tsx +2 -50
- package/src/components/TextInput/styles.ts +3 -8
- package/src/components/TextInput/types.ts +85 -0
- package/src/components/Tooltip/index.tsx +61 -84
- package/src/components/Tooltip/styles.ts +3 -10
- package/src/components/Tooltip/types.ts +46 -0
- package/src/components/Touchable/index.tsx +43 -86
- package/src/components/Touchable/styles.ts +0 -6
- package/src/components/Touchable/types.ts +22 -0
- package/src/components/View/index.tsx +36 -50
- package/src/components/View/styles.ts +0 -6
- package/src/components/View/types.ts +14 -15
- package/src/components/components.ts +2 -3
- package/src/index.ts +1 -0
- package/src/lib/WebStyleRegistry.ts +51 -0
- package/src/lib/hooks/index.ts +5 -0
- package/src/lib/hooks/useBreakpointMatch.ts +8 -7
- package/src/{components/CropPicker/useCropPicker.tsx → lib/hooks/useCropPicker.ts} +66 -13
- package/src/lib/hooks/useFileInput.ts +15 -0
- package/src/lib/hooks/useInfiniteScroll.ts +77 -0
- package/src/lib/hooks/useMediaQuery.ts +4 -3
- package/src/lib/hooks/usePagination.ts +79 -63
- package/src/lib/hooks/useRefresh.ts +87 -0
- package/src/lib/hooks/useStylesFor.ts +13 -0
- package/src/lib/index.ts +1 -0
- package/src/lib/utils/cache.ts +9 -0
- package/src/lib/utils/index.ts +1 -0
- package/src/lib/utils/test.ts +2 -2
- package/src/components/CropPicker/utils.ts +0 -51
- package/src/components/FileInput.tsx +0 -91
- package/src/components/List/PaginationIndicator.tsx +0 -102
- package/src/components/List/useInfiniteScroll.ts +0 -159
- package/src/components/Progress/Bar/styles.tsx +0 -7
- package/src/components/Progress/Bar/types.tsx +0 -30
- package/src/components/Scroll/index.tsx +0 -32
- package/src/components/Scroll/styles.ts +0 -8
- package/src/components/SegmentedControl/SegmentedControlOption.tsx +0 -84
- package/src/components/defaultStyles.ts +0 -79
- /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 {
|
|
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 {
|
|
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 {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
40
|
-
|
|
14
|
+
export * from './styles'
|
|
15
|
+
export * from './types'
|
|
41
16
|
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
} =
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
134
|
-
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
|
|
137
|
+
onValueChange?.(option?.value)
|
|
142
138
|
return
|
|
143
139
|
}
|
|
144
140
|
|
|
145
141
|
if (sectionPressedRef.current !== null) return
|
|
146
142
|
|
|
147
|
-
onValueChange(option
|
|
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
|
|
159
|
-
{label
|
|
160
|
-
<View
|
|
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
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
'
|
|
7
|
-
'
|
|
8
|
-
'
|
|
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,
|
|
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 {
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
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}
|
|
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}
|
|
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
|
|
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
|
|
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}
|
|
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
|
-
|
|
177
|
-
|
|
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
|
-
|
|
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
|
-
|
|
256
|
+
styles,
|
|
267
257
|
optionsStyles,
|
|
268
258
|
placeholderStyles,
|
|
269
259
|
loadingStyles,
|
|
270
260
|
inputMultiValueStyles,
|
|
271
261
|
menuWrapperStyles,
|
|
272
|
-
|
|
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
|
-
|
|
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
|
-
|
|
401
|
-
...
|
|
402
|
-
innerWrapper:
|
|
403
|
-
|
|
404
|
-
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
|
|
518
|
+
WebStyleRegistry.registerComponent(Select)
|