New component library based on ALF (#2459)
* Install on native as well * Add button and link components * Comments * Use new prop * Add some form elements * Add labels to input * Fix line height, add suffix * Date inputs * Autofill styles * Clean up InputDate types * Improve types for InputText, value handling * Enforce a11y props on buttons * Add Dialog, Portal * Dialog contents * Native dialog * Clean up * Fix animations * Improvements to web modal, exiting still broken * Clean up dialog types * Add Prompt, Dialog refinement, mobile refinement * Integrate new design tokens, reorg storybook * Button colors * Dim mode * Reorg * Some styles * Toggles * Improve a11y * Autosize dialog, handle max height, Dialog.ScrolLView not working * Try to use BottomSheet's own APIs * Scrollable dialogs * Add web shadow * Handle overscroll * Styles * Dialog text input * Shadows * Button focus states * Button pressed states * Gradient poc * Gradient colors and hovers * Add hrefAttrs to Link * Some more a11y * Toggle invalid states * Update dialog descriptions for demo * Icons * WIP Toggle cleanup * Refactor toggle to not rely on immediate children * Make Toggle controlled * Clean up Toggles storybook * ToggleButton styles * Improve a11y labels * ToggleButton hover darkmode * Some i18n * Refactor input * Allow extension of input * Remove old input * Improve icons, add CalendarDays * Refactor DateField, web done * Add label example * Clean up old InputDate, DateField android, text area example * Consistent imports * Button context, icons * Add todo * Add closeAllDialogs control * Alignment * Expand color palette * Hitslops, add shortcut to Storybook in dev * Fix multiline on ios * Mark dialog close button as unused
This commit is contained in:
parent
9cbd3c0937
commit
66b8774ecb
60 changed files with 4683 additions and 968 deletions
|
@ -1,541 +0,0 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {CenteredView, ScrollView} from '#/view/com/util/Views'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
|
||||
import {useSetColorMode} from '#/state/shell'
|
||||
import * as tokens from '#/alf/tokens'
|
||||
import {atoms as a, useTheme, useBreakpoints, ThemeProvider as Alf} from '#/alf'
|
||||
import {Button, ButtonText} from '#/view/com/Button'
|
||||
import {Text, H1, H2, H3, H4, H5, H6} from '#/view/com/Typography'
|
||||
|
||||
function ThemeSelector() {
|
||||
const setColorMode = useSetColorMode()
|
||||
|
||||
return (
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<Button
|
||||
type="secondary"
|
||||
size="small"
|
||||
onPress={() => setColorMode('system')}>
|
||||
System
|
||||
</Button>
|
||||
<Button
|
||||
type="secondary"
|
||||
size="small"
|
||||
onPress={() => setColorMode('light')}>
|
||||
Light
|
||||
</Button>
|
||||
<Button
|
||||
type="secondary"
|
||||
size="small"
|
||||
onPress={() => setColorMode('dark')}>
|
||||
Dark
|
||||
</Button>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
function BreakpointDebugger() {
|
||||
const t = useTheme()
|
||||
const breakpoints = useBreakpoints()
|
||||
|
||||
return (
|
||||
<View>
|
||||
<H3 style={[a.pb_md]}>Breakpoint Debugger</H3>
|
||||
<Text style={[a.pb_md]}>
|
||||
Current breakpoint: {!breakpoints.gtMobile && <Text>mobile</Text>}
|
||||
{breakpoints.gtMobile && !breakpoints.gtTablet && <Text>tablet</Text>}
|
||||
{breakpoints.gtTablet && <Text>desktop</Text>}
|
||||
</Text>
|
||||
<Text
|
||||
style={[a.p_md, t.atoms.bg_contrast_100, {fontFamily: 'monospace'}]}>
|
||||
{JSON.stringify(breakpoints, null, 2)}
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
function ThemedSection() {
|
||||
const t = useTheme()
|
||||
|
||||
return (
|
||||
<View style={[t.atoms.bg, a.gap_md, a.p_xl]}>
|
||||
<H3 style={[a.font_bold]}>theme.atoms.text</H3>
|
||||
<View style={[a.flex_1, t.atoms.border, a.border_t]} />
|
||||
<H3 style={[a.font_bold, t.atoms.text_contrast_700]}>
|
||||
theme.atoms.text_contrast_700
|
||||
</H3>
|
||||
<View style={[a.flex_1, t.atoms.border, a.border_t]} />
|
||||
<H3 style={[a.font_bold, t.atoms.text_contrast_500]}>
|
||||
theme.atoms.text_contrast_500
|
||||
</H3>
|
||||
<View style={[a.flex_1, t.atoms.border_contrast_500, a.border_t]} />
|
||||
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
t.atoms.bg,
|
||||
a.align_center,
|
||||
a.justify_center,
|
||||
{height: 60},
|
||||
]}>
|
||||
<Text>theme.bg</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
t.atoms.bg_contrast_100,
|
||||
a.align_center,
|
||||
a.justify_center,
|
||||
{height: 60},
|
||||
]}>
|
||||
<Text>theme.bg_contrast_100</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
t.atoms.bg_contrast_200,
|
||||
a.align_center,
|
||||
a.justify_center,
|
||||
{height: 60},
|
||||
]}>
|
||||
<Text>theme.bg_contrast_200</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
t.atoms.bg_contrast_300,
|
||||
a.align_center,
|
||||
a.justify_center,
|
||||
{height: 60},
|
||||
]}>
|
||||
<Text>theme.bg_contrast_300</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
t.atoms.bg_positive,
|
||||
a.align_center,
|
||||
a.justify_center,
|
||||
{height: 60},
|
||||
]}>
|
||||
<Text>theme.bg_positive</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
t.atoms.bg_negative,
|
||||
a.align_center,
|
||||
a.justify_center,
|
||||
{height: 60},
|
||||
]}>
|
||||
<Text>theme.bg_negative</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
export function DebugScreen() {
|
||||
const t = useTheme()
|
||||
|
||||
return (
|
||||
<ScrollView>
|
||||
<CenteredView style={[t.atoms.bg]}>
|
||||
<View style={[a.p_xl, a.gap_xxl, {paddingBottom: 200}]}>
|
||||
<ThemeSelector />
|
||||
|
||||
<Alf theme="light">
|
||||
<ThemedSection />
|
||||
</Alf>
|
||||
<Alf theme="dark">
|
||||
<ThemedSection />
|
||||
</Alf>
|
||||
|
||||
<H1>Heading 1</H1>
|
||||
<H2>Heading 2</H2>
|
||||
<H3>Heading 3</H3>
|
||||
<H4>Heading 4</H4>
|
||||
<H5>Heading 5</H5>
|
||||
<H6>Heading 6</H6>
|
||||
|
||||
<Text style={[a.text_xxl]}>atoms.text_xxl</Text>
|
||||
<Text style={[a.text_xl]}>atoms.text_xl</Text>
|
||||
<Text style={[a.text_lg]}>atoms.text_lg</Text>
|
||||
<Text style={[a.text_md]}>atoms.text_md</Text>
|
||||
<Text style={[a.text_sm]}>atoms.text_sm</Text>
|
||||
<Text style={[a.text_xs]}>atoms.text_xs</Text>
|
||||
<Text style={[a.text_xxs]}>atoms.text_xxs</Text>
|
||||
|
||||
<View style={[a.gap_md, a.align_start]}>
|
||||
<Button>
|
||||
{({state}) => (
|
||||
<View style={[a.p_md, a.rounded_full, t.atoms.bg_contrast_300]}>
|
||||
<Text>Unstyled button, state: {JSON.stringify(state)}</Text>
|
||||
</View>
|
||||
)}
|
||||
</Button>
|
||||
|
||||
<Button type="primary" size="small">
|
||||
Button
|
||||
</Button>
|
||||
<Button type="secondary" size="small">
|
||||
Button
|
||||
</Button>
|
||||
|
||||
<Button type="primary" size="large">
|
||||
Button
|
||||
</Button>
|
||||
<Button type="secondary" size="large">
|
||||
Button
|
||||
</Button>
|
||||
|
||||
<Button type="secondary" size="small">
|
||||
{({type, size}) => (
|
||||
<>
|
||||
<FontAwesomeIcon icon={['fas', 'plus']} size={12} />
|
||||
<ButtonText type={type} size={size}>
|
||||
With an icon
|
||||
</ButtonText>
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
<Button type="primary" size="large">
|
||||
{({state: _state, ...rest}) => (
|
||||
<>
|
||||
<FontAwesomeIcon icon={['fas', 'plus']} />
|
||||
<ButtonText {...rest}>With an icon</ButtonText>
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
<View style={[a.gap_md]}>
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_0},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_100},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_200},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_300},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_400},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_500},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_600},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_700},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_800},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_900},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_1000},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_0},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_100},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_200},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_300},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_400},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_500},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_600},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_700},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_800},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_900},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_1000},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_0},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_100},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_200},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_300},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_400},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_500},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_600},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_700},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_800},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_900},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_1000},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_0},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_100},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_200},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_300},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_400},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_500},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_600},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_700},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_800},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_900},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_1000},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View>
|
||||
<H3 style={[a.pb_md, a.font_bold]}>Spacing</H3>
|
||||
|
||||
<View style={[a.gap_md]}>
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>xxs (2px)</Text>
|
||||
<View style={[a.flex_1, a.pt_xxs, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>xs (4px)</Text>
|
||||
<View style={[a.flex_1, a.pt_xs, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>sm (8px)</Text>
|
||||
<View style={[a.flex_1, a.pt_sm, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>md (12px)</Text>
|
||||
<View style={[a.flex_1, a.pt_md, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>lg (18px)</Text>
|
||||
<View style={[a.flex_1, a.pt_lg, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>xl (24px)</Text>
|
||||
<View style={[a.flex_1, a.pt_xl, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>xxl (32px)</Text>
|
||||
<View style={[a.flex_1, a.pt_xxl, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<BreakpointDebugger />
|
||||
</View>
|
||||
</CenteredView>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
25
src/view/screens/Storybook/Breakpoints.tsx
Normal file
25
src/view/screens/Storybook/Breakpoints.tsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {atoms as a, useTheme, useBreakpoints} from '#/alf'
|
||||
import {Text, H3} from '#/components/Typography'
|
||||
|
||||
export function Breakpoints() {
|
||||
const t = useTheme()
|
||||
const breakpoints = useBreakpoints()
|
||||
|
||||
return (
|
||||
<View>
|
||||
<H3 style={[a.pb_md]}>Breakpoint Debugger</H3>
|
||||
<Text style={[a.pb_md]}>
|
||||
Current breakpoint: {!breakpoints.gtMobile && <Text>mobile</Text>}
|
||||
{breakpoints.gtMobile && !breakpoints.gtTablet && <Text>tablet</Text>}
|
||||
{breakpoints.gtTablet && <Text>desktop</Text>}
|
||||
</Text>
|
||||
<Text
|
||||
style={[a.p_md, t.atoms.bg_contrast_100, {fontFamily: 'monospace'}]}>
|
||||
{JSON.stringify(breakpoints, null, 2)}
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
124
src/view/screens/Storybook/Buttons.tsx
Normal file
124
src/view/screens/Storybook/Buttons.tsx
Normal file
|
@ -0,0 +1,124 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {atoms as a} from '#/alf'
|
||||
import {
|
||||
Button,
|
||||
ButtonVariant,
|
||||
ButtonColor,
|
||||
ButtonIcon,
|
||||
ButtonText,
|
||||
} from '#/components/Button'
|
||||
import {H1} from '#/components/Typography'
|
||||
import {ArrowTopRight_Stroke2_Corner0_Rounded as ArrowTopRight} from '#/components/icons/ArrowTopRight'
|
||||
import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
|
||||
|
||||
export function Buttons() {
|
||||
return (
|
||||
<View style={[a.gap_md]}>
|
||||
<H1>Buttons</H1>
|
||||
|
||||
<View style={[a.flex_row, a.flex_wrap, a.gap_md, a.align_start]}>
|
||||
{['primary', 'secondary', 'negative'].map(color => (
|
||||
<View key={color} style={[a.gap_md, a.align_start]}>
|
||||
{['solid', 'outline', 'ghost'].map(variant => (
|
||||
<React.Fragment key={variant}>
|
||||
<Button
|
||||
variant={variant as ButtonVariant}
|
||||
color={color as ButtonColor}
|
||||
size="large"
|
||||
label="Click here">
|
||||
Button
|
||||
</Button>
|
||||
<Button
|
||||
disabled
|
||||
variant={variant as ButtonVariant}
|
||||
color={color as ButtonColor}
|
||||
size="large"
|
||||
label="Click here">
|
||||
Button
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</View>
|
||||
))}
|
||||
|
||||
<View style={[a.flex_row, a.gap_md, a.align_start]}>
|
||||
<View style={[a.gap_md, a.align_start]}>
|
||||
{['gradient_sky', 'gradient_midnight', 'gradient_sunrise'].map(
|
||||
name => (
|
||||
<React.Fragment key={name}>
|
||||
<Button
|
||||
variant="gradient"
|
||||
color={name as ButtonColor}
|
||||
size="large"
|
||||
label="Click here">
|
||||
Button
|
||||
</Button>
|
||||
<Button
|
||||
disabled
|
||||
variant="gradient"
|
||||
color={name as ButtonColor}
|
||||
size="large"
|
||||
label="Click here">
|
||||
Button
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
),
|
||||
)}
|
||||
</View>
|
||||
<View style={[a.gap_md, a.align_start]}>
|
||||
{['gradient_sunset', 'gradient_nordic', 'gradient_bonfire'].map(
|
||||
name => (
|
||||
<React.Fragment key={name}>
|
||||
<Button
|
||||
variant="gradient"
|
||||
color={name as ButtonColor}
|
||||
size="large"
|
||||
label="Click here">
|
||||
Button
|
||||
</Button>
|
||||
<Button
|
||||
disabled
|
||||
variant="gradient"
|
||||
color={name as ButtonColor}
|
||||
size="large"
|
||||
label="Click here">
|
||||
Button
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
),
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<Button
|
||||
variant="gradient"
|
||||
color="gradient_sky"
|
||||
size="large"
|
||||
label="Link out">
|
||||
<ButtonText>Link out</ButtonText>
|
||||
<ButtonIcon icon={ArrowTopRight} />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="gradient"
|
||||
color="gradient_sky"
|
||||
size="small"
|
||||
label="Link out">
|
||||
<ButtonText>Link out</ButtonText>
|
||||
<ButtonIcon icon={ArrowTopRight} />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="gradient"
|
||||
color="gradient_sky"
|
||||
size="small"
|
||||
label="Link out">
|
||||
<ButtonIcon icon={Globe} />
|
||||
<ButtonText>See the world</ButtonText>
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
90
src/view/screens/Storybook/Dialogs.tsx
Normal file
90
src/view/screens/Storybook/Dialogs.tsx
Normal file
|
@ -0,0 +1,90 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {atoms as a} from '#/alf'
|
||||
import {Button} from '#/components/Button'
|
||||
import {H3, P} from '#/components/Typography'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import {useDialogStateControlContext} from '#/state/dialogs'
|
||||
|
||||
export function Dialogs() {
|
||||
const control = Dialog.useDialogControl()
|
||||
const prompt = Prompt.usePromptControl()
|
||||
const {closeAllDialogs} = useDialogStateControlContext()
|
||||
|
||||
return (
|
||||
<View style={[a.gap_md]}>
|
||||
<Button
|
||||
variant="outline"
|
||||
color="secondary"
|
||||
size="small"
|
||||
onPress={() => {
|
||||
control.open()
|
||||
prompt.open()
|
||||
}}
|
||||
label="Open basic dialog">
|
||||
Open basic dialog
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="solid"
|
||||
color="primary"
|
||||
size="small"
|
||||
onPress={() => prompt.open()}
|
||||
label="Open prompt">
|
||||
Open prompt
|
||||
</Button>
|
||||
|
||||
<Prompt.Outer control={prompt}>
|
||||
<Prompt.Title>This is a prompt</Prompt.Title>
|
||||
<Prompt.Description>
|
||||
This is a generic prompt component. It accepts a title and a
|
||||
description, as well as two actions.
|
||||
</Prompt.Description>
|
||||
<Prompt.Actions>
|
||||
<Prompt.Cancel>Cancel</Prompt.Cancel>
|
||||
<Prompt.Action>Confirm</Prompt.Action>
|
||||
</Prompt.Actions>
|
||||
</Prompt.Outer>
|
||||
|
||||
<Dialog.Outer
|
||||
control={control}
|
||||
nativeOptions={{sheet: {snapPoints: ['90%']}}}>
|
||||
<Dialog.Handle />
|
||||
|
||||
<Dialog.ScrollableInner
|
||||
accessibilityDescribedBy="dialog-description"
|
||||
accessibilityLabelledBy="dialog-title">
|
||||
<View style={[a.relative, a.gap_md, a.w_full]}>
|
||||
<H3 nativeID="dialog-title">Dialog</H3>
|
||||
<P nativeID="dialog-description">
|
||||
A scrollable dialog with an input within it.
|
||||
</P>
|
||||
<Dialog.Input value="" onChangeText={() => {}} label="Type here" />
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
color="secondary"
|
||||
size="small"
|
||||
onPress={closeAllDialogs}
|
||||
label="Close all dialogs">
|
||||
Close all dialogs
|
||||
</Button>
|
||||
<View style={{height: 1000}} />
|
||||
<View style={[a.flex_row, a.justify_end]}>
|
||||
<Button
|
||||
variant="outline"
|
||||
color="primary"
|
||||
size="small"
|
||||
onPress={() => control.close()}
|
||||
label="Open basic dialog">
|
||||
Close basic dialog
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
</Dialog.ScrollableInner>
|
||||
</Dialog.Outer>
|
||||
</View>
|
||||
)
|
||||
}
|
215
src/view/screens/Storybook/Forms.tsx
Normal file
215
src/view/screens/Storybook/Forms.tsx
Normal file
|
@ -0,0 +1,215 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {atoms as a} from '#/alf'
|
||||
import {H1, H3} from '#/components/Typography'
|
||||
import * as TextField from '#/components/forms/TextField'
|
||||
import {DateField, Label} from '#/components/forms/DateField'
|
||||
import * as Toggle from '#/components/forms/Toggle'
|
||||
import * as ToggleButton from '#/components/forms/ToggleButton'
|
||||
import {Button} from '#/components/Button'
|
||||
import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
|
||||
|
||||
export function Forms() {
|
||||
const [toggleGroupAValues, setToggleGroupAValues] = React.useState(['a'])
|
||||
const [toggleGroupBValues, setToggleGroupBValues] = React.useState(['a', 'b'])
|
||||
const [toggleGroupCValues, setToggleGroupCValues] = React.useState(['a', 'b'])
|
||||
const [toggleGroupDValues, setToggleGroupDValues] = React.useState(['warn'])
|
||||
|
||||
const [value, setValue] = React.useState('')
|
||||
const [date, setDate] = React.useState('2001-01-01')
|
||||
|
||||
return (
|
||||
<View style={[a.gap_4xl, a.align_start]}>
|
||||
<H1>Forms</H1>
|
||||
|
||||
<View style={[a.gap_md, a.align_start, a.w_full]}>
|
||||
<H3>InputText</H3>
|
||||
|
||||
<TextField.Input
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
label="Text field"
|
||||
/>
|
||||
|
||||
<TextField.Root>
|
||||
<TextField.Icon icon={Globe} />
|
||||
<TextField.Input
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
label="Text field"
|
||||
/>
|
||||
</TextField.Root>
|
||||
|
||||
<View style={[a.w_full]}>
|
||||
<TextField.Label>Text field</TextField.Label>
|
||||
<TextField.Root>
|
||||
<TextField.Icon icon={Globe} />
|
||||
<TextField.Input
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
label="Text field"
|
||||
/>
|
||||
<TextField.Suffix label="@gmail.com">@gmail.com</TextField.Suffix>
|
||||
</TextField.Root>
|
||||
</View>
|
||||
|
||||
<View style={[a.w_full]}>
|
||||
<TextField.Label>Textarea</TextField.Label>
|
||||
<TextField.Input
|
||||
multiline
|
||||
numberOfLines={4}
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
label="Text field"
|
||||
/>
|
||||
</View>
|
||||
|
||||
<H3>DateField</H3>
|
||||
|
||||
<View style={[a.w_full]}>
|
||||
<Label>Date</Label>
|
||||
<DateField
|
||||
testID="date"
|
||||
value={date}
|
||||
onChangeDate={date => {
|
||||
console.log(date)
|
||||
setDate(date)
|
||||
}}
|
||||
label="Input"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={[a.gap_md, a.align_start, a.w_full]}>
|
||||
<H3>Toggles</H3>
|
||||
|
||||
<Toggle.Item name="a" label="Click me">
|
||||
<Toggle.Checkbox />
|
||||
<Toggle.Label>Uncontrolled toggle</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
|
||||
<Toggle.Group
|
||||
label="Toggle"
|
||||
type="checkbox"
|
||||
maxSelections={2}
|
||||
values={toggleGroupAValues}
|
||||
onChange={setToggleGroupAValues}>
|
||||
<View style={[a.gap_md]}>
|
||||
<Toggle.Item name="a" label="Click me">
|
||||
<Toggle.Switch />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="b" label="Click me">
|
||||
<Toggle.Switch />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="c" label="Click me">
|
||||
<Toggle.Switch />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="d" disabled label="Click me">
|
||||
<Toggle.Switch />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="e" isInvalid label="Click me">
|
||||
<Toggle.Switch />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
</View>
|
||||
</Toggle.Group>
|
||||
|
||||
<Toggle.Group
|
||||
label="Toggle"
|
||||
type="checkbox"
|
||||
maxSelections={2}
|
||||
values={toggleGroupBValues}
|
||||
onChange={setToggleGroupBValues}>
|
||||
<View style={[a.gap_md]}>
|
||||
<Toggle.Item name="a" label="Click me">
|
||||
<Toggle.Checkbox />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="b" label="Click me">
|
||||
<Toggle.Checkbox />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="c" label="Click me">
|
||||
<Toggle.Checkbox />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="d" disabled label="Click me">
|
||||
<Toggle.Checkbox />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="e" isInvalid label="Click me">
|
||||
<Toggle.Checkbox />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
</View>
|
||||
</Toggle.Group>
|
||||
|
||||
<Toggle.Group
|
||||
label="Toggle"
|
||||
type="radio"
|
||||
values={toggleGroupCValues}
|
||||
onChange={setToggleGroupCValues}>
|
||||
<View style={[a.gap_md]}>
|
||||
<Toggle.Item name="a" label="Click me">
|
||||
<Toggle.Radio />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="b" label="Click me">
|
||||
<Toggle.Radio />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="c" label="Click me">
|
||||
<Toggle.Radio />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="d" disabled label="Click me">
|
||||
<Toggle.Radio />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
<Toggle.Item name="e" isInvalid label="Click me">
|
||||
<Toggle.Radio />
|
||||
<Toggle.Label>Click me</Toggle.Label>
|
||||
</Toggle.Item>
|
||||
</View>
|
||||
</Toggle.Group>
|
||||
</View>
|
||||
|
||||
<Button
|
||||
variant="gradient"
|
||||
color="gradient_nordic"
|
||||
size="small"
|
||||
label="Reset all toggles"
|
||||
onPress={() => {
|
||||
setToggleGroupAValues(['a'])
|
||||
setToggleGroupBValues(['a', 'b'])
|
||||
setToggleGroupCValues(['a'])
|
||||
}}>
|
||||
Reset all toggles
|
||||
</Button>
|
||||
|
||||
<View style={[a.gap_md, a.align_start, a.w_full]}>
|
||||
<H3>ToggleButton</H3>
|
||||
|
||||
<ToggleButton.Group
|
||||
label="Preferences"
|
||||
values={toggleGroupDValues}
|
||||
onChange={setToggleGroupDValues}>
|
||||
<ToggleButton.Button name="hide" label="Hide">
|
||||
Hide
|
||||
</ToggleButton.Button>
|
||||
<ToggleButton.Button name="warn" label="Warn">
|
||||
Warn
|
||||
</ToggleButton.Button>
|
||||
<ToggleButton.Button name="show" label="Show">
|
||||
Show
|
||||
</ToggleButton.Button>
|
||||
</ToggleButton.Group>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
41
src/view/screens/Storybook/Icons.tsx
Normal file
41
src/view/screens/Storybook/Icons.tsx
Normal file
|
@ -0,0 +1,41 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {H1} from '#/components/Typography'
|
||||
import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
|
||||
import {ArrowTopRight_Stroke2_Corner0_Rounded as ArrowTopRight} from '#/components/icons/ArrowTopRight'
|
||||
import {CalendarDays_Stroke2_Corner0_Rounded as CalendarDays} from '#/components/icons/CalendarDays'
|
||||
|
||||
export function Icons() {
|
||||
const t = useTheme()
|
||||
return (
|
||||
<View style={[a.gap_md]}>
|
||||
<H1>Icons</H1>
|
||||
|
||||
<View style={[a.flex_row, a.gap_xl]}>
|
||||
<Globe size="xs" fill={t.atoms.text.color} />
|
||||
<Globe size="sm" fill={t.atoms.text.color} />
|
||||
<Globe size="md" fill={t.atoms.text.color} />
|
||||
<Globe size="lg" fill={t.atoms.text.color} />
|
||||
<Globe size="xl" fill={t.atoms.text.color} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.gap_xl]}>
|
||||
<ArrowTopRight size="xs" fill={t.atoms.text.color} />
|
||||
<ArrowTopRight size="sm" fill={t.atoms.text.color} />
|
||||
<ArrowTopRight size="md" fill={t.atoms.text.color} />
|
||||
<ArrowTopRight size="lg" fill={t.atoms.text.color} />
|
||||
<ArrowTopRight size="xl" fill={t.atoms.text.color} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.gap_xl]}>
|
||||
<CalendarDays size="xs" fill={t.atoms.text.color} />
|
||||
<CalendarDays size="sm" fill={t.atoms.text.color} />
|
||||
<CalendarDays size="md" fill={t.atoms.text.color} />
|
||||
<CalendarDays size="lg" fill={t.atoms.text.color} />
|
||||
<CalendarDays size="xl" fill={t.atoms.text.color} />
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
48
src/view/screens/Storybook/Links.tsx
Normal file
48
src/view/screens/Storybook/Links.tsx
Normal file
|
@ -0,0 +1,48 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {atoms as a} from '#/alf'
|
||||
import {ButtonText} from '#/components/Button'
|
||||
import {Link} from '#/components/Link'
|
||||
import {H1, H3} from '#/components/Typography'
|
||||
|
||||
export function Links() {
|
||||
return (
|
||||
<View style={[a.gap_md, a.align_start]}>
|
||||
<H1>Links</H1>
|
||||
|
||||
<View style={[a.gap_md, a.align_start]}>
|
||||
<Link
|
||||
to="https://blueskyweb.xyz"
|
||||
warnOnMismatchingTextChild
|
||||
style={[a.text_md]}>
|
||||
External
|
||||
</Link>
|
||||
<Link to="https://blueskyweb.xyz" style={[a.text_md]}>
|
||||
<H3>External with custom children</H3>
|
||||
</Link>
|
||||
<Link
|
||||
to="https://blueskyweb.xyz"
|
||||
warnOnMismatchingTextChild
|
||||
style={[a.text_lg]}>
|
||||
https://blueskyweb.xyz
|
||||
</Link>
|
||||
<Link
|
||||
to="https://bsky.app/profile/bsky.app"
|
||||
warnOnMismatchingTextChild
|
||||
style={[a.text_md]}>
|
||||
Internal
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
variant="solid"
|
||||
color="primary"
|
||||
size="large"
|
||||
label="View @bsky.app's profile"
|
||||
to="https://bsky.app/profile/bsky.app">
|
||||
<ButtonText>Link as a button</ButtonText>
|
||||
</Link>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
336
src/view/screens/Storybook/Palette.tsx
Normal file
336
src/view/screens/Storybook/Palette.tsx
Normal file
|
@ -0,0 +1,336 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import * as tokens from '#/alf/tokens'
|
||||
import {atoms as a} from '#/alf'
|
||||
|
||||
export function Palette() {
|
||||
return (
|
||||
<View style={[a.gap_md]}>
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<View
|
||||
style={[a.flex_1, {height: 60, backgroundColor: tokens.color.gray_0}]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_25},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_50},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_100},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_200},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_300},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_400},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_500},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_600},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_700},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_800},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_900},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_950},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_975},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.gray_1000},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_25},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_50},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_100},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_200},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_300},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_400},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_500},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_600},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_700},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_800},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_900},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_950},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.blue_975},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_25},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_50},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_100},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_200},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_300},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_400},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_500},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_600},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_700},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_800},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_900},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_950},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.green_975},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
<View
|
||||
style={[a.flex_1, {height: 60, backgroundColor: tokens.color.red_25}]}
|
||||
/>
|
||||
<View
|
||||
style={[a.flex_1, {height: 60, backgroundColor: tokens.color.red_50}]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_100},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_200},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_300},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_400},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_500},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_600},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_700},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_800},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_900},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_950},
|
||||
]}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
{height: 60, backgroundColor: tokens.color.red_975},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
53
src/view/screens/Storybook/Shadows.tsx
Normal file
53
src/view/screens/Storybook/Shadows.tsx
Normal file
|
@ -0,0 +1,53 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {H1, Text} from '#/components/Typography'
|
||||
|
||||
export function Shadows() {
|
||||
const t = useTheme()
|
||||
|
||||
return (
|
||||
<View style={[a.gap_md]}>
|
||||
<H1>Shadows</H1>
|
||||
|
||||
<View style={[a.flex_row, a.gap_5xl]}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
a.justify_center,
|
||||
a.px_lg,
|
||||
a.py_2xl,
|
||||
t.atoms.bg,
|
||||
t.atoms.shadow_sm,
|
||||
]}>
|
||||
<Text>shadow_sm</Text>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
a.justify_center,
|
||||
a.px_lg,
|
||||
a.py_2xl,
|
||||
t.atoms.bg,
|
||||
t.atoms.shadow_md,
|
||||
]}>
|
||||
<Text>shadow_md</Text>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={[
|
||||
a.flex_1,
|
||||
a.justify_center,
|
||||
a.px_lg,
|
||||
a.py_2xl,
|
||||
t.atoms.bg,
|
||||
t.atoms.shadow_lg,
|
||||
]}>
|
||||
<Text>shadow_lg</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
64
src/view/screens/Storybook/Spacing.tsx
Normal file
64
src/view/screens/Storybook/Spacing.tsx
Normal file
|
@ -0,0 +1,64 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Text, H1} from '#/components/Typography'
|
||||
|
||||
export function Spacing() {
|
||||
const t = useTheme()
|
||||
return (
|
||||
<View style={[a.gap_md]}>
|
||||
<H1>Spacing</H1>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>2xs (2px)</Text>
|
||||
<View style={[a.flex_1, a.pt_2xs, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>xs (4px)</Text>
|
||||
<View style={[a.flex_1, a.pt_xs, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>sm (8px)</Text>
|
||||
<View style={[a.flex_1, a.pt_sm, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>md (12px)</Text>
|
||||
<View style={[a.flex_1, a.pt_md, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>lg (16px)</Text>
|
||||
<View style={[a.flex_1, a.pt_lg, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>xl (20px)</Text>
|
||||
<View style={[a.flex_1, a.pt_xl, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>2xl (24px)</Text>
|
||||
<View style={[a.flex_1, a.pt_2xl, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>3xl (28px)</Text>
|
||||
<View style={[a.flex_1, a.pt_3xl, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>4xl (32px)</Text>
|
||||
<View style={[a.flex_1, a.pt_4xl, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
<Text style={{width: 80}}>5xl (40px)</Text>
|
||||
<View style={[a.flex_1, a.pt_5xl, t.atoms.bg_contrast_300]} />
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
56
src/view/screens/Storybook/Theming.tsx
Normal file
56
src/view/screens/Storybook/Theming.tsx
Normal file
|
@ -0,0 +1,56 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {Palette} from './Palette'
|
||||
|
||||
export function Theming() {
|
||||
const t = useTheme()
|
||||
|
||||
return (
|
||||
<View style={[t.atoms.bg, a.gap_lg, a.p_xl]}>
|
||||
<Palette />
|
||||
|
||||
<Text style={[a.font_bold, a.pt_xl, a.px_md]}>theme.atoms.text</Text>
|
||||
|
||||
<View style={[a.flex_1, t.atoms.border, a.border_t]} />
|
||||
<Text style={[a.font_bold, t.atoms.text_contrast_600, a.px_md]}>
|
||||
theme.atoms.text_contrast_600
|
||||
</Text>
|
||||
|
||||
<View style={[a.flex_1, t.atoms.border, a.border_t]} />
|
||||
<Text style={[a.font_bold, t.atoms.text_contrast_500, a.px_md]}>
|
||||
theme.atoms.text_contrast_500
|
||||
</Text>
|
||||
|
||||
<View style={[a.flex_1, t.atoms.border, a.border_t]} />
|
||||
<Text style={[a.font_bold, t.atoms.text_contrast_400, a.px_md]}>
|
||||
theme.atoms.text_contrast_400
|
||||
</Text>
|
||||
|
||||
<View style={[a.flex_1, t.atoms.border_contrast, a.border_t]} />
|
||||
|
||||
<View style={[a.w_full, a.gap_md]}>
|
||||
<View style={[t.atoms.bg, a.justify_center, a.p_md]}>
|
||||
<Text>theme.atoms.bg</Text>
|
||||
</View>
|
||||
<View style={[t.atoms.bg_contrast_25, a.justify_center, a.p_md]}>
|
||||
<Text>theme.atoms.bg_contrast_25</Text>
|
||||
</View>
|
||||
<View style={[t.atoms.bg_contrast_50, a.justify_center, a.p_md]}>
|
||||
<Text>theme.atoms.bg_contrast_50</Text>
|
||||
</View>
|
||||
<View style={[t.atoms.bg_contrast_100, a.justify_center, a.p_md]}>
|
||||
<Text>theme.atoms.bg_contrast_100</Text>
|
||||
</View>
|
||||
<View style={[t.atoms.bg_contrast_200, a.justify_center, a.p_md]}>
|
||||
<Text>theme.atoms.bg_contrast_200</Text>
|
||||
</View>
|
||||
<View style={[t.atoms.bg_contrast_300, a.justify_center, a.p_md]}>
|
||||
<Text>theme.atoms.bg_contrast_300</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
30
src/view/screens/Storybook/Typography.tsx
Normal file
30
src/view/screens/Storybook/Typography.tsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {atoms as a} from '#/alf'
|
||||
import {Text, H1, H2, H3, H4, H5, H6, P} from '#/components/Typography'
|
||||
|
||||
export function Typography() {
|
||||
return (
|
||||
<View style={[a.gap_md]}>
|
||||
<H1>H1 Heading</H1>
|
||||
<H2>H2 Heading</H2>
|
||||
<H3>H3 Heading</H3>
|
||||
<H4>H4 Heading</H4>
|
||||
<H5>H5 Heading</H5>
|
||||
<H6>H6 Heading</H6>
|
||||
<P>P Paragraph</P>
|
||||
|
||||
<Text style={[a.text_5xl]}>atoms.text_5xl</Text>
|
||||
<Text style={[a.text_4xl]}>atoms.text_4xl</Text>
|
||||
<Text style={[a.text_3xl]}>atoms.text_3xl</Text>
|
||||
<Text style={[a.text_2xl]}>atoms.text_2xl</Text>
|
||||
<Text style={[a.text_xl]}>atoms.text_xl</Text>
|
||||
<Text style={[a.text_lg]}>atoms.text_lg</Text>
|
||||
<Text style={[a.text_md]}>atoms.text_md</Text>
|
||||
<Text style={[a.text_sm]}>atoms.text_sm</Text>
|
||||
<Text style={[a.text_xs]}>atoms.text_xs</Text>
|
||||
<Text style={[a.text_2xs]}>atoms.text_2xs</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
78
src/view/screens/Storybook/index.tsx
Normal file
78
src/view/screens/Storybook/index.tsx
Normal file
|
@ -0,0 +1,78 @@
|
|||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {CenteredView, ScrollView} from '#/view/com/util/Views'
|
||||
|
||||
import {atoms as a, useTheme, ThemeProvider} from '#/alf'
|
||||
import {useSetColorMode} from '#/state/shell'
|
||||
import {Button} from '#/components/Button'
|
||||
|
||||
import {Theming} from './Theming'
|
||||
import {Typography} from './Typography'
|
||||
import {Spacing} from './Spacing'
|
||||
import {Buttons} from './Buttons'
|
||||
import {Links} from './Links'
|
||||
import {Forms} from './Forms'
|
||||
import {Dialogs} from './Dialogs'
|
||||
import {Breakpoints} from './Breakpoints'
|
||||
import {Shadows} from './Shadows'
|
||||
import {Icons} from './Icons'
|
||||
|
||||
export function Storybook() {
|
||||
const t = useTheme()
|
||||
const setColorMode = useSetColorMode()
|
||||
|
||||
return (
|
||||
<ScrollView>
|
||||
<CenteredView style={[t.atoms.bg]}>
|
||||
<View style={[a.p_xl, a.gap_5xl, {paddingBottom: 200}]}>
|
||||
<View style={[a.flex_row, a.align_start, a.gap_md]}>
|
||||
<Button
|
||||
variant="outline"
|
||||
color="primary"
|
||||
size="small"
|
||||
label='Set theme to "system"'
|
||||
onPress={() => setColorMode('system')}>
|
||||
System
|
||||
</Button>
|
||||
<Button
|
||||
variant="solid"
|
||||
color="secondary"
|
||||
size="small"
|
||||
label='Set theme to "system"'
|
||||
onPress={() => setColorMode('light')}>
|
||||
Light
|
||||
</Button>
|
||||
<Button
|
||||
variant="solid"
|
||||
color="secondary"
|
||||
size="small"
|
||||
label='Set theme to "system"'
|
||||
onPress={() => setColorMode('dark')}>
|
||||
Dark
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
<ThemeProvider theme="light">
|
||||
<Theming />
|
||||
</ThemeProvider>
|
||||
<ThemeProvider theme="dim">
|
||||
<Theming />
|
||||
</ThemeProvider>
|
||||
<ThemeProvider theme="dark">
|
||||
<Theming />
|
||||
</ThemeProvider>
|
||||
|
||||
<Typography />
|
||||
<Spacing />
|
||||
<Shadows />
|
||||
<Buttons />
|
||||
<Icons />
|
||||
<Links />
|
||||
<Forms />
|
||||
<Dialogs />
|
||||
<Breakpoints />
|
||||
</View>
|
||||
</CenteredView>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue