Skip to content

Instantly share code, notes, and snippets.

@fsubal
Last active January 21, 2026 13:05
Show Gist options
  • Select an option

  • Save fsubal/68154b20e54c58ecc0c5bb00d41dc98a to your computer and use it in GitHub Desktop.

Select an option

Save fsubal/68154b20e54c58ecc0c5bb00d41dc98a to your computer and use it in GitHub Desktop.
import React from 'react'
interface Props {
ruby: string | string[]
children: string
}
function zipFurigana(ruby: string | string[], text: string) {
const rubyChars = Array.isArray(ruby) ? ruby : [ruby]
const textChars = Array.from(text)
if (rubyChars.length !== textChars.length) {
throw new Error('ふりがなの数が文字数と一致しません')
}
return rubyChars.map((ruby, index) => ({
index,
char: textChars[index],
ruby
}))
}
export function Furigana({ ruby, children }: Props) {
return (
<ruby>
{zipFurigana(ruby, children).map(({ index, char, ruby }) => (
<React.Fragment key={index}>
{char}
<rp>(</rp>
<rt>{ruby}</rt>
<rp>)</rp>
</React.Fragment>
))}
</ruby>
)
}
<Furigana ruby="かんじ">漢字</Furigana>
<Furigana ruby={['かん', 'じ']}>漢字</Furigana>
import React from 'react'
interface Props {
children: Record<string, React.ReactNode>
}
export function Furigana({ children }: Props) {
return (
<ruby>
{Object.entries(children).map(([ruby, chars], index) => (
<React.Fragment key={ruby + chars + index}>
{chars}
<rp>(</rp>
<rt>{ruby}</rt>
<rp>)</rp>
</React.Fragment>
))}
</ruby>
)
}
<Furigana>{{ かんじ: '漢字' }}</Furigana>
<Furigana>{{ かん: '漢', じ: '字' }}</Furigana>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment