Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/otfjs-ui/src/components/font-icon/font-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function FontIcon({ name, size }: FontIconProps) {
if (complexFonts.has(id)) {
return (
<img
src={`${id}.svg`}
src={`/${id}.svg`}
width={size}
height={size}
className={styles.imgPreview}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { memo, useEffect, useMemo, useRef } from 'react'
import { Link, useRouter } from '@tanstack/react-router'

import { useTimeoutAfterSet } from '../../hooks/use-timeout-after-set'
import { handle } from '../../shortcuts/shortcuts'
import { Fonts } from '../../types/fonts'
import { createElementWalkerFactory } from '../../utils/dom'
import { addListener } from '../../utils/event'
import { entriesFilterMap } from '../../utils/object'
import { FontIcon } from '../font-icon/font-icon'
import { useTimeoutAfterSet } from '../../../hooks/use-timeout-after-set'
import { handle } from '../../../shortcuts/shortcuts'
import { Fonts } from '../../../types/fonts'
import { createElementWalkerFactory } from '../../../utils/dom'
import { addListener } from '../../../utils/event'
import { entriesFilterMap } from '../../../utils/object'
import { FontIcon } from '../../font-icon/font-icon'

import styles from './font-grid.module.css'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
.root {
--gap: 26px;

position: relative;
display: grid;
padding-top: 20px;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useDeferredValue, useState } from 'react'

import fonts from '../../fonts.json'
import { SearchBar } from './components/search-bar'
import { FontGrid } from './font-grid'
import { FontGrid } from './font-list.components/font-grid'
import { SearchBar } from './font-list.components/search-bar'

import styles from './no-font-view.module.css'
import styles from './font-list.module.css'

export function NoFontView() {
export function FontList() {
const [filter, setFilter] = useState('')
const deferredSearch = useDeferredValue(filter)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
.head {
grid-area: head;
display: grid;
grid-template-columns: auto 1fr;
height: 97px;
gap: 8px;
padding: 8px;
border-bottom: 1px solid var(--color-border);
background: var(--color-bg-sidebar);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,20 @@ const theme: React.CSSProperties = {

export function JsonView({
data,
/* replacements, */
replacements,
}: {
data: object
replacements?: Record<string, (value: unknown) => any>
}) {
/*
const replacer = useMemo(() => {
if (!replacements) return undefined

return (key: string, value: any): any => {
const r = replacements[key]
if (r) return r(value)
return value
if (replacements) {
data = structuredClone(data)
for (const [key, replace] of Object.entries(replacements)) {
if (key in data) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
;(data as any)[key] = replace((data as any)[key])
Comment on lines +21 to +22
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation uses multiple any type assertions which bypasses TypeScript's type safety. Consider adding a generic type parameter to JsonView to properly type the data object and avoid the need for disabling ESLint rules.

Copilot uses AI. Check for mistakes.
}
}
}, [replacements])
*/
}

return <JsonViewPkg value={data} style={theme} displayDataTypes={false} />
}
26 changes: 19 additions & 7 deletions packages/otfjs-ui/src/components/font-view/font-view.module.css
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
.root {
display: grid;
grid-template-columns: auto 1fr;
gap: 1px;
grid:
'head view' auto
'tabs view' 1fr / 240px 1fr;
height: 100%;
overflow: hidden;

background: var(--color-border);

:where(& > *) {
background: var(--color-bg);
}

@media screen and (max-width: 600px) {
grid:
'head head' auto
'tabs view' 1fr / 100px 1fr;
}
}

.sidebar {
.tabs {
grid-area: tabs;
overflow: scroll;
width: 240px;
box-sizing: content-box;
border-right: 1px solid var(--color-border);
background: var(--color-bg-sidebar);
}

.tabs {
& ul {
list-style: none;
padding: 0;
Expand Down Expand Up @@ -50,6 +61,7 @@
}

.tableView {
grid-area: view;
position: relative;
overflow: scroll;
}
Expand Down
34 changes: 14 additions & 20 deletions packages/otfjs-ui/src/components/font-view/font-view.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useRef, useState } from 'react'
import { useCallback, useRef, useState } from 'react'
import clsx from 'clsx'
import { Font, NameId } from 'otfjs'

Expand All @@ -19,33 +19,19 @@ export function FontView({ font }: FontViewProps) {
return (
<FontContext value={font}>
<div className={styles.root}>
<Sidebar tab={tab} setTab={setTab} />
<Head />
<Tabs tab={tab} setTab={setTab} />
<View tab={tab} />
</div>
</FontContext>
)
}

function Sidebar({
tab,
setTab,
}: {
tab: string
setTab: React.Dispatch<React.SetStateAction<string>>
}) {
return (
<div className={styles.sidebar}>
<Head className="mb-2" />
<Tabs tab={tab} setTab={setTab} />
</div>
)
}

function Tabs({ tab, setTab }: { tab: string; setTab: (tab: string) => void }) {
const font = useFont()

return (
<div className={styles.tabs}>
<div className={`${styles.tabs} pt-2`}>
<ul>
<li>
<button
Expand Down Expand Up @@ -78,11 +64,19 @@ function Overview() {
const font = useFont()
const fontFamily = font.getName(NameId.FontFamilyName)

const value = `${fontFamily}\n\nThe quick brown fox jumps over the lazy dog.\n0123456789\n\n`

const ref = useCallback((el: HTMLTextAreaElement | null) => {
if (!el) return
el.focus()
el.setSelectionRange(el.value.length, el.value.length)
}, [])

return (
<div className={styles.tableView}>
<textarea
autoFocus
defaultValue={fontFamily!}
ref={ref}
defaultValue={value}
style={{ fontFamily: `"${fontFamily}"` }}
className="block h-full w-full resize-none bg-[var(--color-bg)] p-2 text-2xl"
/>
Expand Down
4 changes: 2 additions & 2 deletions packages/otfjs-ui/src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createFileRoute, useRouterState } from '@tanstack/react-router'

import { FontList } from '../components/font-list/font-list'
import { FontView } from '../components/font-view/font-view'
import { NoFontView } from '../components/no-font-view/no-font-view'
import { getFontById } from '../utils/fetch-font'

export const Route = createFileRoute('/')({
Expand All @@ -17,5 +17,5 @@ function Index() {
if (font) return <FontView font={font} />
}

return <NoFontView />
return <FontList />
}