diff --git a/packages/client/src/components/ClientApp.svelte b/packages/client/src/components/ClientApp.svelte
index 7144105fd8..144b5a8dec 100644
--- a/packages/client/src/components/ClientApp.svelte
+++ b/packages/client/src/components/ClientApp.svelte
@@ -44,7 +44,7 @@
import MaintenanceScreen from "components/MaintenanceScreen.svelte"
import SnippetsProvider from "./context/SnippetsProvider.svelte"
import EmbedProvider from "./context/EmbedProvider.svelte"
- import GridNewComponentDNDHandler from "components/preview/GridNewComponentDNDHandler.svelte"
+ import DNDSelectionIndicators from "./preview/DNDSelectionIndicators.svelte"
// Provide contexts
setContext("sdk", SDK)
@@ -267,7 +267,7 @@
{#if $builderStore.inBuilder}
-
+
{/if}
diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte
index 3e22ffada1..67f8fdc63c 100644
--- a/packages/client/src/components/Component.svelte
+++ b/packages/client/src/components/Component.svelte
@@ -120,7 +120,7 @@
$: children = instance._children || []
$: id = instance._id
$: name = isRoot ? "Screen" : instance._instanceName
- $: icon = definition?.icon
+ $: icon = instance._icon || definition?.icon
// Determine if the component is selected or is part of the critical path
// leading to the selected component
diff --git a/packages/client/src/components/preview/DNDHandler.svelte b/packages/client/src/components/preview/DNDHandler.svelte
index f62f21e94c..82db06a623 100644
--- a/packages/client/src/components/preview/DNDHandler.svelte
+++ b/packages/client/src/components/preview/DNDHandler.svelte
@@ -7,10 +7,10 @@
screenStore,
dndStore,
dndParent,
+ dndSource,
dndIsDragging,
isGridScreen,
} from "stores"
- import DNDPlaceholderOverlay from "./DNDPlaceholderOverlay.svelte"
import { Utils } from "@budibase/frontend-core"
import { findComponentById } from "@/utils/components.js"
import { isGridEvent } from "@/utils/grid"
@@ -92,6 +92,8 @@
bounds: component.children[0].getBoundingClientRect(),
parent: parentId,
index,
+ name: component.dataset.name,
+ icon: component.dataset.icon,
})
builderStore.actions.selectComponent(id)
@@ -258,10 +260,10 @@
}
// Check if we're adding a new component rather than moving one
- if (source.newComponentType) {
+ if (source.isNew) {
dropping = true
builderStore.actions.dropNewComponent(
- source.newComponentType,
+ source.type,
drop.parent,
drop.index,
$dndStore.meta.newComponentProps
@@ -335,16 +337,3 @@
document.removeEventListener("drop", onDrop, false)
})
-
-{#if !$isGridScreen}
-
-{/if}
-
-{#if $dndIsDragging}
-
-{/if}
diff --git a/packages/client/src/components/preview/DNDPlaceholderOverlay.svelte b/packages/client/src/components/preview/DNDPlaceholderOverlay.svelte
index 5593fa010d..f06454acce 100644
--- a/packages/client/src/components/preview/DNDPlaceholderOverlay.svelte
+++ b/packages/client/src/components/preview/DNDPlaceholderOverlay.svelte
@@ -1,96 +1,108 @@
-
+
+
+
+
+
+
+
-{#if left != null && top != null && width && height && !waitingForGrid}
-
-{/if}
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/client/src/components/preview/DNDSelectionIndicators.svelte b/packages/client/src/components/preview/DNDSelectionIndicators.svelte
new file mode 100644
index 0000000000..9949f07ace
--- /dev/null
+++ b/packages/client/src/components/preview/DNDSelectionIndicators.svelte
@@ -0,0 +1,27 @@
+
+
+{#if !$isGridScreen}
+
+{/if}
+
+{#if $dndIsDragging}
+
+{/if}
diff --git a/packages/client/src/components/preview/GridDNDHandler.svelte b/packages/client/src/components/preview/GridDNDHandler.svelte
index 569a9879a6..58ba92ab07 100644
--- a/packages/client/src/components/preview/GridDNDHandler.svelte
+++ b/packages/client/src/components/preview/GridDNDHandler.svelte
@@ -4,8 +4,8 @@
builderStore,
componentStore,
dndIsDragging,
- dndIsNewComponent,
dndStore,
+ dndSource,
isGridScreen,
} from "stores"
import { Utils, memo } from "@budibase/frontend-core"
@@ -53,7 +53,7 @@
// If dragging a new component on to a grid screen, tick to allow the
// real component to render in the new position before updating the DND
// store, preventing the green DND overlay from being out of position
- if ($dndIsNewComponent && styles) {
+ if ($dndSource?.isNew && styles) {
dndStore.actions.updateNewComponentProps({
_styles: {
normal: styles,
@@ -222,7 +222,7 @@
const onDragOver = e => {
if (!dragInfo) {
// Check if we're dragging a new component
- if ($dndIsDragging && $dndIsNewComponent && $isGridScreen) {
+ if ($dndIsDragging && $dndSource?.isNew && $isGridScreen) {
startDraggingPlaceholder()
}
return
diff --git a/packages/client/src/components/preview/Indicator.svelte b/packages/client/src/components/preview/Indicator.svelte
index dce7945b29..94940285ff 100644
--- a/packages/client/src/components/preview/Indicator.svelte
+++ b/packages/client/src/components/preview/Indicator.svelte
@@ -14,6 +14,8 @@
export let line = false
export let alignRight = false
export let showResizeAnchors = false
+ export let background = null
+ export let animate = false
const AnchorSides = [
"right",
@@ -33,10 +35,12 @@
class="indicator"
class:flipped
class:line
- style="top: {top}px; left: {left}px; width: {width}px; height: {height}px; --color: {color}; --zIndex: {zIndex};"
+ style="top: {top}px; left: {left}px; width: {width}px; height: {height}px; --color: {color}; --zIndex: {zIndex}; --bg: {background ||
+ 'none'};"
class:withText={!!text}
class:vCompact={height < 40}
class:hCompact={width < 40}
+ class:animate
>
{#if text || icon}
{
mutationObserver.observe(element, {
attributes: true,
- attributeFilter: ["style"],
})
observingMutations = true
}
@@ -108,17 +111,19 @@
}
// Check if we're inside a grid
- if (allowResizeAnchors) {
- nextState.insideGrid = elements[0]?.dataset.insideGrid === "true"
- }
+ nextState.insideGrid = elements[0]?.dataset.insideGrid === "true"
- // Get text to display
- nextState.text = elements[0].dataset.name
- if (nextState.prefix) {
- nextState.text = `${nextState.prefix} ${nextState.text}`
+ // Get text and icon to display
+ if (!text) {
+ nextState.text = elements[0].dataset.name
+ if (nextState.prefix) {
+ nextState.text = `${nextState.prefix} ${nextState.text}`
+ }
}
- if (elements[0].dataset.icon) {
- nextState.icon = elements[0].dataset.icon
+ if (!icon) {
+ if (elements[0].dataset.icon) {
+ nextState.icon = elements[0].dataset.icon
+ }
}
nextState.error = elements[0].classList.contains("error")
@@ -205,5 +210,7 @@
color={state.error ? errorColor : state.color}
componentId={state.componentId}
zIndex={state.zIndex}
+ {background}
+ {animate}
/>
{/each}
diff --git a/packages/client/src/stores/dnd.js b/packages/client/src/stores/dnd.js
index 38c1e8aab8..f6b8fec48c 100644
--- a/packages/client/src/stores/dnd.js
+++ b/packages/client/src/stores/dnd.js
@@ -21,10 +21,17 @@ const createDndStore = () => {
}
const store = writable(initialState)
- const startDraggingExistingComponent = ({ id, parent, bounds, index }) => {
+ const startDraggingExistingComponent = ({
+ id,
+ parent,
+ bounds,
+ index,
+ name,
+ icon,
+ }) => {
store.set({
...initialState,
- source: { id, parent, bounds, index },
+ source: { id, parent, bounds, index, name, icon, isNew: false },
})
}
@@ -62,7 +69,10 @@ const createDndStore = () => {
parent: null,
bounds: { height, width },
index: null,
- newComponentType: component,
+ type: component,
+ isNew: true,
+ name: `New ${definition.name}`,
+ icon: definition.icon,
},
target,
drop,
@@ -118,9 +128,5 @@ export const dndStore = createDndStore()
// or components which depend on DND state unless values actually change.
export const dndParent = derivedMemo(dndStore, x => x.drop?.parent)
export const dndIndex = derivedMemo(dndStore, x => x.drop?.index)
-export const dndBounds = derivedMemo(dndStore, x => x.source?.bounds)
+export const dndSource = derivedMemo(dndStore, x => x.source)
export const dndIsDragging = derivedMemo(dndStore, x => !!x.source)
-export const dndIsNewComponent = derivedMemo(
- dndStore,
- x => x.source?.newComponentType != null
-)
diff --git a/packages/client/src/stores/index.js b/packages/client/src/stores/index.js
index 268b0cc4bf..522fadc643 100644
--- a/packages/client/src/stores/index.js
+++ b/packages/client/src/stores/index.js
@@ -18,14 +18,7 @@ export { environmentStore } from "./environment"
export { eventStore } from "./events"
export { orgStore } from "./org"
export { roleStore } from "./roles"
-export {
- dndStore,
- dndIndex,
- dndParent,
- dndBounds,
- dndIsNewComponent,
- dndIsDragging,
-} from "./dnd"
+export { dndStore, dndIndex, dndParent, dndIsDragging, dndSource } from "./dnd"
export { sidePanelStore } from "./sidePanel"
export { modalStore } from "./modal"
export { hoverStore } from "./hover"
diff --git a/packages/client/src/stores/screens.js b/packages/client/src/stores/screens.js
index 99b943fbd2..df0dc0e365 100644
--- a/packages/client/src/stores/screens.js
+++ b/packages/client/src/stores/screens.js
@@ -3,7 +3,7 @@ import { routeStore } from "./routes"
import { builderStore } from "./builder"
import { appStore } from "./app"
import { orgStore } from "./org"
-import { dndIndex, dndParent, dndIsNewComponent, dndBounds } from "./dnd.js"
+import { dndIndex, dndParent, dndSource } from "./dnd.js"
import { RoleUtils } from "@budibase/frontend-core"
import { findComponentById, findComponentParent } from "../utils/components.js"
import { Helpers } from "@budibase/bbui"
@@ -18,8 +18,7 @@ const createScreenStore = () => {
orgStore,
dndParent,
dndIndex,
- dndIsNewComponent,
- dndBounds,
+ dndSource,
],
([
$appStore,
@@ -28,8 +27,7 @@ const createScreenStore = () => {
$orgStore,
$dndParent,
$dndIndex,
- $dndIsNewComponent,
- $dndBounds,
+ $dndSource,
]) => {
let activeLayout, activeScreen
let screens
@@ -85,7 +83,7 @@ const createScreenStore = () => {
// Remove selected component from tree if we are moving an existing
// component
- if (!$dndIsNewComponent && selectedParent) {
+ if (!$dndSource.isNew && selectedParent) {
selectedParent._children = selectedParent._children?.filter(
x => x._id !== selectedComponentId
)
@@ -97,11 +95,11 @@ const createScreenStore = () => {
_id: DNDPlaceholderID,
_styles: {
normal: {
- width: `${$dndBounds?.width || 400}px`,
- height: `${$dndBounds?.height || 200}px`,
+ width: `${$dndSource?.bounds?.width || 400}px`,
+ height: `${$dndSource?.bounds?.height || 200}px`,
opacity: 0,
- "--default-width": $dndBounds?.width || 400,
- "--default-height": $dndBounds?.height || 200,
+ "--default-width": $dndSource?.bounds?.width || 400,
+ "--default-height": $dndSource?.bounds?.height || 200,
},
},
static: true,