1.2.6: dedicated FontPicker component with in-line type previews
Replaces the bare <select> with a custom combobox that fits the properties panel's visual language: - Trigger looks like the other inputs (var(--bg)/var(--border)/ var(--radius-sm)) and shows the selected font's name rendered in that font itself, with a rotating caret. - Options live in a teleported popover anchored beneath the trigger. Each option renders its own label in its own typeface so the user sees what they're picking before applying it. Active row uses var(--accent-soft) to match the rest of the editor. - Click-outside closes via window pointerdown; Escape closes and returns focus to the trigger. - Storage shape simplified: textFontModel uses '' for system-sans instead of the literal 'system-sans' id, so the model field round- trips through JSON without a placeholder string ever leaking. Updated PropertiesPanel test to walk the new picker (click trigger, read options from .font-popover, click an option) instead of dispatching a select 'change' event. Picker label text doubles as the test selector — System Sans / Inter / Permanent Marker confirm the option list is wired up. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
4c2b7c7c35
commit
8c4f744afc
5 files changed
+258
-23
No files matched your search
@@ -18,8 +18,8 @@ import { sampleLayer } from '@/lib/interpolate'
|
||||
import type { Action, AnimatableProps, Layer } from '@/types/scene'
|
||||
import RangeSlider from './RangeSlider.vue'
|
||||
import ActionEditor from './ActionEditor.vue'
|
||||
import FontPicker from './FontPicker.vue'
|
||||
import { t } from '@/i18n'
|
||||
import { AVAILABLE_FONTS } from '@/lib/fonts'
|
||||
|
||||
const SECTION_STORAGE_KEY = 'animatr:propSections'
|
||||
|
||||
@@ -138,11 +138,14 @@ const textAsset = computed(() => {
|
||||
return a && a.kind === 'text' ? a : null
|
||||
})
|
||||
|
||||
// Empty string represents the system-sans default. Stored as
|
||||
// `undefined` on the asset so the model field round-trips cleanly
|
||||
// through JSON without leaking a bogus 'system-sans' id.
|
||||
const textFontModel = computed({
|
||||
get: () => textAsset.value?.fontFamily ?? 'system-sans',
|
||||
get: () => textAsset.value?.fontFamily ?? '',
|
||||
set: (id: string) => {
|
||||
if (!textAsset.value) return
|
||||
textAsset.value.fontFamily = id === 'system-sans' ? undefined : id
|
||||
textAsset.value.fontFamily = id || undefined
|
||||
},
|
||||
})
|
||||
|
||||
@@ -497,9 +500,7 @@ function deleteSelection() {
|
||||
<label>{{ t('properties.text.fontSize') }}<input type="number" min="1" v-model.number="textAsset.fontSize" /></label>
|
||||
<label>
|
||||
{{ t('properties.text.font') }}
|
||||
<select v-model="textFontModel">
|
||||
<option v-for="f in AVAILABLE_FONTS" :key="f.id" :value="f.id">{{ f.label }}</option>
|
||||
</select>
|
||||
<FontPicker v-model="textFontModel" />
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in new issue
Block a user