@codeleap/web 1.1.0 → 1.1.4
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/components/PageRouter/Router.js +1 -1
- package/dist/components/PageRouter/Router.js.map +1 -1
- package/dist/components/PageRouter/index.js +1 -1
- package/dist/components/PageRouter/index.js.map +1 -1
- package/package.json +3 -2
- package/.eslintignore +0 -2
- package/.eslintrc.js +0 -3
- package/.turbo/turbo-build.log +0 -2
- package/src/components/ActivityIndicator/index.tsx +0 -55
- package/src/components/ActivityIndicator/styles.ts +0 -18
- package/src/components/Button.tsx +0 -67
- package/src/components/CenterWrapper.tsx +0 -24
- package/src/components/Checkbox/index.tsx +0 -47
- package/src/components/Checkbox/styles.ts +0 -57
- package/src/components/ContentView.tsx +0 -48
- package/src/components/Drawer.tsx +0 -114
- package/src/components/FileInput.tsx +0 -48
- package/src/components/FlatList.tsx +0 -77
- package/src/components/HorizontalScroll.tsx +0 -24
- package/src/components/Icon.tsx +0 -29
- package/src/components/Link.tsx +0 -51
- package/src/components/Modal/index.tsx +0 -150
- package/src/components/Modal/styles.ts +0 -49
- package/src/components/Overlay.tsx +0 -25
- package/src/components/PageRouter/Menu.tsx +0 -49
- package/src/components/PageRouter/MenuItem.tsx +0 -57
- package/src/components/PageRouter/Router.tsx +0 -23
- package/src/components/PageRouter/index.tsx +0 -81
- package/src/components/RadioInput/index.tsx +0 -72
- package/src/components/RadioInput/styles.ts +0 -57
- package/src/components/Select.tsx +0 -60
- package/src/components/Slider.tsx +0 -14
- package/src/components/Text.tsx +0 -27
- package/src/components/TextInput.tsx +0 -223
- package/src/components/Tooltip.tsx +0 -138
- package/src/components/Touchable.tsx +0 -47
- package/src/components/View.tsx +0 -54
- package/src/components/index.ts +0 -23
- package/src/index.ts +0 -4
- package/src/lib/hooks.ts +0 -59
- package/src/lib/logger.ts +0 -15
- package/src/lib/utils/cookies.ts +0 -19
- package/src/lib/utils/index.ts +0 -4
- package/src/lib/utils/pollyfils/scroll.ts +0 -59
- package/src/lib/utils/stopPropagation.ts +0 -17
- package/src/types/utility.ts +0 -4
- package/tsconfig.json +0 -42
package/src/components/Icon.tsx
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { ComponentVariants, IconPlaceholder, useComponentStyle, useStyle, IconStyles } from '@codeleap/common'
|
|
2
|
-
|
|
3
|
-
export type IconProps = {
|
|
4
|
-
name:IconPlaceholder
|
|
5
|
-
style?: {
|
|
6
|
-
color: string
|
|
7
|
-
size?:string|number
|
|
8
|
-
width?:string|number
|
|
9
|
-
height?:string|number
|
|
10
|
-
}
|
|
11
|
-
} & ComponentVariants<typeof IconStyles>
|
|
12
|
-
|
|
13
|
-
export const Icon:React.FC<IconProps> = ({name, style, responsiveVariants, variants}) => {
|
|
14
|
-
const {Theme, logger} = useStyle()
|
|
15
|
-
if (!name) return null
|
|
16
|
-
const Component = Theme?.icons?.[name]
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const variantStyles = useComponentStyle('Icon', {
|
|
21
|
-
variants,
|
|
22
|
-
responsiveVariants,
|
|
23
|
-
})
|
|
24
|
-
if (!Component) {
|
|
25
|
-
logger.warn('Icon', `No icon found in theme for name "${name}"`, 'Component')
|
|
26
|
-
return null
|
|
27
|
-
}
|
|
28
|
-
return <Component style={{...variantStyles.icon, ...style}}/>
|
|
29
|
-
}
|
package/src/components/Link.tsx
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/** @jsx jsx */
|
|
2
|
-
import { jsx } from '@emotion/react'
|
|
3
|
-
import { standardizeVariants, useStyle } from '@codeleap/common';
|
|
4
|
-
import { ElementType } from 'react';
|
|
5
|
-
import { TextProps } from './Text';
|
|
6
|
-
import { scrollToElem } from '../lib/utils/pollyfils/scroll';
|
|
7
|
-
import { stopPropagation } from '../lib/utils/stopPropagation';
|
|
8
|
-
import { Text } from './Text';
|
|
9
|
-
|
|
10
|
-
export type LinkProps<T extends ElementType> = TextProps<T> & {
|
|
11
|
-
openNewTab?:boolean
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const Link = <T extends ElementType = 'a'>(linkProps: LinkProps<T>) => {
|
|
15
|
-
const { variants, to, openNewTab, component = 'a', ...props } = linkProps
|
|
16
|
-
|
|
17
|
-
const isExternal = ['http', 'tel', 'mailto'].some(start => to.startsWith(start))
|
|
18
|
-
|
|
19
|
-
const Component = isExternal ? 'a' : component
|
|
20
|
-
const {logger} = useStyle()
|
|
21
|
-
function handleClick(event: React.MouseEvent){
|
|
22
|
-
logger.log('Link pressed', {to, text: linkProps.text }, 'Component')
|
|
23
|
-
if (to){
|
|
24
|
-
if (to.startsWith('#')){
|
|
25
|
-
event.preventDefault()
|
|
26
|
-
stopPropagation(event)
|
|
27
|
-
|
|
28
|
-
scrollToElem(to)
|
|
29
|
-
}
|
|
30
|
-
if (openNewTab){
|
|
31
|
-
window.open(to, '_blank')
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const passedVariants = standardizeVariants(variants || []) as TextProps<T>['variants']
|
|
37
|
-
|
|
38
|
-
const linkPropOverride = {
|
|
39
|
-
[isExternal ? 'href' : 'to']: to,
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return <Text
|
|
43
|
-
component={Component}
|
|
44
|
-
{...props}
|
|
45
|
-
{...linkPropOverride}
|
|
46
|
-
text={props.text}
|
|
47
|
-
|
|
48
|
-
variants={[...passedVariants]}
|
|
49
|
-
onClick={handleClick}
|
|
50
|
-
/>
|
|
51
|
-
}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/** @jsx jsx */
|
|
2
|
-
import { AnyFunction, ComponentVariants, IconPlaceholder, ModalComposition, ModalStyles, useComponentStyle } from '@codeleap/common';
|
|
3
|
-
import { jsx } from '@emotion/react';
|
|
4
|
-
import { ReactNode, useEffect, useLayoutEffect, useRef } from 'react';
|
|
5
|
-
import ReactDOM from 'react-dom';
|
|
6
|
-
import { v4 } from 'uuid';
|
|
7
|
-
import { StylesOf } from '../../types/utility';
|
|
8
|
-
import {Button} from '../Button'
|
|
9
|
-
import {View} from '../View'
|
|
10
|
-
import {Text} from '../Text'
|
|
11
|
-
import { Overlay } from '../Overlay';
|
|
12
|
-
|
|
13
|
-
export * from './styles'
|
|
14
|
-
|
|
15
|
-
export type ModalProps = {
|
|
16
|
-
|
|
17
|
-
open: boolean;
|
|
18
|
-
title?: React.ReactNode;
|
|
19
|
-
toggle: AnyFunction;
|
|
20
|
-
styles?: StylesOf<ModalComposition>
|
|
21
|
-
accessible?:boolean
|
|
22
|
-
showClose?: boolean
|
|
23
|
-
closable?: boolean
|
|
24
|
-
footer?: ReactNode
|
|
25
|
-
} & ComponentVariants<typeof ModalStyles>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
function focusModal(event: FocusEvent, id: string) {
|
|
30
|
-
event.preventDefault();
|
|
31
|
-
const modal = document.getElementById(id);
|
|
32
|
-
if (modal) {
|
|
33
|
-
modal.focus();
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export const ModalContent: React.FC<ModalProps & { id: string }> = (modalProps) => {
|
|
37
|
-
const {
|
|
38
|
-
children,
|
|
39
|
-
closable = true,
|
|
40
|
-
open,
|
|
41
|
-
title = '',
|
|
42
|
-
toggle,
|
|
43
|
-
id,
|
|
44
|
-
responsiveVariants,
|
|
45
|
-
variants,
|
|
46
|
-
styles,
|
|
47
|
-
showClose = true,
|
|
48
|
-
footer,
|
|
49
|
-
...props
|
|
50
|
-
} = modalProps
|
|
51
|
-
|
|
52
|
-
const variantStyles = useComponentStyle('Modal', {
|
|
53
|
-
responsiveVariants,
|
|
54
|
-
variants,
|
|
55
|
-
styles,
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
function closeOnEscPress(e: React.KeyboardEvent<HTMLDivElement>) {
|
|
59
|
-
if (e.key === 'Escape') {
|
|
60
|
-
toggle();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
useLayoutEffect(() => {
|
|
65
|
-
const modal = document.getElementById(id);
|
|
66
|
-
if (modal) {
|
|
67
|
-
modal.focus();
|
|
68
|
-
}
|
|
69
|
-
}, [id]);
|
|
70
|
-
|
|
71
|
-
return (
|
|
72
|
-
<View aria-hidden={!open} css={variantStyles.wrapper} className={open ? 'visible' : ''}>
|
|
73
|
-
<Overlay visible={open} onClick={closable ? toggle : () => {}} css={variantStyles.overlay} />
|
|
74
|
-
<View
|
|
75
|
-
component='section'
|
|
76
|
-
css={{
|
|
77
|
-
...variantStyles.box,
|
|
78
|
-
// visibility: open ? 'visible' : 'hidden',
|
|
79
|
-
}}
|
|
80
|
-
className='content'
|
|
81
|
-
onKeyDown={closeOnEscPress}
|
|
82
|
-
tabIndex={0}
|
|
83
|
-
id={id}
|
|
84
|
-
aria-modal={true}
|
|
85
|
-
role='dialog'
|
|
86
|
-
aria-describedby={`${id}-title`}
|
|
87
|
-
aria-label='Close the modal by presing Escape key'
|
|
88
|
-
{...props}
|
|
89
|
-
>
|
|
90
|
-
{
|
|
91
|
-
(title || showClose) &&
|
|
92
|
-
|
|
93
|
-
<View component='header' className='modal-header header' id={`${id}-title`} css={variantStyles.header}>
|
|
94
|
-
|
|
95
|
-
{typeof title === 'string' ? <Text text={title}/> : title}
|
|
96
|
-
|
|
97
|
-
{
|
|
98
|
-
(showClose && closable) &&
|
|
99
|
-
<Button rightIcon={'close' as IconPlaceholder} variants={['icon']} onPress={toggle}/>
|
|
100
|
-
}
|
|
101
|
-
</View>
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
<View css={variantStyles.body}>
|
|
105
|
-
{children}
|
|
106
|
-
</View>
|
|
107
|
-
{
|
|
108
|
-
footer && <View component='footer' css={variantStyles.footer}>
|
|
109
|
-
{footer}
|
|
110
|
-
</View>
|
|
111
|
-
}
|
|
112
|
-
</View>
|
|
113
|
-
</View>
|
|
114
|
-
);
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
export const Modal: React.FC<ModalProps> = ({accessible, ...props}) => {
|
|
118
|
-
const modalId = useRef(v4());
|
|
119
|
-
|
|
120
|
-
useEffect(() => {
|
|
121
|
-
if (accessible){
|
|
122
|
-
|
|
123
|
-
const currentId = modalId.current;
|
|
124
|
-
const appRoot = document.body;
|
|
125
|
-
appRoot.addEventListener('focusin', (e) => focusModal(e, currentId));
|
|
126
|
-
return () => appRoot.removeEventListener('focusin', (e) => focusModal(e, currentId));
|
|
127
|
-
}
|
|
128
|
-
}, []);
|
|
129
|
-
|
|
130
|
-
useEffect(() => {
|
|
131
|
-
if (accessible){
|
|
132
|
-
|
|
133
|
-
const appRoot = document.body;
|
|
134
|
-
appRoot.setAttribute('aria-hidden', `${props.open}`);
|
|
135
|
-
appRoot.setAttribute('tabindex', `${-1}`);
|
|
136
|
-
}
|
|
137
|
-
}, [props.open]);
|
|
138
|
-
|
|
139
|
-
if (accessible){
|
|
140
|
-
if (props.open) {
|
|
141
|
-
document.body.style.overflow = 'hidden';
|
|
142
|
-
return ReactDOM.createPortal(<ModalContent {...props} id={modalId.current} />, document.body);
|
|
143
|
-
} else {
|
|
144
|
-
document.body.style.overflow = 'visible';
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return <ModalContent {...props} id={modalId.current} />
|
|
150
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { createDefaultVariantFactory, ModalComposition, ModalStyles } from '@codeleap/common'
|
|
2
|
-
|
|
3
|
-
const createModalStyle = createDefaultVariantFactory<ModalComposition>()
|
|
4
|
-
|
|
5
|
-
const transitionDuration = '0.3s'
|
|
6
|
-
|
|
7
|
-
export const WebModalStyles = {
|
|
8
|
-
...ModalStyles,
|
|
9
|
-
default: createModalStyle((theme) => {
|
|
10
|
-
const defaultStyles = ModalStyles.default(theme)
|
|
11
|
-
|
|
12
|
-
return {
|
|
13
|
-
...defaultStyles,
|
|
14
|
-
wrapper: {
|
|
15
|
-
...defaultStyles.wrapper,
|
|
16
|
-
transition: `visibility 0.01s ease`,
|
|
17
|
-
transitionDelay: transitionDuration,
|
|
18
|
-
'& .content': {
|
|
19
|
-
transform: 'scale(0)',
|
|
20
|
-
transition: `transform ${transitionDuration} ease`,
|
|
21
|
-
},
|
|
22
|
-
'&.visible': {
|
|
23
|
-
visibility: 'visible',
|
|
24
|
-
transitionDelay: '0s',
|
|
25
|
-
},
|
|
26
|
-
'&.visible .content': {
|
|
27
|
-
visibility: 'visible',
|
|
28
|
-
transform: 'scale(1)',
|
|
29
|
-
},
|
|
30
|
-
'&.visible .overlay': {
|
|
31
|
-
opacity: 0.5,
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
box: {
|
|
35
|
-
...defaultStyles.box,
|
|
36
|
-
width: '45vw',
|
|
37
|
-
|
|
38
|
-
},
|
|
39
|
-
overlay: {
|
|
40
|
-
...defaultStyles.overlay,
|
|
41
|
-
|
|
42
|
-
transition: `opacity ${transitionDuration} ease`,
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
}),
|
|
48
|
-
}
|
|
49
|
-
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { ComponentVariants, OverlayComposition, OverlayStyles, SmartOmit, StylesOf, useComponentStyle } from '@codeleap/common'
|
|
2
|
-
import { Touchable, TouchableProps } from './Touchable'
|
|
3
|
-
import { View, ViewProps } from './View'
|
|
4
|
-
|
|
5
|
-
export type OverlayProps = {
|
|
6
|
-
visible?:boolean
|
|
7
|
-
styles?: StylesOf<OverlayComposition>
|
|
8
|
-
onPress?: TouchableProps<'div'>['onClick']
|
|
9
|
-
} & ComponentVariants<typeof OverlayStyles> & Partial<SmartOmit<ViewProps<'div'>, 'variants' | 'responsiveVariants'>>
|
|
10
|
-
|
|
11
|
-
export const Overlay:React.FC<OverlayProps> = (overlayProps) => {
|
|
12
|
-
const {visible, responsiveVariants, variants, styles, ...props} = overlayProps
|
|
13
|
-
|
|
14
|
-
const variantStyles = useComponentStyle('Overlay', {
|
|
15
|
-
variants, responsiveVariants, styles,
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
const Component = props.onClick||props.onPress ? Touchable : View
|
|
19
|
-
|
|
20
|
-
return <Component css={{
|
|
21
|
-
...variantStyles.wrapper,
|
|
22
|
-
transition: 'opacity 0.2s ease',
|
|
23
|
-
...(visible ? variantStyles['wrapper:visible'] : {}),
|
|
24
|
-
}} {...props}/>
|
|
25
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { View } from '../View';
|
|
2
|
-
import { CenterWrapper } from '../CenterWrapper';
|
|
3
|
-
import {HorizontalScroll} from '../HorizontalScroll';
|
|
4
|
-
import { MenuItem, MenuItemProps } from './MenuItem';
|
|
5
|
-
import { useStyle, MenuComposition } from '@codeleap/common';
|
|
6
|
-
import { StylesOf } from '../../types/utility';
|
|
7
|
-
|
|
8
|
-
const TabsWrapper = ({children, styles}) => {
|
|
9
|
-
const {Theme} = useStyle()
|
|
10
|
-
const isMobile = Theme.hooks.down('small')
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const wrapperStyle = isMobile ? styles.topMenu : styles.sideMenu
|
|
15
|
-
|
|
16
|
-
if (isMobile){
|
|
17
|
-
return <View css={[wrapperStyle]}>
|
|
18
|
-
<CenterWrapper>
|
|
19
|
-
<View css={styles.mobileMenu}>
|
|
20
|
-
<HorizontalScroll css={styles.horizontalScroll}>
|
|
21
|
-
{children}
|
|
22
|
-
</HorizontalScroll>
|
|
23
|
-
</View>
|
|
24
|
-
</CenterWrapper>
|
|
25
|
-
</View>
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return <View css={[wrapperStyle]}>
|
|
29
|
-
{children}
|
|
30
|
-
</View>
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
type RouterMenuProps = {
|
|
34
|
-
items: MenuItemProps['data'][]
|
|
35
|
-
styles?: StylesOf<MenuComposition>
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
export const Menu:React.FC<RouterMenuProps> = ({items, styles}) => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return <TabsWrapper styles={styles}>
|
|
43
|
-
{
|
|
44
|
-
items.map(data => <MenuItem data={data} key={data.path} styles={styles}/>)
|
|
45
|
-
}
|
|
46
|
-
</TabsWrapper>
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { Text } from '../Text'
|
|
3
|
-
import { Icon } from '../Icon'
|
|
4
|
-
import { Link } from '../Link'
|
|
5
|
-
import { IconPlaceholder, MenuComposition, StylesOf, useStyle } from '@codeleap/common';
|
|
6
|
-
import { url } from '../../lib/utils';
|
|
7
|
-
import {Link as IntlLink} from 'gatsby-plugin-intl'
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const RouterLink:React.FC<any> = (props) => <Link component={IntlLink} {...props}/>
|
|
11
|
-
|
|
12
|
-
export type MenuItemProps = {
|
|
13
|
-
data: {
|
|
14
|
-
icon: IconPlaceholder
|
|
15
|
-
title:string
|
|
16
|
-
path:string
|
|
17
|
-
}
|
|
18
|
-
styles: StylesOf<MenuComposition>
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const MenuItem:React.FC<MenuItemProps> = (props) => {
|
|
22
|
-
const { styles} = props
|
|
23
|
-
const { title, path, icon } = props.data;
|
|
24
|
-
|
|
25
|
-
const { pathname } = url();
|
|
26
|
-
|
|
27
|
-
const selected = pathname.includes(path);
|
|
28
|
-
const { Theme } = useStyle()
|
|
29
|
-
const isMobile = Theme.hooks.down('small')
|
|
30
|
-
|
|
31
|
-
if (isMobile){
|
|
32
|
-
return <RouterLink to={path} css={[styles['menuItem:mobile']]}>
|
|
33
|
-
<Text
|
|
34
|
-
variant={'p3'}
|
|
35
|
-
css={[
|
|
36
|
-
styles['menuItem:text:mobile'],
|
|
37
|
-
selected && styles['menuItem:text:selected'],
|
|
38
|
-
]}
|
|
39
|
-
msg={title}
|
|
40
|
-
/>
|
|
41
|
-
<Icon name={icon} />
|
|
42
|
-
</RouterLink>
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return (<RouterLink to={path}>
|
|
46
|
-
<Icon name={icon} />
|
|
47
|
-
<Text
|
|
48
|
-
variant={'p3'}
|
|
49
|
-
css={[
|
|
50
|
-
styles['menuItem:text'],
|
|
51
|
-
selected && styles['menuItem:text:selected'],
|
|
52
|
-
]}
|
|
53
|
-
msg={title}
|
|
54
|
-
/>
|
|
55
|
-
</RouterLink>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Router as ReachRouter } from '@reach/router';
|
|
3
|
-
|
|
4
|
-
type RouterProps = {
|
|
5
|
-
basePath:string
|
|
6
|
-
style?:any
|
|
7
|
-
defaultPath?:string
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export const Router: React.FC<RouterProps> = (props) => {
|
|
11
|
-
const { children, style, basePath, defaultPath } = props;
|
|
12
|
-
const base = `/:language${basePath}`;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<React.Fragment>
|
|
17
|
-
|
|
18
|
-
<ReachRouter basepath={base}>
|
|
19
|
-
{children}
|
|
20
|
-
</ReachRouter>
|
|
21
|
-
</React.Fragment>
|
|
22
|
-
);
|
|
23
|
-
};
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { View } from '../View'
|
|
2
|
-
import React, { useMemo } from 'react'
|
|
3
|
-
|
|
4
|
-
import { Menu } from './Menu'
|
|
5
|
-
import { Router } from './Router'
|
|
6
|
-
import { ComponentVariants, IconPlaceholder, PageRouterComposition, PageRouterStyles, useComponentStyle } from '@codeleap/common'
|
|
7
|
-
import { StylesOf } from '../../types/utility'
|
|
8
|
-
import { Helmet } from 'react-helmet'
|
|
9
|
-
import { url } from '../../lib/utils'
|
|
10
|
-
|
|
11
|
-
export type RouteProps = {
|
|
12
|
-
title?: string
|
|
13
|
-
path?: string
|
|
14
|
-
menuIcon?: IconPlaceholder
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export * from './Router'
|
|
19
|
-
|
|
20
|
-
type RouterPageProps = {
|
|
21
|
-
basePath:string
|
|
22
|
-
styles?: StylesOf<PageRouterComposition>
|
|
23
|
-
title?: string
|
|
24
|
-
} & ComponentVariants<typeof PageRouterStyles>
|
|
25
|
-
|
|
26
|
-
export const RouterPage:React.FC<RouterPageProps> = (props) => {
|
|
27
|
-
const {children, basePath, variants, title: pageGroupTitle, responsiveVariants, styles} = props
|
|
28
|
-
const pathName = url().pathname
|
|
29
|
-
|
|
30
|
-
const {menuItems, defaultPath} = useMemo(() => {
|
|
31
|
-
const items = []
|
|
32
|
-
|
|
33
|
-
let defaultPath = ''
|
|
34
|
-
|
|
35
|
-
React.Children.forEach(children, (c) => {
|
|
36
|
-
if (React.isValidElement(c) && c.props){
|
|
37
|
-
const {title, path, menuIcon} = c.props
|
|
38
|
-
if ([title, path, menuIcon].some((i) => !i)){
|
|
39
|
-
return
|
|
40
|
-
}
|
|
41
|
-
if (c.props.default) defaultPath = path
|
|
42
|
-
items.push({
|
|
43
|
-
...c.props,
|
|
44
|
-
title,
|
|
45
|
-
path: `${basePath}${path}`,
|
|
46
|
-
icon: menuIcon,
|
|
47
|
-
})
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
menuItems: items,
|
|
53
|
-
defaultPath,
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
}, [children])
|
|
57
|
-
|
|
58
|
-
const variantStyles = useComponentStyle('PageRouter', {variants, responsiveVariants, styles})
|
|
59
|
-
|
|
60
|
-
const currentPage = menuItems.find(({path}) => pathName.includes(path))
|
|
61
|
-
return <>
|
|
62
|
-
<Helmet>
|
|
63
|
-
<title>
|
|
64
|
-
{(pageGroupTitle ? `${pageGroupTitle} | ` : '') + (currentPage ? currentPage?.title : '') }
|
|
65
|
-
</title>
|
|
66
|
-
</Helmet>
|
|
67
|
-
<Menu
|
|
68
|
-
items={menuItems}
|
|
69
|
-
styles={variantStyles}
|
|
70
|
-
/>
|
|
71
|
-
<View css={variantStyles.content}>
|
|
72
|
-
<Router
|
|
73
|
-
defaultPath={defaultPath}
|
|
74
|
-
basePath={basePath}
|
|
75
|
-
>
|
|
76
|
-
{children}
|
|
77
|
-
</Router>
|
|
78
|
-
</View>
|
|
79
|
-
</>
|
|
80
|
-
|
|
81
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { ReactNode, useRef, ComponentPropsWithoutRef } from 'react'
|
|
2
|
-
import {v4} from 'uuid'
|
|
3
|
-
|
|
4
|
-
import {Text } from '../Text'
|
|
5
|
-
import { Touchable } from '../Touchable'
|
|
6
|
-
import { ComponentVariants, RadioInputComposition, RadioInputStyles, StylesOf, useComponentStyle } from '@codeleap/common'
|
|
7
|
-
import { View } from '../View'
|
|
8
|
-
export { WebRadioInputStyles } from './styles'
|
|
9
|
-
|
|
10
|
-
type RadioItem<T extends unknown = any> = {
|
|
11
|
-
value: T,
|
|
12
|
-
label: ReactNode
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const getRadioStyle = (props) => useComponentStyle('RadioInput', props)
|
|
16
|
-
|
|
17
|
-
export type RadioButtonProps = Omit<ComponentPropsWithoutRef<'input'>, 'style'> & {
|
|
18
|
-
item: RadioItem
|
|
19
|
-
select: () => void
|
|
20
|
-
style: StylesOf<RadioInputComposition>
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type RadioGroupProps<T> = {
|
|
24
|
-
options: RadioItem<T>[]
|
|
25
|
-
value: T
|
|
26
|
-
onValueChange(value:T):void
|
|
27
|
-
label:ReactNode
|
|
28
|
-
styles?: StylesOf<RadioInputComposition>
|
|
29
|
-
} & ComponentVariants<typeof RadioInputStyles>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
export const RadioButton:React.FC<RadioButtonProps> = ({item, select, style, checked, ...props}) => {
|
|
33
|
-
const styleByState = checked ? style['button:checked'] : style['button:unchecked']
|
|
34
|
-
return <Touchable onPress={select} css={style.itemWrapper} >
|
|
35
|
-
<View css={{
|
|
36
|
-
...style.button,
|
|
37
|
-
...styleByState,
|
|
38
|
-
'&:after': {
|
|
39
|
-
...style['button:mark'],
|
|
40
|
-
...styleByState?.['&:after'],
|
|
41
|
-
},
|
|
42
|
-
}}/>
|
|
43
|
-
{typeof item.label === 'string' ? <Text text={item.label} css={style.itemText}/> : item.label }
|
|
44
|
-
</Touchable>
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
export const RadioGroup = <T extends unknown>(radioGroupProps:RadioGroupProps<T>) => {
|
|
49
|
-
const {options, value, onValueChange, label, responsiveVariants, variants, styles} = radioGroupProps
|
|
50
|
-
const radioName = useRef(v4()).current
|
|
51
|
-
|
|
52
|
-
const radioStyle = getRadioStyle({
|
|
53
|
-
responsiveVariants,
|
|
54
|
-
variants,
|
|
55
|
-
styles,
|
|
56
|
-
})
|
|
57
|
-
return <View css={radioStyle.wrapper}>
|
|
58
|
-
{typeof label === 'string' ? <Text text={label}/> : label }
|
|
59
|
-
<View css={radioStyle.listWrapper}>
|
|
60
|
-
{
|
|
61
|
-
options?.map((item, idx) => <RadioButton
|
|
62
|
-
item={item}
|
|
63
|
-
key={idx}
|
|
64
|
-
style={radioStyle}
|
|
65
|
-
name={radioName}
|
|
66
|
-
checked={value === item.value}
|
|
67
|
-
select={() => onValueChange(item.value)}
|
|
68
|
-
/>)
|
|
69
|
-
}
|
|
70
|
-
</View>
|
|
71
|
-
</View>
|
|
72
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { createDefaultVariantFactory, RadioInputComposition, RadioInputStyles } from '@codeleap/common';
|
|
2
|
-
|
|
3
|
-
const createRadioStyle = createDefaultVariantFactory<RadioInputComposition>()
|
|
4
|
-
|
|
5
|
-
const defaultStyles = RadioInputStyles.default
|
|
6
|
-
|
|
7
|
-
export const WebRadioInputStyles = {
|
|
8
|
-
...RadioInputStyles,
|
|
9
|
-
default: createRadioStyle((theme) => {
|
|
10
|
-
const style = defaultStyles(theme)
|
|
11
|
-
return {
|
|
12
|
-
...style,
|
|
13
|
-
itemWrapper: {
|
|
14
|
-
...style.itemWrapper,
|
|
15
|
-
cursor: 'pointer',
|
|
16
|
-
},
|
|
17
|
-
button: {
|
|
18
|
-
height: '1em',
|
|
19
|
-
width: '1em',
|
|
20
|
-
borderRadius: theme.borderRadius.large,
|
|
21
|
-
border: theme.border.primary(1),
|
|
22
|
-
|
|
23
|
-
position: 'relative',
|
|
24
|
-
...theme.spacing.marginRight(1),
|
|
25
|
-
|
|
26
|
-
},
|
|
27
|
-
'button:mark': {
|
|
28
|
-
background: theme.colors.primary,
|
|
29
|
-
content: '""',
|
|
30
|
-
position: 'absolute',
|
|
31
|
-
left: '50%',
|
|
32
|
-
top: '50%',
|
|
33
|
-
|
|
34
|
-
transform: 'translate(-50%,-50%)',
|
|
35
|
-
borderRadius: theme.borderRadius.large,
|
|
36
|
-
height: '50%',
|
|
37
|
-
width: '50%',
|
|
38
|
-
visibility: 'hidden',
|
|
39
|
-
},
|
|
40
|
-
'button:checked': {
|
|
41
|
-
'&:after': {
|
|
42
|
-
visibility: 'visible',
|
|
43
|
-
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
}
|
|
47
|
-
}),
|
|
48
|
-
square: createRadioStyle(() => ({
|
|
49
|
-
'button:mark': {
|
|
50
|
-
borderRadius: '1px',
|
|
51
|
-
},
|
|
52
|
-
button: {
|
|
53
|
-
borderRadius: '1px',
|
|
54
|
-
|
|
55
|
-
},
|
|
56
|
-
})),
|
|
57
|
-
}
|