From 99fc69f2d846ee3eff8800795ff98eaee42017cd Mon Sep 17 00:00:00 2001
From: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com>
Date: Sat, 2 Nov 2024 07:37:13 +0530
Subject: [PATCH] fix: UX enhancements (#240)
closes: https://github.com/frappe/builder/issues/229
---
frontend/src/App.vue | 5 +-
frontend/src/components/BlockEditor.vue | 67 ++++++----
frontend/src/components/BlockLayers.vue | 55 ++++++--
frontend/src/components/BlockProperties.vue | 4 +-
frontend/src/components/BuilderBlock.vue | 7 ++
frontend/src/components/BuilderCanvas.vue | 119 +++++++++---------
frontend/src/components/MainMenu.vue | 12 +-
.../src/components/Settings/PageGeneral.vue | 2 +-
frontend/src/components/TextBlock.vue | 10 ++
frontend/src/data/webPage.ts | 1 +
frontend/src/pages/PageBuilderDashboard.vue | 31 ++---
frontend/src/store.ts | 37 +++++-
frontend/src/utils/block.ts | 6 +
13 files changed, 233 insertions(+), 123 deletions(-)
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index 6bb3e568..b1abe423 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -80,7 +80,10 @@ const isDark = useDark({
[id^="headlessui-menu-items"],
[id^="headlessui-combobox-options"] {
- @apply bg-surface-gray-1;
+ @apply bg-surface-white;
+ @apply dark:bg-surface-gray-1;
+ @apply text-text-icons-gray-7;
+
@apply overflow-y-auto;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none;
diff --git a/frontend/src/components/BlockEditor.vue b/frontend/src/components/BlockEditor.vue
index cb3699a9..5a59eacb 100644
--- a/frontend/src/components/BlockEditor.vue
+++ b/frontend/src/components/BlockEditor.vue
@@ -13,26 +13,14 @@
:class="getStyleClasses">
@@ -114,6 +93,41 @@ const guides = setGuides(props.target, canvasProps);
const moving = ref(false);
const preventCLick = ref(false);
+const showPaddingHandler = computed(() => {
+ return (
+ isBlockSelected.value &&
+ !resizing.value &&
+ !props.editable &&
+ !blockController.multipleBlocksSelected() &&
+ !props.block.isSVG() &&
+ !props.block.isText()
+ );
+});
+
+const showMarginHandler = computed(() => {
+ return (
+ isBlockSelected.value &&
+ !props.block.isRoot() &&
+ !resizing.value &&
+ !props.editable &&
+ !blockController.multipleBlocksSelected() &&
+ !props.block.isText()
+ );
+});
+
+const showBorderRadiusHandler = computed(() => {
+ return (
+ isBlockSelected &&
+ !props.block.isRoot() &&
+ !props.block.isText() &&
+ !props.block.isHTML() &&
+ !props.block.isSVG() &&
+ !props.editable &&
+ !resizing &&
+ !blockController.multipleBlocksSelected()
+ );
+});
+
watchEffect(() => {
props.block.getStyle("top");
props.block.getStyle("left");
@@ -189,6 +203,11 @@ const handleClick = (ev: MouseEvent) => {
preventCLick.value = false;
return;
}
+
+ if (props.block.isText() || props.block.isButton() || props.block.isLink()) {
+ store.editableBlock = props.block;
+ }
+
const editorWrapper = editor.value;
editorWrapper.classList.add("pointer-events-none");
let element = document.elementFromPoint(ev.x, ev.y) as HTMLElement;
diff --git a/frontend/src/components/BlockLayers.vue b/frontend/src/components/BlockLayers.vue
index c76f9347..6f4dec13 100644
--- a/frontend/src/components/BlockLayers.vue
+++ b/frontend/src/components/BlockLayers.vue
@@ -72,7 +72,7 @@
-
+
@@ -91,8 +91,15 @@ import BlockContextMenu from "./BlockContextMenu.vue";
import BlockLayers from "./BlockLayers.vue";
import BlocksIcon from "./Icons/Blocks.vue";
+type LayerInstance = InstanceType;
+
const store = useStore();
-const childLayer = ref | null>(null);
+const childLayers = ref([]);
+const childLayer = (el) => {
+ if (el) {
+ childLayers.value.push(el);
+ }
+};
const props = defineProps({
blocks: {
@@ -123,19 +130,39 @@ const isExpanded = (block: Block) => {
return expandedLayers.value.has(block.blockId);
};
+// TODO: Refactor this!
const toggleExpanded = (block: Block) => {
- const blockIndex = props.blocks.findIndex((b) => b.blockId === block.blockId);
- if (blockIndex === -1) {
- childLayer.value?.toggleExpanded(block);
+ if (block.isRoot()) {
return;
}
- if (isExpanded(block) && !block.isRoot()) {
+ if (!blockExits(block)) {
+ const child = childLayers.value.find((layer) => layer.blockExitsInTree(block)) as LayerInstance;
+ if (child) {
+ child.toggleExpanded(block);
+ }
+ }
+ if (isExpanded(block)) {
expandedLayers.value.delete(block.blockId);
} else {
expandedLayers.value.add(block.blockId);
}
};
+// @ts-ignore
+const isExpandedInTree = (block: Block) => {
+ if (!blockExits(block)) {
+ const child = childLayers.value.find((layer) => layer.blockExitsInTree(block)) as LayerInstance;
+ if (child) {
+ return child.isExpandedInTree(block);
+ }
+ }
+ return isExpanded(block);
+};
+
+const blockExits = (block: Block) => {
+ return props.blocks.find((b) => b.blockId === block.blockId);
+};
+
const canShowChildLayer = (block: Block) => {
return (
((isExpanded(block) && block.hasChildren()) || (block.canHaveChildren() && !block.hasChildren())) &&
@@ -161,15 +188,29 @@ watch(
},
);
+// @ts-ignore
const updateParent = (event) => {
event.item.__draggable_context.element.parentBlock = store.activeCanvas?.findBlock(
event.to.closest("[data-block-layer-id]").dataset.blockLayerId,
);
};
+const blockExitsInTree = (block: Block) => {
+ if (blockExits(block)) {
+ return true;
+ }
+ for (const layer of childLayers.value) {
+ if (layer.blockExitsInTree(block)) {
+ return true;
+ }
+ }
+ return false;
+};
+
defineExpose({
- isExpanded,
toggleExpanded,
+ isExpandedInTree,
+ blockExitsInTree,
});