refactor(vue): remove deprecated panel APIs
- Remove FillPickerRoot and useFillPicker from source, exports, and localized docs - Replace the final PanelRow consumer with accessible auto-layout controls - Document the canonical panel and fill composition contracts
This commit is contained in:
parent
27fdef2ea4
commit
a62cec00f8
|
|
@ -268,6 +268,7 @@ Self-review checklist:
|
|||
- `src/components/Shell/**` is for app shell chrome and global app services rendered as components (menu bar, toast viewport, update/status chrome). Shell components may use app shell/editor stores.
|
||||
- `src/components/properties/**`, `src/components/chat/**`, `src/components/LayerTree/**`, `src/components/Toolbar/**`, and similar folders are feature/domain component namespaces. Keep feature-specific controls there unless they are genuinely reusable UI primitives.
|
||||
- Treat existing root-level picker/input/control components as migration candidates when touched; do not expand that pattern.
|
||||
- Property-panel composition uses `PanelGrid`, `PanelFieldGroup`, `PanelItemRow`, and `PropertyItemRow`; do not reintroduce generic row wrappers such as the removed `PanelRow`. Variable-capable fields compose `BindableValue` providers, and fill UIs compose `FillRoot` / `FillSwatch` with a consumer-owned popover rather than rebuilding a combined picker wrapper.
|
||||
- Test locators follow Playwright's user-facing priority: role/name, label, and text first. Multi-part components expose scoped `data-slot` anatomy; app concepts use semantic attributes such as `data-property`, `data-command`, and `data-node-id` when accessible identity is insufficient. Reserve `data-test-id` for rare integration boundaries such as the canvas/editor host, never add `testId`/`testHook` props, and do not manufacture globally unique compound IDs inside shared components.
|
||||
|
||||
- Use reka-ui for UI components (Splitter, ContextMenu, DropdownMenu, etc.)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
- Add accessible color-channel sliders, binding-aware fill primitives, and keyboard-operable gradient stops while separating fill state from popover composition.
|
||||
- Rebuild Fill, Stroke, Effects, and Export controls with shared compact item rows, semantic actions, binding-aware paint fields, and reversible color-picker edits.
|
||||
- Finish the Design panel migration with compact labeled Typography, Variant, Mask, and Page controls plus semantic empty-section states.
|
||||
- Remove the deprecated `FillPickerRoot`, `useFillPicker()`, and `PanelRow` compatibility APIs after migrating consumers to the canonical fill and panel primitives.
|
||||
- Upgrade Vue SDK documentation with shared Tailwind demos, source-generated component API tables, and type-aware Twoslash examples in VitePress.
|
||||
- Add desktop image drag-and-drop into the Tauri app window.
|
||||
- Add open-document discovery for live CLI and MCP automation so agents can target the intended document and page.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ const SDK_COMPONENT_PAGES = [
|
|||
{ text: 'ChannelSlider', slug: 'channel-slider', canonical: true },
|
||||
{ text: 'FillRoot', slug: 'fill-root', canonical: true },
|
||||
{ text: 'FillSwatch', slug: 'fill-swatch', canonical: true },
|
||||
{ text: 'FillPickerRoot', slug: 'fill-picker-root', canonical: true },
|
||||
{ text: 'FontPickerRoot', slug: 'font-picker-root' },
|
||||
{ text: 'GradientEditorRoot', slug: 'gradient-editor-root' },
|
||||
{ text: 'GradientEditorBar', slug: 'gradient-editor-bar' },
|
||||
|
|
@ -58,7 +57,6 @@ const SDK_ADVANCED_PAGES = [
|
|||
{ text: 'useSceneComputed', slug: 'use-scene-computed' },
|
||||
{ text: 'useColorVariableBinding', slug: 'use-color-variable-binding' },
|
||||
{ text: 'useColorBindingProvider', slug: 'use-color-binding-provider', canonical: true },
|
||||
{ text: 'useFillPicker', slug: 'use-fill-picker', canonical: true },
|
||||
{ text: 'useGradientStops', slug: 'use-gradient-stops' },
|
||||
{ text: 'useFontPicker', slug: 'use-font-picker' },
|
||||
{ text: 'usePropScrub', slug: 'use-prop-scrub' },
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ Diese APIs sind öffentlich, aber spezialisierter als die Haupt-Komponenten- und
|
|||
## Picker, Variablen, Locale und Editor-Interna
|
||||
|
||||
- [useColorVariableBinding](./use-color-variable-binding)
|
||||
- [useFillPicker](./use-fill-picker)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
- [useFontPicker](./use-font-picker)
|
||||
- [useOkHCL](./use-okhcl)
|
||||
|
|
|
|||
|
|
@ -22,4 +22,4 @@ const strokeBinding = useColorVariableBinding('strokes')
|
|||
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useStrokeControls](../composables/use-stroke-controls)
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [FillRoot](/programmable/sdk/api/components/fill-root)
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
title: useFillPicker
|
||||
description: Niedrigstufen-Füllungs-Kategorie- und Konvertierungs-Hilfsmittel.
|
||||
---
|
||||
|
||||
# useFillPicker
|
||||
|
||||
`useFillPicker(fill, onUpdate)` gibt abgeleiteten Füllungs-Kategorie-Zustand sowie Konvertierungs-Hilfsmittel zum Wechseln zwischen einfarbigen, Verlaufs- und Bildfüllungen zurück.
|
||||
|
||||
Verwenden Sie es beim Erstellen benutzerdefinierter Füllungs-Picker über `FillPickerRoot` hinaus.
|
||||
|
||||
## Verwandte APIs
|
||||
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
---
|
||||
title: FillPickerRoot
|
||||
description: Headless popover-basiertes Füllungsauswahl-Primitiv.
|
||||
---
|
||||
|
||||
# FillPickerRoot
|
||||
|
||||
`FillPickerRoot` ist ein headless popover-basiertes Füllungsauswahl-Primitiv für einfarbige, Verlaufs- und Bildfüllungen.
|
||||
|
||||
## Props
|
||||
|
||||
<SdkPropsTable
|
||||
:rows="[
|
||||
{ name: 'fill', type: 'Fill', description: 'Aktueller Füllungswert.', required: true },
|
||||
{ name: 'contentClass', type: 'string | undefined', description: 'Optionale Klasse für den Popover-Inhalt.' },
|
||||
{ name: 'swatchClass', type: 'string | undefined', description: 'Optionale Klasse für die Standard-Trigger-Schaltfläche.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Ereignisse
|
||||
|
||||
<SdkEventsTable
|
||||
:rows="[
|
||||
{ name: 'update', payload: 'fill: Fill', description: 'Ausgelöst, wenn sich die Füllung ändert.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Slots
|
||||
|
||||
<SdkSlotsTable
|
||||
:rows="[
|
||||
{ name: 'trigger', props: 'Farbmuster-Stil', description: 'Benutzerdefinierter Trigger mit Farbmuster-Hintergrundstil.' },
|
||||
{ name: 'default', props: 'Füllungszustand + Konvertierungs-Hilfsmittel', description: 'Haupt-Füllungs-Editor-Inhalt.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
### Trigger-Slot-Props
|
||||
|
||||
```ts
|
||||
{
|
||||
style: Record<string, string>
|
||||
}
|
||||
```
|
||||
|
||||
### Standard-Slot-Props
|
||||
|
||||
```ts
|
||||
{
|
||||
fill: Fill
|
||||
category: 'SOLID' | 'GRADIENT' | 'IMAGE'
|
||||
toSolid: () => void
|
||||
toGradient: () => void
|
||||
toImage: () => void
|
||||
update: (fill: Fill) => void
|
||||
}
|
||||
```
|
||||
|
||||
## Beispiel
|
||||
|
||||
```vue
|
||||
<FillPickerRoot :fill="fill" @update="fill = $event">
|
||||
<template #default="{ fill, category, toSolid, toGradient, update }">
|
||||
<div>{{ category }}</div>
|
||||
<button @click="toSolid">Einfarbig</button>
|
||||
<button @click="toGradient">Verlauf</button>
|
||||
<MyFillEditor :fill="fill" @change="update" />
|
||||
</template>
|
||||
</FillPickerRoot>
|
||||
```
|
||||
|
||||
## Verwandte APIs
|
||||
|
||||
- [GradientEditorRoot](./gradient-editor-root)
|
||||
|
|
@ -35,7 +35,6 @@ description: Komponentenreferenz für headless Vue-Primitive in @open-pencil/vue
|
|||
<SdkCardGroup>
|
||||
<SdkCard title="ColorPickerRoot" to="/programmable/sdk/api/components/color-picker-root" description="Popover-basiertes Farbauswahl-Primitiv." />
|
||||
<SdkCard title="ColorInputRoot" to="/programmable/sdk/api/components/color-input-root" description="Headless Farb-Eingabe-Hilfsmittel." />
|
||||
<SdkCard title="FillPickerRoot" to="/programmable/sdk/api/components/fill-picker-root" description="Popover-basiertes Füllungsauswahl-Primitiv." />
|
||||
<SdkCard title="FontPickerRoot" to="/programmable/sdk/api/components/font-picker-root" description="Durchsuchbares Schriftauswahl-Primitiv." />
|
||||
<SdkCard title="GradientEditorRoot" to="/programmable/sdk/api/components/gradient-editor-root" description="Wurzel-Primitiv für Verlaufsbearbeitung." />
|
||||
<SdkCard title="GradientEditorBar" to="/programmable/sdk/api/components/gradient-editor-bar" description="Ziehbare Verlaufsbalken-Primitiv." />
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ Estas APIs son públicas, pero son más especializadas que la superficie princip
|
|||
## Selector, variables, idioma e internos del editor
|
||||
|
||||
- [useColorVariableBinding](./use-color-variable-binding)
|
||||
- [useFillPicker](./use-fill-picker)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
- [useFontPicker](./use-font-picker)
|
||||
- [useOkHCL](./use-okhcl)
|
||||
|
|
|
|||
|
|
@ -22,4 +22,4 @@ const strokeBinding = useColorVariableBinding('strokes')
|
|||
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useStrokeControls](../composables/use-stroke-controls)
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [FillRoot](/programmable/sdk/api/components/fill-root)
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
title: useFillPicker
|
||||
description: Helper de bajo nivel para la categoría de relleno y la conversión.
|
||||
---
|
||||
|
||||
# useFillPicker
|
||||
|
||||
`useFillPicker(fill, onUpdate)` devuelve el estado derivado de la categoría del relleno más helpers de conversión para cambiar entre rellenos sólidos, degradados e imágenes.
|
||||
|
||||
Úsalo cuando construyas selectores de relleno personalizados más allá de `FillPickerRoot`.
|
||||
|
||||
## APIs relacionadas
|
||||
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
---
|
||||
title: FillPickerRoot
|
||||
description: Primitivo headless de selector de relleno basado en popover.
|
||||
---
|
||||
|
||||
# FillPickerRoot
|
||||
|
||||
`FillPickerRoot` es un primitivo headless de selector de relleno basado en popover para rellenos sólidos, degradados e imágenes.
|
||||
|
||||
## Props
|
||||
|
||||
<SdkPropsTable
|
||||
:rows="[
|
||||
{ name: 'fill', type: 'Fill', description: 'Valor de relleno actual.', required: true },
|
||||
{ name: 'contentClass', type: 'string | undefined', description: 'Clase opcional para el contenido del popover.' },
|
||||
{ name: 'swatchClass', type: 'string | undefined', description: 'Clase opcional para el botón trigger por defecto.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Eventos
|
||||
|
||||
<SdkEventsTable
|
||||
:rows="[
|
||||
{ name: 'update', payload: 'fill: Fill', description: 'Emitido cuando el relleno cambia.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Slots
|
||||
|
||||
<SdkSlotsTable
|
||||
:rows="[
|
||||
{ name: 'trigger', props: 'swatch style', description: 'Trigger personalizado con estilo de fondo de muestra.' },
|
||||
{ name: 'default', props: 'fill state + conversion helpers', description: 'Contenido principal del editor de relleno.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
### Props del slot trigger
|
||||
|
||||
```ts
|
||||
{
|
||||
style: Record<string, string>
|
||||
}
|
||||
```
|
||||
|
||||
### Props del slot default
|
||||
|
||||
```ts
|
||||
{
|
||||
fill: Fill
|
||||
category: 'SOLID' | 'GRADIENT' | 'IMAGE'
|
||||
toSolid: () => void
|
||||
toGradient: () => void
|
||||
toImage: () => void
|
||||
update: (fill: Fill) => void
|
||||
}
|
||||
```
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```vue
|
||||
<FillPickerRoot :fill="fill" @update="fill = $event">
|
||||
<template #default="{ fill, category, toSolid, toGradient, update }">
|
||||
<div>{{ category }}</div>
|
||||
<button @click="toSolid">Sólido</button>
|
||||
<button @click="toGradient">Degradado</button>
|
||||
<MyFillEditor :fill="fill" @change="update" />
|
||||
</template>
|
||||
</FillPickerRoot>
|
||||
```
|
||||
|
||||
## APIs relacionadas
|
||||
|
||||
- [GradientEditorRoot](./gradient-editor-root)
|
||||
|
|
@ -35,7 +35,6 @@ description: Referencia de componentes para los primitivos headless de Vue en @o
|
|||
<SdkCardGroup>
|
||||
<SdkCard title="ColorPickerRoot" to="/programmable/sdk/api/components/color-picker-root" description="Primitivo de selector de color basado en popover." />
|
||||
<SdkCard title="ColorInputRoot" to="/programmable/sdk/api/components/color-input-root" description="Helper headless de input de color." />
|
||||
<SdkCard title="FillPickerRoot" to="/programmable/sdk/api/components/fill-picker-root" description="Primitivo de selector de relleno basado en popover." />
|
||||
<SdkCard title="FontPickerRoot" to="/programmable/sdk/api/components/font-picker-root" description="Primitivo de selector de fuente con búsqueda." />
|
||||
<SdkCard title="GradientEditorRoot" to="/programmable/sdk/api/components/gradient-editor-root" description="Primitivo raíz para la edición de degradados." />
|
||||
<SdkCard title="GradientEditorBar" to="/programmable/sdk/api/components/gradient-editor-bar" description="Primitivo de barra de degradado arrastrable." />
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ Ces API sont publiques, mais elles sont plus spécialisées que la surface princ
|
|||
## Sélecteurs, variables, locale et internals d'éditeur
|
||||
|
||||
- [useColorVariableBinding](./use-color-variable-binding)
|
||||
- [useFillPicker](./use-fill-picker)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
- [useFontPicker](./use-font-picker)
|
||||
- [useOkHCL](./use-okhcl)
|
||||
|
|
|
|||
|
|
@ -22,4 +22,4 @@ const strokeBinding = useColorVariableBinding('strokes')
|
|||
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useStrokeControls](../composables/use-stroke-controls)
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [FillRoot](/programmable/sdk/api/components/fill-root)
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
title: useFillPicker
|
||||
description: Helper de bas niveau pour la catégorie de remplissage et la conversion.
|
||||
---
|
||||
|
||||
# useFillPicker
|
||||
|
||||
`useFillPicker(fill, onUpdate)` retourne l'état de catégorie de remplissage dérivé ainsi que des helpers de conversion pour basculer entre les remplissages solides, dégradés et images.
|
||||
|
||||
Utilisez-le pour construire des sélecteurs de remplissage personnalisés au-delà de `FillPickerRoot`.
|
||||
|
||||
## API associées
|
||||
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
---
|
||||
title: FillPickerRoot
|
||||
description: Primitive headless de sélecteur de remplissage basé sur un popover.
|
||||
---
|
||||
|
||||
# FillPickerRoot
|
||||
|
||||
`FillPickerRoot` est une primitive headless de sélecteur de remplissage basé sur un popover pour les remplissages solides, dégradés et images.
|
||||
|
||||
## Props
|
||||
|
||||
<SdkPropsTable
|
||||
:rows="[
|
||||
{ name: 'fill', type: 'Fill', description: 'Valeur de remplissage courante.', required: true },
|
||||
{ name: 'contentClass', type: 'string | undefined', description: 'Classe optionnelle pour le contenu du popover.' },
|
||||
{ name: 'swatchClass', type: 'string | undefined', description: 'Classe optionnelle pour le bouton déclencheur par défaut.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Événements
|
||||
|
||||
<SdkEventsTable
|
||||
:rows="[
|
||||
{ name: 'update', payload: 'fill: Fill', description: 'Émis quand le remplissage change.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Slots
|
||||
|
||||
<SdkSlotsTable
|
||||
:rows="[
|
||||
{ name: 'trigger', props: 'style de l\'échantillon', description: 'Déclencheur personnalisé avec le style de fond de l\'échantillon.' },
|
||||
{ name: 'default', props: 'état du remplissage + helpers de conversion', description: 'Contenu principal de l\'éditeur de remplissage.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
### Props du slot déclencheur
|
||||
|
||||
```ts
|
||||
{
|
||||
style: Record<string, string>
|
||||
}
|
||||
```
|
||||
|
||||
### Props du slot par défaut
|
||||
|
||||
```ts
|
||||
{
|
||||
fill: Fill
|
||||
category: 'SOLID' | 'GRADIENT' | 'IMAGE'
|
||||
toSolid: () => void
|
||||
toGradient: () => void
|
||||
toImage: () => void
|
||||
update: (fill: Fill) => void
|
||||
}
|
||||
```
|
||||
|
||||
## Exemple
|
||||
|
||||
```vue
|
||||
<FillPickerRoot :fill="fill" @update="fill = $event">
|
||||
<template #default="{ fill, category, toSolid, toGradient, update }">
|
||||
<div>{{ category }}</div>
|
||||
<button @click="toSolid">Solide</button>
|
||||
<button @click="toGradient">Dégradé</button>
|
||||
<MyFillEditor :fill="fill" @change="update" />
|
||||
</template>
|
||||
</FillPickerRoot>
|
||||
```
|
||||
|
||||
## API associées
|
||||
|
||||
- [GradientEditorRoot](./gradient-editor-root)
|
||||
|
|
@ -35,7 +35,6 @@ description: Référence des composants pour les primitives Vue headless dans @o
|
|||
<SdkCardGroup>
|
||||
<SdkCard title="ColorPickerRoot" to="/programmable/sdk/api/components/color-picker-root" description="Primitive de sélecteur de couleur basé sur un popover." />
|
||||
<SdkCard title="ColorInputRoot" to="/programmable/sdk/api/components/color-input-root" description="Helper headless pour la saisie de couleur." />
|
||||
<SdkCard title="FillPickerRoot" to="/programmable/sdk/api/components/fill-picker-root" description="Primitive de sélecteur de remplissage basé sur un popover." />
|
||||
<SdkCard title="FontPickerRoot" to="/programmable/sdk/api/components/font-picker-root" description="Primitive de sélecteur de police avec recherche." />
|
||||
<SdkCard title="GradientEditorRoot" to="/programmable/sdk/api/components/gradient-editor-root" description="Primitive racine pour l'édition de dégradés." />
|
||||
<SdkCard title="GradientEditorBar" to="/programmable/sdk/api/components/gradient-editor-bar" description="Primitive de barre de dégradé déplaçable." />
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ Queste API sono pubbliche, ma sono più specializzate rispetto alla superficie p
|
|||
## Picker, variabili, locale e funzionamento interno dell'editor
|
||||
|
||||
- [useColorVariableBinding](./use-color-variable-binding)
|
||||
- [useFillPicker](./use-fill-picker)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
- [useFontPicker](./use-font-picker)
|
||||
- [useOkHCL](./use-okhcl)
|
||||
|
|
|
|||
|
|
@ -22,4 +22,4 @@ const strokeBinding = useColorVariableBinding('strokes')
|
|||
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useStrokeControls](../composables/use-stroke-controls)
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [FillRoot](/programmable/sdk/api/components/fill-root)
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
title: useFillPicker
|
||||
description: Helper di basso livello per la categoria del riempimento e la conversione.
|
||||
---
|
||||
|
||||
# useFillPicker
|
||||
|
||||
`useFillPicker(fill, onUpdate)` restituisce lo stato della categoria di riempimento derivato più gli helper di conversione per passare tra riempimenti solidi, a gradiente e immagine.
|
||||
|
||||
Usalo quando costruisci selettori di riempimento personalizzati oltre a `FillPickerRoot`.
|
||||
|
||||
## API correlate
|
||||
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
---
|
||||
title: FillPickerRoot
|
||||
description: Primitiva popover headless per la selezione del riempimento.
|
||||
---
|
||||
|
||||
# FillPickerRoot
|
||||
|
||||
`FillPickerRoot` è una primitiva popover headless per riempimenti solidi, a gradiente e immagine.
|
||||
|
||||
## Props
|
||||
|
||||
<SdkPropsTable
|
||||
:rows="[
|
||||
{ name: 'fill', type: 'Fill', description: 'Valore riempimento corrente.', required: true },
|
||||
{ name: 'contentClass', type: 'string | undefined', description: 'Classe opzionale per il contenuto del popover.' },
|
||||
{ name: 'swatchClass', type: 'string | undefined', description: 'Classe opzionale per il pulsante trigger predefinito.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Eventi
|
||||
|
||||
<SdkEventsTable
|
||||
:rows="[
|
||||
{ name: 'update', payload: 'fill: Fill', description: 'Emesso quando il riempimento cambia.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Slot
|
||||
|
||||
<SdkSlotsTable
|
||||
:rows="[
|
||||
{ name: 'trigger', props: 'stile campione', description: 'Trigger personalizzato con stile di sfondo campione.' },
|
||||
{ name: 'default', props: 'stato riempimento + helper di conversione', description: 'Contenuto principale dell\'editor del riempimento.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
### Slot prop del trigger
|
||||
|
||||
```ts
|
||||
{
|
||||
style: Record<string, string>
|
||||
}
|
||||
```
|
||||
|
||||
### Slot prop predefiniti
|
||||
|
||||
```ts
|
||||
{
|
||||
fill: Fill
|
||||
category: 'SOLID' | 'GRADIENT' | 'IMAGE'
|
||||
toSolid: () => void
|
||||
toGradient: () => void
|
||||
toImage: () => void
|
||||
update: (fill: Fill) => void
|
||||
}
|
||||
```
|
||||
|
||||
## Esempio
|
||||
|
||||
```vue
|
||||
<FillPickerRoot :fill="fill" @update="fill = $event">
|
||||
<template #default="{ fill, category, toSolid, toGradient, update }">
|
||||
<div>{{ category }}</div>
|
||||
<button @click="toSolid">Solido</button>
|
||||
<button @click="toGradient">Gradiente</button>
|
||||
<MyFillEditor :fill="fill" @change="update" />
|
||||
</template>
|
||||
</FillPickerRoot>
|
||||
```
|
||||
|
||||
## API correlate
|
||||
|
||||
- [GradientEditorRoot](./gradient-editor-root)
|
||||
|
|
@ -35,7 +35,6 @@ description: Riferimento ai componenti per le primitive Vue headless in @open-pe
|
|||
<SdkCardGroup>
|
||||
<SdkCard title="ColorPickerRoot" to="/programmable/sdk/api/components/color-picker-root" description="Primitiva popover per la selezione del colore." />
|
||||
<SdkCard title="ColorInputRoot" to="/programmable/sdk/api/components/color-input-root" description="Helper headless per l'input del colore." />
|
||||
<SdkCard title="FillPickerRoot" to="/programmable/sdk/api/components/fill-picker-root" description="Primitiva popover per la selezione del riempimento." />
|
||||
<SdkCard title="FontPickerRoot" to="/programmable/sdk/api/components/font-picker-root" description="Primitiva searchable per la selezione del font." />
|
||||
<SdkCard title="GradientEditorRoot" to="/programmable/sdk/api/components/gradient-editor-root" description="Primitiva root per l'editor del gradiente." />
|
||||
<SdkCard title="GradientEditorBar" to="/programmable/sdk/api/components/gradient-editor-bar" description="Primitiva barra trascinabile per il gradiente." />
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ Te API są publiczne, ale są bardziej wyspecjalizowane niż główna powierzchn
|
|||
## Selektor, zmienne, język i wewnętrzności edytora
|
||||
|
||||
- [useColorVariableBinding](./use-color-variable-binding)
|
||||
- [useFillPicker](./use-fill-picker)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
- [useFontPicker](./use-font-picker)
|
||||
- [useOkHCL](./use-okhcl)
|
||||
|
|
|
|||
|
|
@ -22,4 +22,4 @@ const strokeBinding = useColorVariableBinding('strokes')
|
|||
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useStrokeControls](../composables/use-stroke-controls)
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [FillRoot](/programmable/sdk/api/components/fill-root)
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
title: useFillPicker
|
||||
description: Niskopoziomowy pomocnik kategorii wypełnienia i konwersji.
|
||||
---
|
||||
|
||||
# useFillPicker
|
||||
|
||||
`useFillPicker(fill, onUpdate)` zwraca pochodny stan kategorii wypełnienia plus pomocniki konwersji do przełączania między wypełnieniami jednolitymi, gradientowymi i obrazkowymi.
|
||||
|
||||
Użyj go przy budowaniu niestandardowych selektorów wypełnień wykraczających poza `FillPickerRoot`.
|
||||
|
||||
## Powiązane API
|
||||
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
---
|
||||
title: FillPickerRoot
|
||||
description: Bezstanowy prymityw selektora wypełnień oparty na popover.
|
||||
---
|
||||
|
||||
# FillPickerRoot
|
||||
|
||||
`FillPickerRoot` to bezstanowy prymityw selektora wypełnień oparty na popover dla wypełnień jednolitych, gradientowych i obrazkowych.
|
||||
|
||||
## Props
|
||||
|
||||
<SdkPropsTable
|
||||
:rows="[
|
||||
{ name: 'fill', type: 'Fill', description: 'Bieżąca wartość wypełnienia.', required: true },
|
||||
{ name: 'contentClass', type: 'string | undefined', description: 'Opcjonalna klasa dla zawartości popover.' },
|
||||
{ name: 'swatchClass', type: 'string | undefined', description: 'Opcjonalna klasa dla domyślnego przycisku wyzwalacza.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Zdarzenia
|
||||
|
||||
<SdkEventsTable
|
||||
:rows="[
|
||||
{ name: 'update', payload: 'fill: Fill', description: 'Emitowane gdy wypełnienie się zmienia.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Sloty
|
||||
|
||||
<SdkSlotsTable
|
||||
:rows="[
|
||||
{ name: 'trigger', props: 'styl próbki', description: 'Niestandardowy wyzwalacz ze stylem tła próbki.' },
|
||||
{ name: 'default', props: 'stan wypełnienia + pomocniki konwersji', description: 'Główna zawartość edytora wypełnień.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
### Właściwości slotu trigger
|
||||
|
||||
```ts
|
||||
{
|
||||
style: Record<string, string>
|
||||
}
|
||||
```
|
||||
|
||||
### Właściwości slotu default
|
||||
|
||||
```ts
|
||||
{
|
||||
fill: Fill
|
||||
category: 'SOLID' | 'GRADIENT' | 'IMAGE'
|
||||
toSolid: () => void
|
||||
toGradient: () => void
|
||||
toImage: () => void
|
||||
update: (fill: Fill) => void
|
||||
}
|
||||
```
|
||||
|
||||
## Przykład
|
||||
|
||||
```vue
|
||||
<FillPickerRoot :fill="fill" @update="fill = $event">
|
||||
<template #default="{ fill, category, toSolid, toGradient, update }">
|
||||
<div>{{ category }}</div>
|
||||
<button @click="toSolid">Jednolite</button>
|
||||
<button @click="toGradient">Gradient</button>
|
||||
<MyFillEditor :fill="fill" @change="update" />
|
||||
</template>
|
||||
</FillPickerRoot>
|
||||
```
|
||||
|
||||
## Powiązane API
|
||||
|
||||
- [GradientEditorRoot](./gradient-editor-root)
|
||||
|
|
@ -35,7 +35,6 @@ description: Dokumentacja komponentów bezstanowych prymitywów Vue w @open-penc
|
|||
<SdkCardGroup>
|
||||
<SdkCard title="ColorPickerRoot" to="/programmable/sdk/api/components/color-picker-root" description="Prymityw selektora kolorów oparty na popover." />
|
||||
<SdkCard title="ColorInputRoot" to="/programmable/sdk/api/components/color-input-root" description="Bezstanowy pomocnik pola wejściowego koloru." />
|
||||
<SdkCard title="FillPickerRoot" to="/programmable/sdk/api/components/fill-picker-root" description="Prymityw selektora wypełnień oparty na popover." />
|
||||
<SdkCard title="FontPickerRoot" to="/programmable/sdk/api/components/font-picker-root" description="Przeszukiwalny prymityw selektora czcionek." />
|
||||
<SdkCard title="GradientEditorRoot" to="/programmable/sdk/api/components/gradient-editor-root" description="Prymityw korzenia do edycji gradientów." />
|
||||
<SdkCard title="GradientEditorBar" to="/programmable/sdk/api/components/gradient-editor-bar" description="Przeciągany prymityw paska gradientu." />
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ These APIs are public, but they are more specialized than the main component and
|
|||
|
||||
- [useColorVariableBinding](./use-color-variable-binding)
|
||||
- [useColorBindingProvider](./use-color-binding-provider)
|
||||
- [useFillPicker](./use-fill-picker)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
- [useFontPicker](./use-font-picker)
|
||||
- [useOkHCL](./use-okhcl)
|
||||
|
|
|
|||
|
|
@ -22,4 +22,4 @@ const strokeBinding = useColorVariableBinding('strokes')
|
|||
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useStrokeControls](../composables/use-stroke-controls)
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [FillRoot](../components/fill-root)
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
---
|
||||
title: useFillPicker
|
||||
description: Low-level fill-category and conversion helper.
|
||||
---
|
||||
|
||||
# useFillPicker
|
||||
|
||||
::: warning Deprecated
|
||||
Use `useFill()` or the [FillRoot](../components/fill-root) primitive. `useFillPicker()` remains as a
|
||||
migration wrapper until the picker cleanup slice.
|
||||
:::
|
||||
|
||||
`useFillPicker(fill, onUpdate)` returns legacy fill category state plus conversion helpers for
|
||||
switching between solid, gradient, and image fills.
|
||||
|
||||
## Related APIs
|
||||
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
---
|
||||
title: FillPickerRoot
|
||||
description: Headless popover-based fill picker primitive.
|
||||
---
|
||||
|
||||
# FillPickerRoot
|
||||
|
||||
::: warning Deprecated
|
||||
Compose [FillRoot](./fill-root), [FillSwatch](./fill-swatch), and your application's popover instead.
|
||||
`FillPickerRoot` remains temporarily available for migration compatibility.
|
||||
:::
|
||||
|
||||
`FillPickerRoot` is the legacy popover-based fill picker for solid, gradient, and image fills.
|
||||
|
||||
## Props
|
||||
|
||||
<SdkPropsTable
|
||||
:rows="[
|
||||
{ name: 'fill', type: 'Fill', description: 'Current fill value.', required: true },
|
||||
{ name: 'contentClass', type: 'string | undefined', description: 'Optional class for the popover content.' },
|
||||
{ name: 'swatchClass', type: 'string | undefined', description: 'Optional class for the default trigger button.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Events
|
||||
|
||||
<SdkEventsTable
|
||||
:rows="[
|
||||
{ name: 'update', payload: 'fill: Fill', description: 'Emitted when the fill changes.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Slots
|
||||
|
||||
<SdkSlotsTable
|
||||
:rows="[
|
||||
{ name: 'trigger', props: 'swatch style', description: 'Custom trigger with swatch background style.' },
|
||||
{ name: 'default', props: 'fill state + conversion helpers', description: 'Main fill editor content.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
### Trigger slot props
|
||||
|
||||
```ts
|
||||
{
|
||||
style: Record<string, string>
|
||||
}
|
||||
```
|
||||
|
||||
### Default slot props
|
||||
|
||||
```ts
|
||||
{
|
||||
fill: Fill
|
||||
category: 'SOLID' | 'GRADIENT' | 'IMAGE'
|
||||
toSolid: () => void
|
||||
toGradient: () => void
|
||||
toImage: () => void
|
||||
update: (fill: Fill) => void
|
||||
}
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```vue
|
||||
<FillPickerRoot :fill="fill" @update="fill = $event">
|
||||
<template #default="{ fill, category, toSolid, toGradient, update }">
|
||||
<div>{{ category }}</div>
|
||||
<button @click="toSolid">Solid</button>
|
||||
<button @click="toGradient">Gradient</button>
|
||||
<MyFillEditor :fill="fill" @change="update" />
|
||||
</template>
|
||||
</FillPickerRoot>
|
||||
```
|
||||
|
||||
## Related APIs
|
||||
|
||||
- [GradientEditorRoot](./gradient-editor-root)
|
||||
|
|
@ -40,7 +40,6 @@ description: Component reference for headless Vue primitives in @open-pencil/vue
|
|||
<SdkCard title="ChannelSlider" to="/programmable/sdk/api/components/channel-slider" description="Accessible scalar slider for OkHCL channels." />
|
||||
<SdkCard title="FillRoot" to="/programmable/sdk/api/components/fill-root" description="Fill category state and conversion actions." />
|
||||
<SdkCard title="FillSwatch" to="/programmable/sdk/api/components/fill-swatch" description="Binding-aware semantic fill preview." />
|
||||
<SdkCard title="FillPickerRoot" to="/programmable/sdk/api/components/fill-picker-root" description="Deprecated popover-based fill picker compatibility primitive." />
|
||||
<SdkCard title="FontPickerRoot" to="/programmable/sdk/api/components/font-picker-root" description="Searchable font picker primitive." />
|
||||
<SdkCard title="GradientEditorRoot" to="/programmable/sdk/api/components/gradient-editor-root" description="Root primitive for gradient editing." />
|
||||
<SdkCard title="GradientEditorBar" to="/programmable/sdk/api/components/gradient-editor-bar" description="Draggable gradient bar primitive." />
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ description: Низкоуровневые и специализированны
|
|||
## Пикеры, переменные, локаль и внутренние части редактора
|
||||
|
||||
- [useColorVariableBinding](./use-color-variable-binding)
|
||||
- [useFillPicker](./use-fill-picker)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
- [useFontPicker](./use-font-picker)
|
||||
- [useOkHCL](./use-okhcl)
|
||||
|
|
|
|||
|
|
@ -22,4 +22,4 @@ const strokeBinding = useColorVariableBinding('strokes')
|
|||
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useStrokeControls](../composables/use-stroke-controls)
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [FillRoot](/programmable/sdk/api/components/fill-root)
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
title: useFillPicker
|
||||
description: Низкоуровневый хелпер категорий заливки и конверсии.
|
||||
---
|
||||
|
||||
# useFillPicker
|
||||
|
||||
`useFillPicker(fill, onUpdate)` возвращает производное состояние категории заливки и хелперы конверсии для переключения между сплошными, градиентными и графическими заливками.
|
||||
|
||||
Используйте его при создании кастомных пикеров заливки за пределами `FillPickerRoot`.
|
||||
|
||||
## Связанные API
|
||||
|
||||
- [FillPickerRoot](../components/fill-picker-root)
|
||||
- [useFillControls](../composables/use-fill-controls)
|
||||
- [useGradientStops](./use-gradient-stops)
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
---
|
||||
title: FillPickerRoot
|
||||
description: Headless-примитив пикера заливки с поповером.
|
||||
---
|
||||
|
||||
# FillPickerRoot
|
||||
|
||||
`FillPickerRoot` — headless-примитив пикера заливки на основе поповера для сплошных, градиентных и графических заливок.
|
||||
|
||||
## Props
|
||||
|
||||
<SdkPropsTable
|
||||
:rows="[
|
||||
{ name: 'fill', type: 'Fill', description: 'Текущее значение заливки.', required: true },
|
||||
{ name: 'contentClass', type: 'string | undefined', description: 'Опциональный класс для содержимого поповера.' },
|
||||
{ name: 'swatchClass', type: 'string | undefined', description: 'Опциональный класс для кнопки триггера по умолчанию.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Events
|
||||
|
||||
<SdkEventsTable
|
||||
:rows="[
|
||||
{ name: 'update', payload: 'fill: Fill', description: 'Генерируется при изменении заливки.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
## Slots
|
||||
|
||||
<SdkSlotsTable
|
||||
:rows="[
|
||||
{ name: 'trigger', props: 'swatch style', description: 'Кастомный триггер со стилем фона свотча.' },
|
||||
{ name: 'default', props: 'fill state + conversion helpers', description: 'Основное содержимое редактора заливки.' }
|
||||
]"
|
||||
/>
|
||||
|
||||
### Пропы слота trigger
|
||||
|
||||
```ts
|
||||
{
|
||||
style: Record<string, string>
|
||||
}
|
||||
```
|
||||
|
||||
### Пропы слота default
|
||||
|
||||
```ts
|
||||
{
|
||||
fill: Fill
|
||||
category: 'SOLID' | 'GRADIENT' | 'IMAGE'
|
||||
toSolid: () => void
|
||||
toGradient: () => void
|
||||
toImage: () => void
|
||||
update: (fill: Fill) => void
|
||||
}
|
||||
```
|
||||
|
||||
## Пример
|
||||
|
||||
```vue
|
||||
<FillPickerRoot :fill="fill" @update="fill = $event">
|
||||
<template #default="{ fill, category, toSolid, toGradient, update }">
|
||||
<div>{{ category }}</div>
|
||||
<button @click="toSolid">Сплошная</button>
|
||||
<button @click="toGradient">Градиент</button>
|
||||
<MyFillEditor :fill="fill" @change="update" />
|
||||
</template>
|
||||
</FillPickerRoot>
|
||||
```
|
||||
|
||||
## Связанные API
|
||||
|
||||
- [GradientEditorRoot](./gradient-editor-root)
|
||||
|
|
@ -35,7 +35,6 @@ description: Справочник компонентов — headless-прими
|
|||
<SdkCardGroup>
|
||||
<SdkCard title="ColorPickerRoot" to="/programmable/sdk/api/components/color-picker-root" description="Headless-примитив пикера цвета с поповером." />
|
||||
<SdkCard title="ColorInputRoot" to="/programmable/sdk/api/components/color-input-root" description="Headless-хелпер для ввода цвета." />
|
||||
<SdkCard title="FillPickerRoot" to="/programmable/sdk/api/components/fill-picker-root" description="Headless-примитив пикера заливки с поповером." />
|
||||
<SdkCard title="FontPickerRoot" to="/programmable/sdk/api/components/font-picker-root" description="Headless-примитив пикера шрифта с поиском." />
|
||||
<SdkCard title="GradientEditorRoot" to="/programmable/sdk/api/components/gradient-editor-root" description="Корневой примитив редактора градиента." />
|
||||
<SdkCard title="GradientEditorBar" to="/programmable/sdk/api/components/gradient-editor-bar" description="Перетаскиваемый примитив полосы градиента." />
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@ Main structural primitives include:
|
|||
- `SegmentedControlRoot`
|
||||
- `ToolbarRoot`
|
||||
- `ColorPickerRoot`
|
||||
- `FillPickerRoot`
|
||||
- `FontPickerRoot`
|
||||
- `NumberFieldRoot` / `NumberFieldInput` / `NumberFieldValue`
|
||||
- `BindableValueRoot` / `BindableValueTrigger` / `BindableValuePicker`
|
||||
|
|
@ -185,7 +184,6 @@ These exports are intentionally public, but they are lower-level or more special
|
|||
- `useBindingProvider()`
|
||||
- `useNumberBindingProvider()`
|
||||
- `useFill()`
|
||||
- `useFillPicker()` (deprecated migration wrapper)
|
||||
- `useGradientStops()`
|
||||
- `useFontPicker()`
|
||||
- `useOkHCL()`
|
||||
|
|
|
|||
|
|
@ -83,6 +83,10 @@
|
|||
"multiplayerCursors": "Cursor anderer Teilnehmer",
|
||||
"direction": "Richtung",
|
||||
"flow": "Fluss",
|
||||
"layoutHorizontal": "Horizontales Layout",
|
||||
"layoutVertical": "Vertikales Layout",
|
||||
"layoutGrid": "Rasterlayout",
|
||||
"layoutWrap": "Layout umbrechen",
|
||||
"auto": "Automatisch",
|
||||
"columns": "Spalten",
|
||||
"rows": "Zeilen",
|
||||
|
|
|
|||
|
|
@ -96,6 +96,10 @@
|
|||
"multiplayerCursors": "Cursores de otros participantes",
|
||||
"direction": "Dirección",
|
||||
"flow": "Flujo",
|
||||
"layoutHorizontal": "Diseño horizontal",
|
||||
"layoutVertical": "Diseño vertical",
|
||||
"layoutGrid": "Diseño de cuadrícula",
|
||||
"layoutWrap": "Ajustar diseño",
|
||||
"auto": "Auto",
|
||||
"columns": "Columnas",
|
||||
"rows": "Filas",
|
||||
|
|
|
|||
|
|
@ -83,6 +83,10 @@
|
|||
"multiplayerCursors": "Curseurs des participants",
|
||||
"direction": "Direction",
|
||||
"flow": "Flux",
|
||||
"layoutHorizontal": "Disposition horizontale",
|
||||
"layoutVertical": "Disposition verticale",
|
||||
"layoutGrid": "Disposition en grille",
|
||||
"layoutWrap": "Retour à la ligne",
|
||||
"auto": "Auto",
|
||||
"columns": "Colonnes",
|
||||
"rows": "Lignes",
|
||||
|
|
|
|||
|
|
@ -83,6 +83,10 @@
|
|||
"multiplayerCursors": "Cursori degli altri partecipanti",
|
||||
"direction": "Direzione",
|
||||
"flow": "Flusso",
|
||||
"layoutHorizontal": "Layout orizzontale",
|
||||
"layoutVertical": "Layout verticale",
|
||||
"layoutGrid": "Layout a griglia",
|
||||
"layoutWrap": "Layout a capo",
|
||||
"auto": "Auto",
|
||||
"columns": "Colonne",
|
||||
"rows": "Righe",
|
||||
|
|
|
|||
|
|
@ -96,6 +96,10 @@
|
|||
"multiplayerCursors": "他の参加者のカーソル",
|
||||
"direction": "方向",
|
||||
"flow": "フロー",
|
||||
"layoutHorizontal": "横方向レイアウト",
|
||||
"layoutVertical": "縦方向レイアウト",
|
||||
"layoutGrid": "グリッドレイアウト",
|
||||
"layoutWrap": "折り返しレイアウト",
|
||||
"auto": "自動",
|
||||
"columns": "列",
|
||||
"rows": "行",
|
||||
|
|
|
|||
|
|
@ -83,6 +83,10 @@
|
|||
"multiplayerCursors": "Kursory innych uczestników",
|
||||
"direction": "Kierunek",
|
||||
"flow": "Przepływ",
|
||||
"layoutHorizontal": "Układ poziomy",
|
||||
"layoutVertical": "Układ pionowy",
|
||||
"layoutGrid": "Układ siatki",
|
||||
"layoutWrap": "Zawijanie układu",
|
||||
"auto": "Auto",
|
||||
"columns": "Kolumny",
|
||||
"rows": "Wiersze",
|
||||
|
|
|
|||
|
|
@ -83,6 +83,10 @@
|
|||
"multiplayerCursors": "Курсоры участников",
|
||||
"direction": "Направление",
|
||||
"flow": "Поток",
|
||||
"layoutHorizontal": "Горизонтальная раскладка",
|
||||
"layoutVertical": "Вертикальная раскладка",
|
||||
"layoutGrid": "Сетка",
|
||||
"layoutWrap": "Перенос элементов",
|
||||
"auto": "Авто",
|
||||
"columns": "Столбцы",
|
||||
"rows": "Строки",
|
||||
|
|
|
|||
|
|
@ -83,6 +83,10 @@
|
|||
"multiplayerCursors": "协作光标",
|
||||
"direction": "方向",
|
||||
"flow": "流向",
|
||||
"layoutHorizontal": "水平布局",
|
||||
"layoutVertical": "垂直布局",
|
||||
"layoutGrid": "网格布局",
|
||||
"layoutWrap": "自动换行",
|
||||
"auto": "自动",
|
||||
"columns": "列",
|
||||
"rows": "行",
|
||||
|
|
|
|||
|
|
@ -171,6 +171,10 @@ export const panelMessageDefaults = {
|
|||
multiplayerCursors: 'Multiplayer cursors',
|
||||
direction: 'Direction',
|
||||
flow: 'Flow',
|
||||
layoutHorizontal: 'Horizontal layout',
|
||||
layoutVertical: 'Vertical layout',
|
||||
layoutGrid: 'Grid layout',
|
||||
layoutWrap: 'Wrap layout',
|
||||
gapAuto: 'Auto gap',
|
||||
horizontalGap: 'Horizontal gap',
|
||||
verticalGap: 'Vertical gap',
|
||||
|
|
|
|||
|
|
@ -114,7 +114,6 @@ export { useVariablesDialogState } from '#vue/variables/dialog/use'
|
|||
export { useVariablesEditor } from '#vue/variables/editor/use'
|
||||
export { useVariablesTable } from '#vue/variables/table/use'
|
||||
export { usePageList } from '#vue/primitives/PageList/usePageList'
|
||||
export { useFillPicker } from '#vue/primitives/FillPicker/useFillPicker'
|
||||
export {
|
||||
fillCategory,
|
||||
fillIsTransparent,
|
||||
|
|
@ -149,7 +148,6 @@ export type {
|
|||
FillSwatchSlotProps,
|
||||
FillSwatchSlots
|
||||
} from '#vue/primitives/Fill'
|
||||
export { FillPickerRoot } from '#vue/primitives/FillPicker'
|
||||
export { FontPickerRoot } from '#vue/primitives/FontPicker'
|
||||
export type { FontFamilyOption, FontPickerUI } from '#vue/primitives/FontPicker'
|
||||
export {
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger } from 'reka-ui'
|
||||
|
||||
import { useFillPicker } from '#vue/primitives/FillPicker/useFillPicker'
|
||||
|
||||
import type { Fill } from '@open-pencil/scene-graph'
|
||||
|
||||
export interface FillPickerUI {
|
||||
content?: string
|
||||
swatch?: string
|
||||
}
|
||||
|
||||
const { fill, ui } = defineProps<{
|
||||
fill: Fill
|
||||
ui?: FillPickerUI
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{ update: [fill: Fill] }>()
|
||||
|
||||
const { category, swatchBg, toSolid, toGradient, toImage } = useFillPicker(
|
||||
computed(() => fill),
|
||||
(updated) => emit('update', updated)
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PopoverRoot>
|
||||
<PopoverTrigger as-child>
|
||||
<slot name="trigger" :style="{ background: swatchBg }">
|
||||
<button :class="ui?.swatch" :style="{ background: swatchBg }" />
|
||||
</slot>
|
||||
</PopoverTrigger>
|
||||
|
||||
<PopoverPortal>
|
||||
<PopoverContent :class="ui?.content" :side-offset="4" side="left">
|
||||
<slot
|
||||
:fill="fill"
|
||||
:category="category"
|
||||
:to-solid="toSolid"
|
||||
:to-gradient="toGradient"
|
||||
:to-image="toImage"
|
||||
/>
|
||||
</PopoverContent>
|
||||
</PopoverPortal>
|
||||
</PopoverRoot>
|
||||
</template>
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
/** @deprecated Compose `FillRoot`, `FillSwatch`, and a popover in the consumer. */
|
||||
export { default as FillPickerRoot } from '#vue/primitives/FillPicker/FillPickerRoot.vue'
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
import type { Ref } from 'vue'
|
||||
|
||||
import type { Fill } from '@open-pencil/scene-graph'
|
||||
|
||||
import { useFill } from '#vue/primitives/Fill/useFill'
|
||||
|
||||
/** @deprecated Use `useFill()` and compose popover behavior in the consumer. */
|
||||
export function useFillPicker(fill: Ref<Fill>, onUpdate: (fill: Fill) => void) {
|
||||
const model = useFill(fill, onUpdate)
|
||||
return {
|
||||
category: model.category,
|
||||
swatchBg: model.swatchBackground,
|
||||
toSolid: model.toSolid,
|
||||
toGradient: model.toGradient,
|
||||
toImage: model.toImage
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +1,27 @@
|
|||
<script setup lang="ts">
|
||||
import IconButton from '@/components/ui/IconButton.vue'
|
||||
import PanelRow from '@/components/ui/panel/PanelRow.vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useI18n, useLayoutControlsContext } from '@open-pencil/vue'
|
||||
|
||||
import IconButton from '@/components/ui/IconButton.vue'
|
||||
|
||||
import type { LayoutMode } from '@open-pencil/scene-graph'
|
||||
|
||||
const ctx = useLayoutControlsContext()
|
||||
|
||||
const { panels } = useI18n()
|
||||
|
||||
const layoutModes: { mode: LayoutMode; test: string }[] = [
|
||||
{ mode: 'HORIZONTAL', test: 'horizontal' },
|
||||
{ mode: 'VERTICAL', test: 'vertical' },
|
||||
{ mode: 'GRID', test: 'grid' }
|
||||
]
|
||||
const layoutModes = computed<Array<{ mode: LayoutMode; label: string }>>(() => [
|
||||
{ mode: 'HORIZONTAL', label: panels.value.layoutHorizontal },
|
||||
{ mode: 'VERTICAL', label: panels.value.layoutVertical },
|
||||
{ mode: 'GRID', label: panels.value.layoutGrid }
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PanelRow>
|
||||
<div class="flex items-center gap-panel">
|
||||
<IconButton
|
||||
v-if="ctx.node.layoutMode === 'NONE'"
|
||||
:label="panels.addAutoLayout"
|
||||
data-test-id="layout-add-auto"
|
||||
@click="ctx.editor.setLayoutMode(ctx.node.id, 'VERTICAL')"
|
||||
>
|
||||
<icon-lucide-plus class="size-3.5" />
|
||||
|
|
@ -29,34 +29,38 @@ const layoutModes: { mode: LayoutMode; test: string }[] = [
|
|||
<IconButton
|
||||
v-else
|
||||
:label="panels.removeAutoLayout"
|
||||
data-test-id="layout-remove-auto"
|
||||
@click="ctx.editor.setLayoutMode(ctx.node.id, 'NONE')"
|
||||
>
|
||||
<icon-lucide-minus class="size-3.5" />
|
||||
</IconButton>
|
||||
</PanelRow>
|
||||
</div>
|
||||
|
||||
<PanelRow v-if="ctx.node.layoutMode !== 'NONE'" class="mt-1.5" gap="sm">
|
||||
<div
|
||||
v-if="ctx.node.layoutMode !== 'NONE'"
|
||||
class="mt-1.5 flex items-center gap-1"
|
||||
role="toolbar"
|
||||
:aria-label="panels.flow"
|
||||
>
|
||||
<IconButton
|
||||
v-for="dir in layoutModes"
|
||||
:key="dir.mode"
|
||||
v-for="direction in layoutModes"
|
||||
:key="direction.mode"
|
||||
:label="direction.label"
|
||||
size="md"
|
||||
:active="dir.mode === 'GRID' ? ctx.isGrid : ctx.node.layoutMode === dir.mode"
|
||||
:data-test-id="`layout-direction-${dir.test}`"
|
||||
@click="ctx.editor.setLayoutMode(ctx.node.id, dir.mode)"
|
||||
:active="direction.mode === 'GRID' ? ctx.isGrid : ctx.node.layoutMode === direction.mode"
|
||||
@click="ctx.editor.setLayoutMode(ctx.node.id, direction.mode)"
|
||||
>
|
||||
<icon-lucide-arrow-right v-if="dir.mode === 'HORIZONTAL'" class="size-3.5" />
|
||||
<icon-lucide-arrow-down v-else-if="dir.mode === 'VERTICAL'" class="size-3.5" />
|
||||
<icon-lucide-arrow-right v-if="direction.mode === 'HORIZONTAL'" class="size-3.5" />
|
||||
<icon-lucide-arrow-down v-else-if="direction.mode === 'VERTICAL'" class="size-3.5" />
|
||||
<icon-lucide-layout-grid v-else class="size-3.5" />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
v-if="ctx.isFlex"
|
||||
:label="panels.layoutWrap"
|
||||
size="md"
|
||||
:active="ctx.node.layoutWrap === 'WRAP'"
|
||||
data-test-id="layout-direction-wrap"
|
||||
@click="ctx.updateProp('layoutWrap', ctx.node.layoutWrap === 'WRAP' ? 'NO_WRAP' : 'WRAP')"
|
||||
>
|
||||
<icon-lucide-wrap-text class="size-3.5" />
|
||||
</IconButton>
|
||||
</PanelRow>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { VNode } from 'vue'
|
||||
import type { ClassValue } from 'tailwind-variants'
|
||||
|
||||
import type { PanelRowTheme } from '@/theme/panel/row'
|
||||
|
||||
export interface PanelRowProps {
|
||||
cols?: keyof PanelRowTheme['variants']['columns']
|
||||
gap?: keyof PanelRowTheme['variants']['gap']
|
||||
class?: ClassValue
|
||||
}
|
||||
|
||||
export interface PanelRowSlots {
|
||||
default(): VNode[]
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { tv } from 'tailwind-variants'
|
||||
|
||||
import theme from '@/theme/panel/row'
|
||||
|
||||
/** @deprecated Prefer PanelGrid for new property-panel layouts. */
|
||||
const { cols = 'auto', gap = 'md', class: className } = defineProps<PanelRowProps>()
|
||||
defineSlots<PanelRowSlots>()
|
||||
const panelRow = tv(theme)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="panelRow({ columns: cols, gap, class: className })">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -3,5 +3,4 @@ export { default as PanelGrid } from './PanelGrid.vue'
|
|||
export { default as PanelHeader } from './PanelHeader.vue'
|
||||
export { default as PanelItemRow } from './PanelItemRow.vue'
|
||||
export { default as PanelRail } from './PanelRail.vue'
|
||||
export { default as PanelRow } from './PanelRow.vue'
|
||||
export { default as PanelSection } from './PanelSection.vue'
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
const panelRowTheme = {
|
||||
base: 'flex items-center',
|
||||
variants: {
|
||||
columns: {
|
||||
auto: '',
|
||||
two: '[&>*]:min-w-0 [&>*]:flex-1',
|
||||
fill: '[&>*:first-child]:min-w-0 [&>*:first-child]:flex-1'
|
||||
},
|
||||
gap: {
|
||||
sm: 'gap-0.5',
|
||||
md: 'gap-panel'
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
columns: 'auto' as const,
|
||||
gap: 'md' as const
|
||||
}
|
||||
}
|
||||
|
||||
export type PanelRowTheme = typeof panelRowTheme
|
||||
export default panelRowTheme
|
||||
|
|
@ -54,14 +54,27 @@ test('Shift+A wraps selection in auto-layout frame', async () => {
|
|||
canvas.assertNoErrors()
|
||||
})
|
||||
|
||||
test('direction button toggles to VERTICAL', async () => {
|
||||
test('direction controls switch between vertical grid and horizontal layout', async () => {
|
||||
await selectFrame()
|
||||
const layout = propertySection(page, 'Auto layout')
|
||||
|
||||
await page.getByTestId('layout-direction-vertical').click()
|
||||
await layout.getByRole('button', { name: 'Vertical layout' }).click()
|
||||
await canvas.waitForRender()
|
||||
expect(expectDefined(await getNodeById(page, frameId), 'frame').layoutMode).toBe('VERTICAL')
|
||||
|
||||
const frame = await getNodeById(page, frameId)
|
||||
expect(expectDefined(frame, 'frame').layoutMode).toBe('VERTICAL')
|
||||
await layout.getByRole('button', { name: 'Grid layout' }).click()
|
||||
await canvas.waitForRender()
|
||||
expect(expectDefined(await getNodeById(page, frameId), 'frame').layoutMode).toBe('GRID')
|
||||
|
||||
await layout.getByRole('button', { name: 'Horizontal layout' }).click()
|
||||
await canvas.waitForRender()
|
||||
expect(expectDefined(await getNodeById(page, frameId), 'frame').layoutMode).toBe('HORIZONTAL')
|
||||
|
||||
await layout.getByRole('button', { name: 'Vertical layout' }).click()
|
||||
await propertyField(page, 'width').getByRole('combobox', { name: 'Width' }).click()
|
||||
await page.getByRole('option', { name: 'Hug' }).click()
|
||||
await canvas.waitForRender()
|
||||
expect(expectDefined(await getNodeById(page, frameId), 'frame').layoutMode).toBe('VERTICAL')
|
||||
canvas.assertNoErrors()
|
||||
})
|
||||
|
||||
|
|
@ -102,7 +115,7 @@ test('gap menu sets auto space-between alignment', async () => {
|
|||
test('wrap mode exposes cross-axis gap control', async () => {
|
||||
await selectFrame()
|
||||
|
||||
await page.getByTestId('layout-direction-wrap').click()
|
||||
await propertySection(page, 'Auto layout').getByRole('button', { name: 'Wrap layout' }).click()
|
||||
await canvas.waitForRender()
|
||||
|
||||
const before = await getNodeById(page, frameId)
|
||||
|
|
@ -253,7 +266,9 @@ test('alignment grid center sets CENTER alignment', async () => {
|
|||
test('remove auto-layout sets layoutMode to NONE', async () => {
|
||||
await selectFrame()
|
||||
|
||||
await page.getByTestId('layout-remove-auto').click()
|
||||
await propertySection(page, 'Auto layout')
|
||||
.getByRole('button', { name: 'Remove auto layout' })
|
||||
.click()
|
||||
await canvas.waitForRender()
|
||||
|
||||
const frame = await getNodeById(page, frameId)
|
||||
|
|
|
|||
Loading…
Reference in a new issue