Use a container as the DND placeholder and use approx size when dragging into grids
This commit is contained in:
parent
803b11d65f
commit
0c2e286ca7
|
@ -446,12 +446,7 @@ export const getFrontendStore = () => {
|
||||||
_id: Helpers.uuid(),
|
_id: Helpers.uuid(),
|
||||||
_component: definition.component,
|
_component: definition.component,
|
||||||
_styles: {
|
_styles: {
|
||||||
normal: {
|
normal: {},
|
||||||
"grid-column-start": 1,
|
|
||||||
"grid-column-end": 2,
|
|
||||||
"grid-row-start": 1,
|
|
||||||
"grid-row-end": 2,
|
|
||||||
},
|
|
||||||
hover: {},
|
hover: {},
|
||||||
active: {},
|
active: {},
|
||||||
},
|
},
|
||||||
|
|
|
@ -87,10 +87,9 @@
|
||||||
"showSettingsBar": true,
|
"showSettingsBar": true,
|
||||||
"size": {
|
"size": {
|
||||||
"width": 400,
|
"width": 400,
|
||||||
"height": 100
|
"height": 200
|
||||||
},
|
},
|
||||||
"styles": [
|
"styles": [
|
||||||
"grid",
|
|
||||||
"padding",
|
"padding",
|
||||||
"size",
|
"size",
|
||||||
"background",
|
"background",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
export let isScreen = false
|
export let isScreen = false
|
||||||
export let isBlock = false
|
export let isBlock = false
|
||||||
export let parent = null
|
export let parent = null
|
||||||
|
export let parentType = null
|
||||||
|
|
||||||
// Get parent contexts
|
// Get parent contexts
|
||||||
const context = getContext("context")
|
const context = getContext("context")
|
||||||
|
@ -165,23 +166,35 @@
|
||||||
$: pad = pad || (interactive && hasChildren && inDndPath)
|
$: pad = pad || (interactive && hasChildren && inDndPath)
|
||||||
$: $dndIsDragging, (pad = false)
|
$: $dndIsDragging, (pad = false)
|
||||||
|
|
||||||
|
// We can apply additional styles automatically if required.
|
||||||
|
// One use case for this is ensuring grid children have proper styles to
|
||||||
|
// display properly inside a grid.
|
||||||
|
$: additionalStyles = getAdditionalStyles(
|
||||||
|
instance._styles?.normal || {},
|
||||||
|
parentType,
|
||||||
|
definition
|
||||||
|
)
|
||||||
|
|
||||||
|
// Compute overall styles
|
||||||
|
$: styles = {
|
||||||
|
...instance._styles,
|
||||||
|
normal: {
|
||||||
|
...instance._styles?.normal,
|
||||||
|
...additionalStyles,
|
||||||
|
},
|
||||||
|
custom: customCSS,
|
||||||
|
id,
|
||||||
|
empty: emptyState,
|
||||||
|
interactive,
|
||||||
|
draggable,
|
||||||
|
editable,
|
||||||
|
}
|
||||||
|
|
||||||
// Update component context
|
// Update component context
|
||||||
$: store.set({
|
$: store.set({
|
||||||
id,
|
id,
|
||||||
children: children.length,
|
children: children.length,
|
||||||
styles: {
|
styles,
|
||||||
...instance._styles,
|
|
||||||
normal: {
|
|
||||||
...instance._styles?.normal,
|
|
||||||
...(selected ? $builderStore.gridStyles : null),
|
|
||||||
},
|
|
||||||
custom: customCSS,
|
|
||||||
id,
|
|
||||||
empty: emptyState,
|
|
||||||
interactive,
|
|
||||||
draggable,
|
|
||||||
editable,
|
|
||||||
},
|
|
||||||
empty: emptyState,
|
empty: emptyState,
|
||||||
selected,
|
selected,
|
||||||
name,
|
name,
|
||||||
|
@ -442,6 +455,54 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getAdditionalStyles = (styles, parentType, definition) => {
|
||||||
|
let newStyles = {}
|
||||||
|
|
||||||
|
// Ensure grid styles are set
|
||||||
|
if (parentType?.endsWith("/grid")) {
|
||||||
|
newStyles = {
|
||||||
|
...newStyles,
|
||||||
|
overflow: "hidden",
|
||||||
|
width: "auto",
|
||||||
|
height: "auto",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guess rough grid size from definition size
|
||||||
|
let columns = 6
|
||||||
|
let rows = 4
|
||||||
|
if (definition.size?.width) {
|
||||||
|
columns = Math.round(definition.size.width / 100)
|
||||||
|
}
|
||||||
|
if (definition.size?.height) {
|
||||||
|
rows = Math.round(definition.size.height / 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure grid position styles are set
|
||||||
|
if (!styles["grid-column-start"]) {
|
||||||
|
newStyles["grid-column-start"] = 1
|
||||||
|
}
|
||||||
|
if (!styles["grid-column-end"]) {
|
||||||
|
newStyles["grid-column-end"] = columns + 1
|
||||||
|
}
|
||||||
|
if (!styles["grid-row-start"]) {
|
||||||
|
newStyles["grid-row-start"] = 1
|
||||||
|
}
|
||||||
|
if (!styles["grid-row-end"]) {
|
||||||
|
newStyles["grid-row-end"] = rows + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure grid end styles aren't before grid start styles
|
||||||
|
if (newStyles["grid-column-end"] <= newStyles["grid-column-start"]) {
|
||||||
|
newStyles["grid-column-end"] = newStyles["grid-column-start"] + 1
|
||||||
|
}
|
||||||
|
if (newStyles["grid-row-end"] <= newStyles["grid-row-start"]) {
|
||||||
|
newStyles["grid-row-end"] = newStyles["grid-row-start"] + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newStyles
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (
|
if (
|
||||||
$appStore.isDevApp &&
|
$appStore.isDevApp &&
|
||||||
|
@ -450,6 +511,7 @@
|
||||||
componentStore.actions.registerInstance(id, {
|
componentStore.actions.registerInstance(id, {
|
||||||
component: instance._component,
|
component: instance._component,
|
||||||
getSettings: () => cachedSettings,
|
getSettings: () => cachedSettings,
|
||||||
|
getStyles: () => styles,
|
||||||
getRawSettings: () => ({ ...staticSettings, ...dynamicSettings }),
|
getRawSettings: () => ({ ...staticSettings, ...dynamicSettings }),
|
||||||
getDataContext: () => get(context),
|
getDataContext: () => get(context),
|
||||||
reload: () => initialise(instance, true),
|
reload: () => initialise(instance, true),
|
||||||
|
@ -490,7 +552,11 @@
|
||||||
<ComponentPlaceholder />
|
<ComponentPlaceholder />
|
||||||
{:else if children.length}
|
{:else if children.length}
|
||||||
{#each children as child (child._id)}
|
{#each children as child (child._id)}
|
||||||
<svelte:self instance={child} parent={id} />
|
<svelte:self
|
||||||
|
instance={child}
|
||||||
|
parent={id}
|
||||||
|
parentType={instance._component}
|
||||||
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
{:else if emptyState}
|
{:else if emptyState}
|
||||||
{#if isScreen}
|
{#if isScreen}
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
<script>
|
|
||||||
import { dndBounds } from "stores"
|
|
||||||
import { DNDPlaceholderID } from "constants"
|
|
||||||
|
|
||||||
$: style = getStyle($dndBounds)
|
|
||||||
|
|
||||||
const getStyle = bounds => {
|
|
||||||
if (!bounds) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return `--height: ${bounds.height}px; --width: ${bounds.width}px;`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if style}
|
|
||||||
<div class="wrapper">
|
|
||||||
<div class="placeholder" id={DNDPlaceholderID} {style} />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.wrapper {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.placeholder {
|
|
||||||
display: block;
|
|
||||||
height: var(--height);
|
|
||||||
width: var(--width);
|
|
||||||
max-height: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -6,7 +6,8 @@
|
||||||
let left, top, height, width
|
let left, top, height, width
|
||||||
|
|
||||||
const updatePosition = () => {
|
const updatePosition = () => {
|
||||||
const node = document.getElementById(DNDPlaceholderID)
|
const node =
|
||||||
|
document.getElementsByClassName(DNDPlaceholderID)[0]?.childNodes[0]
|
||||||
if (!node) {
|
if (!node) {
|
||||||
height = 0
|
height = 0
|
||||||
width = 0
|
width = 0
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount, onDestroy } from "svelte"
|
import { onMount, onDestroy } from "svelte"
|
||||||
import { builderStore, screenStore } from "stores"
|
import { builderStore, componentStore, screenStore } from "stores"
|
||||||
import { Utils } from "@budibase/frontend-core"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
import { findComponentById } from "utils/components.js"
|
import { findComponentById } from "utils/components.js"
|
||||||
|
|
||||||
|
@ -157,16 +157,14 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const compDef = findComponentById(
|
const instance = componentStore.actions.getComponentInstance(dragInfo.id)
|
||||||
$screenStore.activeScreen.props,
|
if (!instance) {
|
||||||
dragInfo.id
|
|
||||||
)
|
|
||||||
if (!compDef) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const styles = instance.getStyles()
|
||||||
const domGrid = getDOMNode(dragInfo.gridId)
|
const domGrid = getDOMNode(dragInfo.gridId)
|
||||||
if (domGrid) {
|
if (domGrid) {
|
||||||
const getStyle = x => parseInt(compDef._styles.normal?.[x] || "0")
|
const getStyle = x => parseInt(styles?.normal?.[x] || "0")
|
||||||
dragInfo.grid = {
|
dragInfo.grid = {
|
||||||
startX: e.clientX,
|
startX: e.clientX,
|
||||||
startY: e.clientY,
|
startY: e.clientY,
|
||||||
|
|
|
@ -32,5 +32,4 @@ export const ActionTypes = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DNDPlaceholderID = "dnd-placeholder"
|
export const DNDPlaceholderID = "dnd-placeholder"
|
||||||
export const DNDPlaceholderType = "dnd-placeholder"
|
|
||||||
export const ScreenslotType = "screenslot"
|
export const ScreenslotType = "screenslot"
|
||||||
|
|
|
@ -5,9 +5,8 @@ import { devToolsStore } from "./devTools"
|
||||||
import { screenStore } from "./screens"
|
import { screenStore } from "./screens"
|
||||||
import { builderStore } from "./builder"
|
import { builderStore } from "./builder"
|
||||||
import Router from "../components/Router.svelte"
|
import Router from "../components/Router.svelte"
|
||||||
import DNDPlaceholder from "../components/preview/DNDPlaceholder.svelte"
|
|
||||||
import * as AppComponents from "../components/app/index.js"
|
import * as AppComponents from "../components/app/index.js"
|
||||||
import { DNDPlaceholderType, ScreenslotType } from "../constants.js"
|
import { ScreenslotType } from "../constants.js"
|
||||||
|
|
||||||
const budibasePrefix = "@budibase/standard-components/"
|
const budibasePrefix = "@budibase/standard-components/"
|
||||||
|
|
||||||
|
@ -103,8 +102,6 @@ const createComponentStore = () => {
|
||||||
// Screenslot is an edge case
|
// Screenslot is an edge case
|
||||||
if (type === ScreenslotType) {
|
if (type === ScreenslotType) {
|
||||||
type = `${budibasePrefix}${type}`
|
type = `${budibasePrefix}${type}`
|
||||||
} else if (type === DNDPlaceholderType) {
|
|
||||||
return {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle built-in components
|
// Handle built-in components
|
||||||
|
@ -124,8 +121,6 @@ const createComponentStore = () => {
|
||||||
}
|
}
|
||||||
if (type === ScreenslotType) {
|
if (type === ScreenslotType) {
|
||||||
return Router
|
return Router
|
||||||
} else if (type === DNDPlaceholderType) {
|
|
||||||
return DNDPlaceholder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle budibase components
|
// Handle budibase components
|
||||||
|
@ -140,6 +135,10 @@ const createComponentStore = () => {
|
||||||
return customComponentManifest?.[type]?.Component
|
return customComponentManifest?.[type]?.Component
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getComponentInstance = id => {
|
||||||
|
return get(store).mountedComponents[id]
|
||||||
|
}
|
||||||
|
|
||||||
const registerCustomComponent = ({ Component, schema, version }) => {
|
const registerCustomComponent = ({ Component, schema, version }) => {
|
||||||
if (!Component || !schema?.schema?.name || !version) {
|
if (!Component || !schema?.schema?.name || !version) {
|
||||||
return
|
return
|
||||||
|
@ -171,6 +170,7 @@ const createComponentStore = () => {
|
||||||
getComponentById,
|
getComponentById,
|
||||||
getComponentDefinition,
|
getComponentDefinition,
|
||||||
getComponentConstructor,
|
getComponentConstructor,
|
||||||
|
getComponentInstance,
|
||||||
registerCustomComponent,
|
registerCustomComponent,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@ import { derived } from "svelte/store"
|
||||||
import { routeStore } from "./routes"
|
import { routeStore } from "./routes"
|
||||||
import { builderStore } from "./builder"
|
import { builderStore } from "./builder"
|
||||||
import { appStore } from "./app"
|
import { appStore } from "./app"
|
||||||
import { dndIndex, dndParent, dndIsNewComponent } from "./dnd.js"
|
import { dndIndex, dndParent, dndIsNewComponent, dndBounds } from "./dnd.js"
|
||||||
import { RoleUtils } from "@budibase/frontend-core"
|
import { RoleUtils } from "@budibase/frontend-core"
|
||||||
import { findComponentById, findComponentParent } from "../utils/components.js"
|
import { findComponentById, findComponentParent } from "../utils/components.js"
|
||||||
import { Helpers } from "@budibase/bbui"
|
import { Helpers } from "@budibase/bbui"
|
||||||
import { DNDPlaceholderID, DNDPlaceholderType } from "constants"
|
import { DNDPlaceholderID } from "constants"
|
||||||
|
|
||||||
const createScreenStore = () => {
|
const createScreenStore = () => {
|
||||||
const store = derived(
|
const store = derived(
|
||||||
|
@ -17,6 +17,7 @@ const createScreenStore = () => {
|
||||||
dndParent,
|
dndParent,
|
||||||
dndIndex,
|
dndIndex,
|
||||||
dndIsNewComponent,
|
dndIsNewComponent,
|
||||||
|
dndBounds,
|
||||||
],
|
],
|
||||||
([
|
([
|
||||||
$appStore,
|
$appStore,
|
||||||
|
@ -25,6 +26,7 @@ const createScreenStore = () => {
|
||||||
$dndParent,
|
$dndParent,
|
||||||
$dndIndex,
|
$dndIndex,
|
||||||
$dndIsNewComponent,
|
$dndIsNewComponent,
|
||||||
|
$dndBounds,
|
||||||
]) => {
|
]) => {
|
||||||
let activeLayout, activeScreen
|
let activeLayout, activeScreen
|
||||||
let screens
|
let screens
|
||||||
|
@ -79,8 +81,15 @@ const createScreenStore = () => {
|
||||||
|
|
||||||
// Insert placeholder component
|
// Insert placeholder component
|
||||||
const placeholder = {
|
const placeholder = {
|
||||||
_component: DNDPlaceholderID,
|
_component: "@budibase/standard-components/container",
|
||||||
_id: DNDPlaceholderType,
|
_id: DNDPlaceholderID,
|
||||||
|
_styles: {
|
||||||
|
normal: {
|
||||||
|
width: `${$dndBounds?.width || 666}px`,
|
||||||
|
height: `${$dndBounds?.height || 666}px`,
|
||||||
|
opacity: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
static: true,
|
static: true,
|
||||||
}
|
}
|
||||||
let parent = findComponentById(activeScreen.props, $dndParent)
|
let parent = findComponentById(activeScreen.props, $dndParent)
|
||||||
|
|
Loading…
Reference in New Issue