@codeleap/web 2.4.6 → 3.0.2

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 (212) hide show
  1. package/package.json +20 -19
  2. package/src/components/ActionIcon/index.tsx +59 -0
  3. package/src/components/ActionIcon/styles.ts +9 -0
  4. package/src/components/ActivityIndicator/index.tsx +78 -0
  5. package/src/components/ActivityIndicator/styles.ts +11 -0
  6. package/src/components/Button/index.tsx +125 -0
  7. package/src/components/Button/styles.ts +22 -0
  8. package/src/components/Checkbox/index.tsx +138 -0
  9. package/src/components/Checkbox/styles.ts +20 -0
  10. package/src/components/Collapse/index.tsx +87 -0
  11. package/src/components/Collapse/styles.ts +8 -0
  12. package/src/components/Drawer/index.tsx +148 -0
  13. package/src/components/Drawer/styles.ts +8 -0
  14. package/src/components/FileInput.tsx +51 -0
  15. package/src/components/Icon/index.tsx +53 -0
  16. package/src/components/Icon/styles.ts +9 -0
  17. package/src/components/InputBase/index.tsx +104 -0
  18. package/src/components/InputBase/styles.ts +167 -0
  19. package/src/components/InputBase/types.ts +28 -0
  20. package/src/components/InputBase/utils.ts +41 -0
  21. package/src/components/Link/index.tsx +69 -0
  22. package/src/components/Link/styles.ts +11 -0
  23. package/src/components/List/index.tsx +103 -0
  24. package/src/components/List/styles.ts +8 -0
  25. package/src/components/LoadingOverlay/index.tsx +34 -0
  26. package/src/components/LoadingOverlay/styles.ts +12 -0
  27. package/src/components/Modal/index.tsx +189 -0
  28. package/src/components/Modal/styles.ts +26 -0
  29. package/src/components/NumberIncrement/index.tsx +292 -0
  30. package/src/components/NumberIncrement/styles.ts +15 -0
  31. package/src/components/Overlay/index.tsx +42 -0
  32. package/src/components/Overlay/styles.ts +8 -0
  33. package/src/components/RadioInput/index.tsx +155 -0
  34. package/src/components/RadioInput/styles.ts +14 -0
  35. package/src/components/Scroll/index.tsx +29 -0
  36. package/src/components/Scroll/styles.ts +8 -0
  37. package/src/components/Select/index.tsx +438 -0
  38. package/src/components/Select/styles.ts +179 -0
  39. package/src/components/Select/types.ts +100 -0
  40. package/src/components/Slider/index.tsx +303 -0
  41. package/src/components/Slider/styles.ts +11 -0
  42. package/src/components/Switch/index.tsx +128 -0
  43. package/src/components/Switch/styles.ts +20 -0
  44. package/src/components/Text/index.tsx +62 -0
  45. package/src/components/Text/styles.ts +9 -0
  46. package/src/components/TextInput/index.tsx +253 -0
  47. package/src/components/TextInput/mask.tsx +165 -0
  48. package/src/components/TextInput/styles.ts +15 -0
  49. package/src/components/Tooltip/index.tsx +155 -0
  50. package/src/components/Tooltip/styles.ts +9 -0
  51. package/src/components/Touchable/index.tsx +72 -0
  52. package/src/components/Touchable/styles.ts +11 -0
  53. package/src/components/View/index.tsx +94 -0
  54. package/src/components/View/styles.ts +8 -0
  55. package/src/components/components.ts +29 -0
  56. package/src/components/defaultStyles.ts +51 -0
  57. package/src/index.ts +6 -0
  58. package/src/lib/OSAlert.tsx +190 -0
  59. package/src/lib/Toast.ts +23 -0
  60. package/src/lib/hooks.ts +340 -0
  61. package/src/lib/index.ts +2 -0
  62. package/src/lib/logger.ts +13 -0
  63. package/src/lib/utils/cookies.ts +13 -0
  64. package/src/lib/utils/index.ts +4 -0
  65. package/src/lib/utils/pollyfils/scroll.ts +65 -0
  66. package/src/lib/utils/stopPropagation.ts +15 -0
  67. package/src/types/index.ts +1 -0
  68. package/src/types/utility.ts +3 -0
  69. package/dist/components/ActivityIndicator/index.d.ts +0 -12
  70. package/dist/components/ActivityIndicator/index.js +0 -57
  71. package/dist/components/ActivityIndicator/index.js.map +0 -1
  72. package/dist/components/ActivityIndicator/styles.d.ts +0 -53
  73. package/dist/components/ActivityIndicator/styles.js +0 -22
  74. package/dist/components/ActivityIndicator/styles.js.map +0 -1
  75. package/dist/components/Button.d.ts +0 -18
  76. package/dist/components/Button.js +0 -67
  77. package/dist/components/Button.js.map +0 -1
  78. package/dist/components/CenterWrapper.d.ts +0 -7
  79. package/dist/components/CenterWrapper.js +0 -28
  80. package/dist/components/CenterWrapper.js.map +0 -1
  81. package/dist/components/Checkbox/index.d.ts +0 -12
  82. package/dist/components/Checkbox/index.js +0 -58
  83. package/dist/components/Checkbox/index.js.map +0 -1
  84. package/dist/components/Checkbox/styles.d.ts +0 -53
  85. package/dist/components/Checkbox/styles.js +0 -64
  86. package/dist/components/Checkbox/styles.js.map +0 -1
  87. package/dist/components/Collapse.d.ts +0 -20
  88. package/dist/components/Collapse.js +0 -68
  89. package/dist/components/Collapse.js.map +0 -1
  90. package/dist/components/ContentView.d.ts +0 -10
  91. package/dist/components/ContentView.js +0 -52
  92. package/dist/components/ContentView.js.map +0 -1
  93. package/dist/components/Drawer.d.ts +0 -23
  94. package/dist/components/Drawer.js +0 -73
  95. package/dist/components/Drawer.js.map +0 -1
  96. package/dist/components/FileInput.d.ts +0 -8
  97. package/dist/components/FileInput.js +0 -69
  98. package/dist/components/FileInput.js.map +0 -1
  99. package/dist/components/HorizontalScroll.d.ts +0 -3
  100. package/dist/components/HorizontalScroll.js +0 -42
  101. package/dist/components/HorizontalScroll.js.map +0 -1
  102. package/dist/components/Icon.d.ts +0 -8
  103. package/dist/components/Icon.js +0 -55
  104. package/dist/components/Icon.js.map +0 -1
  105. package/dist/components/Link.d.ts +0 -7
  106. package/dist/components/Link.js +0 -63
  107. package/dist/components/Link.js.map +0 -1
  108. package/dist/components/List.d.ts +0 -18
  109. package/dist/components/List.js +0 -52
  110. package/dist/components/List.js.map +0 -1
  111. package/dist/components/Modal/index.d.ts +0 -21
  112. package/dist/components/Modal/index.js +0 -116
  113. package/dist/components/Modal/index.js.map +0 -1
  114. package/dist/components/Modal/styles.d.ts +0 -56
  115. package/dist/components/Modal/styles.js +0 -36
  116. package/dist/components/Modal/styles.js.map +0 -1
  117. package/dist/components/Overlay.d.ts +0 -10
  118. package/dist/components/Overlay.js +0 -41
  119. package/dist/components/Overlay.js.map +0 -1
  120. package/dist/components/RadioInput/index.d.ts +0 -21
  121. package/dist/components/RadioInput/index.js +0 -55
  122. package/dist/components/RadioInput/index.js.map +0 -1
  123. package/dist/components/RadioInput/styles.d.ts +0 -54
  124. package/dist/components/RadioInput/styles.js +0 -44
  125. package/dist/components/RadioInput/styles.js.map +0 -1
  126. package/dist/components/RouterPage/Menu.d.ts +0 -10
  127. package/dist/components/RouterPage/Menu.js +0 -36
  128. package/dist/components/RouterPage/Menu.js.map +0 -1
  129. package/dist/components/RouterPage/MenuItem.d.ts +0 -12
  130. package/dist/components/RouterPage/MenuItem.js +0 -42
  131. package/dist/components/RouterPage/MenuItem.js.map +0 -1
  132. package/dist/components/RouterPage/Router.d.ts +0 -8
  133. package/dist/components/RouterPage/Router.js +0 -27
  134. package/dist/components/RouterPage/Router.js.map +0 -1
  135. package/dist/components/RouterPage/index.d.ts +0 -29
  136. package/dist/components/RouterPage/index.js +0 -85
  137. package/dist/components/RouterPage/index.js.map +0 -1
  138. package/dist/components/RouterPage/styles.d.ts +0 -54
  139. package/dist/components/RouterPage/styles.js +0 -87
  140. package/dist/components/RouterPage/styles.js.map +0 -1
  141. package/dist/components/Scroll.d.ts +0 -5
  142. package/dist/components/Scroll.js +0 -24
  143. package/dist/components/Scroll.js.map +0 -1
  144. package/dist/components/Select/Custom.d.ts +0 -8
  145. package/dist/components/Select/Custom.js +0 -104
  146. package/dist/components/Select/Custom.js.map +0 -1
  147. package/dist/components/Select/Multi.d.ts +0 -3
  148. package/dist/components/Select/Multi.js +0 -105
  149. package/dist/components/Select/Multi.js.map +0 -1
  150. package/dist/components/Select/Native.d.ts +0 -17
  151. package/dist/components/Select/Native.js +0 -44
  152. package/dist/components/Select/Native.js.map +0 -1
  153. package/dist/components/Select/index.d.ts +0 -12
  154. package/dist/components/Select/index.js +0 -40
  155. package/dist/components/Select/index.js.map +0 -1
  156. package/dist/components/Select/styles.d.ts +0 -5
  157. package/dist/components/Select/styles.js +0 -57
  158. package/dist/components/Select/styles.js.map +0 -1
  159. package/dist/components/Select/types.d.ts +0 -49
  160. package/dist/components/Select/types.js +0 -3
  161. package/dist/components/Select/types.js.map +0 -1
  162. package/dist/components/Slider.d.ts +0 -5
  163. package/dist/components/Slider.js +0 -39
  164. package/dist/components/Slider.js.map +0 -1
  165. package/dist/components/Text.d.ts +0 -9
  166. package/dist/components/Text.js +0 -43
  167. package/dist/components/Text.js.map +0 -1
  168. package/dist/components/TextInput.d.ts +0 -150
  169. package/dist/components/TextInput.js +0 -125
  170. package/dist/components/TextInput.js.map +0 -1
  171. package/dist/components/Tooltip.d.ts +0 -12
  172. package/dist/components/Tooltip.js +0 -122
  173. package/dist/components/Tooltip.js.map +0 -1
  174. package/dist/components/Touchable.d.ts +0 -15
  175. package/dist/components/Touchable.js +0 -52
  176. package/dist/components/Touchable.js.map +0 -1
  177. package/dist/components/View.d.ts +0 -10
  178. package/dist/components/View.js +0 -62
  179. package/dist/components/View.js.map +0 -1
  180. package/dist/components/index.d.ts +0 -24
  181. package/dist/components/index.js +0 -37
  182. package/dist/components/index.js.map +0 -1
  183. package/dist/index.d.ts +0 -6
  184. package/dist/index.js +0 -25
  185. package/dist/index.js.map +0 -1
  186. package/dist/lib/OSAlert.d.ts +0 -21
  187. package/dist/lib/OSAlert.js +0 -140
  188. package/dist/lib/OSAlert.js.map +0 -1
  189. package/dist/lib/Toast.d.ts +0 -13
  190. package/dist/lib/Toast.js +0 -32
  191. package/dist/lib/Toast.js.map +0 -1
  192. package/dist/lib/hooks.d.ts +0 -28
  193. package/dist/lib/hooks.js +0 -183
  194. package/dist/lib/hooks.js.map +0 -1
  195. package/dist/lib/logger.d.ts +0 -2
  196. package/dist/lib/logger.js +0 -16
  197. package/dist/lib/logger.js.map +0 -1
  198. package/dist/lib/utils/cookies.d.ts +0 -6
  199. package/dist/lib/utils/cookies.js +0 -15
  200. package/dist/lib/utils/cookies.js.map +0 -1
  201. package/dist/lib/utils/index.d.ts +0 -4
  202. package/dist/lib/utils/index.js +0 -23
  203. package/dist/lib/utils/index.js.map +0 -1
  204. package/dist/lib/utils/pollyfils/scroll.d.ts +0 -1
  205. package/dist/lib/utils/pollyfils/scroll.js +0 -66
  206. package/dist/lib/utils/pollyfils/scroll.js.map +0 -1
  207. package/dist/lib/utils/stopPropagation.d.ts +0 -1
  208. package/dist/lib/utils/stopPropagation.js +0 -20
  209. package/dist/lib/utils/stopPropagation.js.map +0 -1
  210. package/dist/types/utility.d.ts +0 -2
  211. package/dist/types/utility.js +0 -3
  212. package/dist/types/utility.js.map +0 -1
@@ -0,0 +1,128 @@
1
+ import * as React from 'react'
2
+ import { ComponentVariants, useDefaultComponentStyle, StylesOf, PropsOf } from '@codeleap/common'
3
+ import { View } from '../View'
4
+ import { SwitchPresets, SwitchComposition } from './styles'
5
+ import { InputBase, InputBaseDefaultOrder, InputBaseProps, selectInputBaseProps } from '../InputBase'
6
+ import { useAnimatedVariantStyles } from '../..'
7
+ import { motion } from 'framer-motion'
8
+
9
+ export * from './styles'
10
+
11
+ export type SwitchProps = Pick<
12
+ InputBaseProps,
13
+ 'debugName' | 'disabled' | 'label'
14
+ > & {
15
+ variants?: ComponentVariants<typeof SwitchPresets>['variants']
16
+ styles?: StylesOf<SwitchComposition>
17
+ value: boolean
18
+ onValueChange: (value: boolean) => void
19
+ onChange?: (value: boolean) => void
20
+ style?: PropsOf<typeof View>['style']
21
+ switchOnLeft?: boolean
22
+ }
23
+
24
+ const reversedOrder = [...InputBaseDefaultOrder].reverse()
25
+
26
+ export const Switch = (props: SwitchProps) => {
27
+ const {
28
+ inputBaseProps,
29
+ others
30
+ } = selectInputBaseProps(props)
31
+ const {
32
+ variants = [],
33
+ style = {},
34
+ styles = {},
35
+ value,
36
+ disabled,
37
+ debugName,
38
+ onValueChange,
39
+ onChange,
40
+ switchOnLeft,
41
+ } = others
42
+
43
+ const variantStyles = useDefaultComponentStyle<'u:Switch', typeof SwitchPresets>('u:Switch', {
44
+ variants,
45
+ styles,
46
+ rootElement: 'wrapper',
47
+ })
48
+
49
+ const trackAnimation = useAnimatedVariantStyles({
50
+ variantStyles,
51
+ animatedProperties: ['track:off','track:disabled', 'track:on', 'track:disabled-on', 'track:disabled-off'],
52
+ updater: () =>{
53
+ 'worklet'
54
+ let disabledStyle = {}
55
+ if(disabled){
56
+ disabledStyle = value ? variantStyles['track:disabled-on'] : variantStyles['track:disabled-off']
57
+ }
58
+ const style = value ? variantStyles['track:on'] : variantStyles['track:off']
59
+
60
+ return {
61
+ ...style,
62
+ ...disabledStyle
63
+ }
64
+ },
65
+ dependencies: [value, disabled],
66
+ })
67
+
68
+ const thumbAnimation = useAnimatedVariantStyles({
69
+ variantStyles,
70
+ animatedProperties: ['thumb:off','thumb:disabled', 'thumb:on', 'thumb:disabled-off', 'thumb:disabled-on'],
71
+ updater: () =>{
72
+ 'worklet'
73
+ let disabledStyle = {}
74
+ if(disabled){
75
+ disabledStyle = value ? variantStyles['thumb:disabled-on'] : variantStyles['thumb:disabled-off']
76
+ }
77
+ const style = value ? variantStyles['thumb:on'] : variantStyles['thumb:off']
78
+ return {
79
+ ...style,
80
+ ...disabledStyle
81
+ }
82
+ },
83
+ dependencies: [value, disabled],
84
+ })
85
+
86
+ const _switchOnLeft = switchOnLeft ?? variantStyles['__props']?.switchOnLeft
87
+
88
+ const handleChange = () => {
89
+ if (disabled) return
90
+ if(onValueChange) onValueChange?.(!value)
91
+ if(onChange) onChange?.(!value)
92
+ }
93
+
94
+ return <InputBase
95
+ {...inputBaseProps}
96
+ debugName={debugName}
97
+ styles={{
98
+ ...variantStyles,
99
+ innerWrapper: [
100
+ variantStyles.innerWrapper,
101
+ ],
102
+ }}
103
+ order={_switchOnLeft ? reversedOrder : InputBaseDefaultOrder}
104
+ style={style}
105
+ disabled={disabled}
106
+ >
107
+ <motion.div
108
+ css={[
109
+ variantStyles.track,
110
+ disabled && variantStyles['track:disabled'],
111
+ ]}
112
+ initial={false}
113
+ animate={trackAnimation}
114
+ transition={variantStyles['track:transition']}
115
+ onClick={handleChange}
116
+ >
117
+ <motion.div
118
+ css={[
119
+ variantStyles.thumb,
120
+ disabled && variantStyles['thumb:disabled'],
121
+ ]}
122
+ initial={false}
123
+ animate={thumbAnimation}
124
+ transition={variantStyles['thumb:transition']}
125
+ />
126
+ </motion.div>
127
+ </InputBase>
128
+ }
@@ -0,0 +1,20 @@
1
+ import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
2
+ import { InputBaseParts, InputBaseStates } from '../InputBase'
3
+
4
+ type AnimatableParts = 'track' | 'thumb'
5
+ export type SwitchParts = InputBaseParts | AnimatableParts
6
+
7
+ export type SwitchAnimationStates = 'on' | 'off' | 'disabled-on' | 'disabled-off'
8
+
9
+ export type SwitchStates = InputBaseStates
10
+
11
+ export type SwitchComposition =
12
+ | SwitchParts
13
+ | `${SwitchParts}:${SwitchStates}`
14
+ | `${AnimatableParts}:transition`
15
+ | `${AnimatableParts}:${SwitchAnimationStates}`
16
+ | '__props'
17
+
18
+ const createSwitchStyle = createDefaultVariantFactory<SwitchComposition>()
19
+
20
+ export const SwitchPresets = includePresets((styles) => createSwitchStyle(() => ({ wrapper: styles })))
@@ -0,0 +1,62 @@
1
+ /** @jsx jsx */
2
+ import { jsx } from '@emotion/react'
3
+ import {
4
+ ComponentVariants,
5
+ useCodeleapContext,
6
+ useDefaultComponentStyle,
7
+ } from '@codeleap/common'
8
+ import { ComponentPropsWithoutRef, ElementType } from 'react'
9
+ import { StylesOf } from '../../types/utility'
10
+ import { TextComposition, TextPresets } from './styles'
11
+
12
+ export * from './styles'
13
+
14
+ export type TextProps<T extends ElementType> = {
15
+ component?: T
16
+ text?: string
17
+ message?: string // is required
18
+ styles?: StylesOf<TextComposition>
19
+ debug?: boolean
20
+ debugName?: string
21
+ } & ComponentPropsWithoutRef<T> &
22
+ ComponentVariants<typeof TextPresets>
23
+
24
+ export const Text = <T extends ElementType>(textProps: TextProps<T>) => {
25
+ const {
26
+ variants = [],
27
+ responsiveVariants = {},
28
+ text = null,
29
+ children,
30
+ component = 'p',
31
+ styles,
32
+ message = null,
33
+ debug = false,
34
+ debugName,
35
+ ...props
36
+ } = textProps
37
+
38
+ const variantStyles = useDefaultComponentStyle('Text', {
39
+ rootElement: 'text',
40
+ responsiveVariants,
41
+ variants,
42
+ styles,
43
+ })
44
+
45
+ const { logger } = useCodeleapContext()
46
+
47
+ const Component = component
48
+
49
+ if (debug) {
50
+ logger.log(`Text ${debugName}`, { variantStyles, text })
51
+ }
52
+
53
+ return (
54
+ //@ts-ignore
55
+ <Component
56
+ css={[variantStyles.text, props.style]}
57
+ {...props}
58
+ >
59
+ {text || children}
60
+ </Component>
61
+ )
62
+ }
@@ -0,0 +1,9 @@
1
+ import { createDefaultVariantFactory, includePresets } from "@codeleap/common"
2
+
3
+ export type TextComposition = 'text'
4
+
5
+ const createTextStyle = createDefaultVariantFactory<TextComposition>()
6
+
7
+ export const TextPresets = includePresets((styles) =>
8
+ createTextStyle(() => ({ text: styles }))
9
+ )
@@ -0,0 +1,253 @@
1
+ import {
2
+ ComponentVariants,
3
+ FormTypes,
4
+ IconPlaceholder,
5
+ TextInputComposition,
6
+ TypeGuards,
7
+ useBooleanToggle,
8
+ useDefaultComponentStyle,
9
+ useValidate,
10
+ yup,
11
+ } from '@codeleap/common'
12
+ import React, {
13
+ ComponentPropsWithoutRef,
14
+ forwardRef,
15
+ useImperativeHandle,
16
+ useRef,
17
+ useState,
18
+ } from 'react'
19
+ import TextareaAutosize from 'react-autosize-textarea'
20
+ import InputMask from 'react-input-mask'
21
+ import { Touchable, TouchableProps } from '../Touchable'
22
+ import { StylesOf } from '../../types/utility'
23
+ import { InputBase, InputBaseProps, selectInputBaseProps } from '../InputBase'
24
+ import { TextInputPresets } from './styles'
25
+ import { getMaskInputProps, TextInputMaskingProps } from './mask'
26
+
27
+ export * from './styles'
28
+ export * from './mask'
29
+
30
+ type NativeTextInputProps = ComponentPropsWithoutRef<'input'>
31
+
32
+ export type TextInputProps =
33
+ Omit<InputBaseProps, 'styles' | 'variants'> &
34
+ Omit<NativeTextInputProps, 'value'|'crossOrigin'> & {
35
+ styles?: StylesOf<TextInputComposition>
36
+ password?: boolean
37
+ validate?: FormTypes.ValidatorWithoutForm<string> | yup.SchemaOf<string>
38
+ debugName?: string
39
+ visibilityToggle?: boolean
40
+ variants?: ComponentVariants<typeof TextInputPresets>['variants']
41
+ value?: NativeTextInputProps['value']
42
+ multiline?: boolean
43
+ onPress?: TouchableProps['onPress']
44
+ onChangeText?: (value: string) => void
45
+ caretColor?: string
46
+ focused?: boolean
47
+ _error?: boolean
48
+ rows?: number
49
+ masking?: TextInputMaskingProps
50
+ }
51
+
52
+ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>((props, inputRef) => {
53
+ const innerInputRef = useRef<HTMLInputElement>(null)
54
+
55
+ const {
56
+ inputBaseProps,
57
+ others,
58
+ } = selectInputBaseProps(props)
59
+
60
+ const {
61
+ variants,
62
+ styles,
63
+ value,
64
+ validate,
65
+ debugName,
66
+ visibilityToggle,
67
+ password,
68
+ onPress,
69
+ multiline,
70
+ caretColor,
71
+ focused,
72
+ _error,
73
+ masking = null,
74
+ ...textInputProps
75
+ } = others
76
+
77
+ const [_isFocused, setIsFocused] = useState(false)
78
+
79
+ const isFocused = _isFocused || focused
80
+
81
+ const [secureTextEntry, toggleSecureTextEntry] = useBooleanToggle(true)
82
+
83
+ const isMultiline = multiline
84
+
85
+ const isMasked = !TypeGuards.isNil(masking)
86
+ const maskProps = isMasked ? getMaskInputProps({ masking }) : null
87
+
88
+ const InputElement = isMasked ? InputMask : isMultiline ? TextareaAutosize : 'input'
89
+
90
+ const variantStyles = useDefaultComponentStyle<'u:TextInput', typeof TextInputPresets>('u:TextInput', {
91
+ variants,
92
+ styles,
93
+ })
94
+
95
+ useImperativeHandle(inputRef, () => {
96
+ return {
97
+ ...innerInputRef.current,
98
+ focus: () => {
99
+ innerInputRef.current?.focus?.()
100
+ },
101
+ isTextInput: true,
102
+ }
103
+ }, [!!innerInputRef?.current?.focus])
104
+
105
+ const isPressable = TypeGuards.isFunction(onPress)
106
+
107
+ const validation = useValidate(
108
+ value,
109
+ TypeGuards.isFunction(maskProps?.validator) ? maskProps?.validator : validate,
110
+ )
111
+
112
+ const handleBlur = React.useCallback((e: React.FocusEvent<HTMLInputElement, Element>) => {
113
+ validation?.onInputBlurred()
114
+ setIsFocused(false)
115
+ props?.onBlur?.(e)
116
+ }, [validation?.onInputBlurred, props?.onBlur])
117
+
118
+ const handleFocus = React.useCallback((e: React.FocusEvent<HTMLInputElement, Element>) => {
119
+ validation?.onInputFocused()
120
+ setIsFocused(true)
121
+ props?.onFocus?.(e)
122
+ }, [validation?.onInputFocused, props?.onFocus])
123
+
124
+ const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
125
+ const _text = event?.target?.value
126
+
127
+ const _value = isMasked && maskProps?.notSaveFormatted
128
+ ? maskProps?.getRawValue(_text)
129
+ : _text
130
+
131
+ if (props?.onChange) props?.onChange(event)
132
+ if (props?.onChangeText) props?.onChangeText(_value)
133
+ }
134
+
135
+ const isDisabled = !!inputBaseProps.disabled
136
+
137
+ const visibilityToggleProps = visibilityToggle ? {
138
+ onPress: toggleSecureTextEntry,
139
+ icon: (secureTextEntry ? 'input-visiblity:hidden' : 'input-visiblity:visible') as IconPlaceholder,
140
+ debugName: `${debugName} toggle visibility`,
141
+ } : null
142
+
143
+ const rightIcon = inputBaseProps?.rightIcon ?? visibilityToggleProps
144
+
145
+ const buttonModeProps = isPressable ? {
146
+ editable: false,
147
+ caretHidden: true,
148
+ } : {}
149
+ const rows = textInputProps?.rows ?? (
150
+ isMultiline ? 2 : undefined
151
+ )
152
+ const hasMultipleLines = isMultiline && (String(value)?.includes('\n') || !!rows)
153
+
154
+ const hasError = !validation.isValid || _error
155
+ const errorMessage = validation.message || _error
156
+
157
+ const placeholderStyles = [
158
+ variantStyles.placeholder,
159
+ isFocused && variantStyles['placeholder:focus'],
160
+ hasError && variantStyles['placeholder:error'],
161
+ isDisabled && variantStyles['placeholder:disabled'],
162
+ ]
163
+
164
+ const selectionStyles = [
165
+ variantStyles.selection,
166
+ isFocused && variantStyles['selection:focus'],
167
+ hasError && variantStyles['selection:error'],
168
+ isDisabled && variantStyles['selection:disabled'],
169
+ ]
170
+
171
+ const secureTextProps = (password && secureTextEntry) && {
172
+ type: 'password',
173
+ }
174
+
175
+ const caretColorStyle = (caretColor || buttonModeProps.caretHidden) && {
176
+ caretColor: buttonModeProps.caretHidden ? 'transparent' : caretColor,
177
+ }
178
+
179
+ const inputBaseAction = isPressable ? 'onPress' : 'onClick'
180
+
181
+ const _wrapperOnInputFocus = {
182
+ [inputBaseAction]: () => {
183
+ innerInputRef.current?.focus?.()
184
+ },
185
+ }
186
+
187
+ return (
188
+ <InputBase
189
+ innerWrapper={isPressable ? Touchable : undefined}
190
+ {...inputBaseProps}
191
+ debugName={debugName}
192
+ error={hasError ? errorMessage : null}
193
+ styles={{
194
+ ...variantStyles,
195
+ innerWrapper: [
196
+ variantStyles.innerWrapper,
197
+ isMultiline && variantStyles['innerWrapper:multiline'],
198
+ hasMultipleLines && variantStyles['innerWrapper:hasMultipleLines'],
199
+ ],
200
+ }}
201
+ innerWrapperProps={{
202
+ ...(inputBaseProps.innerWrapperProps || {}),
203
+ [inputBaseAction]: () => {
204
+ // @ts-ignore
205
+ if (isMasked) innerInputRef.current?.onFocus?.()
206
+ innerInputRef.current?.focus?.()
207
+ if (isPressable) onPress?.()
208
+ },
209
+ debugName,
210
+ }}
211
+ rightIcon={rightIcon}
212
+ focused={isFocused}
213
+ wrapperProps={{
214
+ ...(inputBaseProps.wrapperProps || {}),
215
+ ..._wrapperOnInputFocus,
216
+ }}
217
+ >
218
+ <InputElement
219
+ editable={`${!isPressable && !isDisabled}`}
220
+ {...buttonModeProps}
221
+ {...secureTextProps}
222
+ {...textInputProps}
223
+ value={value}
224
+ onChange={(e) => handleChange(e)}
225
+ onBlur={handleBlur}
226
+ onFocus={handleFocus}
227
+ css={[
228
+ variantStyles.input,
229
+ isMultiline && variantStyles['input:multiline'],
230
+ isFocused && variantStyles['input:focus'],
231
+ hasError && variantStyles['input:error'],
232
+ isDisabled && variantStyles['input:disabled'],
233
+ hasMultipleLines && variantStyles['input:hasMultipleLines'],
234
+ {
235
+ '&::placeholder': placeholderStyles,
236
+ },
237
+ {
238
+ '&::selection': selectionStyles,
239
+ },
240
+ {
241
+ '&:focus': [
242
+ { outline: 'none', borderWidth: 0, borderColor: 'transparent' },
243
+ isFocused && variantStyles['input:focus'],
244
+ caretColorStyle,
245
+ ],
246
+ },
247
+ ]}
248
+ {...maskProps}
249
+ ref={innerInputRef}
250
+ />
251
+ </InputBase>
252
+ )
253
+ })
@@ -0,0 +1,165 @@
1
+ import { FormTypes, TypeGuards } from '@codeleap/common'
2
+
3
+ type beforeMaskedValueChangeArgs = {
4
+ state: {
5
+ value: string | undefined
6
+ selection: {
7
+ start: number
8
+ end: number
9
+ length?: number
10
+ }
11
+ }
12
+ userInput: null | string
13
+ }
14
+
15
+ type FormatChar = `[${string}]`
16
+
17
+ export type MaskProps = {
18
+ obfuscated?: boolean
19
+ mask?: string
20
+ placeholder?: string
21
+ maskChar?: string
22
+ formatChars?: Record<string, FormatChar>
23
+ alwaysShowMask?: boolean
24
+ validator?: FormTypes.ValidatorFunctionWithoutForm
25
+ maskType?: 'BRL' | 'INTERNATIONAL'
26
+ getRawValue?: (value: any) => string
27
+ }
28
+
29
+ export type TextInputMaskTypeProp =
30
+ | 'credit-card'
31
+ | 'cpf'
32
+ | 'cnpj'
33
+ | 'zip-code'
34
+ | 'cel-phone'
35
+ | 'custom'
36
+
37
+ export interface TextInputMaskingProps {
38
+ type: TextInputMaskTypeProp
39
+ options?: MaskProps
40
+ onChangeMask?: (
41
+ newState: beforeMaskedValueChangeArgs['state'],
42
+ oldState: beforeMaskedValueChangeArgs['state'],
43
+ userInput: beforeMaskedValueChangeArgs['userInput']
44
+ ) => beforeMaskedValueChangeArgs['state']
45
+ saveFormatted?: boolean
46
+ }
47
+
48
+ type InputMaskProps = {
49
+ masking: TextInputMaskingProps
50
+ }
51
+
52
+ export const getMaskInputProps = ({ masking }: InputMaskProps): MaskProps & { notSaveFormatted: boolean } => {
53
+ const {
54
+ type = 'custom',
55
+ options = {},
56
+ } = masking
57
+
58
+ const maskType = masking?.options?.maskType ?? 'INTERNATIONAL'
59
+ const phoneType = maskType === 'INTERNATIONAL' ? 'cel-phone' : 'cel-phone-brl'
60
+
61
+ const presetProps = masking?.type === 'cel-phone' ? maskPreset[phoneType] : maskPreset[type]
62
+
63
+ const isObfuscated = options?.obfuscated === true && {
64
+ type: 'password',
65
+ }
66
+
67
+ const notSaveFormatted = (TypeGuards.isBoolean(masking?.saveFormatted) && masking?.saveFormatted === false)
68
+
69
+ const props = {
70
+ ...presetProps,
71
+ ...options,
72
+ ...isObfuscated,
73
+ notSaveFormatted,
74
+ beforeMaskedValueChange: masking?.onChangeMask,
75
+ }
76
+
77
+ const defaultGetRawValue = (value: string) => {
78
+ return String(value)?.replace(/\D/g, '')
79
+ }
80
+
81
+ return {
82
+ ...props,
83
+ validator: notSaveFormatted ? null : props?.validator,
84
+ getRawValue: props?.getRawValue ?? defaultGetRawValue,
85
+ }
86
+ }
87
+
88
+ const format: Record<string, FormatChar> = {
89
+ number: "['0123456789']",
90
+ }
91
+
92
+ const validatorRegExp = (value: string | number, regex: RegExp, error: string) => {
93
+ const isValid = regex.test(String(value))
94
+
95
+ return {
96
+ valid: isValid,
97
+ message: error,
98
+ }
99
+ }
100
+
101
+ export const maskPreset: Record<TextInputMaskTypeProp | 'cel-phone-brl', MaskProps> = {
102
+ 'credit-card': {
103
+ mask: '9999 9999 9999 9999',
104
+ placeholder: 'xxxx xxxx xxxx xxxx',
105
+ formatChars: {
106
+ '9': format.number,
107
+ },
108
+ validator: (value: string) => {
109
+ return validatorRegExp(value, /^\d{4}\s?\d{4}\s?\d{4}\s?\d{4}$/, 'Invalid information')
110
+ },
111
+ },
112
+ 'cpf': {
113
+ mask: '999.999.999-99',
114
+ placeholder: 'xxx.xxx.xxx-xx',
115
+ formatChars: {
116
+ '9': format.number,
117
+ },
118
+ validator: (value: string) => {
119
+ return validatorRegExp(value, /^\d{3}\.\d{3}\.\d{3}-\d{2}$/, 'Invalid CPF')
120
+ },
121
+ },
122
+ 'cnpj': {
123
+ mask: '99.999.999/9999-99',
124
+ placeholder: 'xx.xxx.xxx/xxxx-xx',
125
+ formatChars: {
126
+ '9': format.number,
127
+ },
128
+ validator: (value: string) => {
129
+ return validatorRegExp(value, /^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$/, 'Invalid CNPJ')
130
+ },
131
+ },
132
+ 'zip-code': {
133
+ mask: '99999-999',
134
+ placeholder: 'xxxxx-xxx',
135
+ formatChars: {
136
+ '9': format.number,
137
+ },
138
+ validator: (value: string) => {
139
+ return validatorRegExp(value, /^\d{5}-\d{3}$/, 'Invalid zip code')
140
+ },
141
+ },
142
+ 'cel-phone': {
143
+ mask: '+999 999 999 999',
144
+ placeholder: '+xxx xxx xxx xxx',
145
+ maskType: 'INTERNATIONAL',
146
+ formatChars: {
147
+ '9': format.number,
148
+ },
149
+ validator: (value: string) => {
150
+ return validatorRegExp(value, /^\+\d{3}\s\d{3}\s\d{3}\s\d{3}$/, 'Invalid phone')
151
+ },
152
+ },
153
+ 'cel-phone-brl': {
154
+ mask: '(99) 99999-9999',
155
+ placeholder: '(xx) xxxxx-xxxx',
156
+ maskType: 'BRL',
157
+ formatChars: {
158
+ '9': format.number,
159
+ },
160
+ validator: (value: string) => {
161
+ return validatorRegExp(value, /^\(?\d{2}\)?\s?9?\d{4}-\d{4}$/, 'Invalid phone')
162
+ },
163
+ },
164
+ 'custom': {},
165
+ }
@@ -0,0 +1,15 @@
1
+ import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
2
+ import { ActionIconParts } from '../ActionIcon'
3
+ import { InputBaseParts, InputBaseStates } from '../InputBase'
4
+
5
+ type TextInputParts = InputBaseParts | 'input' | 'placeholder' | 'selection'
6
+ export type TextInputStates = InputBaseStates | 'multiline' | 'hasMultipleLines'
7
+
8
+ export type IconParts = Exclude<ActionIconParts, 'icon' | 'icon:disabled'>
9
+
10
+ export type TextInputComposition = `${TextInputParts}:${TextInputStates}` | TextInputParts
11
+
12
+ const createTextInputStyle =
13
+ createDefaultVariantFactory<TextInputComposition>()
14
+
15
+ export const TextInputPresets = includePresets((styles) => createTextInputStyle(() => ({ wrapper: styles })))