about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2024-09-19 14:41:31 -0500
committerGitHub <noreply@github.com>2024-09-19 14:41:31 -0500
commit8a7fc9ad3f822ba77716a6eacb4c08ab2992c506 (patch)
tree283ea2d9b67da6ea0af2cff7b671b778d00f4297 /src
parent15231604679675633c72583879234402eea0fa2c (diff)
downloadvoidsky-8a7fc9ad3f822ba77716a6eacb4c08ab2992c506.tar.zst
[Neue] Ligatures & composer (#5427)
* Disable contextual ligatures

* Ensure new type styles are applied to the composer

* Clean up using real devices

* Feedback
Diffstat (limited to 'src')
-rw-r--r--src/alf/fonts.ts6
-rw-r--r--src/view/com/composer/text-input/TextInput.tsx53
-rw-r--r--src/view/com/composer/text-input/TextInput.web.tsx30
3 files changed, 66 insertions, 23 deletions
diff --git a/src/alf/fonts.ts b/src/alf/fonts.ts
index ce658fa05..264e51fa8 100644
--- a/src/alf/fonts.ts
+++ b/src/alf/fonts.ts
@@ -108,4 +108,10 @@ export function applyFonts(
       style.fontFamily = style.fontFamily || FAMILIES
     }
   }
+
+  /**
+   * Disable contextual ligatures
+   * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant}
+   */
+  style.fontVariant = ['no-contextual']
 }
diff --git a/src/view/com/composer/text-input/TextInput.tsx b/src/view/com/composer/text-input/TextInput.tsx
index f69c89569..778439259 100644
--- a/src/view/com/composer/text-input/TextInput.tsx
+++ b/src/view/com/composer/text-input/TextInput.tsx
@@ -19,6 +19,7 @@ import PasteInput, {
   PasteInputRef,
 } from '@mattermost/react-native-paste-input'
 
+import {isAndroid} from '#/platform/detection'
 import {POST_IMG_MAX} from 'lib/constants'
 import {usePalette} from 'lib/hooks/usePalette'
 import {downloadAndResize} from 'lib/media/manip'
@@ -26,12 +27,13 @@ import {isUriImage} from 'lib/media/util'
 import {cleanError} from 'lib/strings/errors'
 import {getMentionAt, insertMentionAt} from 'lib/strings/mention-manip'
 import {useTheme} from 'lib/ThemeContext'
-import {isIOS} from 'platform/detection'
 import {
   LinkFacetMatch,
   suggestLinkCardUri,
 } from 'view/com/composer/text-input/text-input-util'
 import {Text} from 'view/com/util/text/Text'
+import {atoms as a, useAlf} from '#/alf'
+import {normalizeTextStyles} from '#/components/Typography'
 import {Autocomplete} from './mobile/Autocomplete'
 
 export interface TextInputRef {
@@ -67,6 +69,7 @@ export const TextInput = forwardRef(function TextInputImpl(
   }: TextInputProps,
   ref,
 ) {
+  const {theme: t, fonts} = useAlf()
   const pal = usePalette('default')
   const textInput = useRef<PasteInputRef>(null)
   const textInputSelection = useRef<Selection>({start: 0, end: 0})
@@ -180,6 +183,33 @@ export const TextInput = forwardRef(function TextInputImpl(
     [onChangeText, richtext, setAutocompletePrefix],
   )
 
+  const inputTextStyle = React.useMemo(() => {
+    const style = normalizeTextStyles(
+      [a.text_xl, a.leading_snug, t.atoms.text],
+      {
+        fontScale: fonts.scaleMultiplier,
+        fontFamily: fonts.family,
+        flags: {},
+      },
+    )
+
+    /*
+     * `PasteInput` appears to prefer no `lineHeight`
+     */
+    style.lineHeight = undefined
+
+    /*
+     * Android impl of `PasteInput` doesn't support the array syntax for `fontVariant`
+     */
+    if (isAndroid) {
+      // @ts-ignore
+      style.fontVariant = style.fontVariant
+        ? style.fontVariant.join(' ')
+        : undefined
+    }
+    return style
+  }, [t, fonts])
+
   const textDecorated = useMemo(() => {
     let i = 0
 
@@ -187,15 +217,12 @@ export const TextInput = forwardRef(function TextInputImpl(
       return (
         <Text
           key={i++}
-          style={[
-            segment.facet ? pal.link : pal.text,
-            styles.textInputFormatting,
-          ]}>
+          style={[inputTextStyle, segment.facet ? pal.link : pal.text]}>
           {segment.text}
         </Text>
       )
     })
-  }, [richtext, pal.link, pal.text])
+  }, [richtext, pal.link, pal.text, inputTextStyle])
 
   return (
     <View style={styles.container}>
@@ -213,12 +240,7 @@ export const TextInput = forwardRef(function TextInputImpl(
         multiline
         scrollEnabled={false}
         numberOfLines={4}
-        style={[
-          pal.text,
-          styles.textInput,
-          styles.textInputFormatting,
-          {textAlignVertical: 'top'},
-        ]}
+        style={[inputTextStyle, styles.textInput, {textAlignVertical: 'top'}]}
         {...props}>
         {textDecorated}
       </PasteInput>
@@ -242,11 +264,4 @@ const styles = StyleSheet.create({
     marginLeft: 8,
     alignSelf: 'flex-start',
   },
-  textInputFormatting: {
-    fontSize: 18,
-    letterSpacing: 0.2,
-    fontWeight: '400',
-    // This is broken on ios right now, so don't set it there.
-    lineHeight: isIOS ? undefined : 23.4, // 1.3*16
-  },
 })
diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx
index 3db25746f..acec61516 100644
--- a/src/view/com/composer/text-input/TextInput.web.tsx
+++ b/src/view/com/composer/text-input/TextInput.web.tsx
@@ -22,7 +22,9 @@ import {
   LinkFacetMatch,
   suggestLinkCardUri,
 } from 'view/com/composer/text-input/text-input-util'
+import {atoms as a, useAlf} from '#/alf'
 import {Portal} from '#/components/Portal'
+import {normalizeTextStyles} from '#/components/Typography'
 import {Text} from '../../util/text/Text'
 import {createSuggestion} from './web/Autocomplete'
 import {Emoji} from './web/EmojiPicker.web'
@@ -58,6 +60,7 @@ export const TextInput = React.forwardRef(function TextInputImpl(
   TextInputProps,
   ref,
 ) {
+  const {theme: t, fonts} = useAlf()
   const autocomplete = useActorAutocompleteFn()
   const pal = usePalette('default')
   const modeClass = useColorSchemeStyle('ProseMirror-light', 'ProseMirror-dark')
@@ -247,13 +250,32 @@ export const TextInput = React.forwardRef(function TextInputImpl(
     },
   }))
 
+  const inputStyle = React.useMemo(() => {
+    const style = normalizeTextStyles(
+      [a.text_lg, a.leading_snug, t.atoms.text],
+      {
+        fontScale: fonts.scaleMultiplier,
+        fontFamily: fonts.family,
+        flags: {},
+      },
+    )
+    /*
+     * TipTap component isn't a RN View and while it seems to convert
+     * `fontSize` to `px`, it doesn't convert `lineHeight`.
+     *
+     * `lineHeight` should always be defined here, this is defensive.
+     */
+    style.lineHeight = style.lineHeight
+      ? ((style.lineHeight + 'px') as unknown as number)
+      : undefined
+    return style
+  }, [t, fonts])
+
   return (
     <>
       <View style={styles.container}>
-        <EditorContent
-          editor={editor}
-          style={{color: pal.text.color as string}}
-        />
+        {/* @ts-ignore inputStyle is fine */}
+        <EditorContent editor={editor} style={inputStyle} />
       </View>
 
       {isDropping && (