@neko-os/ui 0.0.8 → 0.0.9
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.native.js +1 -1
- package/dist/abstractions/ActivityIndicator.web.js +1 -0
- package/dist/abstractions/BlurView.web.js +1 -0
- package/dist/abstractions/FlatList.js +1 -0
- package/dist/abstractions/FlatList.native.js +1 -0
- package/dist/abstractions/FlatList.web.js +1 -0
- package/dist/abstractions/ScrollView.web.js +1 -0
- package/dist/abstractions/helpers/storage.js +1 -0
- package/dist/abstractions/helpers/storage.native.js +1 -0
- package/dist/components/actions/Button.js +1 -1
- package/dist/components/actions/Dropdown.js +1 -1
- package/dist/components/actions/menu/VerticalMenu.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/layout/Layout.js +1 -1
- package/dist/components/list/FlatList.js +1 -0
- package/dist/components/list/index.js +1 -1
- package/dist/components/state/LoadingView.js +1 -1
- package/dist/components/structure/View.js +1 -1
- package/dist/components/structure/bottomDrawer/native/BottomDrawer.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/theme/ThemePicker.js +1 -0
- package/dist/components/theme/ThemePickerDrawer.js +1 -0
- package/dist/components/theme/ThemeStatusBar.js +1 -0
- package/dist/components/theme/ThemeStatusBar.native.js +1 -0
- package/dist/components/theme/ThemeThumb.js +1 -0
- package/dist/components/theme/index.js +1 -0
- package/dist/helpers/index.js +1 -1
- package/dist/helpers/storage.js +1 -0
- package/dist/modifiers/fullColor.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/deepWoodsTheme.js +1 -1
- package/dist/theme/default/forestTheme.js +1 -1
- package/dist/theme/default/hackerTheme.js +1 -1
- package/dist/theme/default/lightTheme.js +1 -1
- package/dist/theme/default/midnightTheme.js +1 -1
- package/dist/theme/default/msdosTheme.js +1 -1
- package/dist/theme/default/oceanTheme.js +1 -1
- package/dist/theme/default/paperTheme.js +1 -0
- 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/format/formatTheme.js +1 -1
- package/dist/theme/helpers/contrastColor.js +1 -1
- package/package.json +1 -1
- package/src/NekoUI.js +13 -1
- package/src/abstractions/ActivityIndicator.native.js +3 -4
- package/src/abstractions/ActivityIndicator.web.js +43 -0
- package/src/abstractions/BlurView.web.js +39 -0
- package/src/abstractions/FlatList.js +39 -0
- package/src/abstractions/FlatList.native.js +32 -0
- package/src/abstractions/FlatList.web.js +3 -0
- package/src/abstractions/ScrollView.web.js +3 -0
- package/src/abstractions/Text.web.js +15 -0
- package/src/abstractions/helpers/storage.js +32 -0
- package/src/abstractions/helpers/storage.native.js +34 -0
- package/src/components/actions/Button.js +1 -0
- package/src/components/actions/Dropdown.js +17 -2
- package/src/components/actions/menu/VerticalMenu.js +1 -1
- package/src/components/index.js +1 -0
- package/src/components/layout/Layout.js +1 -1
- package/src/components/list/FlatList.js +54 -0
- package/src/components/list/index.js +1 -0
- package/src/components/state/LoadingView.js +10 -1
- package/src/components/structure/View.js +2 -0
- package/src/components/structure/bottomDrawer/native/BottomDrawer.js +15 -2
- package/src/components/structure/popover/Popover.js +11 -2
- package/src/components/structure/popover/Popover.native.js +3 -2
- package/src/components/theme/ThemePicker.js +49 -0
- package/src/components/theme/ThemePickerDrawer.js +13 -0
- package/src/components/theme/ThemeStatusBar.js +3 -0
- package/src/components/theme/ThemeStatusBar.native.js +9 -0
- package/src/components/theme/ThemeThumb.js +98 -0
- package/src/components/theme/index.js +3 -0
- package/src/helpers/index.js +1 -0
- package/src/helpers/storage.js +54 -0
- package/src/modifiers/fullColor.js +2 -2
- package/src/theme/ThemeHandler.js +18 -2
- package/src/theme/default/base.js +6 -6
- package/src/theme/default/blackTheme.js +4 -1
- package/src/theme/default/cyberpunkTheme.js +3 -1
- package/src/theme/default/darkTheme.js +3 -1
- package/src/theme/default/deepWoodsTheme.js +4 -2
- package/src/theme/default/forestTheme.js +3 -1
- package/src/theme/default/hackerTheme.js +3 -1
- package/src/theme/default/lightTheme.js +3 -1
- package/src/theme/default/midnightTheme.js +3 -1
- package/src/theme/default/msdosTheme.js +18 -4
- package/src/theme/default/oceanTheme.js +4 -2
- package/src/theme/default/paperTheme.js +35 -0
- package/src/theme/default/pastelTheme.js +3 -1
- package/src/theme/default/sunsetTheme.js +5 -3
- package/src/theme/default/themes.js +7 -10
- package/src/theme/format/formatTheme.js +9 -3
- package/src/theme/helpers/contrastColor.js +49 -11
- package/dist/abstractions/TouchableOpacity.web.js +0 -1
- package/src/abstractions/TouchableOpacity.web.js +0 -3
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { AbsView } from './View'
|
|
2
|
+
|
|
3
|
+
let AbsBlurView
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
const { BlurView } = require('expo-blur') || {}
|
|
7
|
+
AbsBlurView = ({ intensity, tint, disabledForAndroid, style, children, ...props }) => {
|
|
8
|
+
return (
|
|
9
|
+
<BlurView
|
|
10
|
+
intensity={intensity}
|
|
11
|
+
tint={tint}
|
|
12
|
+
style={[style, { overflow: 'hidden' }]}
|
|
13
|
+
experimentalBlurMethod={disabledForAndroid ? 'none' : 'dimezisBlurView'}
|
|
14
|
+
>
|
|
15
|
+
{children}
|
|
16
|
+
</BlurView>
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
// return (
|
|
20
|
+
// <AbsView style={[style, { overflow: 'hidden' }]} {...props}>
|
|
21
|
+
// <BlurView
|
|
22
|
+
// intensity={intensity}
|
|
23
|
+
// tint={tint}
|
|
24
|
+
// style={[style, { width: '100%' }]}
|
|
25
|
+
// experimentalBlurMethod={disabledForAndroid ? 'none' : 'dimezisBlurView'}
|
|
26
|
+
// >
|
|
27
|
+
// {children}
|
|
28
|
+
// </BlurView>
|
|
29
|
+
// </AbsView>
|
|
30
|
+
// )
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
AbsBlurView = (props) => {
|
|
34
|
+
console.warn('expo-blur not instaled.')
|
|
35
|
+
return <AbsView {...props} />
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { AbsBlurView }
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { AbsView } from './View'
|
|
3
|
+
|
|
4
|
+
const defaultRender = () => false
|
|
5
|
+
|
|
6
|
+
export function AbsFlatList({
|
|
7
|
+
data,
|
|
8
|
+
renderItem,
|
|
9
|
+
ListEmptyComponent,
|
|
10
|
+
Empty,
|
|
11
|
+
renderEmpty,
|
|
12
|
+
ListFooterComponent,
|
|
13
|
+
Footer,
|
|
14
|
+
renderFooter,
|
|
15
|
+
ListHeaderComponent,
|
|
16
|
+
Header,
|
|
17
|
+
renderHeader,
|
|
18
|
+
keyExtractor,
|
|
19
|
+
...props
|
|
20
|
+
}) {
|
|
21
|
+
ListEmptyComponent = ListEmptyComponent || Empty || defaultRender
|
|
22
|
+
ListFooterComponent = ListFooterComponent || Footer || renderFooter || defaultRender
|
|
23
|
+
ListHeaderComponent = ListHeaderComponent || Header || renderHeader || defaultRender
|
|
24
|
+
keyExtractor = keyExtractor || ((item, index) => index)
|
|
25
|
+
renderItem = renderItem || defaultRender
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<AbsView {...props}>
|
|
29
|
+
<ListHeaderComponent />
|
|
30
|
+
|
|
31
|
+
{!data?.length && <ListEmptyComponent />}
|
|
32
|
+
{data?.map?.((item, index) => (
|
|
33
|
+
<React.Fragment key={keyExtractor(item, index)}>{renderItem({ item, index })}</React.Fragment>
|
|
34
|
+
))}
|
|
35
|
+
|
|
36
|
+
<ListFooterComponent />
|
|
37
|
+
</AbsView>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { FlatList } from 'react-native'
|
|
2
|
+
|
|
3
|
+
export const AbsFlatList = ({
|
|
4
|
+
style: { height, width, ...style },
|
|
5
|
+
ListEmptyComponent,
|
|
6
|
+
Empty,
|
|
7
|
+
renderEmpty,
|
|
8
|
+
ListFooterComponent,
|
|
9
|
+
Footer,
|
|
10
|
+
renderFooter,
|
|
11
|
+
ListHeaderComponent,
|
|
12
|
+
Header,
|
|
13
|
+
renderHeader,
|
|
14
|
+
|
|
15
|
+
...props
|
|
16
|
+
}) => {
|
|
17
|
+
ListEmptyComponent = ListEmptyComponent || Empty || defaultRender
|
|
18
|
+
ListFooterComponent = ListFooterComponent || Footer || renderFooter || defaultRender
|
|
19
|
+
ListHeaderComponent = ListHeaderComponent || Header || renderHeader || defaultRender
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<FlatList
|
|
23
|
+
height={height}
|
|
24
|
+
width={width}
|
|
25
|
+
{...props}
|
|
26
|
+
ListEmptyComponent={ListEmptyComponent}
|
|
27
|
+
ListFooterComponent={ListFooterComponent}
|
|
28
|
+
ListHeaderComponent={ListHeaderComponent}
|
|
29
|
+
contentContainerStyle={style}
|
|
30
|
+
/>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
// export const AbsText = ({ numberOfLines, style, ...props }) => {
|
|
2
|
+
// style = style || {}
|
|
3
|
+
|
|
4
|
+
// const limitLinesStyle = !!numberOfLines
|
|
5
|
+
// ? {
|
|
6
|
+
// display: '-webkit-box',
|
|
7
|
+
// WebkitLineClamp: numberOfLines,
|
|
8
|
+
// WebkitBoxOrient: 'vertical',
|
|
9
|
+
// overflow: 'hidden',
|
|
10
|
+
// }
|
|
11
|
+
// : {}
|
|
12
|
+
|
|
13
|
+
// return <AbsText {...props} style={[limitLinesStyle, style]} />
|
|
14
|
+
// }
|
|
15
|
+
|
|
1
16
|
import { Text as RNText } from 'react-native'
|
|
2
17
|
|
|
3
18
|
export const AbsText = RNText
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
function set(key, value) {
|
|
2
|
+
return localStorage.setItem(key, value)
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function setAsync(key, value) {
|
|
6
|
+
return Promise.resulve(set(key, value))
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function get(key) {
|
|
10
|
+
return localStorage.getItem(key)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getAsync(key) {
|
|
14
|
+
return Promise.resulve(get(key))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function remove(key) {
|
|
18
|
+
return localStorage.removeItem(key)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function removeAsync(key) {
|
|
22
|
+
return Promise.resulve(remove(key))
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const AbsStorage = {
|
|
26
|
+
set,
|
|
27
|
+
setAsync,
|
|
28
|
+
get,
|
|
29
|
+
getAsync,
|
|
30
|
+
remove,
|
|
31
|
+
removeAsync,
|
|
32
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
let set = () => console.warn('expo-sqlite not installed. Neko Storage needs expo-sqlite to work properly')
|
|
2
|
+
let setAsync = () => Promise.resolve(set())
|
|
3
|
+
|
|
4
|
+
let get = () => console.warn('expo-sqlite not installed. Neko Storage needs expo-sqlite to work properly')
|
|
5
|
+
let getAsync = () => Promise.resolve(get())
|
|
6
|
+
|
|
7
|
+
let remove = () => console.warn('expo-sqlite not installed. Neko Storage needs expo-sqlite to work properly')
|
|
8
|
+
let removeAsync = () => Promise.resolve(remove())
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const StorageModule = require('expo-sqlite/kv-store')
|
|
12
|
+
if (StorageModule?.default) {
|
|
13
|
+
const Storage = StorageModule.default
|
|
14
|
+
set = Storage.setItemSync.bind(Storage)
|
|
15
|
+
setAsync = Storage.setItem.bind(Storage)
|
|
16
|
+
|
|
17
|
+
get = Storage.getItemSync.bind(Storage)
|
|
18
|
+
getAsync = Storage.getItem.bind(Storage)
|
|
19
|
+
|
|
20
|
+
remove = Storage.removeItemSync.bind(Storage)
|
|
21
|
+
removeAsync = Storage.removeItem.bind(Storage)
|
|
22
|
+
}
|
|
23
|
+
} catch (e) {
|
|
24
|
+
console.log('expo-sqlite not available:', e)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const AbsStorage = {
|
|
28
|
+
set,
|
|
29
|
+
setAsync,
|
|
30
|
+
get,
|
|
31
|
+
getAsync,
|
|
32
|
+
remove,
|
|
33
|
+
removeAsync,
|
|
34
|
+
}
|
|
@@ -31,6 +31,8 @@ export function Dropdown({ items, ...rootProps }) {
|
|
|
31
31
|
popoverProps,
|
|
32
32
|
iconLabelProps,
|
|
33
33
|
children,
|
|
34
|
+
placement,
|
|
35
|
+
gap,
|
|
34
36
|
...props
|
|
35
37
|
} = formattedProps
|
|
36
38
|
|
|
@@ -38,17 +40,29 @@ export function Dropdown({ items, ...rootProps }) {
|
|
|
38
40
|
<View className="neko-dropdown" {...props}>
|
|
39
41
|
<Popover
|
|
40
42
|
useParentMinWidth
|
|
41
|
-
placement=
|
|
43
|
+
placement={placement || 'bottomLeft'}
|
|
42
44
|
trigger={trigger}
|
|
43
45
|
padding="xs"
|
|
44
46
|
useBottomDrawer={{ native: true, sm: true, md: true }}
|
|
47
|
+
bottomDrawerProps={{
|
|
48
|
+
bg: 'mainBG',
|
|
49
|
+
contentProps: { bg: 'overlayBG', br: 'lg', margin: 'md' },
|
|
50
|
+
}}
|
|
45
51
|
{...popoverProps}
|
|
46
52
|
renderContent={({ onClose }) => {
|
|
47
53
|
const handleChange = (...params) => {
|
|
48
54
|
if (onChange) onChange(...params)
|
|
49
55
|
onClose()
|
|
50
56
|
}
|
|
51
|
-
return
|
|
57
|
+
return (
|
|
58
|
+
<Menu
|
|
59
|
+
vertical
|
|
60
|
+
items={items}
|
|
61
|
+
onChange={handleChange}
|
|
62
|
+
_linkPaddingV="lg"
|
|
63
|
+
_linkProps={{ borderB: true, padding: 'lg', borderL: 0, brColor: 'divider' }}
|
|
64
|
+
/>
|
|
65
|
+
)
|
|
52
66
|
}}
|
|
53
67
|
>
|
|
54
68
|
{children || (
|
|
@@ -59,6 +73,7 @@ export function Dropdown({ items, ...rootProps }) {
|
|
|
59
73
|
strong={strong}
|
|
60
74
|
color={color}
|
|
61
75
|
invert
|
|
76
|
+
gap={gap}
|
|
62
77
|
{...iconLabelProps}
|
|
63
78
|
/>
|
|
64
79
|
</Link>
|
|
@@ -42,7 +42,7 @@ function LinkItem({
|
|
|
42
42
|
marginR={3}
|
|
43
43
|
borderL={3}
|
|
44
44
|
marginV={-4}
|
|
45
|
-
|
|
45
|
+
brColor={active ? activeColor : 'transparent'}
|
|
46
46
|
bg={bg}
|
|
47
47
|
transition="border-color 0.5s ease, background 0.3s ease"
|
|
48
48
|
hover={{ br: 0 }}
|
package/src/components/index.js
CHANGED
|
@@ -32,7 +32,7 @@ export function Layout({ children, ...rootProps }) {
|
|
|
32
32
|
|
|
33
33
|
return (
|
|
34
34
|
<LayoutContext.Provider value={value}>
|
|
35
|
-
<View className="neko-layout" bg="
|
|
35
|
+
<View className="neko-layout" bg="mainBG" flex relative {...rootProps} ref={layoutRef}>
|
|
36
36
|
{children}
|
|
37
37
|
</View>
|
|
38
38
|
</LayoutContext.Provider>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { pipe } from 'ramda'
|
|
2
|
+
|
|
3
|
+
import { AbsFlatList } from '../../abstractions/FlatList'
|
|
4
|
+
import { useAnimationModifier } from '../../modifiers/animation'
|
|
5
|
+
import { useBackgroundModifier } from '../../modifiers/background'
|
|
6
|
+
import { useBorderModifier } from '../../modifiers/border'
|
|
7
|
+
import { useDefaultModifier } from '../../modifiers/default'
|
|
8
|
+
import { useDisplayModifier } from '../../modifiers/display'
|
|
9
|
+
import { useFlexModifier } from '../../modifiers/flex'
|
|
10
|
+
import { useFlexWrapperModifier } from '../../modifiers/flexWrapper'
|
|
11
|
+
import { useMarginModifier } from '../../modifiers/margin'
|
|
12
|
+
import { useOverflowModifier } from '../../modifiers/overflow'
|
|
13
|
+
import { usePaddingModifier } from '../../modifiers/padding'
|
|
14
|
+
import { usePositionModifier } from '../../modifiers/position'
|
|
15
|
+
import { useShadowModifier } from '../../modifiers/shadow'
|
|
16
|
+
import { useSizeModifier } from '../../modifiers/size'
|
|
17
|
+
import { useStateModifier } from '../../modifiers/state'
|
|
18
|
+
import { useThemeComponentModifier } from '../../modifiers/themeComponent'
|
|
19
|
+
|
|
20
|
+
const DEFAULT_PROPS = ([_, { horizontal }]) => {
|
|
21
|
+
const overflowKey = horizontal ? 'scrollX' : 'scrollY'
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
[overflowKey]: true,
|
|
25
|
+
row: !!horizontal,
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function FlatList({ children, ...rootProps }) {
|
|
30
|
+
const [_, props] = pipe(
|
|
31
|
+
useThemeComponentModifier('FlatList'),
|
|
32
|
+
useDefaultModifier(DEFAULT_PROPS),
|
|
33
|
+
useFlexWrapperModifier,
|
|
34
|
+
useDisplayModifier,
|
|
35
|
+
useAnimationModifier,
|
|
36
|
+
useStateModifier,
|
|
37
|
+
useSizeModifier,
|
|
38
|
+
usePositionModifier,
|
|
39
|
+
useOverflowModifier,
|
|
40
|
+
usePaddingModifier,
|
|
41
|
+
useMarginModifier,
|
|
42
|
+
useFlexModifier,
|
|
43
|
+
useBackgroundModifier,
|
|
44
|
+
useBorderModifier,
|
|
45
|
+
useShadowModifier
|
|
46
|
+
)([{}, rootProps])
|
|
47
|
+
// useNormalView = useResponsiveValue(useNormalView)
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<AbsFlatList className="neko-flat-list" {...props}>
|
|
51
|
+
{children}
|
|
52
|
+
</AbsFlatList>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
@@ -18,7 +18,16 @@ export function LoadingView({ active, children, size, color, replaceChildren, no
|
|
|
18
18
|
return (
|
|
19
19
|
<View className="neko-loading-view" relative {...props}>
|
|
20
20
|
{children}
|
|
21
|
-
<View
|
|
21
|
+
<View
|
|
22
|
+
className="neko-laoding-view-overlay"
|
|
23
|
+
bg="mainBG_op90"
|
|
24
|
+
absolute
|
|
25
|
+
top={0}
|
|
26
|
+
left={0}
|
|
27
|
+
right={0}
|
|
28
|
+
bottom={0}
|
|
29
|
+
center
|
|
30
|
+
>
|
|
22
31
|
{loader}
|
|
23
32
|
</View>
|
|
24
33
|
</View>
|
|
@@ -4,6 +4,7 @@ import { AbsView } from '../../abstractions/View'
|
|
|
4
4
|
import { useAnimationModifier } from '../../modifiers/animation'
|
|
5
5
|
import { useBackgroundModifier } from '../../modifiers/background'
|
|
6
6
|
import { useBorderModifier } from '../../modifiers/border'
|
|
7
|
+
import { useCursorModifier } from '../../modifiers/cursor'
|
|
7
8
|
import { useDisplayModifier } from '../../modifiers/display'
|
|
8
9
|
import { useFlexModifier } from '../../modifiers/flex'
|
|
9
10
|
import { useFlexWrapperModifier } from '../../modifiers/flexWrapper'
|
|
@@ -21,6 +22,7 @@ export function View({ children, ...rootProps }) {
|
|
|
21
22
|
useThemeComponentModifier('View'),
|
|
22
23
|
useFlexWrapperModifier,
|
|
23
24
|
useDisplayModifier,
|
|
25
|
+
useCursorModifier,
|
|
24
26
|
useAnimationModifier,
|
|
25
27
|
useStateModifier,
|
|
26
28
|
useSizeModifier,
|
|
@@ -189,8 +189,21 @@ function InnerContent({
|
|
|
189
189
|
|
|
190
190
|
<DrawerProvider value={contextValue}>
|
|
191
191
|
<GestureDetector gesture={panGesture}>
|
|
192
|
-
<Animated.View
|
|
193
|
-
|
|
192
|
+
<Animated.View
|
|
193
|
+
style={[styles.container, { height: SCREEN_HEIGHT }, animatedSheetStyle]}
|
|
194
|
+
pointerEvents="box-none"
|
|
195
|
+
>
|
|
196
|
+
<View
|
|
197
|
+
flex
|
|
198
|
+
bg="overlayBG"
|
|
199
|
+
shadow
|
|
200
|
+
paddingB={useSafeArea && bottomInset}
|
|
201
|
+
borderRadiusT="xxxl"
|
|
202
|
+
marginL="auto"
|
|
203
|
+
marginR="auto"
|
|
204
|
+
fullW
|
|
205
|
+
{...props}
|
|
206
|
+
>
|
|
194
207
|
<DrawerHandle hide={hideHandle} />
|
|
195
208
|
<View flex {...contentProps}>
|
|
196
209
|
{children}
|
|
@@ -15,6 +15,7 @@ export function Popover({
|
|
|
15
15
|
parentWidth,
|
|
16
16
|
parentMinWidth,
|
|
17
17
|
useBottomDrawer = {},
|
|
18
|
+
bottomDrawerProps = {},
|
|
18
19
|
...props
|
|
19
20
|
}) {
|
|
20
21
|
const shouldUseDrawer = useResponsiveValue(useBottomDrawer)
|
|
@@ -64,7 +65,15 @@ export function Popover({
|
|
|
64
65
|
React.useEffect(() => () => onClose(), [])
|
|
65
66
|
|
|
66
67
|
if (shouldUseDrawer) {
|
|
67
|
-
return
|
|
68
|
+
return (
|
|
69
|
+
<DrawerPopover
|
|
70
|
+
content={content}
|
|
71
|
+
renderContent={renderContent}
|
|
72
|
+
children={children}
|
|
73
|
+
{...props}
|
|
74
|
+
{...bottomDrawerProps}
|
|
75
|
+
/>
|
|
76
|
+
)
|
|
68
77
|
}
|
|
69
78
|
|
|
70
79
|
const child = React.Children.only(children)
|
|
@@ -87,7 +96,7 @@ function DrawerPopover({ children, content, renderContent, snapPoints, ...props
|
|
|
87
96
|
<>
|
|
88
97
|
{React.cloneElement(child, childProps)}
|
|
89
98
|
|
|
90
|
-
<BottomDrawer open={open} onClose={onClose} snapPoints={snapPoints}>
|
|
99
|
+
<BottomDrawer open={open} onClose={onClose} snapPoints={snapPoints} {...props}>
|
|
91
100
|
{renderContent({ onClose })}
|
|
92
101
|
</BottomDrawer>
|
|
93
102
|
</>
|
|
@@ -13,6 +13,7 @@ export function Popover({
|
|
|
13
13
|
placement = 'bottom',
|
|
14
14
|
children,
|
|
15
15
|
useBottomDrawer = {},
|
|
16
|
+
bottomDrawerProps = {},
|
|
16
17
|
snapPoints,
|
|
17
18
|
...props
|
|
18
19
|
}) {
|
|
@@ -59,7 +60,7 @@ export function Popover({
|
|
|
59
60
|
<View ref={ref}>
|
|
60
61
|
{children}
|
|
61
62
|
|
|
62
|
-
<BottomDrawer open={open} onClose={onClose} snapPoints={snapPoints}>
|
|
63
|
+
<BottomDrawer open={open} onClose={onClose} snapPoints={snapPoints} {...bottomDrawerProps}>
|
|
63
64
|
{renderContent({ onClose: onClose })}
|
|
64
65
|
</BottomDrawer>
|
|
65
66
|
</View>
|
|
@@ -72,7 +73,7 @@ export function Popover({
|
|
|
72
73
|
|
|
73
74
|
{open && (
|
|
74
75
|
<Modal transparent visible={open} animationType="fade" onRequestClose={onClose}>
|
|
75
|
-
<View fullW flex fullH bg="
|
|
76
|
+
<View fullW flex fullH bg="backdrop_op50">
|
|
76
77
|
<TouchableWithoutFeedback onPress={onClose}>
|
|
77
78
|
<View style={{ flex: 1 }}>
|
|
78
79
|
{triggerRect && (
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { mapObjIndexed, mergeDeepRight, values, pipe, filter } from 'ramda'
|
|
2
|
+
|
|
3
|
+
import { DEFAULT_THEMES, useThemeHandler } from '../../theme'
|
|
4
|
+
import { IconLabel } from '../presentation'
|
|
5
|
+
import { Link } from '../actions'
|
|
6
|
+
import { Picker } from '../inputs'
|
|
7
|
+
import { ThemeThumb } from './ThemeThumb'
|
|
8
|
+
|
|
9
|
+
export function ThemePicker({ onChange, onlyKeys, hideKeys }) {
|
|
10
|
+
const { activeThemeKey, setActiveThemeKey, themes, onChangeTheme } = useThemeHandler()
|
|
11
|
+
|
|
12
|
+
let options = pipe(
|
|
13
|
+
mergeDeepRight(DEFAULT_THEMES),
|
|
14
|
+
mapObjIndexed((obj, key) => ({ ...obj, value: key, key })),
|
|
15
|
+
values,
|
|
16
|
+
filter((item) => {
|
|
17
|
+
if (item.value === '_all') return false
|
|
18
|
+
if (onlyKeys && onlyKeys.includes(item.value)) return true
|
|
19
|
+
if (hideKeys && hideKeys.includes(item.value)) return false
|
|
20
|
+
return true
|
|
21
|
+
})
|
|
22
|
+
)(themes)
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Picker
|
|
26
|
+
colSpan={12}
|
|
27
|
+
gap="lg"
|
|
28
|
+
value={activeThemeKey}
|
|
29
|
+
onChange={(key) => {
|
|
30
|
+
setActiveThemeKey(key)
|
|
31
|
+
onChangeTheme?.(key)
|
|
32
|
+
onChange?.(key)
|
|
33
|
+
}}
|
|
34
|
+
options={options}
|
|
35
|
+
renderOption={({ option, selected, onChange }) => (
|
|
36
|
+
<Link onPress={onChange} gap="xs">
|
|
37
|
+
<ThemeThumb value={option.value} />
|
|
38
|
+
<IconLabel
|
|
39
|
+
center
|
|
40
|
+
label={option.label}
|
|
41
|
+
icon={selected && 'checkbox-circle-fill'}
|
|
42
|
+
color={selected ? 'primary' : 'text3'}
|
|
43
|
+
strong
|
|
44
|
+
/>
|
|
45
|
+
</Link>
|
|
46
|
+
)}
|
|
47
|
+
/>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BottomDrawer } from '../structure'
|
|
2
|
+
import { ScrollView } from '../list/ScrollView'
|
|
3
|
+
import { ThemePicker } from './ThemePicker'
|
|
4
|
+
|
|
5
|
+
export function ThemePickerDrawer({ open, onClose, onChange }) {
|
|
6
|
+
return (
|
|
7
|
+
<BottomDrawer open={open} onClose={onClose} maxWidth={550} snapPoints={['50%', '85%']}>
|
|
8
|
+
<ScrollView padding="md">
|
|
9
|
+
<ThemePicker onChange={onChange} />
|
|
10
|
+
</ScrollView>
|
|
11
|
+
</BottomDrawer>
|
|
12
|
+
)
|
|
13
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { View } from '../structure'
|
|
2
|
+
import { useFormattedTheme } from '../../theme/format/formatTheme'
|
|
3
|
+
import { useResponsiveValue } from '../../responsive'
|
|
4
|
+
import { useThemeHandler } from '../../theme'
|
|
5
|
+
|
|
6
|
+
export function ThemeThumb({ value }) {
|
|
7
|
+
const { themes } = useThemeHandler()
|
|
8
|
+
const { colors, label } = useFormattedTheme(themes, value)
|
|
9
|
+
const isMobile = useResponsiveValue({ smd: true, df: false })
|
|
10
|
+
|
|
11
|
+
if (isMobile) {
|
|
12
|
+
return (
|
|
13
|
+
<View centerH>
|
|
14
|
+
<View
|
|
15
|
+
bg={colors.mainBG}
|
|
16
|
+
height={175}
|
|
17
|
+
fullW
|
|
18
|
+
br="md"
|
|
19
|
+
hiddenOverflow
|
|
20
|
+
border={2}
|
|
21
|
+
brColor={colors.divider}
|
|
22
|
+
maxWidth={100}
|
|
23
|
+
>
|
|
24
|
+
<View bg={colors.overlayBG} height={25} padding={8} row borderB brColor={colors.divider}>
|
|
25
|
+
<View width={25} fullH bg={colors.primary} br="xxs" />
|
|
26
|
+
<View flex />
|
|
27
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
28
|
+
</View>
|
|
29
|
+
|
|
30
|
+
<View flex padding={6}>
|
|
31
|
+
<View br="md" bg={colors.overlayBG} flex gap={8} padding={8} border brColor={colors.divider}>
|
|
32
|
+
<View bg={colors.text2} height={4} br="xxs" />
|
|
33
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
34
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
35
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
36
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
37
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
38
|
+
|
|
39
|
+
<View flex />
|
|
40
|
+
|
|
41
|
+
<View height={6} fullW bg={colors.primary} br="xxs" />
|
|
42
|
+
</View>
|
|
43
|
+
</View>
|
|
44
|
+
|
|
45
|
+
<View
|
|
46
|
+
bg={colors.overlayBG}
|
|
47
|
+
height={25}
|
|
48
|
+
padding={8}
|
|
49
|
+
row
|
|
50
|
+
borderT
|
|
51
|
+
brColor={colors.divider}
|
|
52
|
+
justify="space-around"
|
|
53
|
+
centerV
|
|
54
|
+
>
|
|
55
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
56
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
57
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
58
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
59
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
60
|
+
</View>
|
|
61
|
+
</View>
|
|
62
|
+
</View>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<View bg={colors.mainBG} height={175} fullW br="md" hiddenOverflow border={2} brColor={colors.divider}>
|
|
68
|
+
<View bg={colors.overlayBG} height={25} paddingV={8} paddingH={12} row borderB brColor={colors.divider}>
|
|
69
|
+
<View width={25} bg={colors.primary} br="xxs" />
|
|
70
|
+
<View flex />
|
|
71
|
+
<View ratio={1} fullH bg={colors.text4} round />
|
|
72
|
+
</View>
|
|
73
|
+
|
|
74
|
+
<View row padding={12} paddingT={8} gap={6} flex>
|
|
75
|
+
<View br="xs" bg={colors.overlayBG} flex gap={6} padding={7} border brColor={colors.divider}>
|
|
76
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
77
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
78
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
79
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
80
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
81
|
+
</View>
|
|
82
|
+
<View br="xs" bg={colors.overlayBG} flex={4} gap={8} padding={7} border brColor={colors.divider}>
|
|
83
|
+
<View bg={colors.text2} height={4} br="xxs" width={30} />
|
|
84
|
+
<View bg={colors.text4} height={2} br="xxs" width={'80%'} />
|
|
85
|
+
<View bg={colors.text4} height={2} br="xxs" width={'80%'} />
|
|
86
|
+
<View bg={colors.text4} height={2} br="xxs" width={'80%'} />
|
|
87
|
+
<View bg={colors.text4} height={2} br="xxs" width={'80%'} />
|
|
88
|
+
<View bg={colors.text4} height={2} br="xxs" width={'80%'} />
|
|
89
|
+
<View flex />
|
|
90
|
+
<View row toRight gap={6}>
|
|
91
|
+
<View width={25} height={8} bg={colors.text4} br="xxs" />
|
|
92
|
+
<View width={25} height={8} bg={colors.primary} br="xxs" />
|
|
93
|
+
</View>
|
|
94
|
+
</View>
|
|
95
|
+
</View>
|
|
96
|
+
</View>
|
|
97
|
+
)
|
|
98
|
+
}
|
package/src/helpers/index.js
CHANGED