diff --git a/src/view/com/composer/AltTextCounterWrapper.tsx b/src/view/com/composer/AltTextCounterWrapper.tsx
deleted file mode 100644
index cdb7df5200..0000000000
--- a/src/view/com/composer/AltTextCounterWrapper.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import {View} from 'react-native'
-
-import {MAX_ALT_TEXT} from '#/lib/constants'
-import {CharProgress} from '#/view/com/composer/char-progress/CharProgress'
-import {atoms as a, useTheme} from '#/alf'
-
-export function AltTextCounterWrapper({
- altText,
- children,
-}: {
- altText?: string
- children: React.ReactNode
-}) {
- const t = useTheme()
- return (
-
-
- {children}
-
- )
-}
diff --git a/src/view/com/composer/GifAltText.tsx b/src/view/com/composer/GifAltText.tsx
index b7565e6b6d..af24d1250f 100644
--- a/src/view/com/composer/GifAltText.tsx
+++ b/src/view/com/composer/GifAltText.tsx
@@ -3,6 +3,7 @@ import {TouchableOpacity, View} from 'react-native'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Plural, Trans} from '@lingui/react/macro'
+import {countGraphemes} from 'unicode-segmenter/grapheme'
import {HITSLOP_10, MAX_ALT_TEXT} from '#/lib/constants'
import {parseAltFromGIFDescription} from '#/lib/gif-alt-text'
@@ -11,7 +12,6 @@ import {
parseEmbedPlayerFromUrl,
} from '#/lib/strings/embed-player'
import {useResolveGifQuery} from '#/state/queries/resolve-link'
-import {AltTextCounterWrapper} from '#/view/com/composer/AltTextCounterWrapper'
import {atoms as a, useTheme} from '#/alf'
import {Admonition} from '#/components/Admonition'
import {Button, ButtonText} from '#/components/Button'
@@ -146,6 +146,8 @@ function AltTextInner({
const t = useTheme()
const {_, i18n} = useLingui()
+ const altTextLength = countGraphemes(altText)
+
return (
@@ -153,7 +155,9 @@ function AltTextInner({
- Descriptive alt text
+
+ Descriptive alt text ({altTextLength}/{MAX_ALT_TEXT})
+
- {altText.length > MAX_ALT_TEXT && (
+ {altTextLength > MAX_ALT_TEXT && (
-
+
-
-
-
+
{/* below the text input to force tab order */}
diff --git a/src/view/com/composer/photos/ImageAltTextDialog.tsx b/src/view/com/composer/photos/ImageAltTextDialog.tsx
index 08de8d8d99..5b47ef211b 100644
--- a/src/view/com/composer/photos/ImageAltTextDialog.tsx
+++ b/src/view/com/composer/photos/ImageAltTextDialog.tsx
@@ -4,11 +4,11 @@ import {Image} from 'expo-image'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Plural, Trans} from '@lingui/react/macro'
+import {countGraphemes} from 'unicode-segmenter'
import {MAX_ALT_TEXT} from '#/lib/constants'
import {enforceLen} from '#/lib/strings/helpers'
import {type ComposerImage} from '#/state/gallery'
-import {AltTextCounterWrapper} from '#/view/com/composer/AltTextCounterWrapper'
import {atoms as a, tokens, useTheme} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
@@ -91,6 +91,8 @@ const ImageAltTextInner = ({
}
}, [image, screenWidth])
+ const altTextLength = countGraphemes(altText)
+
return (
@@ -121,7 +123,9 @@ const ImageAltTextInner = ({
- Descriptive alt text
+
+ Descriptive alt text ({altTextLength}/{MAX_ALT_TEXT})
+
- {altText.length > MAX_ALT_TEXT && (
+ {altTextLength > MAX_ALT_TEXT && (
-
+
-
-
-
+
)