-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: convert kanji reference table to React component
- Loading branch information
Showing
5 changed files
with
305 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
import { ReferenceAbbreviation } from '../../common/refs'; | ||
import { KanjiReferencesTable } from './KanjiReferencesTable'; | ||
|
||
const TEST_ENTRY = { | ||
c: '日', | ||
r: { | ||
py: ['ri4'], | ||
on: ['ニチ', 'ジツ'], | ||
kun: ['ひ', '-び', '-か'], | ||
na: [ | ||
'あ', | ||
'あき', | ||
'いる', | ||
'く', | ||
'くさ', | ||
'こう', | ||
'す', | ||
'たち', | ||
'に', | ||
'にっ', | ||
'につ', | ||
'へ', | ||
], | ||
}, | ||
m: ['day', 'sun', 'Japan', 'counter for days'], | ||
rad: { | ||
x: 72, | ||
b: '⽇', | ||
k: '日', | ||
na: ['ひ'], | ||
m: ['day', 'sun', 'Japan', 'counter for days'], | ||
m_lang: 'en', | ||
}, | ||
refs: { | ||
nelson_c: 2097, | ||
nelson_n: 2410, | ||
halpern_njecd: 3027, | ||
halpern_kkld_2ed: 2606, | ||
heisig6: 12, | ||
henshall: 62, | ||
sh_kk2: 5, | ||
kanji_in_context: 16, | ||
busy_people: '1.A', | ||
kodansha_compact: 963, | ||
skip: '3-3-1', | ||
sh_desc: '4c0.1', | ||
conning: 1, | ||
}, | ||
misc: { | ||
sc: 4, | ||
gr: 1, | ||
freq: 1, | ||
jlpt: 4, | ||
kk: 10, | ||
wk: 2, | ||
jlptn: 5, | ||
}, | ||
m_lang: 'en', | ||
comp: [], | ||
cf: [], | ||
}; | ||
|
||
function ReferencesVariant({ | ||
title, | ||
references, | ||
}: { | ||
title: string; | ||
references: Array<ReferenceAbbreviation>; | ||
}) { | ||
return ( | ||
<div> | ||
<h2>{title}</h2> | ||
<KanjiReferencesTable entry={TEST_ENTRY} kanjiReferences={references} /> | ||
</div> | ||
); | ||
} | ||
|
||
export default function () { | ||
return ( | ||
<div | ||
style={{ | ||
background: 'var(--bg-color)', | ||
color: 'var(--text-color)', | ||
padding: '18px', | ||
display: 'flex', | ||
flexDirection: 'column', | ||
gap: '40px', | ||
}} | ||
> | ||
<ReferencesVariant | ||
title="Even number of rows (last row filled)" | ||
references={[ | ||
'radical', | ||
'nelson_r', | ||
'kk', | ||
'py', | ||
'jlpt', | ||
'unicode', | ||
'conning', | ||
'halpern_njecd', | ||
'halpern_kkld_2ed', | ||
'heisig6', | ||
'henshall', | ||
'sh_kk2', | ||
'nelson_c', | ||
]} | ||
/> | ||
|
||
<ReferencesVariant | ||
title="Even number of rows (last row not filled)" | ||
references={[ | ||
'radical', | ||
'nelson_r', | ||
'kk', | ||
'py', | ||
'jlpt', | ||
'unicode', | ||
'conning', | ||
'halpern_njecd', | ||
'halpern_kkld_2ed', | ||
'heisig6', | ||
'henshall', | ||
'sh_kk2', | ||
]} | ||
/> | ||
|
||
<ReferencesVariant | ||
title="Odd number of rows (last row filled)" | ||
references={[ | ||
'radical', | ||
'nelson_r', | ||
'kk', | ||
'py', | ||
'jlpt', | ||
'unicode', | ||
'conning', | ||
'halpern_njecd', | ||
'halpern_kkld_2ed', | ||
'heisig6', | ||
'henshall', | ||
'sh_kk2', | ||
'nelson_c', | ||
'nelson_n', | ||
'skip', | ||
]} | ||
/> | ||
|
||
<ReferencesVariant | ||
title="Odd number of rows (last row not filled)" | ||
references={[ | ||
'radical', | ||
'nelson_r', | ||
'kk', | ||
'py', | ||
'jlpt', | ||
'unicode', | ||
'conning', | ||
'halpern_njecd', | ||
'halpern_kkld_2ed', | ||
'heisig6', | ||
'henshall', | ||
'sh_kk2', | ||
'nelson_c', | ||
'nelson_n', | ||
]} | ||
/> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { KanjiResult } from '@birchill/jpdict-idb'; | ||
import { useMemo } from 'preact/hooks'; | ||
|
||
import { useLocale } from '../../common/i18n'; | ||
import { | ||
getSelectedReferenceLabels, | ||
ReferenceAbbreviation, | ||
} from '../../common/refs'; | ||
import { classes } from '../../utils/classes'; | ||
|
||
import { getReferenceValue } from '../reference-value'; | ||
|
||
type Props = { | ||
entry: KanjiResult; | ||
kanjiReferences: Array<ReferenceAbbreviation>; | ||
}; | ||
|
||
export function KanjiReferencesTable({ entry, kanjiReferences }: Props) { | ||
const { t, langTag } = useLocale(); | ||
|
||
const referenceTableInfo = useMemo(() => { | ||
const referenceNames = getSelectedReferenceLabels(kanjiReferences, t); | ||
const referenceTableInfo = []; | ||
for (const ref of referenceNames) { | ||
// Don't show the Nelson radical if it's the same as the regular radical | ||
// (in which case it will be empty) and we're showing the regular radical. | ||
if ( | ||
ref.ref === 'nelson_r' && | ||
!entry.rad.nelson && | ||
kanjiReferences.includes('radical') | ||
) { | ||
continue; | ||
} | ||
|
||
const value = getReferenceValue(entry, ref.ref, t) || '-'; | ||
referenceTableInfo.push({ | ||
name: { | ||
lang: ref.lang, | ||
value: ref.short || ref.full, | ||
}, | ||
value: { | ||
lang: | ||
ref.ref === 'radical' || ref.ref === 'nelson_r' ? 'ja' : undefined, | ||
value, | ||
}, | ||
highlight: false, | ||
}); | ||
} | ||
|
||
// Now we go through and toggle the styles to get the desired alternating | ||
// effect. | ||
// | ||
// We can't easily use nth-child voodoo here because we need to | ||
// handle unbalanced columns etc. We also can't easily do this in the loop | ||
// where we generate the cells because we don't know how many references we | ||
// will generate at that point. | ||
for (const [index, cellInfo] of [...referenceTableInfo].entries()) { | ||
const row = index % Math.ceil(referenceTableInfo.length / 2); | ||
if (row % 2 === 0) { | ||
cellInfo.highlight = true; | ||
} | ||
} | ||
|
||
return referenceTableInfo; | ||
}, [t, kanjiReferences]); | ||
|
||
// The layout we want is something in-between what CSS grid and CSS multicol | ||
// can do. See: | ||
// | ||
// https://twitter.com/brianskold/status/1186198347184398336 | ||
// | ||
// In the stylesheet we make let the table flow horizontally, but then here | ||
// where we know the number of rows, we update it to produce the desired | ||
// vertical flow. | ||
let gridAutoFlow: string | undefined; | ||
let gridTemplateRows: string | undefined; | ||
if (referenceTableInfo.length > 1) { | ||
gridAutoFlow = 'column'; | ||
gridTemplateRows = `repeat(${Math.ceil( | ||
referenceTableInfo.length / 2 | ||
)}, minmax(min-content, max-content))`; | ||
} | ||
|
||
return ( | ||
<div | ||
class="references" | ||
lang={langTag} | ||
style={{ gridAutoFlow, gridTemplateRows }} | ||
> | ||
{referenceTableInfo.map((cellInfo) => ( | ||
<div class={classes('ref', cellInfo.highlight && '-highlight')}> | ||
<span class="name" lang={cellInfo.name.lang}> | ||
{cellInfo.name.value} | ||
</span> | ||
<span class="value" lang={cellInfo.value.lang}> | ||
{cellInfo.value.value} | ||
</span> | ||
</div> | ||
))} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import type { RenderableProps } from 'preact'; | ||
import { useSelect } from 'react-cosmos/client'; | ||
|
||
import { I18nProvider } from '../../common/i18n'; | ||
import { EmptyProps } from '../../utils/type-helpers'; | ||
|
||
export default ({ children }: RenderableProps<EmptyProps>) => { | ||
const [locale] = useSelect('locale', { | ||
options: ['en', 'ja', 'zh_hans'], | ||
}); | ||
|
||
const [themeName] = useSelect('theme', { | ||
options: ['black', 'light', 'blue', 'lightblue', 'yellow'], | ||
defaultValue: 'light', | ||
}); | ||
|
||
return ( | ||
<I18nProvider locale={locale}> | ||
<div className={`theme-${themeName}`}>{children}</div> | ||
</I18nProvider> | ||
); | ||
}; |
Oops, something went wrong.