@neko-os/ui 0.0.4 → 0.0.6
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/ActivityIndicator.js +1 -0
- package/dist/abstractions/ActivityIndicator.native.js +1 -0
- package/dist/abstractions/AnimatedView.js +1 -0
- package/dist/abstractions/AnimatedView.native.js +1 -0
- package/dist/abstractions/BKTouchableOpacity.js +0 -0
- package/dist/abstractions/DraggableSlideView.js +1 -0
- package/dist/abstractions/DraggableSlideView.native.js +1 -0
- package/dist/abstractions/HiddenInput.js +1 -0
- package/dist/abstractions/HiddenInput.native.js +1 -0
- package/dist/abstractions/Icon.js +1 -1
- package/dist/abstractions/Icon.native.js +1 -1
- package/dist/abstractions/Icon.web.js +1 -1
- package/dist/abstractions/Image.js +1 -0
- package/dist/abstractions/Image.native.js +1 -0
- package/dist/abstractions/Image.web.js +1 -0
- package/dist/abstractions/Platform.js +1 -0
- package/dist/abstractions/Platform.native.js +1 -0
- package/dist/abstractions/Platform.web.js +1 -0
- package/dist/abstractions/SafeAreaView.js +1 -0
- package/dist/abstractions/SafeAreaView.native.js +1 -0
- package/dist/abstractions/Switch.js +1 -0
- package/dist/abstractions/Switch.native.js +1 -0
- package/dist/abstractions/Table.js +1 -0
- package/dist/abstractions/Table.native.js +1 -0
- package/dist/abstractions/Text.js +1 -1
- package/dist/abstractions/TextInput.js +1 -0
- package/dist/abstractions/TextInput.native.js +1 -0
- package/dist/abstractions/TextInput.web.js +1 -0
- package/dist/abstractions/TouchableOpacity.js +1 -1
- package/dist/abstractions/TouchableOpacity.native.js +1 -0
- package/dist/abstractions/TouchableOpacity.web.js +1 -0
- package/dist/abstractions/View.js +1 -1
- package/dist/abstractions/helpers/componentSize.js +1 -0
- package/dist/abstractions/helpers/componentSize.native.js +1 -0
- package/dist/abstractions/helpers/transformStyle.js +1 -0
- package/dist/abstractions/helpers/transformStyle.native.js +1 -0
- package/dist/abstractions/helpers/windowWidth.js +1 -0
- package/dist/abstractions/helpers/windowWidth.native.js +1 -0
- package/dist/abstractions/helpers/windowWidth.web.js +1 -0
- package/dist/components/actions/Breadcrumb.js +1 -0
- package/dist/components/actions/Button.js +1 -0
- package/dist/components/actions/Dropdown.js +1 -0
- package/dist/components/actions/Link.js +1 -0
- package/dist/components/actions/index.js +1 -0
- package/dist/components/actions/menu/HorizontalMenu.js +1 -0
- package/dist/components/actions/menu/Menu.js +1 -0
- package/dist/components/actions/menu/SubmenuWrapper.js +1 -0
- package/dist/components/actions/menu/VerticalMenu.js +1 -0
- package/dist/components/animations/AnimatedView.js +1 -0
- package/dist/components/animations/DraggableSlideView.js +1 -0
- package/dist/components/animations/index.js +1 -0
- package/dist/components/calendar/DayPicker.js +1 -0
- package/dist/components/calendar/_helpers/calendarDays.js +1 -0
- package/dist/components/calendar/index.js +1 -0
- package/dist/components/feedback/index.js +1 -0
- package/dist/components/feedback/notifications/Notification.js +1 -0
- package/dist/components/feedback/notifications/NotificationsHandler.js +1 -0
- package/dist/components/form/Form.js +1 -0
- package/dist/components/form/FormGroup.js +1 -0
- package/dist/components/form/FormItem.js +1 -0
- package/dist/components/form/FormList.js +1 -0
- package/dist/components/form/FormWrapperComponent.js +1 -0
- package/dist/components/form/FormWrapperComponent.native.js +1 -0
- package/dist/components/form/SubmitButton.js +1 -0
- package/dist/{form → components/form}/index.js +1 -1
- package/dist/components/form/useNewForm.js +1 -0
- package/dist/components/form/useWatch.js +1 -0
- package/dist/components/helpers/LazyRender.js +1 -0
- package/dist/components/helpers/LazyRender.native.js +1 -0
- package/dist/components/helpers/Portal.js +1 -0
- package/dist/components/helpers/PortalHandler.js +1 -0
- package/dist/components/helpers/Responsive.js +1 -0
- package/dist/components/helpers/Separator.js +1 -0
- package/dist/components/helpers/VerticalView.js +1 -0
- package/dist/components/helpers/index.js +1 -0
- package/dist/components/index.js +1 -0
- package/dist/components/inputs/Checkbox.js +1 -0
- package/dist/components/inputs/InputWrapper.js +1 -0
- package/dist/components/inputs/Picker.js +1 -0
- package/dist/components/inputs/Radio.js +1 -0
- package/dist/components/inputs/Switch.js +1 -0
- package/dist/components/inputs/TextInput.js +1 -0
- package/dist/components/inputs/index.js +1 -0
- package/dist/components/layout/Layout.js +1 -0
- package/dist/components/layout/LayoutContent.js +1 -0
- package/dist/components/layout/LayoutHeader.js +1 -0
- package/dist/components/layout/LayoutSider.js +1 -0
- package/dist/components/layout/index.js +1 -0
- package/dist/components/presentation/Avatar.js +1 -0
- package/dist/components/presentation/AvatarLabel.js +1 -0
- package/dist/components/presentation/Badge.js +1 -0
- package/dist/components/presentation/ContentLabel.js +1 -0
- package/dist/components/presentation/Icon.js +1 -0
- package/dist/components/presentation/IconLabel.js +1 -0
- package/dist/components/presentation/Image.js +1 -0
- package/dist/components/presentation/LabelValue.js +1 -0
- package/dist/components/presentation/Result.js +1 -0
- package/dist/components/presentation/ResultBar.js +1 -0
- package/dist/components/presentation/Tag.js +1 -0
- package/dist/components/presentation/Tooltip.js +1 -0
- package/dist/components/presentation/index.js +1 -0
- package/dist/components/state/Loading.js +1 -0
- package/dist/components/state/LoadingView.js +1 -0
- package/dist/components/state/index.js +1 -0
- package/dist/components/structure/Accordion.js +1 -0
- package/dist/components/structure/AccordionGroup.js +1 -0
- package/dist/components/structure/Card.js +1 -0
- package/dist/components/structure/Col.js +1 -0
- package/dist/components/structure/Row.js +1 -0
- package/dist/components/structure/SafeAreaView.js +1 -0
- package/dist/components/structure/View.js +1 -0
- package/dist/components/structure/index.js +1 -0
- package/dist/components/structure/overlay/OverlayHandler.js +1 -0
- package/dist/components/structure/overlay/OverlayHandler.native.js +1 -0
- package/dist/components/structure/overlay/OverlayWrapper.js +1 -0
- package/dist/components/structure/overlay/calculatePosition.js +1 -0
- package/dist/components/structure/overlay/smartPlacement.js +1 -0
- package/dist/components/structure/popover/Popover.js +1 -0
- package/dist/components/structure/popover/Popover.native.js +1 -0
- package/dist/components/structure/popover/PopoverContent.js +1 -0
- package/dist/components/table/DataTable.js +1 -0
- package/dist/components/table/Pagination.js +1 -0
- package/dist/components/table/Table.js +1 -0
- package/dist/components/table/TableCol.js +1 -0
- package/dist/components/table/TableHeader.js +1 -0
- package/dist/components/table/TableHeaderRow.js +1 -0
- package/dist/components/table/TableRow.js +1 -0
- package/dist/components/table/index.js +1 -0
- package/dist/components/text/Text.js +1 -0
- package/dist/components/text/VerticalText.js +1 -0
- package/dist/components/text/index.js +1 -0
- package/dist/helpers/debounce.js +1 -0
- package/dist/helpers/index.js +1 -0
- package/dist/helpers/options.js +1 -0
- package/dist/helpers/random.js +1 -0
- package/dist/index.css +15 -0
- package/dist/index.js +1 -1
- package/dist/modifiers/alignConverter.js +1 -0
- package/dist/modifiers/animation.js +1 -0
- package/dist/modifiers/animations/animatedEffects.js +1 -0
- package/dist/modifiers/animations/animatedEffects.native.js +1 -0
- package/dist/modifiers/animations/animatedEffects.web.js +1 -0
- package/dist/modifiers/animations/fadeEffect.js +1 -0
- package/dist/modifiers/animations/fadeEffect.native.js +1 -0
- package/dist/modifiers/animations/slideEffect.js +1 -0
- package/dist/modifiers/animations/slideEffect.native.js +1 -0
- package/dist/modifiers/applyStyles.js +1 -0
- package/dist/modifiers/background.js +1 -1
- package/dist/modifiers/border.js +1 -1
- package/dist/modifiers/colorConverter.js +1 -0
- package/dist/modifiers/default.js +1 -0
- package/dist/modifiers/display.js +1 -0
- package/dist/modifiers/flex.js +1 -1
- package/dist/modifiers/flexWrapper.js +1 -1
- package/dist/modifiers/fullColor.js +1 -0
- package/dist/modifiers/grid.js +1 -0
- package/dist/modifiers/logger.js +1 -0
- package/dist/modifiers/margin.js +1 -1
- package/dist/modifiers/overflow.js +1 -0
- package/dist/modifiers/padding.js +1 -1
- package/dist/modifiers/position.js +1 -1
- package/dist/modifiers/responsiveConverter.js +1 -0
- package/dist/modifiers/shadow.js +1 -1
- package/dist/modifiers/size.js +1 -1
- package/dist/modifiers/sizeConverter.js +1 -0
- package/dist/modifiers/state.js +1 -0
- package/dist/modifiers/text.js +1 -1
- package/dist/modifiers/textConverter.js +1 -0
- package/dist/modifiers/themeComponent.js +1 -0
- package/dist/responsive/ResponsiveHandler.js +1 -0
- package/dist/responsive/index.js +1 -0
- package/dist/responsive/responsiveHooks.js +1 -0
- package/dist/theme/ThemeHandler.js +1 -1
- package/dist/theme/default/base.js +1 -1
- package/dist/theme/default/cyberpunkTheme.js +1 -1
- package/dist/theme/default/darkTheme.js +1 -1
- package/dist/theme/default/deepWoodsTheme.js +1 -1
- package/dist/theme/default/forestTheme.js +1 -1
- package/dist/theme/default/hackerTheme.js +1 -0
- package/dist/theme/default/lightTheme.js +1 -1
- package/dist/theme/default/midnightTheme.js +1 -1
- package/dist/theme/default/msdosTheme.js +1 -0
- package/dist/theme/default/oceanTheme.js +1 -1
- package/dist/theme/default/pastelTheme.js +1 -1
- package/dist/theme/default/sunsetTheme.js +1 -1
- package/dist/theme/default/themes.js +1 -1
- package/dist/theme/helpers/colorScale.js +1 -0
- package/dist/theme/helpers/contrastColor.js +1 -0
- package/dist/theme/helpers/dynamicColor.js +1 -0
- package/dist/theme/helpers/mergePreset.js +1 -0
- package/dist/theme/helpers/relatedScales.js +1 -0
- package/dist/theme/helpers/sizeScale.js +1 -1
- package/dist/theme/helpers/textScale.js +1 -0
- package/package.json +8 -4
- package/src/NekoUI.js +15 -1
- package/src/abstractions/ActivityIndicator.js +31 -0
- package/src/abstractions/ActivityIndicator.native.js +44 -0
- package/src/abstractions/AnimatedView.js +3 -0
- package/src/abstractions/AnimatedView.native.js +6 -0
- package/src/abstractions/BKTouchableOpacity.js +12 -0
- package/src/abstractions/DraggableSlideView.js +85 -0
- package/src/abstractions/DraggableSlideView.native.js +62 -0
- package/src/abstractions/HiddenInput.js +3 -0
- package/src/abstractions/HiddenInput.native.js +3 -0
- package/src/abstractions/Icon.js +4 -20
- package/src/abstractions/Icon.native.js +11 -2
- package/src/abstractions/Icon.web.js +11 -2
- package/src/abstractions/Image.js +12 -0
- package/src/abstractions/Image.native.js +7 -0
- package/src/abstractions/Image.web.js +7 -0
- package/src/abstractions/Platform.js +1 -0
- package/src/abstractions/Platform.native.js +3 -0
- package/src/abstractions/Platform.web.js +3 -0
- package/src/abstractions/SafeAreaView.js +3 -0
- package/src/abstractions/SafeAreaView.native.js +3 -0
- package/src/abstractions/Switch.js +97 -0
- package/src/abstractions/Switch.native.js +12 -0
- package/src/abstractions/Table.js +29 -0
- package/src/abstractions/Table.native.js +19 -0
- package/src/abstractions/Text.js +13 -2
- package/src/abstractions/TextInput.js +3 -0
- package/src/abstractions/TextInput.native.js +5 -0
- package/src/abstractions/TextInput.web.js +5 -0
- package/src/abstractions/TouchableOpacity.js +3 -11
- package/src/abstractions/TouchableOpacity.native.js +3 -0
- package/src/abstractions/TouchableOpacity.web.js +3 -0
- package/src/abstractions/View.js +2 -2
- package/src/abstractions/helpers/componentSize.js +13 -0
- package/src/abstractions/helpers/componentSize.native.js +12 -0
- package/src/abstractions/helpers/transformStyle.js +8 -0
- package/src/abstractions/helpers/transformStyle.native.js +3 -0
- package/src/abstractions/helpers/windowWidth.js +13 -0
- package/src/abstractions/helpers/windowWidth.native.js +6 -0
- package/src/abstractions/helpers/windowWidth.web.js +6 -0
- package/src/components/actions/Breadcrumb.js +47 -0
- package/src/components/actions/Button.js +67 -0
- package/src/components/actions/Dropdown.js +68 -0
- package/src/components/actions/Link.js +52 -0
- package/src/components/actions/index.js +5 -0
- package/src/components/actions/menu/HorizontalMenu.js +96 -0
- package/src/components/actions/menu/Menu.js +7 -0
- package/src/components/actions/menu/SubmenuWrapper.js +16 -0
- package/src/components/actions/menu/VerticalMenu.js +107 -0
- package/src/components/animations/AnimatedView.js +45 -0
- package/src/components/animations/DraggableSlideView.js +42 -0
- package/src/components/animations/index.js +2 -0
- package/src/components/calendar/DayPicker.js +91 -0
- package/src/components/calendar/_helpers/calendarDays.js +16 -0
- package/src/components/calendar/index.js +1 -0
- package/src/components/feedback/index.js +1 -0
- package/src/components/feedback/notifications/Notification.js +37 -0
- package/src/components/feedback/notifications/NotificationsHandler.js +65 -0
- package/src/components/form/Form.js +25 -0
- package/src/{form → components/form}/FormGroup.js +4 -4
- package/src/components/form/FormItem.js +56 -0
- package/src/{form → components/form}/FormList.js +47 -11
- package/src/components/form/FormWrapperComponent.js +43 -0
- package/src/components/form/FormWrapperComponent.native.js +5 -0
- package/src/components/form/SubmitButton.js +20 -0
- package/src/{form → components/form}/index.js +3 -1
- package/src/components/form/useNewForm.js +67 -0
- package/src/components/form/useWatch.js +70 -0
- package/src/components/helpers/LazyRender.js +55 -0
- package/src/components/helpers/LazyRender.native.js +58 -0
- package/src/components/helpers/Portal.js +21 -0
- package/src/components/helpers/PortalHandler.js +32 -0
- package/src/components/helpers/Responsive.js +18 -0
- package/src/components/helpers/Separator.js +45 -0
- package/src/components/helpers/VerticalView.js +34 -0
- package/src/components/helpers/index.js +6 -0
- package/src/components/index.js +13 -0
- package/src/components/inputs/Checkbox.js +56 -0
- package/src/components/inputs/InputWrapper.js +79 -0
- package/src/components/inputs/Picker.js +116 -0
- package/src/components/inputs/Radio.js +55 -0
- package/src/components/inputs/Switch.js +60 -0
- package/src/components/inputs/TextInput.js +22 -0
- package/src/components/inputs/index.js +6 -0
- package/src/components/layout/Layout.js +40 -0
- package/src/components/layout/LayoutContent.js +42 -0
- package/src/components/layout/LayoutHeader.js +69 -0
- package/src/components/layout/LayoutSider.js +64 -0
- package/src/components/layout/index.js +4 -0
- package/src/components/presentation/Avatar.js +79 -0
- package/src/components/presentation/AvatarLabel.js +58 -0
- package/src/components/presentation/Badge.js +90 -0
- package/src/components/presentation/ContentLabel.js +43 -0
- package/src/components/presentation/Icon.js +20 -0
- package/src/components/presentation/IconLabel.js +39 -0
- package/src/components/presentation/Image.js +33 -0
- package/src/components/presentation/LabelValue.js +49 -0
- package/src/components/presentation/Result.js +60 -0
- package/src/components/presentation/ResultBar.js +56 -0
- package/src/components/presentation/Tag.js +69 -0
- package/src/components/presentation/Tooltip.js +43 -0
- package/src/components/presentation/index.js +11 -0
- package/src/components/state/Loading.js +20 -0
- package/src/components/state/LoadingView.js +28 -0
- package/src/components/state/index.js +2 -0
- package/src/components/structure/Accordion.js +69 -0
- package/src/components/structure/AccordionGroup.js +35 -0
- package/src/components/structure/Card.js +45 -0
- package/src/components/structure/Col.js +22 -0
- package/src/components/structure/Row.js +42 -0
- package/src/components/structure/SafeAreaView.js +42 -0
- package/src/components/structure/View.js +42 -0
- package/src/components/structure/index.js +8 -0
- package/src/components/structure/overlay/OverlayHandler.js +70 -0
- package/src/components/structure/overlay/OverlayHandler.native.js +6 -0
- package/src/components/structure/overlay/OverlayWrapper.js +52 -0
- package/src/components/structure/overlay/calculatePosition.js +29 -0
- package/src/components/structure/overlay/smartPlacement.js +32 -0
- package/src/components/structure/popover/Popover.js +69 -0
- package/src/components/structure/popover/Popover.native.js +75 -0
- package/src/components/structure/popover/PopoverContent.js +18 -0
- package/src/components/table/DataTable.js +57 -0
- package/src/components/table/Pagination.js +128 -0
- package/src/components/table/Table.js +65 -0
- package/src/components/table/TableCol.js +67 -0
- package/src/components/table/TableHeader.js +69 -0
- package/src/components/table/TableHeaderRow.js +31 -0
- package/src/components/table/TableRow.js +30 -0
- package/src/components/table/index.js +7 -0
- package/src/components/text/Text.js +32 -0
- package/src/components/text/VerticalText.js +29 -0
- package/src/components/text/index.js +2 -0
- package/src/helpers/debounce.js +9 -0
- package/src/helpers/index.js +3 -0
- package/src/helpers/options.js +65 -0
- package/src/helpers/random.js +5 -0
- package/src/index.css +15 -0
- package/src/index.js +3 -5
- package/src/modifiers/alignConverter.js +11 -0
- package/src/modifiers/animation.js +18 -0
- package/src/modifiers/animations/animatedEffects.js +63 -0
- package/src/modifiers/animations/animatedEffects.native.js +53 -0
- package/src/modifiers/animations/animatedEffects.web.js +3 -0
- package/src/modifiers/animations/fadeEffect.js +43 -0
- package/src/modifiers/animations/fadeEffect.native.js +33 -0
- package/src/modifiers/animations/slideEffect.js +61 -0
- package/src/modifiers/animations/slideEffect.native.js +53 -0
- package/src/modifiers/applyStyles.js +7 -0
- package/src/modifiers/background.js +10 -7
- package/src/modifiers/border.js +40 -13
- package/src/modifiers/colorConverter.js +13 -0
- package/src/modifiers/default.js +9 -0
- package/src/modifiers/display.js +22 -0
- package/src/modifiers/flex.js +11 -8
- package/src/modifiers/flexWrapper.js +58 -14
- package/src/modifiers/fullColor.js +29 -0
- package/src/modifiers/grid.js +27 -0
- package/src/modifiers/logger.js +6 -0
- package/src/modifiers/margin.js +10 -7
- package/src/modifiers/overflow.js +23 -0
- package/src/modifiers/padding.js +10 -7
- package/src/modifiers/position.js +20 -9
- package/src/modifiers/responsiveConverter.js +19 -0
- package/src/modifiers/shadow.js +10 -7
- package/src/modifiers/size.js +18 -9
- package/src/modifiers/sizeConverter.js +12 -0
- package/src/modifiers/state.js +33 -0
- package/src/modifiers/text.js +14 -13
- package/src/modifiers/textConverter.js +12 -0
- package/src/modifiers/themeComponent.js +11 -0
- package/src/responsive/ResponsiveHandler.js +28 -0
- package/src/responsive/index.js +2 -0
- package/src/responsive/responsiveHooks.js +54 -0
- package/src/theme/ThemeHandler.js +31 -33
- package/src/theme/default/base.js +29 -17
- package/src/theme/default/cyberpunkTheme.js +1 -0
- package/src/theme/default/darkTheme.js +2 -1
- package/src/theme/default/deepWoodsTheme.js +1 -0
- package/src/theme/default/forestTheme.js +1 -0
- package/src/theme/default/hackerTheme.js +40 -0
- package/src/theme/default/lightTheme.js +1 -0
- package/src/theme/default/midnightTheme.js +1 -0
- package/src/theme/default/msdosTheme.js +40 -0
- package/src/theme/default/oceanTheme.js +1 -0
- package/src/theme/default/pastelTheme.js +1 -0
- package/src/theme/default/sunsetTheme.js +1 -0
- package/src/theme/default/themes.js +4 -0
- package/src/theme/helpers/colorScale.js +11 -0
- package/src/theme/helpers/contrastColor.js +20 -0
- package/src/theme/helpers/dynamicColor.js +32 -0
- package/src/theme/helpers/mergePreset.js +7 -0
- package/src/theme/helpers/relatedScales.js +34 -0
- package/src/theme/helpers/sizeScale.js +17 -4
- package/src/theme/helpers/textScale.js +15 -0
- package/dist/actions/Button.js +0 -1
- package/dist/actions/index.js +0 -1
- package/dist/form/Form.js +0 -1
- package/dist/form/FormGroup.js +0 -1
- package/dist/form/FormItem.js +0 -1
- package/dist/form/FormList.js +0 -1
- package/dist/form/FormWrapperComponent.js +0 -1
- package/dist/form/FormWrapperComponent.native.js +0 -1
- package/dist/form/useForm.js +0 -1
- package/dist/modifiers/fullColor.js.js +0 -1
- package/dist/presentation/Icon.js +0 -1
- package/dist/presentation/Tag.js +0 -1
- package/dist/presentation/index.js +0 -1
- package/dist/structure/Card.js +0 -1
- package/dist/structure/View.js +0 -1
- package/dist/structure/index.js +0 -1
- package/dist/text/Text.js +0 -1
- package/dist/text/index.js +0 -1
- package/dist/theme/default/base.native.js +0 -1
- package/dist/theme/default/base.web.js +0 -1
- package/src/actions/Button.js +0 -48
- package/src/actions/index.js +0 -1
- package/src/form/Form.js +0 -14
- package/src/form/FormItem.js +0 -34
- package/src/form/FormWrapperComponent.js +0 -8
- package/src/form/FormWrapperComponent.native.js +0 -5
- package/src/form/useForm.js +0 -65
- package/src/modifiers/fullColor.js.js +0 -30
- package/src/presentation/Icon.js +0 -14
- package/src/presentation/Tag.js +0 -32
- package/src/presentation/index.js +0 -2
- package/src/structure/Card.js +0 -36
- package/src/structure/View.js +0 -34
- package/src/structure/index.js +0 -2
- package/src/text/Text.js +0 -20
- package/src/text/index.js +0 -1
- package/src/theme/default/base.native.js +0 -58
- package/src/theme/default/base.web.js +0 -3
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Dropdown } from '../Dropdown'
|
|
2
|
+
import { Icon } from '../../presentation/Icon'
|
|
3
|
+
import { View } from '../../structure/View'
|
|
4
|
+
|
|
5
|
+
export function SubmenuWrapper({ item, children, placement, hideIcon, ...props }) {
|
|
6
|
+
if (!item.subItems?.length) return children
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<Dropdown popoverProps={{ placement: placement || 'rightTop' }} items={item.subItems} trigger="hover" {...props}>
|
|
10
|
+
<View flex row gap="xxs" center fullH>
|
|
11
|
+
{children}
|
|
12
|
+
{!hideIcon && <Icon name="arrow-right-s-line" />}
|
|
13
|
+
</View>
|
|
14
|
+
</Dropdown>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { omit, pipe } from 'ramda'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import tinycolor from 'tinycolor2'
|
|
4
|
+
|
|
5
|
+
import { Divider } from '../../helpers/Separator'
|
|
6
|
+
import { IconText } from '../../presentation/IconLabel'
|
|
7
|
+
import { Link } from '../Link'
|
|
8
|
+
import { SubmenuWrapper } from './SubmenuWrapper'
|
|
9
|
+
import { Text } from '../../text/Text'
|
|
10
|
+
import { View } from '../../structure/View'
|
|
11
|
+
import { useColorConverter } from '../../../modifiers/colorConverter'
|
|
12
|
+
import { useSizeConverter } from '../../../modifiers/sizeConverter'
|
|
13
|
+
import { useThemeComponentModifier } from '../../../modifiers/themeComponent'
|
|
14
|
+
|
|
15
|
+
function LinkItem({
|
|
16
|
+
item,
|
|
17
|
+
linkPaddingH = 'md',
|
|
18
|
+
linkPaddingV = 'xs',
|
|
19
|
+
handlePress,
|
|
20
|
+
linkProps,
|
|
21
|
+
activeIndex,
|
|
22
|
+
activeKey,
|
|
23
|
+
activeColor = 'primary',
|
|
24
|
+
color,
|
|
25
|
+
sizeCode,
|
|
26
|
+
index,
|
|
27
|
+
...props
|
|
28
|
+
}) {
|
|
29
|
+
activeColor = activeColor || 'primary'
|
|
30
|
+
let { active, key, ...childProps } = omit(['onClick', 'onPress'], item)
|
|
31
|
+
if (!active && activeIndex >= 0) active = activeIndex === index
|
|
32
|
+
if (!active && activeKey !== undefined) active = activeKey === item.key
|
|
33
|
+
const bg = active && tinycolor(color).setAlpha(0.03).toString()
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<SubmenuWrapper item={item} onChange={handlePress} activeKey={activeKey} color={color}>
|
|
37
|
+
<Link
|
|
38
|
+
fullW
|
|
39
|
+
center
|
|
40
|
+
paddingH={linkPaddingH}
|
|
41
|
+
paddingV={linkPaddingV}
|
|
42
|
+
marginR={3}
|
|
43
|
+
borderL={3}
|
|
44
|
+
marginV={!!active && -4}
|
|
45
|
+
borderColor={active ? activeColor : 'transparent'}
|
|
46
|
+
bg={bg}
|
|
47
|
+
transition="border-color 0.5s ease, background 0.3s ease"
|
|
48
|
+
{...linkProps}
|
|
49
|
+
onPress={() => handlePress(item, index)}
|
|
50
|
+
>
|
|
51
|
+
<IconText paddingV={active && 4} color={active ? activeColor : color} fullW size={sizeCode} {...childProps} />
|
|
52
|
+
</Link>
|
|
53
|
+
</SubmenuWrapper>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function DividerItem({ linkPaddingH = 'md', item }) {
|
|
58
|
+
let content = <Divider height="xxs" line {...item} />
|
|
59
|
+
if (!item.label) return content
|
|
60
|
+
return (
|
|
61
|
+
<>
|
|
62
|
+
{content}
|
|
63
|
+
<Text size="xs" color="text4" paddingH={linkPaddingH || 'md'} strong {...item} />
|
|
64
|
+
</>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function Item({ item, ...props }) {
|
|
69
|
+
if (item.type === 'divider') return <DividerItem item={item} {...props} />
|
|
70
|
+
return <LinkItem item={item} {...props} />
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function VerticalMenu(rootProps) {
|
|
74
|
+
const [{ sizeCode, color }, formattedProps] = pipe(
|
|
75
|
+
useColorConverter('text'),
|
|
76
|
+
useSizeConverter('icons', 'md'),
|
|
77
|
+
useThemeComponentModifier('VerticalMenu') //
|
|
78
|
+
)([{}, rootProps])
|
|
79
|
+
|
|
80
|
+
let { gap = 'sm', items, onChange, onChangeIndex, ...props } = formattedProps
|
|
81
|
+
|
|
82
|
+
const handlePress = React.useCallback(
|
|
83
|
+
(item, index) => {
|
|
84
|
+
if (!!onChange) onChange(item, index)
|
|
85
|
+
if (!!onChangeIndex) onChangeIndex(index)
|
|
86
|
+
if (!!item.onPress) item.onPress()
|
|
87
|
+
if (!!item.onClick) item.onClick()
|
|
88
|
+
},
|
|
89
|
+
[onChange, onChangeIndex]
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<View className="neko-vertical-menu" gap={gap} width="100%" {...props}>
|
|
94
|
+
{items.map((item, index) => (
|
|
95
|
+
<Item
|
|
96
|
+
key={item.key || index}
|
|
97
|
+
item={item}
|
|
98
|
+
handlePress={handlePress}
|
|
99
|
+
color={color}
|
|
100
|
+
sizeCode={sizeCode}
|
|
101
|
+
index={index}
|
|
102
|
+
{...props}
|
|
103
|
+
/>
|
|
104
|
+
))}
|
|
105
|
+
</View>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { pipe } from 'ramda'
|
|
2
|
+
|
|
3
|
+
import { AbsAnimatedView } from '../../abstractions/AnimatedView'
|
|
4
|
+
import { useAnimatedEffects } from '../../modifiers/animations/animatedEffects'
|
|
5
|
+
import { useBackgroundModifier } from '../../modifiers/background'
|
|
6
|
+
import { useBorderModifier } from '../../modifiers/border'
|
|
7
|
+
import { useDisplayModifier } from '../../modifiers/display'
|
|
8
|
+
import { useFlexModifier } from '../../modifiers/flex'
|
|
9
|
+
import { useFlexWrapperModifier } from '../../modifiers/flexWrapper'
|
|
10
|
+
import { useMarginModifier } from '../../modifiers/margin'
|
|
11
|
+
import { useOverflowModifier } from '../../modifiers/overflow'
|
|
12
|
+
import { usePaddingModifier } from '../../modifiers/padding'
|
|
13
|
+
import { usePositionModifier } from '../../modifiers/position'
|
|
14
|
+
import { useShadowModifier } from '../../modifiers/shadow'
|
|
15
|
+
import { useSizeModifier } from '../../modifiers/size'
|
|
16
|
+
import { useStateModifier } from '../../modifiers/state'
|
|
17
|
+
import { useThemeComponentModifier } from '../../modifiers/themeComponent'
|
|
18
|
+
|
|
19
|
+
export function AnimatedView({ children, ...rootProps }) {
|
|
20
|
+
const [{ lazy, render, hasOpened }, props] = pipe(
|
|
21
|
+
useAnimatedEffects,
|
|
22
|
+
useThemeComponentModifier('AnimatedView'),
|
|
23
|
+
useFlexWrapperModifier,
|
|
24
|
+
useDisplayModifier,
|
|
25
|
+
useStateModifier,
|
|
26
|
+
useSizeModifier,
|
|
27
|
+
usePositionModifier,
|
|
28
|
+
useOverflowModifier,
|
|
29
|
+
usePaddingModifier,
|
|
30
|
+
useMarginModifier,
|
|
31
|
+
useFlexModifier,
|
|
32
|
+
useBackgroundModifier,
|
|
33
|
+
useBorderModifier,
|
|
34
|
+
useShadowModifier
|
|
35
|
+
)([{}, rootProps])
|
|
36
|
+
|
|
37
|
+
if (lazy && !hasOpened) return null
|
|
38
|
+
if (!render) return null
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<AbsAnimatedView className="neko-animated-view" {...props}>
|
|
42
|
+
{children}
|
|
43
|
+
</AbsAnimatedView>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { pipe } from 'ramda'
|
|
2
|
+
|
|
3
|
+
import { AbsDraggableSlideView } from '../../abstractions/DraggableSlideView'
|
|
4
|
+
import { useAnimationModifier } from '../../modifiers/animation'
|
|
5
|
+
import { useBackgroundModifier } from '../../modifiers/background'
|
|
6
|
+
import { useBorderModifier } from '../../modifiers/border'
|
|
7
|
+
import { useDisplayModifier } from '../../modifiers/display'
|
|
8
|
+
import { useFlexModifier } from '../../modifiers/flex'
|
|
9
|
+
import { useFlexWrapperModifier } from '../../modifiers/flexWrapper'
|
|
10
|
+
import { useMarginModifier } from '../../modifiers/margin'
|
|
11
|
+
import { useOverflowModifier } from '../../modifiers/overflow'
|
|
12
|
+
import { usePaddingModifier } from '../../modifiers/padding'
|
|
13
|
+
import { usePositionModifier } from '../../modifiers/position'
|
|
14
|
+
import { useShadowModifier } from '../../modifiers/shadow'
|
|
15
|
+
import { useSizeModifier } from '../../modifiers/size'
|
|
16
|
+
import { useStateModifier } from '../../modifiers/state'
|
|
17
|
+
import { useThemeComponentModifier } from '../../modifiers/themeComponent'
|
|
18
|
+
|
|
19
|
+
export function DraggableSlideView({ children, ...rootProps }) {
|
|
20
|
+
const [_, props] = pipe(
|
|
21
|
+
useThemeComponentModifier('DraggableSlideView'),
|
|
22
|
+
useFlexWrapperModifier,
|
|
23
|
+
useDisplayModifier,
|
|
24
|
+
useAnimationModifier,
|
|
25
|
+
useStateModifier,
|
|
26
|
+
useSizeModifier,
|
|
27
|
+
usePositionModifier,
|
|
28
|
+
useOverflowModifier,
|
|
29
|
+
usePaddingModifier,
|
|
30
|
+
useMarginModifier,
|
|
31
|
+
useFlexModifier,
|
|
32
|
+
useBackgroundModifier,
|
|
33
|
+
useBorderModifier,
|
|
34
|
+
useShadowModifier
|
|
35
|
+
)([{}, rootProps])
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<AbsDraggableSlideView className="neko-draggable-slide-view" {...props}>
|
|
39
|
+
{children}
|
|
40
|
+
</AbsDraggableSlideView>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import dayjs from 'dayjs'
|
|
3
|
+
|
|
4
|
+
import { Col } from '../structure/Col'
|
|
5
|
+
import { Grid } from '../structure/Row'
|
|
6
|
+
import { Icon } from '../presentation/Icon'
|
|
7
|
+
import { Link } from '../actions/Link'
|
|
8
|
+
import { Text } from '../text/Text'
|
|
9
|
+
import { View } from '../structure/View'
|
|
10
|
+
import { useCalendarDays } from './_helpers/calendarDays'
|
|
11
|
+
|
|
12
|
+
export function DayPicker({ initialValue, value, onChange, ...props }) {
|
|
13
|
+
const [localValue, setLocalValue] = React.useState(dayjs(initialValue))
|
|
14
|
+
value = value === undefined ? localValue : value
|
|
15
|
+
const handleChange = (v) => {
|
|
16
|
+
setLocalValue(v)
|
|
17
|
+
onChange?.(v)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const [currentMonth, setCurrentMonth] = React.useState(() =>
|
|
21
|
+
initialValue ? dayjs(initialValue).startOf('month') : dayjs().startOf('month')
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
const prevMonth = () => setCurrentMonth((m) => m.subtract(1, 'month'))
|
|
25
|
+
const nextMonth = () => setCurrentMonth((m) => m.add(1, 'month'))
|
|
26
|
+
|
|
27
|
+
const prevYear = () => setCurrentMonth((m) => m.subtract(1, 'year'))
|
|
28
|
+
const nextYear = () => setCurrentMonth((m) => m.add(1, 'year'))
|
|
29
|
+
|
|
30
|
+
const { weekdayLabels, cells } = useCalendarDays(currentMonth)
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<View className="neko-day-picker" width={250} {...props}>
|
|
34
|
+
<View className="neko-date-picker-header" row centerV gap="xxs" height={30}>
|
|
35
|
+
<Link onPress={prevYear} aria-label="Previous year" padding="xxs" paddingL={0}>
|
|
36
|
+
<Icon name="arrow-left-double-line" />
|
|
37
|
+
</Link>
|
|
38
|
+
|
|
39
|
+
<Link onPress={prevMonth} aria-label="Previous month" padding="xxs">
|
|
40
|
+
<Icon name="arrow-left-s-line" />
|
|
41
|
+
</Link>
|
|
42
|
+
|
|
43
|
+
<Text center flex>
|
|
44
|
+
{currentMonth.format('MMM YYYY')}
|
|
45
|
+
</Text>
|
|
46
|
+
|
|
47
|
+
<Link onPress={nextMonth} aria-label="Next month" padding="xxs">
|
|
48
|
+
<Icon name="arrow-right-s-line" />
|
|
49
|
+
</Link>
|
|
50
|
+
|
|
51
|
+
<Link onPress={nextYear} aria-label="Next year" padding="xxs" paddingR={0}>
|
|
52
|
+
<Icon name="arrow-right-double-line" />
|
|
53
|
+
</Link>
|
|
54
|
+
</View>
|
|
55
|
+
|
|
56
|
+
<View className="neko-day-picker-week" row center gap="sm">
|
|
57
|
+
{weekdayLabels.map((w) => (
|
|
58
|
+
<View key={w} flex height={30} center>
|
|
59
|
+
<Text center sm text4>
|
|
60
|
+
{w}
|
|
61
|
+
</Text>
|
|
62
|
+
</View>
|
|
63
|
+
))}
|
|
64
|
+
</View>
|
|
65
|
+
|
|
66
|
+
<Grid className="neko-day-picker-days" colSpan={24 / 7} gap="sm">
|
|
67
|
+
{cells.map((val, idx) => {
|
|
68
|
+
const dateVal = currentMonth.date(val)
|
|
69
|
+
const isActive = dateVal.isSame(value, 'day')
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<Col key={idx} className="day-cell" center>
|
|
73
|
+
<Link
|
|
74
|
+
ratio={1}
|
|
75
|
+
width={30}
|
|
76
|
+
center
|
|
77
|
+
br="md"
|
|
78
|
+
onPress={() => !!val && handleChange(dateVal)}
|
|
79
|
+
bg={isActive && 'primary'}
|
|
80
|
+
>
|
|
81
|
+
<Text sm text2 center strong={isActive}>
|
|
82
|
+
{val != null ? val : ''}
|
|
83
|
+
</Text>
|
|
84
|
+
</Link>
|
|
85
|
+
</Col>
|
|
86
|
+
)
|
|
87
|
+
})}
|
|
88
|
+
</Grid>
|
|
89
|
+
</View>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
export function useCalendarDays(currentMonth) {
|
|
4
|
+
return React.useMemo(() => {
|
|
5
|
+
const startWeekday = currentMonth.startOf('month').day()
|
|
6
|
+
const daysInMonth = currentMonth.daysInMonth()
|
|
7
|
+
|
|
8
|
+
const blanks = Array.from({ length: startWeekday }, () => null)
|
|
9
|
+
const days = Array.from({ length: daysInMonth }, (_, i) => i + 1)
|
|
10
|
+
const cells = [...blanks, ...days]
|
|
11
|
+
|
|
12
|
+
const weekdayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
|
|
13
|
+
|
|
14
|
+
return { weekdayLabels, cells }
|
|
15
|
+
}, [currentMonth.month(), currentMonth.year()])
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DayPicker'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './notifications/NotificationsHandler'
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { AnimatedView } from '../../animations/AnimatedView'
|
|
4
|
+
import { Icon } from '../../presentation/Icon'
|
|
5
|
+
import { Link } from '../../actions/Link'
|
|
6
|
+
import { ResultBar } from '../../presentation/ResultBar'
|
|
7
|
+
|
|
8
|
+
export function Notification({ time, ...props }) {
|
|
9
|
+
const [open, setOpen] = React.useState(true)
|
|
10
|
+
|
|
11
|
+
React.useEffect(() => {
|
|
12
|
+
setTimeout(() => setOpen(false), time - 500)
|
|
13
|
+
}, [])
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<AnimatedView
|
|
17
|
+
open={open}
|
|
18
|
+
className="neko-notification"
|
|
19
|
+
slide={{ from: 'right' }}
|
|
20
|
+
fade
|
|
21
|
+
zIndex={120}
|
|
22
|
+
maxWidth="100%"
|
|
23
|
+
bg="overlayBG"
|
|
24
|
+
br="sm"
|
|
25
|
+
unmountOnClose
|
|
26
|
+
>
|
|
27
|
+
<ResultBar
|
|
28
|
+
{...props}
|
|
29
|
+
rightContent={
|
|
30
|
+
<Link onPress={() => setOpen(false)}>
|
|
31
|
+
<Icon name="close-line" text4 />
|
|
32
|
+
</Link>
|
|
33
|
+
}
|
|
34
|
+
/>
|
|
35
|
+
</AnimatedView>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { is } from 'ramda'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import { Notification } from './Notification'
|
|
5
|
+
import { SafeAreaView } from '../../structure/SafeAreaView'
|
|
6
|
+
import { View } from '../../structure/View'
|
|
7
|
+
import { useResponsiveValue } from '../../../responsive/responsiveHooks'
|
|
8
|
+
|
|
9
|
+
const NotificationsContext = React.createContext(null)
|
|
10
|
+
|
|
11
|
+
export const useNotifications = () => React.useContext(NotificationsContext) || {}
|
|
12
|
+
|
|
13
|
+
let idCounter = 0
|
|
14
|
+
|
|
15
|
+
export function useNotifier() {
|
|
16
|
+
const { add, remove } = useNotifications()
|
|
17
|
+
const notify = (data, opts, type) => {
|
|
18
|
+
const key = ++idCounter
|
|
19
|
+
const time = opts?.time || 6000
|
|
20
|
+
|
|
21
|
+
if (is(String, data)) data = { title: data }
|
|
22
|
+
|
|
23
|
+
const timerId = setTimeout(() => remove(key), time)
|
|
24
|
+
add(key, { ...data, type, opts, timerId, time })
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
notify,
|
|
29
|
+
info: (data, opts) => notify(data, opts, 'info'),
|
|
30
|
+
error: (data, opts) => notify(data, opts, 'error'),
|
|
31
|
+
warning: (data, opts) => notify(data, opts, 'warning'),
|
|
32
|
+
success: (data, opts) => notify(data, opts, 'success'),
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function NotificationsHandler({ children }) {
|
|
37
|
+
const width = useResponsiveValue({ sm: '100%', df: 400 })
|
|
38
|
+
const [messages, setMessages] = React.useState([])
|
|
39
|
+
|
|
40
|
+
const add = React.useCallback((key, data) => {
|
|
41
|
+
setMessages((prev) => [{ key, ...data }, ...prev])
|
|
42
|
+
}, [])
|
|
43
|
+
|
|
44
|
+
const remove = React.useCallback((key) => {
|
|
45
|
+
setMessages((prev) => prev.filter((p) => p.key !== key))
|
|
46
|
+
}, [])
|
|
47
|
+
|
|
48
|
+
const value = React.useMemo(() => ({ add, remove }), [add, remove])
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<NotificationsContext.Provider value={value}>
|
|
52
|
+
{children}
|
|
53
|
+
|
|
54
|
+
{!!messages.length && (
|
|
55
|
+
<View fixed top={0} right={0} padding="md" width={width} maxWidth="100%" pointerEvents="box-none">
|
|
56
|
+
<SafeAreaView gap="xs">
|
|
57
|
+
{messages.map(({ key, ...item }) => (
|
|
58
|
+
<Notification key={key} {...item} />
|
|
59
|
+
))}
|
|
60
|
+
</SafeAreaView>
|
|
61
|
+
</View>
|
|
62
|
+
)}
|
|
63
|
+
</NotificationsContext.Provider>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { FormWrapperComponent } from './FormWrapperComponent'
|
|
4
|
+
import { LoadingView } from '../state/LoadingView'
|
|
5
|
+
import { useNewForm } from './useNewForm'
|
|
6
|
+
|
|
7
|
+
const FormContext = React.createContext(null)
|
|
8
|
+
export const useFormState = () => React.useContext(FormContext)
|
|
9
|
+
export const useFormInstance = () => useFormState()?.form
|
|
10
|
+
export const useForm = useFormInstance
|
|
11
|
+
|
|
12
|
+
export function Form({ form, onSubmit, initialValues, children, loading, disabled, ...props }) {
|
|
13
|
+
const defaultForm = useNewForm({ onSubmit, initialValues })
|
|
14
|
+
form = form || defaultForm
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<FormContext.Provider value={{ loading, disabled, form }}>
|
|
18
|
+
<LoadingView active={loading} noWrapper>
|
|
19
|
+
<FormWrapperComponent form={form} gap="md" {...props}>
|
|
20
|
+
{children}
|
|
21
|
+
</FormWrapperComponent>
|
|
22
|
+
</LoadingView>
|
|
23
|
+
</FormContext.Provider>
|
|
24
|
+
)
|
|
25
|
+
}
|
|
@@ -4,17 +4,17 @@ const FormGroupContext = React.createContext(null)
|
|
|
4
4
|
const useGroupPath = () => React.useContext(FormGroupContext)?.path || []
|
|
5
5
|
|
|
6
6
|
export function useRelativePath(name, opts) {
|
|
7
|
-
const {
|
|
7
|
+
const { isAbsolutePath } = opts
|
|
8
8
|
const listPath = !!name ? (Array.isArray(name) ? name : [name]) : []
|
|
9
9
|
const parentPath = useGroupPath()
|
|
10
10
|
|
|
11
|
-
if (
|
|
11
|
+
if (!!isAbsolutePath) return listPath
|
|
12
12
|
|
|
13
13
|
return [...parentPath, ...listPath]
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export function FormGroup({ name }) {
|
|
17
|
-
const path = useRelativePath(name, {
|
|
16
|
+
export function FormGroup({ name, children }) {
|
|
17
|
+
const path = useRelativePath(name, { isAbsolutePath: false })
|
|
18
18
|
const value = { path }
|
|
19
19
|
|
|
20
20
|
return <FormGroupContext.Provider value={value}>{children}</FormGroupContext.Provider>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { FormGroup, useRelativePath } from './FormGroup'
|
|
4
|
+
import { Text } from '../text/Text'
|
|
5
|
+
import { View } from '../structure/View'
|
|
6
|
+
import { clearProps } from '../../modifiers/_helpers'
|
|
7
|
+
import { useFormInstance, useFormState } from './Form'
|
|
8
|
+
|
|
9
|
+
export function FormItem({ name, label, isAbsolutePath, children, useDefaultValue, ...props }) {
|
|
10
|
+
const form = useFormInstance()
|
|
11
|
+
const formState = useFormState()
|
|
12
|
+
const listPath = useRelativePath(name, { isAbsolutePath })
|
|
13
|
+
const [value, setValue] = React.useState(form.getFieldValue(listPath))
|
|
14
|
+
const error = form.getError(listPath)
|
|
15
|
+
|
|
16
|
+
React.useEffect(() => {
|
|
17
|
+
return form.registerListener(listPath, (val) => setValue(val))
|
|
18
|
+
}, [listPath.join('$NEKOJOIN$')])
|
|
19
|
+
|
|
20
|
+
const handleChange = (e) => {
|
|
21
|
+
const val = e?.target?.value ?? e
|
|
22
|
+
form.setFieldValue(listPath, val)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let valueKey = 'value'
|
|
26
|
+
if (!!useDefaultValue) valueKey = 'defaultValue'
|
|
27
|
+
|
|
28
|
+
const childProps = clearProps({
|
|
29
|
+
[valueKey]: value === undefined ? '' : value,
|
|
30
|
+
onChange: handleChange,
|
|
31
|
+
// loading: formState?.loading === true || undefined,
|
|
32
|
+
disabled: formState?.disabled === true || undefined,
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
let content
|
|
36
|
+
if (typeof children === 'function') {
|
|
37
|
+
content = children(childProps)
|
|
38
|
+
} else {
|
|
39
|
+
const child = React.Children.only(children)
|
|
40
|
+
content = React.cloneElement(child, { ...child.props, ...childProps })
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<FormGroup name={listPath}>
|
|
45
|
+
<View {...props}>
|
|
46
|
+
{label && (
|
|
47
|
+
<Text sm marginB="xxs">
|
|
48
|
+
{label}
|
|
49
|
+
</Text>
|
|
50
|
+
)}
|
|
51
|
+
{content}
|
|
52
|
+
{error && <Text color="red">{error}</Text>}
|
|
53
|
+
</View>
|
|
54
|
+
</FormGroup>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
@@ -1,29 +1,49 @@
|
|
|
1
|
-
import { Text } from 'react-native'
|
|
2
1
|
import React from 'react'
|
|
3
2
|
|
|
4
3
|
import { FormGroup, useRelativePath } from './FormGroup'
|
|
4
|
+
import { Text } from '../text/Text'
|
|
5
5
|
import { useFormInstance } from './Form'
|
|
6
6
|
|
|
7
7
|
const FormListContext = React.createContext(null)
|
|
8
8
|
const useFormList = () => React.useContext(FormListContext)
|
|
9
9
|
|
|
10
|
-
export function FormList({ name,
|
|
10
|
+
export function FormList({ name, isAbsolutePath, children }) {
|
|
11
11
|
const form = useFormInstance()
|
|
12
|
-
const listPath = useRelativePath(name, {
|
|
12
|
+
const listPath = useRelativePath(name, { isAbsolutePath })
|
|
13
13
|
// To avoid watch being recalled
|
|
14
14
|
const listPathStr = listPath.join('$NEKOJOIN$')
|
|
15
15
|
const error = form.getError(listPath)
|
|
16
16
|
|
|
17
|
+
// Counter to generate unique keys
|
|
18
|
+
const keyCounter = React.useRef(0)
|
|
19
|
+
// Map to track keys by value reference
|
|
20
|
+
const keysMap = React.useRef(new WeakMap())
|
|
21
|
+
|
|
22
|
+
const generateFields = (items) => {
|
|
23
|
+
if (!Array.isArray(items)) return []
|
|
24
|
+
return items.map((item, index) => {
|
|
25
|
+
let key
|
|
26
|
+
if (typeof item === 'object' && item !== null) {
|
|
27
|
+
key = keysMap.current.get(item)
|
|
28
|
+
if (!key) {
|
|
29
|
+
key = `field_${keyCounter.current++}`
|
|
30
|
+
keysMap.current.set(item, key)
|
|
31
|
+
}
|
|
32
|
+
} else {
|
|
33
|
+
key = `field_${keyCounter.current++}`
|
|
34
|
+
}
|
|
35
|
+
return { key, name: index }
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
17
39
|
const [fields, setFields] = React.useState(() => {
|
|
18
40
|
const initial = form.getFieldValue(listPath) || []
|
|
19
|
-
return initial
|
|
41
|
+
return generateFields(initial)
|
|
20
42
|
})
|
|
21
43
|
|
|
22
44
|
React.useEffect(() => {
|
|
23
45
|
return form.registerListener(listPath, (val) => {
|
|
24
|
-
|
|
25
|
-
setFields(val.map((_, index) => ({ key: index, name: index })))
|
|
26
|
-
}
|
|
46
|
+
setFields(generateFields(val))
|
|
27
47
|
})
|
|
28
48
|
}, [listPathStr])
|
|
29
49
|
|
|
@@ -45,6 +65,15 @@ export function FormList({ name, relative, children }) {
|
|
|
45
65
|
)
|
|
46
66
|
}
|
|
47
67
|
|
|
68
|
+
const duplicate = (index) => {
|
|
69
|
+
const current = form.getFieldValue(listPath) || []
|
|
70
|
+
const value = current[index]
|
|
71
|
+
if (!value) return
|
|
72
|
+
// Deep clone the value to avoid reference issues
|
|
73
|
+
const clonedValue = typeof value === 'object' ? { ...value } : value
|
|
74
|
+
addOn(index + 1, clonedValue)
|
|
75
|
+
}
|
|
76
|
+
|
|
48
77
|
const move = (fromIndex, toIndex) => {
|
|
49
78
|
const current = form.getFieldValue(listPath) || []
|
|
50
79
|
if (fromIndex < 0 || fromIndex >= current.length) return
|
|
@@ -71,17 +100,24 @@ export function FormList({ name, relative, children }) {
|
|
|
71
100
|
replace,
|
|
72
101
|
remove,
|
|
73
102
|
move,
|
|
103
|
+
duplicate,
|
|
74
104
|
}),
|
|
75
105
|
[listPathStr]
|
|
76
106
|
)
|
|
77
107
|
|
|
108
|
+
let content
|
|
109
|
+
if (typeof children === 'function') {
|
|
110
|
+
content = children(fields, actions)
|
|
111
|
+
} else {
|
|
112
|
+
const child = React.Children.only(children)
|
|
113
|
+
content = React.cloneElement(child, { ...child.props, fields, ...actions })
|
|
114
|
+
}
|
|
115
|
+
|
|
78
116
|
return (
|
|
79
117
|
<FormGroup name={listPath}>
|
|
80
118
|
<FormListContext.Provider value={actions}>
|
|
81
|
-
{
|
|
82
|
-
|
|
83
|
-
: React.cloneElement(React.Children.only(children), { fields, ...actions })}
|
|
84
|
-
{error && <Text style={{ color: 'red' }}>{error}</Text>}
|
|
119
|
+
{content}
|
|
120
|
+
{error && <Text color="red">{error}</Text>}
|
|
85
121
|
</FormListContext.Provider>
|
|
86
122
|
</FormGroup>
|
|
87
123
|
)
|