diff --git a/packages/vue/src/controls/number-variable-binding/use.ts b/packages/vue/src/controls/number-variable-binding/use.ts
index 366caeb7b..b1228b676 100644
--- a/packages/vue/src/controls/number-variable-binding/use.ts
+++ b/packages/vue/src/controls/number-variable-binding/use.ts
@@ -6,7 +6,26 @@ import type { VariableCollection } from '@open-pencil/core/scene-graph'
const FALLBACK_NUMBER_VARIABLE_NAME = 'New number'
-type NumberBindingPath = 'width' | 'height'
+export type NumberBindingPath =
+ | 'width'
+ | 'height'
+ | 'minWidth'
+ | 'maxWidth'
+ | 'minHeight'
+ | 'maxHeight'
+ | 'cornerRadius'
+ | 'topLeftRadius'
+ | 'topRightRadius'
+ | 'bottomLeftRadius'
+ | 'bottomRightRadius'
+ | 'itemSpacing'
+ | 'counterAxisSpacing'
+ | 'paddingTop'
+ | 'paddingRight'
+ | 'paddingBottom'
+ | 'paddingLeft'
+ | 'opacity'
+ | 'fontSize'
export function useNumberVariableBinding(path: NumberBindingPath) {
const binding = useVariableBinding({
diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts
index 9f63ddf73..24cb89719 100644
--- a/packages/vue/src/index.ts
+++ b/packages/vue/src/index.ts
@@ -56,6 +56,7 @@ export type { ExportFormatId } from '#vue/document/export/use'
export { useFillControls } from '#vue/controls/fill/use'
export { useColorVariableBinding } from '#vue/controls/color-variable-binding/use'
export { useNumberVariableBinding } from '#vue/controls/number-variable-binding/use'
+export type { NumberBindingPath } from '#vue/controls/number-variable-binding/use'
export { useVariableBinding } from '#vue/controls/variable-binding/use'
export type {
VariableBindingState,
diff --git a/src/components/properties/AppearanceSection.vue b/src/components/properties/AppearanceSection.vue
index df3bd796b..04ba6d02b 100644
--- a/src/components/properties/AppearanceSection.vue
+++ b/src/components/properties/AppearanceSection.vue
@@ -4,6 +4,7 @@ import { computed, ref } from 'vue'
import { useAppearance, useI18n } from '@open-pencil/vue'
import ScrubInput from '@/components/ScrubInput.vue'
+import VariableScrubInput from '@/components/properties/VariableScrubInput.vue'
import Tip from '@/components/ui/Tip.vue'
import { useSectionUI } from '@/components/ui/section'
@@ -65,7 +66,23 @@ function onToggleCorners() {
+
commitProp('opacity', v / 100, p / 100)"
+ >
+
+
+
+
+ commitProp('cornerRadius', v, p)"
+ >
+
+
+
+
- commitCornerProp('topLeftRadius', v, p)"
>
@@ -139,11 +172,13 @@ function onToggleCorners() {
-
-
+ commitCornerProp('topRightRadius', v, p)"
>
@@ -158,11 +193,13 @@ function onToggleCorners() {
-
-
+ commitCornerProp('bottomLeftRadius', v, p)"
>
@@ -177,11 +214,13 @@ function onToggleCorners() {
-
-
+ commitCornerProp('bottomRightRadius', v, p)"
>
@@ -196,7 +235,7 @@ function onToggleCorners() {
-
+
diff --git a/src/components/properties/LayoutSection/FlexControls.vue b/src/components/properties/LayoutSection/FlexControls.vue
index 5442f38b4..72aadf705 100644
--- a/src/components/properties/LayoutSection/FlexControls.vue
+++ b/src/components/properties/LayoutSection/FlexControls.vue
@@ -13,6 +13,7 @@ import {
import AppSelect from '@/components/ui/AppSelect.vue'
import ScrubInput from '@/components/ScrubInput.vue'
+import VariableScrubInput from '@/components/properties/VariableScrubInput.vue'
import ClipContentControl from '@/components/properties/LayoutSection/ClipContentControl.vue'
import PaddingControls from '@/components/properties/LayoutSection/PaddingControls.vue'
import { useSelectUI } from '@/components/ui/select'
@@ -57,12 +58,14 @@ function isAlignmentActive(primary: LayoutAlign, counter: string) {
- ctx.commitProp('itemSpacing', v, p)"
>
@@ -73,13 +76,15 @@ function isAlignmentActive(primary: LayoutAlign, counter: string) {
/>
-
-
+ ctx.commitProp('counterAxisSpacing', v, p)"
>
@@ -90,7 +95,7 @@ function isAlignmentActive(primary: LayoutAlign, counter: string) {
/>
-
+
-import ScrubInput from '@/components/ScrubInput.vue'
+import VariableScrubInput from '@/components/properties/VariableScrubInput.vue'
import { useLayoutControlsContext } from '@open-pencil/vue'
import type { PaddingProp } from '@/components/properties/LayoutSection/types'
@@ -19,36 +19,42 @@ const paddingSides: Array<{ prop: PaddingProp; icon: string }> = [
v-if="!ctx.showIndividualPadding && ctx.hasSymmetricPadding"
class="mt-1.5 grid grid-cols-2 gap-1.5"
>
-
-
-
+
-
+
- ctx.commitProp(side.prop, v, p)"
>
@@ -58,6 +64,6 @@ const paddingSides: Array<{ prop: PaddingProp; icon: string }> = [
-
+
diff --git a/src/components/properties/TypographySection.vue b/src/components/properties/TypographySection.vue
index d3bc1b6dc..257b87d0b 100644
--- a/src/components/properties/TypographySection.vue
+++ b/src/components/properties/TypographySection.vue
@@ -5,6 +5,7 @@ import { TypographyControlsRoot, useI18n } from '@open-pencil/vue'
import FontPicker from '@/components/FontPicker.vue'
import ScrubInput from '@/components/ScrubInput.vue'
+import VariableScrubInput from '@/components/properties/VariableScrubInput.vue'
import AppSelect from '@/components/ui/AppSelect.vue'
import Tip from '@/components/ui/Tip.vue'
import { useSectionUI } from '@/components/ui/section'
@@ -47,11 +48,13 @@ const sectionCls = useSectionUI()
:options="ctx.weights"
@update:model-value="ctx.setWeight(+$event)"
/>
-
ctx.commitProp('fontSize', v, p)"
/>
diff --git a/src/components/properties/VariableScrubInput.vue b/src/components/properties/VariableScrubInput.vue
new file mode 100644
index 000000000..022fb9799
--- /dev/null
+++ b/src/components/properties/VariableScrubInput.vue
@@ -0,0 +1,113 @@
+
+
+
+ emit('commit', v, p)"
+ >
+
+
+
+
+
+
+
+
+
+