diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js
index aaa0eb0184..061cd4c6b5 100644
--- a/packages/builder/src/builderStore/store/frontend.js
+++ b/packages/builder/src/builderStore/store/frontend.js
@@ -5,6 +5,7 @@ import {
selectedComponent,
screenHistoryStore,
automationHistoryStore,
+ store,
} from "builderStore"
import {
datasources,
@@ -85,7 +86,6 @@ const INITIAL_FRONTEND_STATE = {
selectedScreenId: null,
selectedComponentId: null,
selectedLayoutId: null,
- hoverComponentId: null,
// Client state
selectedComponentInstance: null,
@@ -93,6 +93,9 @@ const INITIAL_FRONTEND_STATE = {
// Onboarding
onboarding: false,
tourNodes: null,
+
+ // UI state
+ hoveredComponentId: null,
}
export const getFrontendStore = () => {
@@ -1414,6 +1417,18 @@ export const getFrontendStore = () => {
return state
})
},
+ hover: (componentId, notifyClient = true) => {
+ if (componentId === get(store).hoveredComponentId) {
+ return
+ }
+ store.update(state => {
+ state.hoveredComponentId = componentId
+ return state
+ })
+ if (notifyClient) {
+ store.actions.preview.sendEvent("hover-component", componentId)
+ }
+ },
},
links: {
save: async (url, title) => {
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
index 65ea172012..2127392bb9 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
@@ -36,14 +36,12 @@
// Determine selected component ID
$: selectedComponentId = $store.selectedComponentId
- $: hoverComponentId = $store.hoverComponentId
$: previewData = {
appId: $store.appId,
layout,
screen,
selectedComponentId,
- hoverComponentId,
theme: $store.theme,
customTheme: $store.customTheme,
previewDevice: $store.previewDevice,
@@ -119,8 +117,8 @@
error = event.error || "An unknown error occurred"
} else if (type === "select-component" && data.id) {
$store.selectedComponentId = data.id
- } else if (type === "hover-component" && data.id) {
- $store.hoverComponentId = data.id
+ } else if (type === "hover-component") {
+ store.actions.components.hover(data.id, false)
} else if (type === "update-prop") {
await store.actions.components.updateSetting(data.prop, data.value)
} else if (type === "update-styles") {
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/ComponentTree.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/ComponentTree.svelte
index 8d4d64e4be..315c0a331e 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/ComponentTree.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/ComponentTree.svelte
@@ -90,16 +90,7 @@
return findComponentPath($selectedComponent, component._id)?.length > 0
}
- const handleMouseover = componentId => {
- if ($store.hoverComponentId !== componentId) {
- $store.hoverComponentId = componentId
- }
- }
- const handleMouseout = componentId => {
- if ($store.hoverComponentId === componentId) {
- $store.hoverComponentId = null
- }
- }
+ const hover = store.actions.components.hover
@@ -120,9 +111,9 @@
on:dragover={dragover(component, index)}
on:iconClick={() => toggleNodeOpen(component._id)}
on:drop={onDrop}
- hovering={$store.hoverComponentId === component._id}
- on:mouseenter={() => handleMouseover(component._id)}
- on:mouseleave={() => handleMouseout(component._id)}
+ hovering={$store.hoveredComponentId === component._id}
+ on:mouseenter={() => hover(component._id)}
+ on:mouseleave={() => hover(null)}
text={getComponentText(component)}
icon={getComponentIcon(component)}
iconTooltip={getComponentName(component)}
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/index.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/index.svelte
index 1e2ea47e63..0f7e71255d 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/index.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/index.svelte
@@ -12,6 +12,9 @@
let scrolling = false
+ $: screenComponentId = `${$store.selectedScreenId}-screen`
+ $: navComponentId = `${$store.selectedScreenId}-navigation`
+
const toNewComponentRoute = () => {
if ($isActive(`./:componentId/new`)) {
$goto(`./:componentId`)
@@ -33,16 +36,7 @@
scrolling = e.target.scrollTop !== 0
}
- const handleMouseover = componentId => {
- if ($store.hoverComponentId !== componentId) {
- $store.hoverComponentId = componentId
- }
- }
- const handleMouseout = componentId => {
- if ($store.hoverComponentId === componentId) {
- $store.hoverComponentId = null
- }
- }
+ const hover = store.actions.components.hover
@@ -65,46 +59,31 @@
scrollable
icon="WebPage"
on:drop={onDrop}
- on:click={() => {
- $store.selectedComponentId = `${$store.selectedScreenId}-screen`
- }}
- hovering={$store.hoverComponentId ===
- `${$store.selectedScreenId}-screen`}
- on:mouseenter={() =>
- handleMouseover(`${$store.selectedScreenId}-screen`)}
- on:mouseleave={() =>
- handleMouseout(`${$store.selectedScreenId}-screen`)}
- id={`component-screen`}
- selectedBy={$userSelectedResourceMap[
- `${$store.selectedScreenId}-screen`
- ]}
+ on:click={() => ($store.selectedComponentId = screenComponentId)}
+ hovering={$store.hoveredComponentId === screenComponentId}
+ on:mouseenter={() => hover(`${$store.selectedScreenId}-screen`)}
+ on:mouseleave={() => hover(null)}
+ id="component-screen"
+ selectedBy={$userSelectedResourceMap[screenComponentId]}
>
{
- $store.selectedComponentId = `${$store.selectedScreenId}-navigation`
- }}
- hovering={$store.hoverComponentId ===
- `${$store.selectedScreenId}-navigation`}
- on:mouseenter={() =>
- handleMouseover(`${$store.selectedScreenId}-navigation`)}
- on:mouseleave={() =>
- handleMouseout(`${$store.selectedScreenId}-navigation`)}
- id={`component-nav`}
- selectedBy={$userSelectedResourceMap[
- `${$store.selectedScreenId}-navigation`
- ]}
+ on:click={() => ($store.selectedComponentId = navComponentId)}
+ hovering={$store.hoveredComponentId === navComponentId}
+ on:mouseenter={() => hover(navComponentId)}
+ on:mouseleave={() => hover(null)}
+ id="component-nav"
+ selectedBy={$userSelectedResourceMap[navComponentId]}
/>
import { onMount, onDestroy } from "svelte"
import IndicatorSet from "./IndicatorSet.svelte"
- import { builderStore, dndIsDragging } from "stores"
+ import { builderStore, dndIsDragging, hoverStore } from "stores"
- $: componentId = $builderStore.hoverComponentId
+ $: componentId = $hoverStore.hoveredComponentId
$: zIndex = componentId === $builderStore.selectedComponentId ? 900 : 920
const onMouseOver = e => {
@@ -23,12 +23,12 @@
}
if (newId !== componentId) {
- builderStore.actions.hoverComponent(newId)
+ hoverStore.actions.hoverComponent(newId)
}
}
const onMouseLeave = () => {
- builderStore.actions.hoverComponent(null)
+ hoverStore.actions.hoverComponent(null)
}
onMount(() => {
diff --git a/packages/client/src/index.js b/packages/client/src/index.js
index 044c900c9d..48cbfcb20d 100644
--- a/packages/client/src/index.js
+++ b/packages/client/src/index.js
@@ -7,6 +7,7 @@ import {
environmentStore,
dndStore,
eventStore,
+ hoverStore,
} from "./stores"
import loadSpectrumIcons from "@budibase/bbui/spectrum-icons-rollup.js"
import { get } from "svelte/store"
@@ -32,7 +33,6 @@ const loadBudibase = async () => {
layout: window["##BUDIBASE_PREVIEW_LAYOUT##"],
screen: window["##BUDIBASE_PREVIEW_SCREEN##"],
selectedComponentId: window["##BUDIBASE_SELECTED_COMPONENT_ID##"],
- hoverComponentId: window["##BUDIBASE_HOVER_COMPONENT_ID##"],
previewId: window["##BUDIBASE_PREVIEW_ID##"],
theme: window["##BUDIBASE_PREVIEW_THEME##"],
customTheme: window["##BUDIBASE_PREVIEW_CUSTOM_THEME##"],
@@ -76,6 +76,8 @@ const loadBudibase = async () => {
} else {
dndStore.actions.reset()
}
+ } else if (type === "hover-component") {
+ hoverStore.actions.hoverComponent(data)
}
}
diff --git a/packages/client/src/stores/builder.js b/packages/client/src/stores/builder.js
index f92e6b9df9..036558e8b2 100644
--- a/packages/client/src/stores/builder.js
+++ b/packages/client/src/stores/builder.js
@@ -8,7 +8,6 @@ const createBuilderStore = () => {
inBuilder: false,
screen: null,
selectedComponentId: null,
- hoverComponentId: null,
editMode: false,
previewId: null,
theme: null,
@@ -24,16 +23,6 @@ const createBuilderStore = () => {
}
const store = writable(initialState)
const actions = {
- hoverComponent: id => {
- if (id === get(store).hoverComponentId) {
- return
- }
- store.update(state => ({
- ...state,
- hoverComponentId: id,
- }))
- eventStore.actions.dispatchEvent("hover-component", { id })
- },
selectComponent: id => {
if (id === get(store).selectedComponentId) {
return
diff --git a/packages/client/src/stores/hover.js b/packages/client/src/stores/hover.js
new file mode 100644
index 0000000000..24f315a126
--- /dev/null
+++ b/packages/client/src/stores/hover.js
@@ -0,0 +1,25 @@
+import { get, writable } from "svelte/store"
+import { eventStore } from "./events.js"
+
+const createHoverStore = () => {
+ const store = writable({
+ hoveredComponentId: null,
+ })
+
+ const hoverComponent = id => {
+ if (id === get(store).hoveredComponentId) {
+ return
+ }
+ store.set({ hoveredComponentId: id })
+ eventStore.actions.dispatchEvent("hover-component", { id })
+ }
+
+ return {
+ ...store,
+ actions: {
+ hoverComponent,
+ },
+ }
+}
+
+export const hoverStore = createHoverStore()
diff --git a/packages/client/src/stores/index.js b/packages/client/src/stores/index.js
index 1b1b9d46bc..2149c72481 100644
--- a/packages/client/src/stores/index.js
+++ b/packages/client/src/stores/index.js
@@ -1,3 +1,5 @@
+import { writable } from "svelte/store"
+
export { authStore } from "./auth"
export { appStore } from "./app"
export { notificationStore } from "./notification"
@@ -27,6 +29,7 @@ export {
dndIsDragging,
} from "./dnd"
export { sidePanelStore } from "./sidePanel"
+export { hoverStore } from "./hover"
// Context stores are layered and duplicated, so it is not a singleton
export { createContextStore } from "./context"
diff --git a/packages/server/src/api/controllers/static/templates/preview.hbs b/packages/server/src/api/controllers/static/templates/preview.hbs
index e5b97afd66..63c61baa9f 100644
--- a/packages/server/src/api/controllers/static/templates/preview.hbs
+++ b/packages/server/src/api/controllers/static/templates/preview.hbs
@@ -63,7 +63,6 @@
// Extract data from message
const {
selectedComponentId,
- hoverComponentId,
layout,
screen,
appId,
@@ -82,7 +81,6 @@
window["##BUDIBASE_PREVIEW_LAYOUT##"] = layout
window["##BUDIBASE_PREVIEW_SCREEN##"] = screen
window["##BUDIBASE_SELECTED_COMPONENT_ID##"] = selectedComponentId
- window["##BUDIBASE_HOVER_COMPONENT_ID##"] = hoverComponentId
window["##BUDIBASE_PREVIEW_ID##"] = Math.random()
window["##BUDIBASE_PREVIEW_THEME##"] = theme
window["##BUDIBASE_PREVIEW_CUSTOM_THEME##"] = customTheme