@neko-os/ui 0.0.13 → 0.2.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/dist/NekoUI.js +1 -1
- package/dist/abstractions/FlatList.native.js +1 -1
- package/dist/abstractions/KeyboardAvoidingView.js +1 -0
- package/dist/abstractions/KeyboardAvoidingView.native.js +1 -0
- package/dist/abstractions/ScrollView.native.js +1 -1
- package/dist/components/actions/ActionsDrawer.js +1 -0
- package/dist/components/actions/Button.js +1 -1
- package/dist/components/actions/FloatingMenu.js +1 -0
- package/dist/components/actions/index.js +1 -1
- package/dist/components/animations/AnimatedTopBar.js +1 -0
- package/dist/components/animations/AnimatedTopBar.native.js +1 -0
- package/dist/components/animations/AnimatedTopBar.web.js +1 -0
- package/dist/components/animations/ParallaxHeader.js +1 -0
- package/dist/components/animations/ParallaxHeader.native.js +1 -0
- package/dist/components/animations/ParallaxHeader.web.js +1 -0
- package/dist/components/animations/ReanimatedScrollHandler.js +1 -0
- package/dist/components/animations/ReanimatedScrollHandler.native.js +1 -0
- package/dist/components/animations/ReanimatedScrollHandler.web.js +1 -0
- package/dist/components/animations/index.js +1 -1
- package/dist/components/feedback/alerter.js +1 -1
- package/dist/components/feedback/confirmer.js +1 -1
- package/dist/components/form/FormItem.js +1 -1
- package/dist/components/form/FormList.js +1 -1
- package/dist/components/form/SubmitButton.js +1 -1
- package/dist/components/form/index.js +1 -1
- package/dist/components/form/useNewForm.js +1 -1
- package/dist/components/form/validation/defaultMessages.js +1 -0
- package/dist/components/form/validation/index.js +1 -0
- package/dist/components/form/validation/normalizeRules.js +1 -0
- package/dist/components/form/validation/shouldValidateOn.js +1 -0
- package/dist/components/form/validation/validateRules.js +1 -0
- package/dist/components/form/validation/validators.js +1 -0
- package/dist/components/index.js +1 -1
- package/dist/components/inputs/InputWrapper.js +1 -1
- package/dist/components/inputs/NumberInput.js +1 -1
- package/dist/components/inputs/Picker.js +1 -1
- package/dist/components/inputs/Select.js +1 -1
- package/dist/components/modals/bottomDrawer/index.js +1 -0
- package/dist/components/modals/bottomDrawer/index.native.js +1 -0
- package/dist/components/modals/bottomDrawer/index.web.js +1 -0
- package/dist/components/modals/bottomDrawer/native/BottomDrawer.js +1 -0
- package/dist/components/modals/bottomDrawer/native/DrawerContext.js +1 -0
- package/dist/components/modals/bottomDrawer/native/DrawerHandle.js +1 -0
- package/dist/components/modals/bottomDrawer/native/DrawerScrollView.js +1 -0
- package/dist/components/modals/bottomDrawer/native/createDrawerScrollComponent.js +1 -0
- package/dist/components/modals/bottomDrawer/web/BottomDrawer.js +1 -0
- package/dist/components/modals/drawer/Drawer.js +1 -0
- package/dist/components/modals/index.js +1 -0
- package/dist/components/modals/modal/Modal.js +1 -0
- package/dist/components/modals/modal/Modal.native.js +1 -0
- package/dist/components/modals/modal/ModalBackdrop.js +1 -0
- package/dist/components/modals/modal/ModalContent.js +1 -0
- package/dist/components/modals/modal/ModalFooter.js +1 -0
- package/dist/components/modals/modal/ModalHeader.js +1 -0
- package/dist/components/modals/modal/handler/ModalsHandler.js +1 -0
- package/dist/components/modals/router/ModalRoute.js +1 -0
- package/dist/components/modals/router/ModalsRouter.js +1 -0
- package/dist/components/modals/router/ModalsRouterContext.js +1 -0
- package/dist/components/modals/router/index.js +1 -0
- package/dist/components/modals/router/useAllModalsParams.js +1 -0
- package/dist/components/modals/router/useModalParams.js +1 -0
- package/dist/components/modals/router/useModalsNavigation.js +1 -0
- package/dist/components/modals/router/useUpdateModalContainer.js +1 -0
- package/dist/components/presentation/Avatar.js +1 -1
- package/dist/components/presentation/AvatarLabel.js +1 -1
- package/dist/components/presentation/LabelValue.js +1 -1
- package/dist/components/presentation/Result.js +1 -1
- package/dist/components/presentation/Tooltip.js +1 -1
- package/dist/components/sections/Section.js +1 -0
- package/dist/components/sections/SectionItem.js +1 -0
- package/dist/components/sections/SectionItemDropdown.js +1 -0
- package/dist/components/sections/SectionItemLink.js +1 -0
- package/dist/components/sections/index.js +1 -0
- package/dist/components/state/StatePresenter.js +1 -0
- package/dist/components/state/index.js +1 -1
- package/dist/components/structure/BlurView.js +1 -1
- package/dist/components/structure/KeyboardAvoidingView.js +1 -0
- package/dist/components/structure/TopBar.js +1 -0
- package/dist/components/structure/index.js +1 -1
- package/dist/components/structure/popover/Popover.js +1 -1
- package/dist/components/structure/popover/Popover.native.js +1 -1
- package/dist/components/structure/popover/Popover_BU.js +1 -1
- package/dist/components/text/DateText.js +1 -0
- package/dist/components/text/index.js +1 -1
- package/dist/components/theme/ThemePicker.js +1 -1
- package/dist/components/theme/ThemePickerDrawer.js +1 -1
- package/dist/helpers/index.js +1 -1
- package/dist/helpers/storage.js +1 -1
- package/dist/responsive/responsiveHooks.js +1 -1
- package/dist/theme/ThemeHandler.js +1 -1
- package/dist/theme/default/base.js +1 -1
- package/dist/theme/default/blackTheme.js +1 -1
- package/dist/theme/default/cyberpunkTheme.js +1 -1
- package/dist/theme/default/darkTheme.js +1 -1
- package/dist/theme/default/hackerTheme.js +1 -1
- package/dist/theme/default/lightTheme.js +1 -1
- package/dist/theme/default/paperTheme.js +1 -1
- package/dist/theme/default/themes.js +1 -1
- package/package.json +1 -1
- package/src/NekoUI.js +1 -1
- package/src/abstractions/FlatList.native.js +2 -1
- package/src/abstractions/KeyboardAvoidingView.js +3 -0
- package/src/abstractions/KeyboardAvoidingView.native.js +3 -0
- package/src/abstractions/ScrollView.native.js +2 -2
- package/src/components/actions/ActionsDrawer.js +68 -0
- package/src/components/actions/Button.js +2 -1
- package/src/components/actions/FloatingMenu.js +39 -0
- package/src/components/actions/index.js +2 -0
- package/src/components/animations/AnimatedTopBar.js +10 -0
- package/src/components/animations/AnimatedTopBar.native.js +34 -0
- package/src/components/animations/AnimatedTopBar.web.js +1 -0
- package/src/components/animations/ParallaxHeader.js +9 -0
- package/src/components/animations/ParallaxHeader.native.js +32 -0
- package/src/components/animations/ParallaxHeader.web.js +32 -0
- package/src/components/animations/ReanimatedScrollHandler.js +8 -0
- package/src/components/animations/ReanimatedScrollHandler.native.js +24 -0
- package/src/components/animations/ReanimatedScrollHandler.web.js +1 -0
- package/src/components/animations/index.js +3 -0
- package/src/components/feedback/alerter.js +1 -1
- package/src/components/feedback/confirmer.js +1 -1
- package/src/components/form/FormItem.js +42 -5
- package/src/components/form/FormList.js +23 -4
- package/src/components/form/SubmitButton.js +4 -2
- package/src/components/form/index.js +1 -0
- package/src/components/form/useNewForm.js +108 -15
- package/src/components/form/validation/defaultMessages.js +20 -0
- package/src/components/form/validation/index.js +5 -0
- package/src/components/form/validation/normalizeRules.js +22 -0
- package/src/components/form/validation/shouldValidateOn.js +21 -0
- package/src/components/form/validation/validateRules.js +83 -0
- package/src/components/form/validation/validators.js +82 -0
- package/src/components/index.js +2 -0
- package/src/components/inputs/InputWrapper.js +1 -1
- package/src/components/inputs/NumberInput.js +6 -5
- package/src/components/inputs/Picker.js +3 -2
- package/src/components/inputs/Select.js +31 -15
- package/src/components/modals/bottomDrawer/index.js +3 -0
- package/src/components/{structure → modals}/bottomDrawer/index.native.js +2 -1
- package/src/components/{structure → modals}/bottomDrawer/index.web.js +2 -1
- package/src/components/{structure → modals}/bottomDrawer/native/BottomDrawer.js +15 -21
- package/src/components/{structure → modals}/bottomDrawer/native/DrawerHandle.js +1 -1
- package/src/components/modals/bottomDrawer/native/DrawerScrollView.js +5 -0
- package/src/components/modals/bottomDrawer/native/createDrawerScrollComponent.js +131 -0
- package/src/components/modals/index.js +4 -0
- package/src/components/{structure → modals}/modal/Modal.native.js +1 -1
- package/src/components/{structure → modals}/modal/ModalBackdrop.js +1 -1
- package/src/components/{structure → modals}/modal/ModalContent.js +1 -1
- package/src/components/{structure → modals}/modal/ModalFooter.js +1 -1
- package/src/components/{structure → modals}/modal/ModalHeader.js +1 -1
- package/src/components/modals/router/ModalRoute.js +15 -0
- package/src/components/modals/router/ModalsRouter.js +120 -0
- package/src/components/modals/router/ModalsRouterContext.js +16 -0
- package/src/components/modals/router/index.js +6 -0
- package/src/components/modals/router/useAllModalsParams.js +6 -0
- package/src/components/modals/router/useModalParams.js +6 -0
- package/src/components/modals/router/useModalsNavigation.js +6 -0
- package/src/components/modals/router/useUpdateModalContainer.js +6 -0
- package/src/components/presentation/Avatar.js +2 -2
- package/src/components/presentation/AvatarLabel.js +2 -0
- package/src/components/presentation/LabelValue.js +7 -5
- package/src/components/presentation/Result.js +2 -2
- package/src/components/presentation/Tooltip.js +1 -1
- package/src/components/sections/Section.js +50 -0
- package/src/components/sections/SectionItem.js +24 -0
- package/src/components/sections/SectionItemDropdown.js +68 -0
- package/src/components/sections/SectionItemLink.js +33 -0
- package/src/components/sections/index.js +4 -0
- package/src/components/state/StatePresenter.js +41 -0
- package/src/components/state/index.js +1 -0
- package/src/components/structure/BlurView.js +1 -0
- package/src/components/structure/KeyboardAvoidingView.js +52 -0
- package/src/components/structure/TopBar.js +45 -0
- package/src/components/structure/index.js +2 -3
- package/src/components/structure/popover/Popover.js +1 -1
- package/src/components/structure/popover/Popover.native.js +1 -1
- package/src/components/structure/popover/Popover_BU.js +1 -1
- package/src/components/text/DateText.js +11 -0
- package/src/components/text/index.js +1 -0
- package/src/components/theme/ThemePicker.js +1 -2
- package/src/components/theme/ThemePickerDrawer.js +3 -4
- package/src/helpers/index.js +1 -0
- package/src/helpers/storage.js +32 -9
- package/src/responsive/responsiveHooks.js +6 -0
- package/src/theme/ThemeHandler.js +6 -3
- package/src/theme/default/base.js +16 -4
- package/src/theme/default/blackTheme.js +33 -21
- package/src/theme/default/cyberpunkTheme.js +24 -22
- package/src/theme/default/darkTheme.js +1 -0
- package/src/theme/default/hackerTheme.js +40 -19
- package/src/theme/default/lightTheme.js +1 -0
- package/src/theme/default/paperTheme.js +14 -0
- package/src/theme/default/themes.js +0 -9
- package/dist/components/structure/bottomDrawer/index.js +0 -1
- package/dist/components/structure/bottomDrawer/index.native.js +0 -1
- package/dist/components/structure/bottomDrawer/index.web.js +0 -1
- package/dist/components/structure/bottomDrawer/native/BottomDrawer.js +0 -1
- package/dist/components/structure/bottomDrawer/native/DrawerContext.js +0 -1
- package/dist/components/structure/bottomDrawer/native/DrawerHandle.js +0 -1
- package/dist/components/structure/bottomDrawer/native/DrawerScrollView.js +0 -1
- package/dist/components/structure/bottomDrawer/web/BottomDrawer.js +0 -1
- package/dist/components/structure/drawer/Drawer.js +0 -1
- package/dist/components/structure/modal/Modal.js +0 -1
- package/dist/components/structure/modal/Modal.native.js +0 -1
- package/dist/components/structure/modal/ModalBackdrop.js +0 -1
- package/dist/components/structure/modal/ModalContent.js +0 -1
- package/dist/components/structure/modal/ModalFooter.js +0 -1
- package/dist/components/structure/modal/ModalHeader.js +0 -1
- package/dist/components/structure/modal/handler/ModalsHandler.js +0 -1
- package/dist/theme/default/deepWoodsTheme.js +0 -1
- package/dist/theme/default/forestTheme.js +0 -1
- package/dist/theme/default/midnightTheme.js +0 -1
- package/dist/theme/default/msdosTheme.js +0 -1
- package/dist/theme/default/oceanTheme.js +0 -1
- package/dist/theme/default/pastelTheme.js +0 -1
- package/dist/theme/default/sunsetTheme.js +0 -1
- package/src/components/structure/bottomDrawer/index.js +0 -1
- package/src/components/structure/bottomDrawer/native/DrawerScrollView.js +0 -83
- package/src/theme/default/deepWoodsTheme.js +0 -34
- package/src/theme/default/forestTheme.js +0 -34
- package/src/theme/default/midnightTheme.js +0 -34
- package/src/theme/default/msdosTheme.js +0 -55
- package/src/theme/default/oceanTheme.js +0 -34
- package/src/theme/default/pastelTheme.js +0 -34
- package/src/theme/default/sunsetTheme.js +0 -35
- /package/dist/components/{structure → modals}/bottomDrawer/native/utils.js +0 -0
- /package/dist/components/{structure → modals}/drawer/Drawer.native.js +0 -0
- /package/dist/components/{structure → modals}/drawer/Drawer.web.js +0 -0
- /package/dist/components/{structure → modals}/drawer/index.js +0 -0
- /package/dist/components/{structure → modals}/modal/index.js +0 -0
- /package/src/components/{structure → modals}/bottomDrawer/native/DrawerContext.js +0 -0
- /package/src/components/{structure → modals}/bottomDrawer/native/utils.js +0 -0
- /package/src/components/{structure → modals}/bottomDrawer/web/BottomDrawer.js +0 -0
- /package/src/components/{structure → modals}/drawer/Drawer.js +0 -0
- /package/src/components/{structure → modals}/drawer/Drawer.native.js +0 -0
- /package/src/components/{structure → modals}/drawer/Drawer.web.js +0 -0
- /package/src/components/{structure → modals}/drawer/index.js +0 -0
- /package/src/components/{structure → modals}/modal/Modal.js +0 -0
- /package/src/components/{structure → modals}/modal/handler/ModalsHandler.js +0 -0
- /package/src/components/{structure → modals}/modal/index.js +0 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { path as getPath } from 'ramda'
|
|
2
|
+
import { validators } from './validators'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Validates a value against an array of rules
|
|
6
|
+
* @param {any} value - The value to validate
|
|
7
|
+
* @param {Array} rules - Array of rule objects
|
|
8
|
+
* @param {string} trigger - Current validation trigger ('onSubmit', 'onBlur', 'onChange')
|
|
9
|
+
* @returns {Promise<string|null>} - First error message or null if valid
|
|
10
|
+
*/
|
|
11
|
+
export async function validateRules(value, rules, trigger = 'onSubmit') {
|
|
12
|
+
if (!rules || rules.length === 0) return null
|
|
13
|
+
|
|
14
|
+
for (const rule of rules) {
|
|
15
|
+
const ruleTrigger = rule.trigger || 'onSubmit'
|
|
16
|
+
const triggers = Array.isArray(ruleTrigger) ? ruleTrigger : [ruleTrigger]
|
|
17
|
+
|
|
18
|
+
// Always run on submit, otherwise check trigger match
|
|
19
|
+
if (trigger !== 'onSubmit' && !triggers.includes(trigger)) {
|
|
20
|
+
continue
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let error = null
|
|
24
|
+
|
|
25
|
+
// Custom validator takes precedence
|
|
26
|
+
if (rule.validator) {
|
|
27
|
+
try {
|
|
28
|
+
await rule.validator(rule, value)
|
|
29
|
+
} catch (e) {
|
|
30
|
+
error = e.message || rule.message || 'Validation failed'
|
|
31
|
+
}
|
|
32
|
+
} else {
|
|
33
|
+
// Run built-in validators
|
|
34
|
+
if (rule.required) {
|
|
35
|
+
error = validators.required(value, rule)
|
|
36
|
+
}
|
|
37
|
+
if (!error && rule.type) {
|
|
38
|
+
error = validators.type(value, rule)
|
|
39
|
+
}
|
|
40
|
+
if (!error && rule.min !== undefined) {
|
|
41
|
+
error = validators.min(value, rule)
|
|
42
|
+
}
|
|
43
|
+
if (!error && rule.max !== undefined) {
|
|
44
|
+
error = validators.max(value, rule)
|
|
45
|
+
}
|
|
46
|
+
if (!error && rule.pattern) {
|
|
47
|
+
error = validators.pattern(value, rule)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (error) {
|
|
52
|
+
return error
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return null
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Validates multiple fields at once (for form-level validation)
|
|
61
|
+
* @param {Object} values - All form values
|
|
62
|
+
* @param {Map} rulesRegistry - Map of field path keys to { path: array, rules: array }
|
|
63
|
+
* @returns {Promise<Object>} - Object of path key -> error message
|
|
64
|
+
*/
|
|
65
|
+
export async function validateAllFields(values, rulesRegistry) {
|
|
66
|
+
const errors = {}
|
|
67
|
+
const validationPromises = []
|
|
68
|
+
|
|
69
|
+
rulesRegistry.forEach(({ path, rules }, pathKey) => {
|
|
70
|
+
const value = getPath(path, values)
|
|
71
|
+
|
|
72
|
+
validationPromises.push(
|
|
73
|
+
validateRules(value, rules, 'onSubmit').then((error) => {
|
|
74
|
+
if (error) {
|
|
75
|
+
errors[pathKey] = error
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
await Promise.all(validationPromises)
|
|
82
|
+
return errors
|
|
83
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { defaultMessages } from './defaultMessages'
|
|
2
|
+
|
|
3
|
+
const isEmpty = (value) => {
|
|
4
|
+
if (value === undefined || value === null) return true
|
|
5
|
+
if (typeof value === 'string' && value.trim() === '') return true
|
|
6
|
+
if (Array.isArray(value) && value.length === 0) return true
|
|
7
|
+
return false
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const validators = {
|
|
11
|
+
required: (value, rule) => {
|
|
12
|
+
if (isEmpty(value)) {
|
|
13
|
+
return rule.message || defaultMessages.required
|
|
14
|
+
}
|
|
15
|
+
return null
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
type: (value, rule) => {
|
|
19
|
+
if (isEmpty(value)) return null
|
|
20
|
+
|
|
21
|
+
const typeValidators = {
|
|
22
|
+
email: (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v),
|
|
23
|
+
url: (v) => {
|
|
24
|
+
try {
|
|
25
|
+
new URL(v)
|
|
26
|
+
return true
|
|
27
|
+
} catch {
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
number: (v) => !isNaN(Number(v)),
|
|
32
|
+
integer: (v) => Number.isInteger(Number(v)) && !isNaN(Number(v)),
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const validator = typeValidators[rule.type]
|
|
36
|
+
if (validator && !validator(value)) {
|
|
37
|
+
return rule.message || defaultMessages.type[rule.type] || `Invalid ${rule.type}`
|
|
38
|
+
}
|
|
39
|
+
return null
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
min: (value, rule) => {
|
|
43
|
+
if (isEmpty(value)) return null
|
|
44
|
+
|
|
45
|
+
if (typeof value === 'string' && value.length < rule.min) {
|
|
46
|
+
return rule.message || defaultMessages.min.string(rule.min)
|
|
47
|
+
}
|
|
48
|
+
if (typeof value === 'number' && value < rule.min) {
|
|
49
|
+
return rule.message || defaultMessages.min.number(rule.min)
|
|
50
|
+
}
|
|
51
|
+
if (Array.isArray(value) && value.length < rule.min) {
|
|
52
|
+
return rule.message || defaultMessages.min.array(rule.min)
|
|
53
|
+
}
|
|
54
|
+
return null
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
max: (value, rule) => {
|
|
58
|
+
if (isEmpty(value)) return null
|
|
59
|
+
|
|
60
|
+
if (typeof value === 'string' && value.length > rule.max) {
|
|
61
|
+
return rule.message || defaultMessages.max.string(rule.max)
|
|
62
|
+
}
|
|
63
|
+
if (typeof value === 'number' && value > rule.max) {
|
|
64
|
+
return rule.message || defaultMessages.max.number(rule.max)
|
|
65
|
+
}
|
|
66
|
+
if (Array.isArray(value) && value.length > rule.max) {
|
|
67
|
+
return rule.message || defaultMessages.max.array(rule.max)
|
|
68
|
+
}
|
|
69
|
+
return null
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
pattern: (value, rule) => {
|
|
73
|
+
if (isEmpty(value)) return null
|
|
74
|
+
|
|
75
|
+
const regex = rule.pattern instanceof RegExp ? rule.pattern : new RegExp(rule.pattern)
|
|
76
|
+
|
|
77
|
+
if (!regex.test(String(value))) {
|
|
78
|
+
return rule.message || defaultMessages.pattern
|
|
79
|
+
}
|
|
80
|
+
return null
|
|
81
|
+
},
|
|
82
|
+
}
|
package/src/components/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export * from './animations'
|
|
|
3
3
|
export * from './form'
|
|
4
4
|
export * from './presentation'
|
|
5
5
|
export * from './structure'
|
|
6
|
+
export * from './modals'
|
|
6
7
|
export * from './text'
|
|
7
8
|
export * from './helpers'
|
|
8
9
|
export * from './inputs'
|
|
@@ -14,3 +15,4 @@ export * from './calendar'
|
|
|
14
15
|
export * from './list'
|
|
15
16
|
export * from './tabs'
|
|
16
17
|
export * from './theme'
|
|
18
|
+
export * from './sections'
|
|
@@ -48,7 +48,7 @@ export function InputWrapper({
|
|
|
48
48
|
if (!!suffix && is(String, suffix)) suffix = <Text>{suffix}</Text>
|
|
49
49
|
if (!prefix && !!prefixIcon) prefix = <Icon name={prefixIcon} size={sizeCode} color={prefixIconColor} />
|
|
50
50
|
if (!suffix && !!suffixIcon) suffix = <Icon name={suffixIcon} size={sizeCode} color={suffixIconColor} />
|
|
51
|
-
if (!prefix && !!error) suffix = <Icon name="
|
|
51
|
+
if (!prefix && !!error) suffix = <Icon name="alert-fill" size={sizeCode} red />
|
|
52
52
|
if (!!loading) suffix = <Loading size={sizeCode} />
|
|
53
53
|
|
|
54
54
|
let borderColor = !!hover ? 'primary_op40' : 'divider'
|
|
@@ -73,11 +73,11 @@ export function formatNumericValue(newValue, prevValue, options = {}) {
|
|
|
73
73
|
return numericValue
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
export function NumberInput({ onChange, value, useInt, precision, min, max, error, ...props }) {
|
|
76
|
+
export function NumberInput({ onChange, onBlur, value, useInt, precision, min, max, error, ...props }) {
|
|
77
77
|
const [hasError, setHasError] = React.useState(false)
|
|
78
78
|
const [inputValue, setInputValue] = React.useState(value)
|
|
79
79
|
const [localValue, setLocalValue] = React.useState(value)
|
|
80
|
-
React.useEffect(() => setInputValue(value), [value])
|
|
80
|
+
React.useEffect(() => setInputValue(value?.toString() || ''), [value])
|
|
81
81
|
|
|
82
82
|
if (useInt) precision = 0
|
|
83
83
|
if (!useInt && precision === 0) useInt = true
|
|
@@ -85,6 +85,7 @@ export function NumberInput({ onChange, value, useInt, precision, min, max, erro
|
|
|
85
85
|
|
|
86
86
|
return (
|
|
87
87
|
<TextInput
|
|
88
|
+
{...props}
|
|
88
89
|
onChange={(newValue) => {
|
|
89
90
|
const numericValue = formatNumericValue(newValue, localValue, opts)
|
|
90
91
|
setInputValue(newValue?.toString() || '')
|
|
@@ -92,14 +93,14 @@ export function NumberInput({ onChange, value, useInt, precision, min, max, erro
|
|
|
92
93
|
onChange?.(numericValue)
|
|
93
94
|
setHasError(!isValidNumber(newValue, opts))
|
|
94
95
|
}}
|
|
95
|
-
onBlur={() => {
|
|
96
|
-
setInputValue(localValue)
|
|
96
|
+
onBlur={(e) => {
|
|
97
|
+
setInputValue(localValue?.toString() || '')
|
|
97
98
|
setHasError(!isValidNumber(localValue, opts))
|
|
99
|
+
onBlur?.(e)
|
|
98
100
|
}}
|
|
99
101
|
value={inputValue}
|
|
100
102
|
keyboardType={useInt ? 'number-pad' : 'decimal-pad'}
|
|
101
103
|
error={error || hasError}
|
|
102
|
-
{...props}
|
|
103
104
|
/>
|
|
104
105
|
)
|
|
105
106
|
}
|
|
@@ -2,9 +2,10 @@ import { is } from 'ramda'
|
|
|
2
2
|
import React from 'react'
|
|
3
3
|
|
|
4
4
|
import { Col } from '../structure/Col'
|
|
5
|
-
import {
|
|
5
|
+
import { DrawerFlatList } from '../modals/bottomDrawer'
|
|
6
6
|
import { LoadingView } from '../state/LoadingView'
|
|
7
7
|
import { Row } from '../structure/Row'
|
|
8
|
+
import { View } from '../structure'
|
|
8
9
|
import { normalizeString } from '../../helpers/string'
|
|
9
10
|
import { useOptions } from '../../helpers/options'
|
|
10
11
|
|
|
@@ -94,7 +95,7 @@ function DefaultPickerWrapper({ renderItem, options, ...props }) {
|
|
|
94
95
|
|
|
95
96
|
function FlatListPickerWrapper({ renderItem, options, valueKey, ...props }) {
|
|
96
97
|
return (
|
|
97
|
-
<
|
|
98
|
+
<DrawerFlatList
|
|
98
99
|
keyExtractor={(i) => i[valueKey]}
|
|
99
100
|
data={options}
|
|
100
101
|
divider
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { dissoc } from 'ramda'
|
|
1
2
|
import React from 'react'
|
|
2
3
|
|
|
3
4
|
import { Icon, IconLabel } from '../presentation'
|
|
@@ -38,6 +39,7 @@ export function Select({
|
|
|
38
39
|
pickerProps,
|
|
39
40
|
popoverProps,
|
|
40
41
|
popoverMaxHeight,
|
|
42
|
+
snapPoints,
|
|
41
43
|
...props
|
|
42
44
|
}) {
|
|
43
45
|
const [focus, setFocus] = React.useState(false)
|
|
@@ -52,7 +54,17 @@ export function Select({
|
|
|
52
54
|
onEndReached = onEndReached || pickerProps?.onEndReached
|
|
53
55
|
renderFooter = renderFooter || pickerProps?.renderFooter
|
|
54
56
|
renderHeader = renderHeader || pickerProps?.renderHeader
|
|
55
|
-
pickerProps = {
|
|
57
|
+
pickerProps = {
|
|
58
|
+
...pickerProps,
|
|
59
|
+
|
|
60
|
+
labelKey,
|
|
61
|
+
valueKey,
|
|
62
|
+
useRawOption,
|
|
63
|
+
multiple,
|
|
64
|
+
onEndReached,
|
|
65
|
+
renderFooter,
|
|
66
|
+
renderHeader,
|
|
67
|
+
}
|
|
56
68
|
|
|
57
69
|
popoverMaxHeight = popoverMaxHeight || 300
|
|
58
70
|
|
|
@@ -93,7 +105,10 @@ export function Select({
|
|
|
93
105
|
const finalRenderOption = React.useCallback(
|
|
94
106
|
(params) => {
|
|
95
107
|
if (!!renderOption) return renderOption(params)
|
|
96
|
-
|
|
108
|
+
let { option, labelKey, selected } = params
|
|
109
|
+
if (option?.id) option = dissoc('id', option)
|
|
110
|
+
if (option?.color) option = { ...option, color: undefined, iconColor: option.color }
|
|
111
|
+
|
|
97
112
|
return <IconLabel {...option} label={option?.[labelKey]} flex strong={selected} />
|
|
98
113
|
},
|
|
99
114
|
[renderOption]
|
|
@@ -103,7 +118,7 @@ export function Select({
|
|
|
103
118
|
<Popover
|
|
104
119
|
trigger="click"
|
|
105
120
|
placement={placement || 'bottomLeft'}
|
|
106
|
-
snapPoints={[450]}
|
|
121
|
+
snapPoints={snapPoints || [450]}
|
|
107
122
|
useBottomDrawer={useBottomDrawer}
|
|
108
123
|
parentWidth
|
|
109
124
|
padding={0}
|
|
@@ -112,17 +127,6 @@ export function Select({
|
|
|
112
127
|
maxHeight={popoverMaxHeight}
|
|
113
128
|
{...popoverProps}
|
|
114
129
|
renderContent={({ onClose }) => (
|
|
115
|
-
<>
|
|
116
|
-
{useBottomDrawer && useSearch && (
|
|
117
|
-
<View padding="md" paddingB="xs">
|
|
118
|
-
<TextInput
|
|
119
|
-
prefixIcon="search-line"
|
|
120
|
-
prefixIconColor="text4"
|
|
121
|
-
value={search}
|
|
122
|
-
onChange={handleChangeSearch}
|
|
123
|
-
/>
|
|
124
|
-
</View>
|
|
125
|
-
)}
|
|
126
130
|
<Picker
|
|
127
131
|
row={false}
|
|
128
132
|
options={searchOptions(options, search, { labelKey })}
|
|
@@ -137,6 +141,19 @@ export function Select({
|
|
|
137
141
|
if (!multiple) onClose()
|
|
138
142
|
}}
|
|
139
143
|
{...pickerProps}
|
|
144
|
+
renderHeader={useBottomDrawer && useSearch ? () => (
|
|
145
|
+
<>
|
|
146
|
+
<View padding="md" paddingB="xs">
|
|
147
|
+
<TextInput
|
|
148
|
+
prefixIcon="search-line"
|
|
149
|
+
prefixIconColor="text4"
|
|
150
|
+
value={search}
|
|
151
|
+
onChange={handleChangeSearch}
|
|
152
|
+
/>
|
|
153
|
+
</View>
|
|
154
|
+
{renderHeader?.()}
|
|
155
|
+
</>
|
|
156
|
+
) : renderHeader}
|
|
140
157
|
renderOption={({ option, selected, onChange }) => (
|
|
141
158
|
<Link
|
|
142
159
|
row
|
|
@@ -156,7 +173,6 @@ export function Select({
|
|
|
156
173
|
</Link>
|
|
157
174
|
)}
|
|
158
175
|
/>
|
|
159
|
-
</>
|
|
160
176
|
)}
|
|
161
177
|
>
|
|
162
178
|
<Input
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { BottomDrawer } from './native/BottomDrawer'
|
|
2
|
-
export { DrawerScrollView } from './native/DrawerScrollView'
|
|
2
|
+
export { DrawerScrollView, DrawerFlatList } from './native/DrawerScrollView'
|
|
3
|
+
export { createDrawerScrollComponent } from './native/createDrawerScrollComponent'
|
|
3
4
|
export { DrawerHandle } from './native/DrawerHandle'
|
|
4
5
|
export { DrawerProvider, useDrawerContext } from './native/DrawerContext'
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { BottomDrawer } from './native/BottomDrawer'
|
|
2
|
-
export { DrawerScrollView } from './native/DrawerScrollView'
|
|
2
|
+
export { DrawerScrollView, DrawerFlatList } from './native/DrawerScrollView'
|
|
3
|
+
export { createDrawerScrollComponent } from './native/createDrawerScrollComponent'
|
|
3
4
|
export { DrawerHandle } from './native/DrawerHandle'
|
|
4
5
|
export { DrawerProvider, useDrawerContext } from './native/DrawerContext'
|
|
@@ -6,14 +6,13 @@ import Animated, {
|
|
|
6
6
|
useAnimatedStyle,
|
|
7
7
|
withSpring,
|
|
8
8
|
runOnJS,
|
|
9
|
-
useAnimatedReaction,
|
|
10
9
|
} from 'react-native-reanimated'
|
|
11
10
|
import React from 'react'
|
|
12
11
|
|
|
13
12
|
import { DrawerHandle } from './DrawerHandle'
|
|
14
13
|
import { DrawerProvider } from './DrawerContext'
|
|
15
14
|
import { Pressable } from '../../../actions/Pressable'
|
|
16
|
-
import { View } from '
|
|
15
|
+
import { View } from '../../../structure/View'
|
|
17
16
|
import { normalizeSnapPoints, findClosestSnapPoint } from './utils'
|
|
18
17
|
import { useColors } from '../../../../theme/ThemeHandler'
|
|
19
18
|
|
|
@@ -47,9 +46,6 @@ function InnerContent({
|
|
|
47
46
|
const colors = useColors()
|
|
48
47
|
|
|
49
48
|
const translateY = useSharedValue(SCREEN_HEIGHT)
|
|
50
|
-
const scrollOffset = useSharedValue(0)
|
|
51
|
-
const scrollEnabled = useSharedValue(false)
|
|
52
|
-
const isScrolling = useSharedValue(false)
|
|
53
49
|
const snapIndex = useSharedValue(0)
|
|
54
50
|
const velocityY = useSharedValue(0)
|
|
55
51
|
|
|
@@ -67,8 +63,6 @@ function InnerContent({
|
|
|
67
63
|
snapIndex.value = 0
|
|
68
64
|
} else {
|
|
69
65
|
translateY.value = withSpring(SCREEN_HEIGHT, animationConfig, () => {
|
|
70
|
-
scrollOffset.value = 0
|
|
71
|
-
scrollEnabled.value = false
|
|
72
66
|
runOnJS(setRender)(false)
|
|
73
67
|
})
|
|
74
68
|
snapIndex.value = -1
|
|
@@ -84,15 +78,6 @@ function InnerContent({
|
|
|
84
78
|
return () => backHandler.remove()
|
|
85
79
|
}, [open, onClose])
|
|
86
80
|
|
|
87
|
-
useAnimatedReaction(
|
|
88
|
-
() => translateY.value,
|
|
89
|
-
(currentY) => {
|
|
90
|
-
const atMaxSnapPoint = currentY <= SCREEN_HEIGHT - maxSnapPoint
|
|
91
|
-
scrollEnabled.value = atMaxSnapPoint
|
|
92
|
-
},
|
|
93
|
-
[]
|
|
94
|
-
)
|
|
95
|
-
|
|
96
81
|
let handleClose = React.useCallback(() => {
|
|
97
82
|
onClose?.()
|
|
98
83
|
}, [onClose])
|
|
@@ -112,9 +97,11 @@ function InnerContent({
|
|
|
112
97
|
|
|
113
98
|
// contexto manual para gesto
|
|
114
99
|
const gestureStartTranslateY = useSharedValue(0)
|
|
100
|
+
const panRef = React.useRef()
|
|
115
101
|
|
|
116
102
|
const panGesture = React.useMemo(() => {
|
|
117
103
|
return Gesture.Pan()
|
|
104
|
+
.withRef(panRef)
|
|
118
105
|
.enabled(enableHandlePanningGesture || enableContentPanningGesture)
|
|
119
106
|
.onStart(() => {
|
|
120
107
|
gestureStartTranslateY.value = translateY.value
|
|
@@ -135,7 +122,11 @@ function InnerContent({
|
|
|
135
122
|
const currentPosition = SCREEN_HEIGHT - translateY.value
|
|
136
123
|
const shouldClose =
|
|
137
124
|
!!handleClose &&
|
|
138
|
-
(
|
|
125
|
+
(
|
|
126
|
+
velocityY.value > 1500 ||
|
|
127
|
+
(velocityY.value > 800 && currentPosition < minSnapPoint) ||
|
|
128
|
+
currentPosition < minSnapPoint * 0.35
|
|
129
|
+
)
|
|
139
130
|
|
|
140
131
|
if (shouldClose) {
|
|
141
132
|
runOnJS(handleClose)()
|
|
@@ -168,15 +159,18 @@ function InnerContent({
|
|
|
168
159
|
const contextValue = React.useMemo(
|
|
169
160
|
() => ({
|
|
170
161
|
translateY,
|
|
171
|
-
scrollOffset,
|
|
172
|
-
scrollEnabled,
|
|
173
|
-
isScrolling,
|
|
174
162
|
snapIndex,
|
|
175
163
|
maxSnapPoint,
|
|
176
164
|
snapTo,
|
|
177
165
|
animationConfig,
|
|
166
|
+
panRef,
|
|
167
|
+
normalizedSnapPoints,
|
|
168
|
+
SCREEN_HEIGHT,
|
|
169
|
+
minSnapPoint,
|
|
170
|
+
handleClose,
|
|
171
|
+
velocityY,
|
|
178
172
|
}),
|
|
179
|
-
[maxSnapPoint]
|
|
173
|
+
[maxSnapPoint, normalizedSnapPoints, SCREEN_HEIGHT, minSnapPoint, handleClose]
|
|
180
174
|
)
|
|
181
175
|
|
|
182
176
|
return (
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { FlatList, ScrollView } from '../../../list'
|
|
2
|
+
import { createDrawerScrollComponent } from './createDrawerScrollComponent'
|
|
3
|
+
|
|
4
|
+
export const DrawerScrollView = createDrawerScrollComponent(ScrollView)
|
|
5
|
+
export const DrawerFlatList = createDrawerScrollComponent(FlatList)
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Gesture, GestureDetector } from 'react-native-gesture-handler'
|
|
2
|
+
import Animated, {
|
|
3
|
+
useSharedValue,
|
|
4
|
+
useAnimatedScrollHandler,
|
|
5
|
+
useAnimatedRef,
|
|
6
|
+
scrollTo,
|
|
7
|
+
withSpring,
|
|
8
|
+
runOnJS,
|
|
9
|
+
} from 'react-native-reanimated'
|
|
10
|
+
import React from 'react'
|
|
11
|
+
|
|
12
|
+
import { findClosestSnapPoint, clamp } from './utils'
|
|
13
|
+
import { useDrawerContext } from './DrawerContext'
|
|
14
|
+
|
|
15
|
+
export function createDrawerScrollComponent(Component) {
|
|
16
|
+
const AnimatedComponent = Animated.createAnimatedComponent(Component)
|
|
17
|
+
|
|
18
|
+
function DrawerScrollComponent({ ref, onScroll, ...props }) {
|
|
19
|
+
const {
|
|
20
|
+
translateY,
|
|
21
|
+
panRef,
|
|
22
|
+
normalizedSnapPoints,
|
|
23
|
+
SCREEN_HEIGHT,
|
|
24
|
+
maxSnapPoint,
|
|
25
|
+
minSnapPoint,
|
|
26
|
+
handleClose,
|
|
27
|
+
animationConfig,
|
|
28
|
+
snapIndex,
|
|
29
|
+
} = useDrawerContext()
|
|
30
|
+
|
|
31
|
+
const scrollRef = useAnimatedRef()
|
|
32
|
+
const scrollOffset = useSharedValue(0)
|
|
33
|
+
const prevTranslationY = useSharedValue(0)
|
|
34
|
+
const drawerMoved = useSharedValue(false)
|
|
35
|
+
|
|
36
|
+
React.useImperativeHandle(ref, () => scrollRef.current)
|
|
37
|
+
|
|
38
|
+
const maxPosition = SCREEN_HEIGHT - maxSnapPoint
|
|
39
|
+
|
|
40
|
+
const panGesture = React.useMemo(() => {
|
|
41
|
+
return Gesture.Pan()
|
|
42
|
+
.activeOffsetY([-10, 10])
|
|
43
|
+
.blocksExternalGesture(panRef)
|
|
44
|
+
.onStart(() => {
|
|
45
|
+
prevTranslationY.value = 0
|
|
46
|
+
drawerMoved.value = false
|
|
47
|
+
})
|
|
48
|
+
.onUpdate((event) => {
|
|
49
|
+
const delta = event.translationY - prevTranslationY.value
|
|
50
|
+
prevTranslationY.value = event.translationY
|
|
51
|
+
|
|
52
|
+
const currentY = translateY.value
|
|
53
|
+
const atMaxSnap = currentY <= maxPosition + 1
|
|
54
|
+
const atScrollTop = scrollOffset.value <= 0
|
|
55
|
+
|
|
56
|
+
if (drawerMoved.value) {
|
|
57
|
+
const newY = clamp(currentY + delta, maxPosition, SCREEN_HEIGHT)
|
|
58
|
+
translateY.value = newY
|
|
59
|
+
scrollTo(scrollRef, 0, 0, false)
|
|
60
|
+
|
|
61
|
+
if (newY <= maxPosition + 1 && delta < 0) {
|
|
62
|
+
drawerMoved.value = false
|
|
63
|
+
}
|
|
64
|
+
} else if (!atMaxSnap) {
|
|
65
|
+
drawerMoved.value = true
|
|
66
|
+
const newY = clamp(currentY + delta, maxPosition, SCREEN_HEIGHT)
|
|
67
|
+
translateY.value = newY
|
|
68
|
+
scrollTo(scrollRef, 0, 0, false)
|
|
69
|
+
} else if (atScrollTop && delta > 0) {
|
|
70
|
+
drawerMoved.value = true
|
|
71
|
+
const newY = clamp(currentY + delta, maxPosition, SCREEN_HEIGHT)
|
|
72
|
+
translateY.value = newY
|
|
73
|
+
scrollTo(scrollRef, 0, 0, false)
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
.onEnd((event) => {
|
|
77
|
+
if (!drawerMoved.value) return
|
|
78
|
+
|
|
79
|
+
const currentPosition = SCREEN_HEIGHT - translateY.value
|
|
80
|
+
const velocity = event.velocityY
|
|
81
|
+
|
|
82
|
+
const shouldClose =
|
|
83
|
+
!!handleClose &&
|
|
84
|
+
(velocity > 1500 ||
|
|
85
|
+
(velocity > 800 && currentPosition < minSnapPoint) ||
|
|
86
|
+
currentPosition < minSnapPoint * 0.35)
|
|
87
|
+
|
|
88
|
+
if (shouldClose) {
|
|
89
|
+
runOnJS(handleClose)()
|
|
90
|
+
} else {
|
|
91
|
+
const closestSnapIndex = findClosestSnapPoint(currentPosition, normalizedSnapPoints, velocity)
|
|
92
|
+
const targetSnapPoint = normalizedSnapPoints[closestSnapIndex]
|
|
93
|
+
translateY.value = withSpring(SCREEN_HEIGHT - targetSnapPoint, animationConfig)
|
|
94
|
+
snapIndex.value = closestSnapIndex
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
}, [panRef, maxPosition, normalizedSnapPoints, minSnapPoint, handleClose, animationConfig])
|
|
98
|
+
|
|
99
|
+
const nativeGesture = React.useMemo(() => Gesture.Native(), [])
|
|
100
|
+
|
|
101
|
+
const composedGesture = React.useMemo(
|
|
102
|
+
() => Gesture.Simultaneous(panGesture, nativeGesture),
|
|
103
|
+
[panGesture, nativeGesture]
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
const animatedScrollHandler = useAnimatedScrollHandler({
|
|
107
|
+
onScroll: (event) => {
|
|
108
|
+
scrollOffset.value = event.contentOffset.y
|
|
109
|
+
if (onScroll) {
|
|
110
|
+
runOnJS(onScroll)(event)
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<GestureDetector gesture={composedGesture}>
|
|
117
|
+
<AnimatedComponent
|
|
118
|
+
ref={scrollRef}
|
|
119
|
+
style={{ flex: 1 }}
|
|
120
|
+
onScroll={animatedScrollHandler}
|
|
121
|
+
scrollEventThrottle={16}
|
|
122
|
+
bounces={false}
|
|
123
|
+
overScrollMode="never"
|
|
124
|
+
{...props}
|
|
125
|
+
/>
|
|
126
|
+
</GestureDetector>
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return DrawerScrollComponent
|
|
131
|
+
}
|
|
@@ -6,7 +6,7 @@ import { ModalContent } from './ModalContent'
|
|
|
6
6
|
import { ModalFooter } from './ModalFooter'
|
|
7
7
|
import { ModalHeader } from './ModalHeader'
|
|
8
8
|
import { Pressable } from '../../actions/Pressable'
|
|
9
|
-
import { View } from '
|
|
9
|
+
import { View } from '../../structure/View'
|
|
10
10
|
import { useDefaultModifier } from '../../../modifiers/default'
|
|
11
11
|
import { useThemeComponentModifier } from '../../../modifiers/themeComponent'
|
|
12
12
|
|
|
@@ -2,7 +2,7 @@ import { pipe } from 'ramda'
|
|
|
2
2
|
import React from 'react'
|
|
3
3
|
|
|
4
4
|
import { AnimatedView } from '../../animations/AnimatedView'
|
|
5
|
-
import { SafeAreaView } from '
|
|
5
|
+
import { SafeAreaView } from '../../structure/SafeAreaView'
|
|
6
6
|
import { useDefaultModifier } from '../../../modifiers/default'
|
|
7
7
|
import { useThemeComponentModifier } from '../../../modifiers/themeComponent'
|
|
8
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { pipe } from 'ramda'
|
|
2
2
|
|
|
3
|
-
import { View } from '
|
|
3
|
+
import { View } from '../../structure/View'
|
|
4
4
|
import { moveScale } from '../../../theme/helpers/sizeScale'
|
|
5
5
|
import { useDefaultModifier } from '../../../modifiers/default'
|
|
6
6
|
import { useSizeConverter } from '../../../modifiers/sizeConverter'
|
|
@@ -3,7 +3,7 @@ import { pipe } from 'ramda'
|
|
|
3
3
|
import { Icon } from '../../presentation/Icon'
|
|
4
4
|
import { Link } from '../../actions/Link'
|
|
5
5
|
import { Text } from '../../text/Text'
|
|
6
|
-
import { View } from '
|
|
6
|
+
import { View } from '../../structure/View'
|
|
7
7
|
import { moveScale } from '../../../theme/helpers/sizeScale'
|
|
8
8
|
import { useDefaultModifier } from '../../../modifiers/default'
|
|
9
9
|
import { useSizeConverter } from '../../../modifiers/sizeConverter'
|