@neko-os/ui 0.2.1 → 0.2.3

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/README.md CHANGED
@@ -1,79 +1,3 @@
1
1
  # Neko UI
2
2
 
3
3
  Universal React Native UI library (works on react-native, react-native-web and react).
4
-
5
- ## Install
6
-
7
- ```
8
- yarn add @neko-os/ui ramda dayjs
9
- ```
10
-
11
- ### Web or native-web
12
-
13
- ```
14
- yarn add react-native-web
15
- ```
16
-
17
- ### Vite config
18
-
19
- vite.config.js:
20
-
21
- ```js
22
- import { defineConfig } from 'vite'
23
- import react from '@vitejs/plugin-react'
24
- import path from 'path'
25
-
26
- export default defineConfig({
27
- plugins: [react()],
28
- resolve: {
29
- alias: {
30
- 'react-native': 'react-native-web',
31
- 'react-native-svg': 'react-native-svg-web',
32
- },
33
- extensions: ['.web.js', '.js', '.jsx', '.json'],
34
- },
35
- })
36
- ```
37
-
38
- ## Usage (TODO)
39
-
40
- ```js
41
- import { SimpleLinesChart } from '@neko-os/ui
42
-
43
- const DATA = [
44
- {
45
- serie: 'A',
46
- data: [
47
- { x: 'Jan', y: 50 },
48
- { x: 'Feb', y: 80 },
49
- { x: 'Mar', y: 40 },
50
- { x: 'Apr', y: 120 },
51
- { x: 'May', y: 70 },
52
- ],
53
- },
54
- {
55
- serie: 'B',
56
- data: [
57
- { x: 'Jan', y: 30 },
58
- { x: 'Feb', y: 60 },
59
- { x: 'Mar', y: 90 },
60
- { x: 'Apr', y: 75 },
61
- { x: 'May', y: 100 },
62
- ],
63
- },
64
-
65
- {
66
- serie: 'C',
67
- data: [
68
- { x: 'Jan', y: 3 },
69
- { x: 'Feb', y: 6 },
70
- { x: 'Mar', y: 9 },
71
- { x: 'Apr', y: 7 },
72
- { x: 'May', y: 10 },
73
- ],
74
- },
75
- ]
76
-
77
-
78
- <SimpleLinesChart data={DATA} />
79
- ```
@@ -1 +1 @@
1
- import _objectDestructuringEmpty from"@babel/runtime/helpers/objectDestructuringEmpty";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";var _excluded=["items","onChange","title","subtitle","onClose"],_excluded2=["topBarProps","menuProps"];var _jsxFileName="/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/actions/ActionsDrawer.js";import{pipe}from'ramda';import{TopBar,View}from"../structure";import{BottomDrawer,DrawerScrollView}from"../modals/bottomDrawer";import{Menu}from"./menu/Menu";import{Section}from"../sections";import{useDefaultModifier}from"../../modifiers/default";import{useThemeComponentModifier}from"../../modifiers/themeComponent";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";var DEFAULT_PROPS={useSafeArea:false,bg:'mainBG',topBarProps:{useSafeArea:false},menuProps:{vertical:true,linkPaddingH:'md',linkMinHeight:'xl',withDivider:true}};function Content(_ref){var items=_ref.items,title=_ref.title,subtitle=_ref.subtitle,onClose=_ref.onClose,onChange=_ref.onChange,topBarProps=_ref.topBarProps,menuProps=_ref.menuProps;var handleChange=function handleChange(){for(var _len=arguments.length,params=new Array(_len),_key=0;_key<_len;_key++){params[_key]=arguments[_key];}onChange==null?void 0:onChange.apply(void 0,params);onClose();};return _jsxs(_Fragment,{children:[_jsx(TopBar,Object.assign({title:title,subtitle:subtitle},topBarProps)),_jsx(View,{flex:true,children:_jsxs(DrawerScrollView,{children:[!title&&_jsx(View,{paddingT:"md"}),_jsx(Section,{children:_jsx(Menu,Object.assign({items:items,onChange:handleChange},menuProps))}),_jsx(View,{height:100})]})})]});}export function ActionsDrawer(_ref2){var items=_ref2.items,onChange=_ref2.onChange,title=_ref2.title,subtitle=_ref2.subtitle,onClose=_ref2.onClose,rootProps=_objectWithoutProperties(_ref2,_excluded);var _pipe=pipe(useThemeComponentModifier('ActionsDrawer'),useDefaultModifier(DEFAULT_PROPS))([{},rootProps]),_pipe2=_slicedToArray(_pipe,2);_objectDestructuringEmpty(_pipe2[0]);var formattedProps=_pipe2[1];var topBarProps=formattedProps.topBarProps,menuProps=formattedProps.menuProps,props=_objectWithoutProperties(formattedProps,_excluded2);return _jsx(BottomDrawer,Object.assign({onClose:onClose},props,{children:_jsx(Content,{onClose:onClose,topBarProps:topBarProps,menuProps:menuProps,title:title,subtitle:subtitle,onChange:onChange,items:items})}));}
1
+ import _objectDestructuringEmpty from"@babel/runtime/helpers/objectDestructuringEmpty";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";var _excluded=["items","onChange","title","subtitle","onClose","snapPoints"],_excluded2=["topBarProps","menuProps"];var _jsxFileName="/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/actions/ActionsDrawer.js";import{pipe}from'ramda';import React from'react';import{BottomDrawer,DrawerScrollView}from"../modals/bottomDrawer";import{Menu}from"./menu/Menu";import{Section}from"../sections";import{TopBar,View}from"../structure";import{useDefaultModifier}from"../../modifiers/default";import{useTheme}from"../../theme";import{useThemeComponentModifier}from"../../modifiers/themeComponent";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";var DEFAULT_PROPS={useSafeArea:false,bg:'mainBG',topBarProps:{useSafeArea:false},menuProps:{vertical:true,linkPaddingH:'md',linkMinHeight:'xl',withDivider:true}};function Content(_ref){var items=_ref.items,title=_ref.title,subtitle=_ref.subtitle,onClose=_ref.onClose,onChange=_ref.onChange,topBarProps=_ref.topBarProps,menuProps=_ref.menuProps;var handleChange=function handleChange(){for(var _len=arguments.length,params=new Array(_len),_key=0;_key<_len;_key++){params[_key]=arguments[_key];}onChange==null?void 0:onChange.apply(void 0,params);onClose();};return _jsxs(_Fragment,{children:[_jsx(TopBar,Object.assign({title:title,subtitle:subtitle},topBarProps)),_jsx(View,{flex:true,children:_jsxs(DrawerScrollView,{children:[!title&&_jsx(View,{paddingT:"md"}),_jsx(Section,{children:_jsx(Menu,Object.assign({items:items,onChange:handleChange},menuProps))}),_jsx(View,{height:100})]})})]});}export function ActionsDrawer(_ref2){var items=_ref2.items,onChange=_ref2.onChange,title=_ref2.title,subtitle=_ref2.subtitle,onClose=_ref2.onClose,snapPoints=_ref2.snapPoints,rootProps=_objectWithoutProperties(_ref2,_excluded);var _useTheme=useTheme(),elementHeights=_useTheme.elementHeights,spaces=_useTheme.spaces;var _pipe=pipe(useThemeComponentModifier('ActionsDrawer'),useDefaultModifier(DEFAULT_PROPS))([{},rootProps]),_pipe2=_slicedToArray(_pipe,2);_objectDestructuringEmpty(_pipe2[0]);var formattedProps=_pipe2[1];var topBarProps=formattedProps.topBarProps,menuProps=formattedProps.menuProps,props=_objectWithoutProperties(formattedProps,_excluded2);snapPoints=React.useMemo(function(){var _snapPoints;if(!!((_snapPoints=snapPoints)!=null&&_snapPoints.length))return snapPoints;var safeSpace=(!!title?elementHeights.xxl:spaces.sm)+spaces.md+spaces.sm;var itemHeight=elementHeights[menuProps==null?void 0:menuProps.linkMinHeight];var itemsLength=Math.min(8,items.length);return[itemsLength*itemHeight+safeSpace];},[snapPoints,title,items]);return _jsx(BottomDrawer,Object.assign({onClose:onClose,snapPoints:snapPoints},props,{children:_jsx(Content,{onClose:onClose,topBarProps:topBarProps,menuProps:menuProps,title:title,subtitle:subtitle,onChange:onChange,items:items})}));}
@@ -1 +1 @@
1
- import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";var _jsxFileName="/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/actions/Button.js";var _excluded=["children"],_excluded2=["label","icon","textProps","iconProps","gap","invert","size","iconLabelProps"];import{pipe}from'ramda';import{AbsTouchableOpacity}from"../../abstractions/TouchableOpacity";import{IconLabel}from"../presentation/IconLabel";import{useBackgroundModifier}from"../../modifiers/background";import{useBorderModifier}from"../../modifiers/border";import{useColorConverter}from"../../modifiers/colorConverter";import{useCursorModifier}from"../../modifiers/cursor";import{useDefaultModifier}from"../../modifiers/default";import{useDisplayModifier}from"../../modifiers/display";import{useFlexModifier}from"../../modifiers/flex";import{useFlexWrapperModifier}from"../../modifiers/flexWrapper";import{useFullColorModifier}from"../../modifiers/fullColor";import{useHoverConverter}from"../../modifiers/hover";import{useMarginModifier}from"../../modifiers/margin";import{usePaddingModifier}from"../../modifiers/padding";import{usePositionModifier}from"../../modifiers/position";import{useSizeConverter}from"../../modifiers/sizeConverter";import{useSizeModifier}from"../../modifiers/size";import{useStateModifier}from"../../modifiers/state";import{useThemeComponentModifier}from"../../modifiers/themeComponent";import{jsx as _jsx}from"react/jsx-runtime";var DEFAULT_PROPS=function DEFAULT_PROPS(_ref){var _ref2=_slicedToArray(_ref,1),sizeCode=_ref2[0].sizeCode;return{paddingH:sizeCode,paddingV:2,height:sizeCode,br:sizeCode,border:1,center:true,pointer:true,hover:{opacity:0.7}};};export function Button(_ref3){var children=_ref3.children,rootProps=_objectWithoutProperties(_ref3,_excluded);var _pipe=pipe(useColorConverter('primary'),useSizeConverter('elementHeights','md'),useThemeComponentModifier('Button'),useDefaultModifier(DEFAULT_PROPS),useHoverConverter,useCursorModifier,useFullColorModifier,useDisplayModifier,useStateModifier,useSizeModifier,usePositionModifier,usePaddingModifier,useMarginModifier,useFlexModifier,useFlexWrapperModifier,useBackgroundModifier,useBorderModifier)([{},rootProps]),_pipe2=_slicedToArray(_pipe,2),_pipe2$=_pipe2[0],loading=_pipe2$.loading,fontColor=_pipe2$.fontColor,sizeCode=_pipe2$.sizeCode,formattedProps=_pipe2[1];var label=formattedProps.label,icon=formattedProps.icon,textProps=formattedProps.textProps,iconProps=formattedProps.iconProps,gap=formattedProps.gap,invert=formattedProps.invert,size=formattedProps.size,iconLabelProps=formattedProps.iconLabelProps,props=_objectWithoutProperties(formattedProps,_excluded2);return _jsx(AbsTouchableOpacity,Object.assign({className:"neko-button neko-wave-click-effect",type:"button"},props,{children:children||_jsx(IconLabel,Object.assign({center:true,color:fontColor,size:sizeCode,label:label,icon:icon,gap:gap,invert:invert,textProps:Object.assign({strong:true},textProps),iconProps:iconProps,loading:loading},iconLabelProps))}));}
1
+ import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";var _jsxFileName="/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/actions/Button.js";var _excluded=["children"],_excluded2=["label","icon","textProps","iconProps","gap","invert","size","iconLabelProps"];import{pipe}from'ramda';import{AbsTouchableOpacity}from"../../abstractions/TouchableOpacity";import{IconLabel}from"../presentation/IconLabel";import{useBackgroundModifier}from"../../modifiers/background";import{useBorderModifier}from"../../modifiers/border";import{useColorConverter}from"../../modifiers/colorConverter";import{useCursorModifier}from"../../modifiers/cursor";import{useDefaultModifier}from"../../modifiers/default";import{useDisplayModifier}from"../../modifiers/display";import{useFlexModifier}from"../../modifiers/flex";import{useFlexWrapperModifier}from"../../modifiers/flexWrapper";import{useFullColorModifier}from"../../modifiers/fullColor";import{useHoverConverter}from"../../modifiers/hover";import{useMarginModifier}from"../../modifiers/margin";import{usePaddingModifier}from"../../modifiers/padding";import{usePositionModifier}from"../../modifiers/position";import{useShadowModifier}from"../../modifiers/shadow";import{useSizeConverter}from"../../modifiers/sizeConverter";import{useSizeModifier}from"../../modifiers/size";import{useStateModifier}from"../../modifiers/state";import{useThemeComponentModifier}from"../../modifiers/themeComponent";import{jsx as _jsx}from"react/jsx-runtime";var DEFAULT_PROPS=function DEFAULT_PROPS(_ref){var _ref2=_slicedToArray(_ref,1),sizeCode=_ref2[0].sizeCode;return{paddingH:sizeCode,paddingV:2,height:sizeCode,br:sizeCode,border:1,center:true,pointer:true,hover:{opacity:0.7}};};export function Button(_ref3){var children=_ref3.children,rootProps=_objectWithoutProperties(_ref3,_excluded);var _pipe=pipe(useColorConverter('primary'),useSizeConverter('elementHeights','md'),useThemeComponentModifier('Button'),useDefaultModifier(DEFAULT_PROPS),useShadowModifier,useHoverConverter,useCursorModifier,useFullColorModifier,useDisplayModifier,useStateModifier,useSizeModifier,usePositionModifier,usePaddingModifier,useMarginModifier,useFlexModifier,useFlexWrapperModifier,useBackgroundModifier,useBorderModifier)([{},rootProps]),_pipe2=_slicedToArray(_pipe,2),_pipe2$=_pipe2[0],loading=_pipe2$.loading,fontColor=_pipe2$.fontColor,sizeCode=_pipe2$.sizeCode,formattedProps=_pipe2[1];var label=formattedProps.label,icon=formattedProps.icon,textProps=formattedProps.textProps,iconProps=formattedProps.iconProps,gap=formattedProps.gap,invert=formattedProps.invert,size=formattedProps.size,iconLabelProps=formattedProps.iconLabelProps,props=_objectWithoutProperties(formattedProps,_excluded2);return _jsx(AbsTouchableOpacity,Object.assign({className:"neko-button neko-wave-click-effect",type:"button"},props,{children:children||_jsx(IconLabel,Object.assign({center:true,color:fontColor,size:sizeCode,label:label,icon:icon,gap:gap,invert:invert,textProps:Object.assign({strong:true},textProps),iconProps:iconProps,loading:loading},iconLabelProps))}));}
@@ -1 +1 @@
1
- var _jsxFileName="/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/modals/bottomDrawer/native/DrawerContext.js";import React from'react';import{jsx as _jsx}from"react/jsx-runtime";var DrawerContext=React.createContext(null);export function DrawerProvider(_ref){var children=_ref.children,value=_ref.value;return _jsx(DrawerContext.Provider,{value:value,children:children});}export function useDrawerContext(){var context=React.useContext(DrawerContext);if(!context){throw new Error('useDrawerContext must be used within a DrawerProvider');}return context;}
1
+ var _jsxFileName="/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/modals/bottomDrawer/native/DrawerContext.js";import React from'react';import{jsx as _jsx}from"react/jsx-runtime";var DrawerContext=React.createContext(null);export function DrawerProvider(_ref){var children=_ref.children,value=_ref.value;return _jsx(DrawerContext.Provider,{value:value,children:children});}export function useDrawerContext(){var context=React.useContext(DrawerContext);if(!context){return{outOfContext:true};}return context;}
@@ -1 +1 @@
1
- import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";var _jsxFileName="/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/modals/bottomDrawer/native/createDrawerScrollComponent.js";var _excluded=["ref","onScroll"];import{Gesture,GestureDetector}from'react-native-gesture-handler';import Animated,{useSharedValue,useAnimatedScrollHandler,useAnimatedRef,scrollTo,withSpring,runOnJS}from'react-native-reanimated';import React from'react';import{findClosestSnapPoint,clamp}from"./utils";import{useDrawerContext}from"./DrawerContext";import{jsx as _jsx}from"react/jsx-runtime";export function createDrawerScrollComponent(Component){var AnimatedComponent=Animated.createAnimatedComponent(Component);function DrawerScrollComponent(_ref){var ref=_ref.ref,_onScroll=_ref.onScroll,props=_objectWithoutProperties(_ref,_excluded);var _useDrawerContext=useDrawerContext(),translateY=_useDrawerContext.translateY,panRef=_useDrawerContext.panRef,normalizedSnapPoints=_useDrawerContext.normalizedSnapPoints,SCREEN_HEIGHT=_useDrawerContext.SCREEN_HEIGHT,maxSnapPoint=_useDrawerContext.maxSnapPoint,minSnapPoint=_useDrawerContext.minSnapPoint,handleClose=_useDrawerContext.handleClose,animationConfig=_useDrawerContext.animationConfig,snapIndex=_useDrawerContext.snapIndex;var scrollRef=useAnimatedRef();var scrollOffset=useSharedValue(0);var prevTranslationY=useSharedValue(0);var drawerMoved=useSharedValue(false);React.useImperativeHandle(ref,function(){return scrollRef.current;});var maxPosition=SCREEN_HEIGHT-maxSnapPoint;var panGesture=React.useMemo(function(){return Gesture.Pan().activeOffsetY([-10,10]).blocksExternalGesture(panRef).onStart(function(){prevTranslationY.value=0;drawerMoved.value=false;}).onUpdate(function(event){var delta=event.translationY-prevTranslationY.value;prevTranslationY.value=event.translationY;var currentY=translateY.value;var atMaxSnap=currentY<=maxPosition+1;var atScrollTop=scrollOffset.value<=0;if(drawerMoved.value){var newY=clamp(currentY+delta,maxPosition,SCREEN_HEIGHT);translateY.value=newY;scrollTo(scrollRef,0,0,false);if(newY<=maxPosition+1&&delta<0){drawerMoved.value=false;}}else if(!atMaxSnap){drawerMoved.value=true;var _newY=clamp(currentY+delta,maxPosition,SCREEN_HEIGHT);translateY.value=_newY;scrollTo(scrollRef,0,0,false);}else if(atScrollTop&&delta>0){drawerMoved.value=true;var _newY2=clamp(currentY+delta,maxPosition,SCREEN_HEIGHT);translateY.value=_newY2;scrollTo(scrollRef,0,0,false);}}).onEnd(function(event){if(!drawerMoved.value)return;var currentPosition=SCREEN_HEIGHT-translateY.value;var velocity=event.velocityY;var shouldClose=!!handleClose&&(velocity>1500||velocity>800&&currentPosition<minSnapPoint||currentPosition<minSnapPoint*0.35);if(shouldClose){runOnJS(handleClose)();}else{var closestSnapIndex=findClosestSnapPoint(currentPosition,normalizedSnapPoints,velocity);var targetSnapPoint=normalizedSnapPoints[closestSnapIndex];translateY.value=withSpring(SCREEN_HEIGHT-targetSnapPoint,animationConfig);snapIndex.value=closestSnapIndex;}});},[panRef,maxPosition,normalizedSnapPoints,minSnapPoint,handleClose,animationConfig]);var nativeGesture=React.useMemo(function(){return Gesture.Native();},[]);var composedGesture=React.useMemo(function(){return Gesture.Simultaneous(panGesture,nativeGesture);},[panGesture,nativeGesture]);var animatedScrollHandler=useAnimatedScrollHandler({onScroll:function onScroll(event){scrollOffset.value=event.contentOffset.y;if(_onScroll){runOnJS(_onScroll)(event);}}});return _jsx(GestureDetector,{gesture:composedGesture,children:_jsx(AnimatedComponent,Object.assign({ref:scrollRef,style:{flex:1},onScroll:animatedScrollHandler,scrollEventThrottle:16,bounces:false,overScrollMode:"never"},props))});}return DrawerScrollComponent;}
1
+ import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";var _jsxFileName="/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/modals/bottomDrawer/native/createDrawerScrollComponent.js";var _excluded=["ref","onScroll"];import{Gesture,GestureDetector}from'react-native-gesture-handler';import Animated,{useSharedValue,useAnimatedScrollHandler,useAnimatedRef,scrollTo,withSpring,runOnJS}from'react-native-reanimated';import React from'react';import{findClosestSnapPoint,clamp}from"./utils";import{useDrawerContext}from"./DrawerContext";import{jsx as _jsx}from"react/jsx-runtime";export function createDrawerScrollComponent(Component){var AnimatedComponent=Animated.createAnimatedComponent(Component);function DrawerScrollComponent(_ref){var ref=_ref.ref,_onScroll=_ref.onScroll,props=_objectWithoutProperties(_ref,_excluded);var _useDrawerContext=useDrawerContext(),translateY=_useDrawerContext.translateY,panRef=_useDrawerContext.panRef,normalizedSnapPoints=_useDrawerContext.normalizedSnapPoints,SCREEN_HEIGHT=_useDrawerContext.SCREEN_HEIGHT,maxSnapPoint=_useDrawerContext.maxSnapPoint,minSnapPoint=_useDrawerContext.minSnapPoint,handleClose=_useDrawerContext.handleClose,animationConfig=_useDrawerContext.animationConfig,snapIndex=_useDrawerContext.snapIndex;var scrollRef=useAnimatedRef();var scrollOffset=useSharedValue(0);var prevTranslationY=useSharedValue(0);var drawerMoved=useSharedValue(false);React.useImperativeHandle(ref,function(){return scrollRef.current;});var maxPosition=SCREEN_HEIGHT-maxSnapPoint;var panGesture=React.useMemo(function(){return Gesture.Pan().activeOffsetY([-10,10]).blocksExternalGesture(panRef).onStart(function(){prevTranslationY.value=0;drawerMoved.value=false;}).onUpdate(function(event){var delta=event.translationY-prevTranslationY.value;prevTranslationY.value=event.translationY;var currentY=translateY.value;var atMaxSnap=currentY<=maxPosition+1;var atScrollTop=scrollOffset.value<=0;if(drawerMoved.value){var newY=clamp(currentY+delta,maxPosition,SCREEN_HEIGHT);translateY.value=newY;scrollTo(scrollRef,0,0,false);if(newY<=maxPosition+1&&delta<0){drawerMoved.value=false;}}else if(!atMaxSnap){drawerMoved.value=true;var _newY=clamp(currentY+delta,maxPosition,SCREEN_HEIGHT);translateY.value=_newY;scrollTo(scrollRef,0,0,false);}else if(atScrollTop&&delta>0){drawerMoved.value=true;var _newY2=clamp(currentY+delta,maxPosition,SCREEN_HEIGHT);translateY.value=_newY2;scrollTo(scrollRef,0,0,false);}}).onEnd(function(event){if(!drawerMoved.value)return;var currentPosition=SCREEN_HEIGHT-translateY.value;var velocity=event.velocityY;var shouldClose=!!handleClose&&(velocity>1500||velocity>800&&currentPosition<minSnapPoint||currentPosition<minSnapPoint*0.35);if(shouldClose){runOnJS(handleClose)();}else{var closestSnapIndex=findClosestSnapPoint(currentPosition,normalizedSnapPoints,velocity);var targetSnapPoint=normalizedSnapPoints[closestSnapIndex];translateY.value=withSpring(SCREEN_HEIGHT-targetSnapPoint,animationConfig);snapIndex.value=closestSnapIndex;}});},[panRef,maxPosition,normalizedSnapPoints,minSnapPoint,handleClose,animationConfig]);var nativeGesture=React.useMemo(function(){return Gesture.Native();},[]);var composedGesture=React.useMemo(function(){return Gesture.Simultaneous(panGesture,nativeGesture);},[panGesture,nativeGesture]);var animatedScrollHandler=useAnimatedScrollHandler({onScroll:function onScroll(event){scrollOffset.value=event.contentOffset.y;if(_onScroll){runOnJS(_onScroll)(event);}}});return _jsx(GestureDetector,{gesture:composedGesture,children:_jsx(AnimatedComponent,Object.assign({ref:scrollRef,style:{flex:1},onScroll:animatedScrollHandler,scrollEventThrottle:16,bounces:false,overScrollMode:"never"},props))});}function ConditionalDrawerScrollComponent(props){var _useDrawerContext2=useDrawerContext(),outOfContext=_useDrawerContext2.outOfContext;if(outOfContext)return _jsx(Component,Object.assign({},props));return _jsx(DrawerScrollComponent,Object.assign({},props));}return ConditionalDrawerScrollComponent;}
@@ -1 +1 @@
1
- import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";var _jsxFileName="/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/structure/TopBar.js";var _excluded=["right","left","WrapperView","children"];import{Text}from"../text";import{View}from"./View";import{useResponsiveConverter}from"../../modifiers/responsiveConverter";import{useSafeAreaInsets}from"../../abstractions/helpers/useSafeAreaInsets";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export function TopBar(_ref){var right=_ref.right,left=_ref.left,WrapperView=_ref.WrapperView,children=_ref.children,rootProps=_objectWithoutProperties(_ref,_excluded);var _useSafeAreaInsets=useSafeAreaInsets(),safeTop=_useSafeAreaInsets.top;var _useResponsiveConvert=useResponsiveConverter([])([{},rootProps]),_useResponsiveConvert2=_slicedToArray(_useResponsiveConvert,2),_=_useResponsiveConvert2[0],props=_useResponsiveConvert2[1];var _props$useSafeArea=props.useSafeArea,useSafeArea=_props$useSafeArea===void 0?true:_props$useSafeArea,title=props.title,subtitle=props.subtitle;var hasContent=!!title||!!subtitle||!!children||!!right||!!left;WrapperView=WrapperView||View;return _jsx(WrapperView,Object.assign({paddingT:useSafeArea&&safeTop},props,{children:!!hasContent&&_jsxs(View,{minH:"md",centerV:true,row:true,paddingH:"md",paddingV:"sm",gap:"sm",fullW:true,children:[_jsx(View,{flex:1,toLeft:true,children:left}),_jsxs(View,{center:true,flex:3,children:[children||_jsx(Text,{center:true,h6:true,numberOfLines:1,children:title}),subtitle&&_jsx(Text,{center:true,xs:true,numberOfLines:1,children:subtitle})]}),_jsx(View,{flex:1,toRight:true,children:right})]})}));}
1
+ import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";var _jsxFileName="/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/structure/TopBar.js";var _excluded=["right","left","WrapperView","children"];import{Text}from"../text";import{View}from"./View";import{useResponsiveConverter}from"../../modifiers/responsiveConverter";import{useSafeAreaInsets}from"../../abstractions/helpers/useSafeAreaInsets";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export function TopBar(_ref){var right=_ref.right,left=_ref.left,WrapperView=_ref.WrapperView,children=_ref.children,rootProps=_objectWithoutProperties(_ref,_excluded);var _useSafeAreaInsets=useSafeAreaInsets(),safeTop=_useSafeAreaInsets.top;var _useResponsiveConvert=useResponsiveConverter([])([{},rootProps]),_useResponsiveConvert2=_slicedToArray(_useResponsiveConvert,2),_=_useResponsiveConvert2[0],props=_useResponsiveConvert2[1];var _props$useSafeArea=props.useSafeArea,useSafeArea=_props$useSafeArea===void 0?true:_props$useSafeArea,title=props.title,subtitle=props.subtitle;var hasContent=!!title||!!subtitle||!!children||!!right||!!left;WrapperView=WrapperView||View;return _jsx(WrapperView,Object.assign({paddingT:useSafeArea&&safeTop},props,{children:!!hasContent&&_jsxs(View,{minH:"xxl",centerV:true,row:true,paddingH:"md",paddingV:"sm",gap:"sm",fullW:true,children:[_jsx(View,{flex:1,toLeft:true,children:left}),_jsxs(View,{center:true,flex:3,children:[children||_jsx(Text,{center:true,h6:true,numberOfLines:1,children:title}),subtitle&&_jsx(Text,{center:true,xs:true,numberOfLines:1,children:subtitle})]}),_jsx(View,{flex:1,toRight:true,children:right})]})}));}
@@ -1 +1 @@
1
- import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";var _excluded=["color"],_excluded2=["outline","contrastTolerance","fill","bg"];import tinycolor from'tinycolor2';import{getContrastColor}from"../theme/helpers/contrastColor";import{useGetColor}from"../theme/ThemeHandler";export function useFullColorModifier(_ref){var _ref2=_slicedToArray(_ref,2),_ref2$=_ref2[0],color=_ref2$.color,values=_objectWithoutProperties(_ref2$,_excluded),_ref2$2=_ref2[1],outline=_ref2$2.outline,contrastTolerance=_ref2$2.contrastTolerance,fill=_ref2$2.fill,forcedBG=_ref2$2.bg,props=_objectWithoutProperties(_ref2$2,_excluded2);var getColor=useGetColor();var bg=color;var bgObj=tinycolor(getColor(bg));var borderColor=color;var fontColor='text';if(!!outline&&fill!==true){bg='transparent';fontColor=color;}else{fontColor=getContrastColor(bgObj,[getColor('overlayBG'),getColor('text')],contrastTolerance);}return[Object.assign({},values,{fontColor:fontColor}),Object.assign({},props,{bg:forcedBG||bg,borderColor:borderColor})];}
1
+ import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";var _excluded=["color"],_excluded2=["outline","contrastTolerance","fill","bg","borderColor"];import tinycolor from'tinycolor2';import{getContrastColor}from"../theme/helpers/contrastColor";import{useGetColor}from"../theme/ThemeHandler";export function useFullColorModifier(_ref){var _ref2=_slicedToArray(_ref,2),_ref2$=_ref2[0],color=_ref2$.color,values=_objectWithoutProperties(_ref2$,_excluded),_ref2$2=_ref2[1],outline=_ref2$2.outline,contrastTolerance=_ref2$2.contrastTolerance,fill=_ref2$2.fill,forcedBG=_ref2$2.bg,explicitBorderColor=_ref2$2.borderColor,props=_objectWithoutProperties(_ref2$2,_excluded2);var getColor=useGetColor();var bg=color;var bgObj=tinycolor(getColor(bg));var borderColor=explicitBorderColor!=null?explicitBorderColor:color;var fontColor='text';if(!!outline&&fill!==true){bg='transparent';fontColor=color;}else{fontColor=getContrastColor(bgObj,[getColor('overlayBG'),getColor('text')],contrastTolerance);}return[Object.assign({},values,{fontColor:fontColor}),Object.assign({},props,{bg:forcedBG||bg,borderColor:borderColor})];}
@@ -1 +1 @@
1
- import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import tinycolor from'tinycolor2';var variations=[10,20,30,40,50,60,70,80,90];export function generateColorVariants(colors){var isDark=tinycolor((colors==null?void 0:colors.overlayBG)||(colors==null?void 0:colors.bg)).isDark();var result={};Object.entries(colors).forEach(function(_ref){var _ref2=_slicedToArray(_ref,2),key=_ref2[0],value=_ref2[1];result[key]=value;variations.forEach(function(amount){if(amount<=60){var lightenSignal=!isDark?'-':'+';var darkenSignal=isDark?'-':'+';result[`${key}${lightenSignal}${amount}`]=tinycolor(value).lighten(amount).toString();result[`${key}${darkenSignal}${amount}`]=tinycolor(value).darken(amount).toString();}result[`${key}_op${amount}`]=tinycolor(value).setAlpha(amount/100).toString();});});return result;}export function applyColorVariantsOnTheme(theme){return Object.assign({},theme,{colors:generateColorVariants(theme.colors)});}
1
+ import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import tinycolor from'tinycolor2';var variations=[10,20,30,40,50,60,70,80,90];export function generateColorVariants(colors){var isDark=tinycolor((colors==null?void 0:colors.overlayBG)||(colors==null?void 0:colors.bg)).isDark();var result={};Object.entries(colors).forEach(function(_ref){var _ref2=_slicedToArray(_ref,2),key=_ref2[0],value=_ref2[1];result[key]=value;variations.forEach(function(amount){if(amount<=40){var lightenSignal=!isDark?'-':'+';var darkenSignal=isDark?'-':'+';result[`${key}${lightenSignal}${amount}`]=tinycolor(value).lighten(amount).toString();result[`${key}${darkenSignal}${amount}`]=tinycolor(value).darken(amount).toString();}result[`${key}_op${amount}`]=tinycolor(value).setAlpha(amount/100).toString();});});return result;}export function applyColorVariantsOnTheme(theme){return Object.assign({},theme,{colors:generateColorVariants(theme.colors)});}
@@ -1 +1 @@
1
- import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";var _excluded=["color"];import{omit,keys}from'ramda';import{DEFAULT_DARK_THEME}from"../default/darkTheme";var SCALE=keys(DEFAULT_DARK_THEME.colors);export function getColorFromProps(_ref,defaultValue){var color=_ref.color,props=_objectWithoutProperties(_ref,_excluded);if(!!color)return[color,props];color=SCALE.find(function(key){return!!props[key];})||defaultValue;return[color,omit(SCALE,props)];}
1
+ import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";var _excluded=["color"];import{omit,keys}from'ramda';import{DEFAULT_DARK_THEME}from"../default/darkTheme";var EXCLUDED_KEYS=['shadow','transparent'];var SCALE=keys(DEFAULT_DARK_THEME.colors).filter(function(k){return!EXCLUDED_KEYS.includes(k);});export function getColorFromProps(_ref,defaultValue){var color=_ref.color,props=_objectWithoutProperties(_ref,_excluded);if(!!color)return[color,props];color=SCALE.find(function(key){return!!props[key];})||defaultValue;return[color,omit(SCALE,props)];}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neko-os/ui",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "author": "Christian Storch <ccstorch@gmail.com>",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -1,10 +1,12 @@
1
1
  import { pipe } from 'ramda'
2
+ import React from 'react'
2
3
 
3
- import { TopBar, View } from '../structure'
4
4
  import { BottomDrawer, DrawerScrollView } from '../modals/bottomDrawer'
5
5
  import { Menu } from './menu/Menu'
6
6
  import { Section } from '../sections'
7
+ import { TopBar, View } from '../structure'
7
8
  import { useDefaultModifier } from '../../modifiers/default'
9
+ import { useTheme } from '../../theme'
8
10
  import { useThemeComponentModifier } from '../../modifiers/themeComponent'
9
11
 
10
12
  const DEFAULT_PROPS = {
@@ -44,7 +46,8 @@ function Content({ items, title, subtitle, onClose, onChange, topBarProps, menuP
44
46
  )
45
47
  }
46
48
 
47
- export function ActionsDrawer({ items, onChange, title, subtitle, onClose, ...rootProps }) {
49
+ export function ActionsDrawer({ items, onChange, title, subtitle, onClose, snapPoints, ...rootProps }) {
50
+ const { elementHeights, spaces } = useTheme()
48
51
  const [{}, formattedProps] = pipe(
49
52
  useThemeComponentModifier('ActionsDrawer'), //
50
53
  useDefaultModifier(DEFAULT_PROPS)
@@ -52,8 +55,18 @@ export function ActionsDrawer({ items, onChange, title, subtitle, onClose, ...ro
52
55
 
53
56
  const { topBarProps, menuProps, ...props } = formattedProps
54
57
 
58
+ // Auto height
59
+ snapPoints = React.useMemo(() => {
60
+ if (!!snapPoints?.length) return snapPoints
61
+ // Title bar + padding + safe footer space
62
+ const safeSpace = (!!title ? elementHeights.xxl : spaces.sm) + spaces.md + spaces.sm
63
+ const itemHeight = elementHeights[menuProps?.linkMinHeight]
64
+ const itemsLength = Math.min(8, items.length)
65
+ return [itemsLength * itemHeight + safeSpace]
66
+ }, [snapPoints, title, items])
67
+
55
68
  return (
56
- <BottomDrawer onClose={onClose} {...props}>
69
+ <BottomDrawer onClose={onClose} snapPoints={snapPoints} {...props}>
57
70
  <Content
58
71
  onClose={onClose}
59
72
  topBarProps={topBarProps}
@@ -15,6 +15,7 @@ import { useHoverConverter } from '../../modifiers/hover'
15
15
  import { useMarginModifier } from '../../modifiers/margin'
16
16
  import { usePaddingModifier } from '../../modifiers/padding'
17
17
  import { usePositionModifier } from '../../modifiers/position'
18
+ import { useShadowModifier } from '../../modifiers/shadow'
18
19
  import { useSizeConverter } from '../../modifiers/sizeConverter'
19
20
  import { useSizeModifier } from '../../modifiers/size'
20
21
  import { useStateModifier } from '../../modifiers/state'
@@ -39,6 +40,7 @@ export function Button({ children, ...rootProps }) {
39
40
  useSizeConverter('elementHeights', 'md'),
40
41
  useThemeComponentModifier('Button'),
41
42
  useDefaultModifier(DEFAULT_PROPS),
43
+ useShadowModifier,
42
44
  useHoverConverter,
43
45
  useCursorModifier,
44
46
  useFullColorModifier,
@@ -1,21 +1,17 @@
1
- import React from 'react';
1
+ import React from 'react'
2
2
 
3
- const DrawerContext = React.createContext(null);
3
+ const DrawerContext = React.createContext(null)
4
4
 
5
5
  export function DrawerProvider({ children, value }) {
6
- return (
7
- <DrawerContext.Provider value={value}>
8
- {children}
9
- </DrawerContext.Provider>
10
- );
6
+ return <DrawerContext.Provider value={value}>{children}</DrawerContext.Provider>
11
7
  }
12
8
 
13
9
  export function useDrawerContext() {
14
- const context = React.useContext(DrawerContext);
10
+ const context = React.useContext(DrawerContext)
15
11
 
16
12
  if (!context) {
17
- throw new Error('useDrawerContext must be used within a DrawerProvider');
13
+ return { outOfContext: true }
18
14
  }
19
15
 
20
- return context;
21
- }
16
+ return context
17
+ }
@@ -127,5 +127,13 @@ export function createDrawerScrollComponent(Component) {
127
127
  )
128
128
  }
129
129
 
130
- return DrawerScrollComponent
130
+ function ConditionalDrawerScrollComponent(props) {
131
+ const { outOfContext } = useDrawerContext()
132
+
133
+ if (outOfContext) return <Component {...props} />
134
+
135
+ return <DrawerScrollComponent {...props} />
136
+ }
137
+
138
+ return ConditionalDrawerScrollComponent
131
139
  }
@@ -16,7 +16,7 @@ export function TopBar({ right, left, WrapperView, children, ...rootProps }) {
16
16
  return (
17
17
  <WrapperView paddingT={useSafeArea && safeTop} {...props}>
18
18
  {!!hasContent && (
19
- <View minH="md" centerV row paddingH="md" paddingV="sm" gap="sm" fullW>
19
+ <View minH="xxl" centerV row paddingH="md" paddingV="sm" gap="sm" fullW>
20
20
  <View flex={1} toLeft>
21
21
  {left}
22
22
  </View>
@@ -5,13 +5,13 @@ import { useGetColor } from '../theme/ThemeHandler'
5
5
 
6
6
  export function useFullColorModifier([
7
7
  { color, ...values },
8
- { outline, contrastTolerance, fill, bg: forcedBG, ...props },
8
+ { outline, contrastTolerance, fill, bg: forcedBG, borderColor: explicitBorderColor, ...props },
9
9
  ]) {
10
10
  const getColor = useGetColor()
11
11
 
12
12
  let bg = color
13
13
  const bgObj = tinycolor(getColor(bg))
14
- let borderColor = color
14
+ let borderColor = explicitBorderColor ?? color
15
15
  let fontColor = 'text'
16
16
 
17
17
  if (!!outline && fill !== true) {
@@ -10,7 +10,7 @@ export function generateColorVariants(colors) {
10
10
  result[key] = value
11
11
 
12
12
  variations.forEach((amount) => {
13
- if (amount <= 60) {
13
+ if (amount <= 40) {
14
14
  const lightenSignal = !isDark ? '-' : '+'
15
15
  const darkenSignal = isDark ? '-' : '+'
16
16
  result[`${key}${lightenSignal}${amount}`] = tinycolor(value).lighten(amount).toString()
@@ -2,7 +2,8 @@ import { omit, keys } from 'ramda'
2
2
 
3
3
  import { DEFAULT_DARK_THEME } from '../default/darkTheme'
4
4
 
5
- const SCALE = keys(DEFAULT_DARK_THEME.colors)
5
+ const EXCLUDED_KEYS = ['shadow', 'transparent']
6
+ const SCALE = keys(DEFAULT_DARK_THEME.colors).filter((k) => !EXCLUDED_KEYS.includes(k))
6
7
 
7
8
  export function getColorFromProps({ color, ...props }, defaultValue) {
8
9
  if (!!color) return [color, props]