Skip to content

Instantly share code, notes, and snippets.

@cupofcrazy
Created April 17, 2025 02:21
Show Gist options
  • Select an option

  • Save cupofcrazy/a2c093d6932228dd8c8f192ad830d2ea to your computer and use it in GitHub Desktop.

Select an option

Save cupofcrazy/a2c093d6932228dd8c8f192ad830d2ea to your computer and use it in GitHub Desktop.
Word Count input component for Sanity.io Portable Text
import { useFormValue } from 'sanity'
import { Flex, Badge, Inline } from '@sanity/ui'
import { PortableTextBlock } from '@portabletext/types'
export const WordCount = (props: any) => {
const content = useFormValue(props.path) as PortableTextBlock[]
const countWords = (blocks: PortableTextBlock[]): number => {
if (!blocks) return 0
return blocks.reduce((count, block) => {
if (block._type === 'block' && block.children) {
return count + block.children.reduce((childCount, child) => {
if (child._type === 'span' && child.text) {
return childCount + child.text.trim().split(/\s+/).length
}
return childCount
}, 0)
}
return count
}, 0)
}
const wordCount = countWords(content)
const isEmpty = wordCount === 0
return (
<Flex direction="column" gap={2}>
<Inline>
<Badge
tone={isEmpty ? 'default' : 'primary'}
radius="full"
padding={2}
>
{isEmpty ? 'No words' : `Words: ${wordCount}`}
</Badge>
</Inline>
{props.renderDefault(props)}
</Flex>
)
}
@cupofcrazy
Copy link
Author

cupofcrazy commented Apr 17, 2025

next.js version

import { Badge, Inline, Stack } from '@sanity/ui'
import { toPlainText } from 'next-sanity'

export const WordCount = (props: any) => {
  const wordCount = toPlainText(props.value).split(/\s+/).length
  const isEmpty = wordCount === 0

  return (
    <Stack space={2}>
      {props.renderDefault({ ...props, initialActive: true })}
      <Inline>
        <Badge
          tone={isEmpty ? 'default' : 'primary'} 
          radius="full" 
          padding={2}
      >
        {isEmpty ? 'No words' : `Words: ${wordCount}`}
      </Badge>
      </Inline>
      
    </Stack>
  )
} 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment