about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2024-10-14 04:06:07 -0500
committerGitHub <noreply@github.com>2024-10-14 12:06:07 +0300
commit830b4bee9c738576769b75218dadc6b1de1ba3a3 (patch)
tree44cdef83dfc29fde3670df88a8e339bf77c92d28 /src
parent7f3b5366e6908cff28295fbc4efee53550f0b4ea (diff)
downloadvoidsky-830b4bee9c738576769b75218dadc6b1de1ba3a3.tar.zst
Add Admonition component (#5680)
* Add Admonition component

* Tweak mobile padding

* Format
Diffstat (limited to 'src')
-rw-r--r--src/components/Admonition.tsx118
-rw-r--r--src/view/screens/Storybook/Admonitions.tsx36
-rw-r--r--src/view/screens/Storybook/index.tsx4
3 files changed, 157 insertions, 1 deletions
diff --git a/src/components/Admonition.tsx b/src/components/Admonition.tsx
new file mode 100644
index 000000000..7c8682119
--- /dev/null
+++ b/src/components/Admonition.tsx
@@ -0,0 +1,118 @@
+import React from 'react'
+import {View} from 'react-native'
+
+import {atoms as a, useBreakpoints, useTheme} from '#/alf'
+import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo'
+import {Eye_Stroke2_Corner0_Rounded as InfoIcon} from '#/components/icons/Eye'
+import {Leaf_Stroke2_Corner0_Rounded as TipIcon} from '#/components/icons/Leaf'
+import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
+import {Text as BaseText, TextProps} from '#/components/Typography'
+
+const colors = {
+  warning: {
+    light: '#DFBC00',
+    dark: '#BFAF1F',
+  },
+}
+
+type Context = {
+  type: 'info' | 'tip' | 'warning' | 'error'
+}
+
+const Context = React.createContext<Context>({
+  type: 'info',
+})
+
+export function Icon() {
+  const t = useTheme()
+  const {type} = React.useContext(Context)
+  const Icon = {
+    info: InfoIcon,
+    tip: TipIcon,
+    warning: WarningIcon,
+    error: ErrorIcon,
+  }[type]
+  const fill = {
+    info: t.atoms.text_contrast_medium.color,
+    tip: t.palette.primary_500,
+    warning: colors.warning.light,
+    error: t.palette.negative_500,
+  }[type]
+  return <Icon fill={fill} size="md" />
+}
+
+export function Text({
+  children,
+  style,
+  ...rest
+}: Pick<TextProps, 'children' | 'style'>) {
+  return (
+    <BaseText
+      {...rest}
+      style={[
+        a.flex_1,
+        a.text_sm,
+        a.leading_snug,
+        {
+          paddingTop: 1,
+        },
+        style,
+      ]}>
+      {children}
+    </BaseText>
+  )
+}
+
+export function Row({children}: {children: React.ReactNode}) {
+  return <View style={[a.flex_row, a.gap_sm]}>{children}</View>
+}
+
+export function Outer({
+  children,
+  type = 'info',
+}: {
+  children: React.ReactNode
+  type?: Context['type']
+}) {
+  const t = useTheme()
+  const {gtMobile} = useBreakpoints()
+  const borderColor = {
+    info: t.atoms.border_contrast_low.borderColor,
+    tip: t.atoms.border_contrast_low.borderColor,
+    warning: t.atoms.border_contrast_low.borderColor,
+    error: t.atoms.border_contrast_low.borderColor,
+  }[type]
+  return (
+    <Context.Provider value={{type}}>
+      <View
+        style={[
+          gtMobile ? a.p_md : a.p_sm,
+          a.rounded_sm,
+          a.border,
+          t.atoms.bg_contrast_25,
+          {
+            borderColor,
+          },
+        ]}>
+        {children}
+      </View>
+    </Context.Provider>
+  )
+}
+
+export function Admonition({
+  children,
+  type,
+}: {
+  children: TextProps['children']
+  type?: Context['type']
+}) {
+  return (
+    <Outer type={type}>
+      <Row>
+        <Icon />
+        <Text>{children}</Text>
+      </Row>
+    </Outer>
+  )
+}
diff --git a/src/view/screens/Storybook/Admonitions.tsx b/src/view/screens/Storybook/Admonitions.tsx
new file mode 100644
index 000000000..ca97ebb23
--- /dev/null
+++ b/src/view/screens/Storybook/Admonitions.tsx
@@ -0,0 +1,36 @@
+import React from 'react'
+import {View} from 'react-native'
+
+import {atoms as a} from '#/alf'
+import {Admonition} from '#/components/Admonition'
+import {InlineLinkText} from '#/components/Link'
+import {H1} from '#/components/Typography'
+
+export function Admonitions() {
+  return (
+    <View style={[a.gap_md]}>
+      <H1>Admonitions</H1>
+
+      <Admonition>The quick brown fox jumps over the lazy dog.</Admonition>
+      <Admonition type="info">
+        How happy the blameless vestal's lot, the world forgetting by the world
+        forgot.{' '}
+        <InlineLinkText
+          label="test"
+          to="https://letterboxd.com/film/eternal-sunshine-of-the-spotless-mind/">
+          Eternal sunshine of the spotless mind
+        </InlineLinkText>
+        ! Each pray'r accepted, and each wish resign'd.
+      </Admonition>
+      <Admonition type="tip">
+        The quick brown fox jumps over the lazy dog.
+      </Admonition>
+      <Admonition type="warning">
+        The quick brown fox jumps over the lazy dog.
+      </Admonition>
+      <Admonition type="error">
+        The quick brown fox jumps over the lazy dog.
+      </Admonition>
+    </View>
+  )
+}
diff --git a/src/view/screens/Storybook/index.tsx b/src/view/screens/Storybook/index.tsx
index ec6bab13e..c737dad5b 100644
--- a/src/view/screens/Storybook/index.tsx
+++ b/src/view/screens/Storybook/index.tsx
@@ -7,6 +7,7 @@ import {CenteredView} from '#/view/com/util/Views'
 import {ListContained} from '#/view/screens/Storybook/ListContained'
 import {atoms as a, ThemeProvider, useTheme} from '#/alf'
 import {Button, ButtonText} from '#/components/Button'
+import {Admonitions} from './Admonitions'
 import {Breakpoints} from './Breakpoints'
 import {Buttons} from './Buttons'
 import {Dialogs} from './Dialogs'
@@ -80,7 +81,7 @@ function StorybookInner() {
               </Button>
             </View>
 
-            <Forms />
+            <Admonitions />
 
             <ThemeProvider theme="light">
               <Theming />
@@ -92,6 +93,7 @@ function StorybookInner() {
               <Theming />
             </ThemeProvider>
 
+            <Forms />
             <Buttons />
             <Typography />
             <Spacing />