-
-
- commitProp('x', v, p)" />
- commitProp('y', v, p)" />
-
-
-
-
-
diff --git a/src/components/properties/AppearanceSection.vue b/src/components/properties/AppearanceSection.vue
new file mode 100644
index 000000000..91b34d680
--- /dev/null
+++ b/src/components/properties/AppearanceSection.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+ commitProp('opacity', v / 100, p / 100)"
+ />
+
+
+
diff --git a/src/components/properties/FillSection.vue b/src/components/properties/FillSection.vue
new file mode 100644
index 000000000..3a2d24d90
--- /dev/null
+++ b/src/components/properties/FillSection.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ colorHex(fill.color) }}
+
+
+
+
diff --git a/src/components/properties/LayoutSection.vue b/src/components/properties/LayoutSection.vue
new file mode 100644
index 000000000..0b4c109ab
--- /dev/null
+++ b/src/components/properties/LayoutSection.vue
@@ -0,0 +1,256 @@
+
+
+
+
+
+
+
+
+
commitProp('width', v, p)" />
+
+
+
+
+
+
+
+
+
+
commitProp('height', v, p)" />
+
+
+
+
+
+
+
+
+
+
+ commitProp('cornerRadius', v, p)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
commitProp('itemSpacing', v, p)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/properties/PositionSection.vue b/src/components/properties/PositionSection.vue
new file mode 100644
index 000000000..233cb8740
--- /dev/null
+++ b/src/components/properties/PositionSection.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ commitProp('x', v, p)" />
+ commitProp('y', v, p)" />
+
+
+ commitProp('rotation', v, p)" />
+
+
+
diff --git a/src/components/properties/StrokeSection.vue b/src/components/properties/StrokeSection.vue
new file mode 100644
index 000000000..85408ec19
--- /dev/null
+++ b/src/components/properties/StrokeSection.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+ {{ colorHex(stroke.color) }}
+
+
+
+
+
diff --git a/src/components/properties/TypographySection.vue b/src/components/properties/TypographySection.vue
new file mode 100644
index 000000000..7ec27e53b
--- /dev/null
+++ b/src/components/properties/TypographySection.vue
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No fonts found
+
+
+
+
+
+
+
+
+ commitProp('fontSize', v, p)"
+ />
+
+
+
+
+ commitProp('lineHeight', v, p)"
+ >
+
+
+
+
+ commitProp('letterSpacing', v, p)"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/composables/use-node-props.ts b/src/composables/use-node-props.ts
new file mode 100644
index 000000000..c38602d3f
--- /dev/null
+++ b/src/composables/use-node-props.ts
@@ -0,0 +1,33 @@
+import { useEditorStore } from '../stores/editor'
+
+import type { SceneNode } from '../engine/scene-graph'
+
+export function useNodeProps() {
+ const store = useEditorStore()
+
+ function updateProp(key: string, value: number | string) {
+ if (store.selectedNodes.value.length > 1) {
+ for (const n of store.selectedNodes.value) {
+ store.updateNode(n.id, { [key]: value })
+ }
+ } else {
+ const node = store.selectedNode.value
+ if (node) store.updateNode(node.id, { [key]: value })
+ }
+ }
+
+ function commitProp(key: string, _value: number | string, previous: number | string) {
+ if (store.selectedNodes.value.length > 1) {
+ for (const n of store.selectedNodes.value) {
+ store.commitNodeUpdate(n.id, { [key]: previous } as Partial
, `Change ${key}`)
+ }
+ } else {
+ const node = store.selectedNode.value
+ if (node) {
+ store.commitNodeUpdate(node.id, { [key]: previous } as Partial, `Change ${key}`)
+ }
+ }
+ }
+
+ return { store, updateProp, commitProp }
+}