MCPcopy Create free account
hub / github.com/ZenNotes/zennotes / StatusBar

Function StatusBar

packages/app-core/src/components/StatusBar.tsx:16–51  ·  view source on GitHub ↗
({ note }: { note: NoteContent })

Source from the content-addressed store, hash-verified

14 * at render time.
15 */
16export function StatusBar({ note }: { note: NoteContent }): JSX.Element {
17 const notes = useStore((s) => s.notes)
18
19 const { words, characters, minutes } = useMemo(() => {
20 const body = note.body
21 const w = countWords(body)
22 const c = body.length
23 const m = Math.max(1, Math.round(w / 200))
24 return { words: w, characters: c, minutes: m }
25 }, [note.body])
26
27 // Backlinks depend only on the active note's *path* and the vault's
28 // wikilink metadata — never on the note body. Keying the memo on
29 // `note.path` (instead of the whole `note` object, which changes on every
30 // keystroke) keeps this O(n) scan off the typing hot path while producing
31 // an identical count.
32 const backlinks = useMemo(() => {
33 return backlinksForNote(notes as NoteMeta[], note).length
34 }, [note.path, notes])
35
36 return (
37 <div
38 className="flex h-8 shrink-0 items-center justify-end gap-5 px-6 text-xs text-ink-500"
39 style={{ borderTop: '1px solid var(--glass-stroke)' }}
40 >
41 <Stat>
42 {backlinks} {backlinks === 1 ? 'backlink' : 'backlinks'}
43 </Stat>
44 <Stat>
45 {words.toLocaleString()} {words === 1 ? 'word' : 'words'}
46 </Stat>
47 <Stat>{characters.toLocaleString()} characters</Stat>
48 <Stat>{minutes} min read</Stat>
49 </div>
50 )
51}
52
53function Stat({ children }: { children: React.ReactNode }): JSX.Element {
54 return <span className="tabular-nums">{children}</span>

Callers

nothing calls this directly

Calls 2

countWordsFunction · 0.90
backlinksForNoteFunction · 0.90

Tested by

no test coverage detected