From e85df5415605886cd49ef7b56a9ddfab83f433ec Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 12 Jan 2024 11:22:29 -0600 Subject: [PATCH] Integrate new design tokens, reorg storybook --- src/Navigation.tsx | 4 +- src/alf/atoms.ts | 312 ++++++-- src/alf/themes.ts | 88 ++- src/alf/tokens.ts | 112 +-- src/view/com/Button.tsx | 2 +- src/view/com/Dialog/index.tsx | 2 +- src/view/com/Prompt.tsx | 4 +- src/view/com/Typography.tsx | 12 +- .../com/forms/InputDate/index.android.tsx | 4 +- src/view/com/forms/InputDate/index.tsx | 4 +- src/view/com/forms/InputDate/index.web.tsx | 4 +- src/view/com/forms/InputText.tsx | 4 +- src/view/icons/Logo.tsx | 5 +- src/view/screens/Debug.tsx | 520 ------------ src/view/screens/DebugNew.tsx | 746 ------------------ src/view/screens/Storybook/Breakpoints.tsx | 25 + src/view/screens/Storybook/Buttons.tsx | 120 +++ src/view/screens/Storybook/Dialogs.tsx | 69 ++ src/view/screens/Storybook/Forms.tsx | 66 ++ src/view/screens/Storybook/Palette.tsx | 279 +++++++ src/view/screens/Storybook/Spacing.tsx | 64 ++ src/view/screens/Storybook/Theming.tsx | 56 ++ src/view/screens/Storybook/Typography.tsx | 29 + src/view/screens/Storybook/index.tsx | 69 ++ 24 files changed, 1138 insertions(+), 1462 deletions(-) delete mode 100644 src/view/screens/Debug.tsx delete mode 100644 src/view/screens/DebugNew.tsx create mode 100644 src/view/screens/Storybook/Breakpoints.tsx create mode 100644 src/view/screens/Storybook/Buttons.tsx create mode 100644 src/view/screens/Storybook/Dialogs.tsx create mode 100644 src/view/screens/Storybook/Forms.tsx create mode 100644 src/view/screens/Storybook/Palette.tsx create mode 100644 src/view/screens/Storybook/Spacing.tsx create mode 100644 src/view/screens/Storybook/Theming.tsx create mode 100644 src/view/screens/Storybook/Typography.tsx create mode 100644 src/view/screens/Storybook/index.tsx diff --git a/src/Navigation.tsx b/src/Navigation.tsx index 76a893c68c..534ba28d5b 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -61,7 +61,7 @@ import {ProfileListScreen} from './view/screens/ProfileList' import {PostThreadScreen} from './view/screens/PostThread' import {PostLikedByScreen} from './view/screens/PostLikedBy' import {PostRepostedByScreen} from './view/screens/PostRepostedBy' -import {DebugScreen} from './view/screens/DebugNew' +import {Storybook} from './view/screens/Storybook' import {LogScreen} from './view/screens/Log' import {SupportScreen} from './view/screens/Support' import {PrivacyPolicyScreen} from './view/screens/PrivacyPolicy' @@ -191,7 +191,7 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) { /> DebugScreen} + getComponent={() => Storybook} options={{title: title('Debug'), requireAuth: true}} /> + style={[atoms.font_bold, atoms.text_center, ...textStyles, style]}> {children} ) diff --git a/src/view/com/Dialog/index.tsx b/src/view/com/Dialog/index.tsx index 7f7a630a14..5a832e6fe4 100644 --- a/src/view/com/Dialog/index.tsx +++ b/src/view/com/Dialog/index.tsx @@ -91,7 +91,7 @@ export function Inner(props: DialogInnerProps) { ) { return (

+ style={[a.font_bold, t.atoms.text_contrast_600, a.pb_sm]}> {children}

) @@ -82,7 +82,7 @@ export function Description({children}: React.PropsWithChildren<{}>) { const t = useTheme() const {descriptionId} = React.useContext(Context) return ( -

+

{children}

) diff --git a/src/view/com/Typography.tsx b/src/view/com/Typography.tsx index 029fc2e24f..66cf0720de 100644 --- a/src/view/com/Typography.tsx +++ b/src/view/com/Typography.tsx @@ -19,7 +19,7 @@ export function H1({style, ...rest}: TextProps) { ) } @@ -35,7 +35,7 @@ export function H2({style, ...rest}: TextProps) { ) } @@ -51,7 +51,7 @@ export function H3({style, ...rest}: TextProps) { ) } @@ -67,7 +67,7 @@ export function H4({style, ...rest}: TextProps) { ) } @@ -83,7 +83,7 @@ export function H5({style, ...rest}: TextProps) { ) } @@ -99,7 +99,7 @@ export function H6({style, ...rest}: TextProps) { ) } diff --git a/src/view/com/forms/InputDate/index.android.tsx b/src/view/com/forms/InputDate/index.android.tsx index a492ad7da9..13b1ac25d2 100644 --- a/src/view/com/forms/InputDate/index.android.tsx +++ b/src/view/com/forms/InputDate/index.android.tsx @@ -87,8 +87,8 @@ export function InputDate({ nativeID={labelId} style={[ atoms.text_sm, - atoms.font_semibold, - t.atoms.text_contrast_700, + atoms.font_bold, + t.atoms.text_contrast_600, atoms.mb_sm, ]}> {label} diff --git a/src/view/com/forms/InputDate/index.tsx b/src/view/com/forms/InputDate/index.tsx index eb642c3a08..89a19560b7 100644 --- a/src/view/com/forms/InputDate/index.tsx +++ b/src/view/com/forms/InputDate/index.tsx @@ -48,8 +48,8 @@ export function InputDate({ nativeID={labelId} style={[ atoms.text_sm, - atoms.font_semibold, - t.atoms.text_contrast_700, + atoms.font_bold, + t.atoms.text_contrast_600, atoms.mb_sm, ]}> {label} diff --git a/src/view/com/forms/InputDate/index.web.tsx b/src/view/com/forms/InputDate/index.web.tsx index 33a7473850..87e41e8e65 100644 --- a/src/view/com/forms/InputDate/index.web.tsx +++ b/src/view/com/forms/InputDate/index.web.tsx @@ -85,8 +85,8 @@ export function InputDate({ nativeID={labelId} style={[ atoms.text_sm, - atoms.font_semibold, - t.atoms.text_contrast_700, + atoms.font_bold, + t.atoms.text_contrast_600, atoms.mb_sm, ]}> {label} diff --git a/src/view/com/forms/InputText.tsx b/src/view/com/forms/InputText.tsx index c573a3c650..f66f817422 100644 --- a/src/view/com/forms/InputText.tsx +++ b/src/view/com/forms/InputText.tsx @@ -100,8 +100,8 @@ export function InputText({ nativeID={labelId} style={[ atoms.text_sm, - atoms.font_semibold, - t.atoms.text_contrast_700, + atoms.font_bold, + t.atoms.text_contrast_600, atoms.mb_sm, ]}> {label} diff --git a/src/view/icons/Logo.tsx b/src/view/icons/Logo.tsx index 9f9f57fc85..9212381a9e 100644 --- a/src/view/icons/Logo.tsx +++ b/src/view/icons/Logo.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {StyleSheet} from 'react-native' +import {StyleSheet, TextProps} from 'react-native' import Svg, { Path, Defs, @@ -15,7 +15,8 @@ const ratio = 57 / 64 type Props = { fill?: PathProps['fill'] -} & SvgProps + style?: TextProps['style'] +} & Omit export const Logo = React.forwardRef(function LogoImpl(props: Props, ref) { const {fill, ...rest} = props diff --git a/src/view/screens/Debug.tsx b/src/view/screens/Debug.tsx deleted file mode 100644 index 0e0464200e..0000000000 --- a/src/view/screens/Debug.tsx +++ /dev/null @@ -1,520 +0,0 @@ -import React from 'react' -import {ScrollView, View} from 'react-native' -import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types' -import {ViewHeader} from '../com/util/ViewHeader' -import {ThemeProvider, PaletteColorName} from 'lib/ThemeContext' -import {usePalette} from 'lib/hooks/usePalette' -import {s} from 'lib/styles' -import * as Toast from 'view/com/util/Toast' -import {Text} from '../com/util/text/Text' -import {ViewSelector} from '../com/util/ViewSelector' -import {EmptyState} from '../com/util/EmptyState' -import * as LoadingPlaceholder from '../com/util/LoadingPlaceholder' -import {Button, ButtonType} from '../com/util/forms/Button' -import {DropdownButton, DropdownItem} from '../com/util/forms/DropdownButton' -import {ToggleButton} from '../com/util/forms/ToggleButton' -import {RadioGroup} from '../com/util/forms/RadioGroup' -import {ErrorScreen} from '../com/util/error/ErrorScreen' -import {ErrorMessage} from '../com/util/error/ErrorMessage' - -const MAIN_VIEWS = ['Base', 'Controls', 'Error', 'Notifs'] - -export const DebugScreen = ({}: NativeStackScreenProps< - CommonNavigatorParams, - 'Debug' ->) => { - const [colorScheme, setColorScheme] = React.useState<'light' | 'dark'>( - 'light', - ) - const onToggleColorScheme = () => { - setColorScheme(colorScheme === 'light' ? 'dark' : 'light') - } - return ( - - - - ) -} - -function DebugInner({ - colorScheme, - onToggleColorScheme, -}: { - colorScheme: 'light' | 'dark' - onToggleColorScheme: () => void -}) { - const [currentView, setCurrentView] = React.useState(0) - const pal = usePalette('default') - - const renderItem = (item: any) => { - return ( - - - - - {item.currentView === 3 ? ( - - ) : item.currentView === 2 ? ( - - ) : item.currentView === 1 ? ( - - ) : ( - - )} - - ) - } - - const items = [{currentView}] - - return ( - - - - - ) -} - -function Heading({label}: {label: string}) { - const pal = usePalette('default') - return ( - - - {label} - - - ) -} - -function BaseView() { - return ( - - - - - - - - - - - - - - - - ) -} - -function ControlsView() { - return ( - - - - - - - - - - - - ) -} - -function ErrorView() { - return ( - - - {}} - /> - - - - - - - - - {}} - /> - - - {}} - numberOfLines={1} - /> - - - ) -} - -function NotifsView() { - const triggerPush = () => { - // TODO: implement local notification for testing - } - const triggerToast = () => { - Toast.show('The task has been completed') - } - const triggerToast2 = () => { - Toast.show('The task has been completed successfully and with no problems') - } - return ( - - - - - - - ) -} - -function BreakpointDebugger() { - const t = useTheme() - const breakpoints = useBreakpoints() - - return ( - -

Breakpoint Debugger

- - Current breakpoint: {!breakpoints.gtMobile && mobile} - {breakpoints.gtMobile && !breakpoints.gtTablet && tablet} - {breakpoints.gtTablet && desktop} - - - {JSON.stringify(breakpoints, null, 2)} - -
- ) -} - -function ThemedSection() { - const t = useTheme() - - return ( - -

theme.atoms.text

- -

- theme.atoms.text_contrast_700 -

- -

- theme.atoms.text_contrast_500 -

- - - - - theme.bg - - - theme.bg_contrast_100 - - - - - theme.bg_contrast_200 - - - theme.bg_contrast_300 - - - - - theme.bg_positive - - - theme.bg_negative - - - - ) -} - -export function Buttons() { - const t = useTheme() - - return ( - - - - - - - - - - - - - - - - - External - - -

External with custom children

- - - https://blueskyweb.xyz - - - Internal - - - - {({props}) => Link as a button} - -
- ) -} - -function Forms() { - return ( - - console.log(text)} - /> - console.log(text)} - /> - console.log(text)} - icon={Logo} - /> - console.log(text)} - icon={Logo} - suffix={() => .bksy.social} - /> - - console.log(date)} - accessibilityLabel="Date" - accessibilityHint="Enter a date" - /> - console.log(date)} - accessibilityLabel="Date" - accessibilityHint="Enter a date" - /> - - ) -} - -function Dialogs() { - const control = Dialog.useDialogControl() - const prompt = Prompt.usePromptControl() - - return ( - <> - - - - - - Are you sure? - - This action cannot be undone. This action cannot be undone. This - action cannot be undone. - - - Cancel - Confirm - - - - - - - -

Dialog

-

Description

- - - -
-
-
- - ) -} - -export function DebugScreen() { - const t = useTheme() - - return ( - - - - - - - - - - - - - - - - - -

Heading 1

-

Heading 2

-

Heading 3

-

Heading 4

-
Heading 5
-
Heading 6
- - atoms.text_xxl - atoms.text_xl - atoms.text_lg - atoms.text_md - atoms.text_sm - atoms.text_xs - atoms.text_xxs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Spacing

- - - - xxs (2px) - - - - - xs (4px) - - - - - sm (8px) - - - - - md (12px) - - - - - lg (18px) - - - - - xl (24px) - - - - - xxl (32px) - - - - - - - -
-
- ) -} diff --git a/src/view/screens/Storybook/Breakpoints.tsx b/src/view/screens/Storybook/Breakpoints.tsx new file mode 100644 index 0000000000..34a9dbfd6e --- /dev/null +++ b/src/view/screens/Storybook/Breakpoints.tsx @@ -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 '#/view/com/Typography' + +export function Breakpoints() { + const t = useTheme() + const breakpoints = useBreakpoints() + + return ( + +

Breakpoint Debugger

+ + Current breakpoint: {!breakpoints.gtMobile && mobile} + {breakpoints.gtMobile && !breakpoints.gtTablet && tablet} + {breakpoints.gtTablet && desktop} + + + {JSON.stringify(breakpoints, null, 2)} + +
+ ) +} diff --git a/src/view/screens/Storybook/Buttons.tsx b/src/view/screens/Storybook/Buttons.tsx new file mode 100644 index 0000000000..41993cc29b --- /dev/null +++ b/src/view/screens/Storybook/Buttons.tsx @@ -0,0 +1,120 @@ +import React from 'react' +import {View} from 'react-native' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' + +import {atoms as a, useTheme} from '#/alf' +import {Button, ButtonText} from '#/view/com/Button' +import {Link} from '#/view/com/Link' +import {Text, H3} from '#/view/com/Typography' + +export function Buttons() { + const t = useTheme() + + return ( + + + + + + + + + + + + + + + + + External + + +

External with custom children

+ + + https://blueskyweb.xyz + + + Internal + + + + {({props}) => Link as a button} + +
+ ) +} diff --git a/src/view/screens/Storybook/Dialogs.tsx b/src/view/screens/Storybook/Dialogs.tsx new file mode 100644 index 0000000000..e0fcf0f811 --- /dev/null +++ b/src/view/screens/Storybook/Dialogs.tsx @@ -0,0 +1,69 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a} from '#/alf' +import {Button} from '#/view/com/Button' +import {H3, P} from '#/view/com/Typography' +import * as Dialog from '#/view/com/Dialog' +import * as Prompt from '#/view/com/Prompt' + +export function Dialogs() { + const control = Dialog.useDialogControl() + const prompt = Prompt.usePromptControl() + + return ( + <> + + + + + + Are you sure? + + This action cannot be undone. This action cannot be undone. This + action cannot be undone. + + + Cancel + Confirm + + + + + + + +

Dialog

+

Description

+ + + +
+
+
+ + ) +} diff --git a/src/view/screens/Storybook/Forms.tsx b/src/view/screens/Storybook/Forms.tsx new file mode 100644 index 0000000000..198b0582ec --- /dev/null +++ b/src/view/screens/Storybook/Forms.tsx @@ -0,0 +1,66 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a} from '#/alf' +import {Text} from '#/view/com/Typography' +import {InputText} from '#/view/com/forms/InputText' +import {InputDate, utils} from '#/view/com/forms/InputDate' +import {Logo} from '#/view/icons/Logo' + +export function Forms() { + return ( + + console.log(text)} + /> + console.log(text)} + /> + console.log(text)} + icon={Logo} + /> + console.log(text)} + icon={Logo} + suffix={() => .bksy.social} + /> + + console.log(date)} + accessibilityLabel="Date" + accessibilityHint="Enter a date" + /> + console.log(date)} + accessibilityLabel="Date" + accessibilityHint="Enter a date" + /> + + ) +} diff --git a/src/view/screens/Storybook/Palette.tsx b/src/view/screens/Storybook/Palette.tsx new file mode 100644 index 0000000000..1844f8d900 --- /dev/null +++ b/src/view/screens/Storybook/Palette.tsx @@ -0,0 +1,279 @@ +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 ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/src/view/screens/Storybook/Spacing.tsx b/src/view/screens/Storybook/Spacing.tsx new file mode 100644 index 0000000000..c162779340 --- /dev/null +++ b/src/view/screens/Storybook/Spacing.tsx @@ -0,0 +1,64 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/view/com/Typography' + +export function Spacing() { + const t = useTheme() + return ( + + + + 2xs (2px) + + + + + xs (4px) + + + + + sm (8px) + + + + + md (12px) + + + + + lg (16px) + + + + + xl (20px) + + + + + 2xl (24px) + + + + + 3xl (28px) + + + + + 4xl (32px) + + + + + 5xl (40px) + + + + + ) +} diff --git a/src/view/screens/Storybook/Theming.tsx b/src/view/screens/Storybook/Theming.tsx new file mode 100644 index 0000000000..68a402683d --- /dev/null +++ b/src/view/screens/Storybook/Theming.tsx @@ -0,0 +1,56 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/view/com/Typography' +import {Palette} from './Palette' + +export function Theming() { + const t = useTheme() + + return ( + + + + theme.atoms.text + + + + theme.atoms.text_contrast_600 + + + + + theme.atoms.text_contrast_500 + + + + + theme.atoms.text_contrast_400 + + + + + + + theme.atoms.bg + + + theme.atoms.bg_contrast_25 + + + theme.atoms.bg_contrast_50 + + + theme.atoms.bg_contrast_100 + + + theme.atoms.bg_contrast_200 + + + theme.atoms.bg_contrast_300 + + + + ) +} diff --git a/src/view/screens/Storybook/Typography.tsx b/src/view/screens/Storybook/Typography.tsx new file mode 100644 index 0000000000..470d17f913 --- /dev/null +++ b/src/view/screens/Storybook/Typography.tsx @@ -0,0 +1,29 @@ +import React from 'react' + +import {atoms as a} from '#/alf' +import {Text, H1, H2, H3, H4, H5, H6, P} from '#/view/com/Typography' + +export function Typography() { + return ( + <> +

H1 Heading

+

H2 Heading

+

H3 Heading

+

H4 Heading

+
H5 Heading
+
H6 Heading
+

P Paragraph

+ + atoms.text_5xl + atoms.text_4xl + atoms.text_3xl + atoms.text_2xl + atoms.text_xl + atoms.text_lg + atoms.text_md + atoms.text_sm + atoms.text_xs + atoms.text_2xs + + ) +} diff --git a/src/view/screens/Storybook/index.tsx b/src/view/screens/Storybook/index.tsx new file mode 100644 index 0000000000..642eae9f7f --- /dev/null +++ b/src/view/screens/Storybook/index.tsx @@ -0,0 +1,69 @@ +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 '#/view/com/Button' + +import {Theming} from './Theming' +import {Typography} from './Typography' +import {Spacing} from './Spacing' +import {Buttons} from './Buttons' +import {Forms} from './Forms' +import {Dialogs} from './Dialogs' +import {Breakpoints} from './Breakpoints' + +export function Storybook() { + const t = useTheme() + const setColorMode = useSetColorMode() + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + ) +}