fix: make fill hex editable and quiet local font probing

* fix: make fill hex editable and suppress premature local font warnings

- FillSection: replace read-only hex span with editable input for solid
  fills (matching existing stroke behavior); gradient/image fills and
  variable-bound fills keep the display span
- FontManager.findLocalFont: guard on localFontAccessState === 'granted'
  before calling queryLocalFonts(), eliminating SecurityError console
  warnings on load when the user hasn't yet granted font access
- .gitignore: add .opencode/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: apply oxfmt formatting to FillSection.vue

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Danila Poyarkov <dev@dannote.net>
This commit is contained in:
rcoenen 2026-06-06 06:28:46 -04:00 committed by GitHub
parent c4e21af7ee
commit a9ee01fc13
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 30 additions and 1 deletions

3
.gitignore vendored
View file

@ -48,3 +48,6 @@ vue-stream-markdown/
# Agent scratch space (reviews, test artifacts)
scratch/
# OpenCode
.opencode/

View file

@ -528,6 +528,7 @@ export class FontManager {
options: FindLocalFontOptions = {}
): Promise<ArrayBuffer | null> {
if (!IS_BROWSER || !window.queryLocalFonts) return null
if (this.localFontAccessState !== 'granted') return null
try {
const fonts = await window.queryLocalFonts()
const match = chooseLocalFontMatch(fonts, family, style)

View file

@ -1,5 +1,6 @@
<script setup lang="ts">
import { PropertyListRoot, useFillControls, useOkHCL, useI18n } from '@open-pencil/vue'
import { PropertyListRoot, useFillControls, useOkHCL, useI18n, inputValue } from '@open-pencil/vue'
import { colorToHexRaw, parseColor } from '@open-pencil/core/color'
import FillPicker from '@/components/FillPicker.vue'
import Tip from '@/components/ui/Tip.vue'
@ -31,6 +32,19 @@ function updateFill(
}
update(index, fill)
}
function updateFillHex(
activeNode: SceneNode | null | undefined,
index: number,
fill: Fill,
hex: string,
update: (index: number, fill: Fill) => void
) {
if (fill.type !== 'SOLID') return
const parsed = parseColor(hex.startsWith('#') ? hex : `#${hex}`)
if (!parsed) return
updateFill(activeNode, index, { ...fill, color: { ...parsed, a: fill.color.a } }, update)
}
</script>
<template>
@ -80,7 +94,18 @@ function updateFill(
@update="updateFill(activeNode, i, $event, actions.update)"
/>
<input
v-if="
fill.type === 'SOLID' && !(activeNode && fillCtx.getBoundVariable(activeNode.id, i))
"
data-test-id="fill-hex-input"
class="min-w-0 flex-1 border-none bg-transparent font-mono text-xs text-surface outline-none"
:value="colorToHexRaw(fill.color)"
maxlength="6"
@change="updateFillHex(activeNode, i, fill, inputValue($event), actions.update)"
/>
<span
v-else
class="min-w-0 flex-1 truncate font-mono text-xs"
:class="
activeNode && fillCtx.getBoundVariable(activeNode.id, i)