refactor(font): inject font-load status as a prop, decoupling UI from the store

FontApplicator and FontSampler no longer read fontLifecycleManager. They take a
`status` prop (FontLoadStatus | undefined) supplied by the composing widget;
FontList and SampleList resolve status once per visible row and pass it down.

FSD+ dependency inversion: the entity/feature UI depends on a value, not the
lifecycle store. Removes FontApplicator's value-import of the store (one step
toward an inert ./ui barrel) and drops the duplicate getFontStatus read per row
in FontList. FontSampler is now status-decoupled and trivially relocatable to
entities/Font/ui.
This commit is contained in:
Ilia Mashkov
2026-06-01 12:06:30 +03:00
parent 28a8e49915
commit fcd61be4fa
6 changed files with 52 additions and 46 deletions
@@ -21,6 +21,11 @@ const { Story } = defineMeta({
control: 'object',
description: 'Font information object',
},
status: {
control: 'select',
options: ['loading', 'loaded', 'error'],
description: 'Font-load status, supplied by the composing widget and forwarded to FontApplicator',
},
text: {
control: 'text',
description: 'Editable sample text (two-way bindable)',
@@ -85,6 +90,7 @@ const mockGeorgia: UnifiedFont = {
name="Default"
args={{
font: mockArial,
status: 'loaded',
text: 'The quick brown fox jumps over the lazy dog',
index: 0,
}}
@@ -101,6 +107,7 @@ const mockGeorgia: UnifiedFont = {
name="Long Text"
args={{
font: mockGeorgia,
status: 'loaded',
text:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.',
index: 1,
@@ -6,6 +6,7 @@
<script lang="ts">
import {
FontApplicator,
type FontLoadStatus,
type UnifiedFont,
} from '$entities/Font';
import { typographySettingsStore } from '$features/AdjustTypography/model';
@@ -23,6 +24,12 @@ interface Props {
* Font info
*/
font: UnifiedFont;
/**
* Current font-load status, supplied by the composing widget so this
* component (and FontApplicator) stay decoupled from the lifecycle store.
* `undefined` means not tracked yet (treated as not-yet-revealed).
*/
status: FontLoadStatus | undefined;
/**
* Sample text
*/
@@ -34,7 +41,7 @@ interface Props {
index?: number;
}
let { font, text = $bindable(), index = 0 }: Props = $props();
let { font, status, text = $bindable(), index = 0 }: Props = $props();
// Adjust the property name to match your UnifiedFont type
const fontType = $derived((font as any).type ?? (font as any).category ?? '');
@@ -132,7 +139,7 @@ const stats = $derived([
<!-- ── Main content area ──────────────────────────────────────────── -->
<div class="flex-1 p-4 sm:p-5 md:p-8 flex items-center overflow-hidden bg-paper dark:bg-dark-card relative z-10">
<FontApplicator {font} weight={typographySettingsStore.weight}>
<FontApplicator {font} {status}>
<ContentEditable
bind:text
fontSize={typographySettingsStore.renderedSize}