Improve new component DND for grids and add mobile support
This commit is contained in:
parent
5e98580b60
commit
6f8e669107
|
@ -189,12 +189,6 @@
|
||||||
// Scroll the selected element into view
|
// Scroll the selected element into view
|
||||||
$: selected && scrollIntoView()
|
$: selected && scrollIntoView()
|
||||||
|
|
||||||
// When dragging and dropping, pad components to allow dropping between
|
|
||||||
// nested layers. Only reset this when dragging stops.
|
|
||||||
let pad = false
|
|
||||||
$: pad = pad || (interactive && hasChildren && inDndPath)
|
|
||||||
$: $dndIsDragging, (pad = false)
|
|
||||||
|
|
||||||
// Themes
|
// Themes
|
||||||
$: currentTheme = $context?.device?.theme
|
$: currentTheme = $context?.device?.theme
|
||||||
$: darkMode = !currentTheme?.includes("light")
|
$: darkMode = !currentTheme?.includes("light")
|
||||||
|
@ -206,8 +200,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metadata to pass into grid action to apply CSS
|
// Metadata to pass into grid action to apply CSS
|
||||||
const insideGrid =
|
const checkGrid = x =>
|
||||||
parent?._component.endsWith("/container") && parent?.layout === "grid"
|
x?._component.endsWith("/container") && x?.layout === "grid"
|
||||||
|
$: insideGrid = checkGrid(parent)
|
||||||
|
$: isGrid = checkGrid(instance)
|
||||||
$: gridMetadata = {
|
$: gridMetadata = {
|
||||||
insideGrid,
|
insideGrid,
|
||||||
ignoresLayout: definition?.ignoresLayout === true,
|
ignoresLayout: definition?.ignoresLayout === true,
|
||||||
|
@ -219,6 +215,12 @@
|
||||||
errored: errorState,
|
errored: errorState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When dragging and dropping, pad components to allow dropping between
|
||||||
|
// nested layers. Only reset this when dragging stops.
|
||||||
|
let pad = false
|
||||||
|
$: pad = pad || (!isGrid && interactive && hasChildren && inDndPath)
|
||||||
|
$: $dndIsDragging, (pad = false)
|
||||||
|
|
||||||
// Update component context
|
// Update component context
|
||||||
$: store.set({
|
$: store.set({
|
||||||
id,
|
id,
|
||||||
|
|
|
@ -6,8 +6,11 @@
|
||||||
let left, top, height, width
|
let left, top, height, width
|
||||||
|
|
||||||
const updatePosition = () => {
|
const updatePosition = () => {
|
||||||
const node =
|
let node = document.getElementsByClassName(DNDPlaceholderID)[0]
|
||||||
document.getElementsByClassName(DNDPlaceholderID)[0]?.childNodes[0]
|
const insideGrid = node?.dataset.insideGrid === "true"
|
||||||
|
if (!insideGrid) {
|
||||||
|
node = document.getElementsByClassName(`${DNDPlaceholderID}-dom`)[0]
|
||||||
|
}
|
||||||
if (!node) {
|
if (!node) {
|
||||||
height = 0
|
height = 0
|
||||||
width = 0
|
width = 0
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { writable } from "svelte/store"
|
import { writable } from "svelte/store"
|
||||||
import { computed } from "../utils/computed.js"
|
import { derivedMemo } from "@budibase/frontend-core"
|
||||||
|
|
||||||
const createDndStore = () => {
|
const createDndStore = () => {
|
||||||
const initialState = {
|
const initialState = {
|
||||||
|
@ -78,11 +78,11 @@ export const dndStore = createDndStore()
|
||||||
// performance by deriving any state that needs to be externally observed.
|
// performance by deriving any state that needs to be externally observed.
|
||||||
// By doing this and using primitives, we can avoid invalidating other stores
|
// By doing this and using primitives, we can avoid invalidating other stores
|
||||||
// or components which depend on DND state unless values actually change.
|
// or components which depend on DND state unless values actually change.
|
||||||
export const dndParent = computed(dndStore, x => x.drop?.parent)
|
export const dndParent = derivedMemo(dndStore, x => x.drop?.parent)
|
||||||
export const dndIndex = computed(dndStore, x => x.drop?.index)
|
export const dndIndex = derivedMemo(dndStore, x => x.drop?.index)
|
||||||
export const dndBounds = computed(dndStore, x => x.source?.bounds)
|
export const dndBounds = derivedMemo(dndStore, x => x.source?.bounds)
|
||||||
export const dndIsDragging = computed(dndStore, x => !!x.source)
|
export const dndIsDragging = derivedMemo(dndStore, x => !!x.source)
|
||||||
export const dndIsNewComponent = computed(
|
export const dndIsNewComponent = derivedMemo(
|
||||||
dndStore,
|
dndStore,
|
||||||
x => x.source?.newComponentType != null
|
x => x.source?.newComponentType != null
|
||||||
)
|
)
|
||||||
|
|
|
@ -92,6 +92,8 @@ const createScreenStore = () => {
|
||||||
width: `${$dndBounds?.width || 400}px`,
|
width: `${$dndBounds?.width || 400}px`,
|
||||||
height: `${$dndBounds?.height || 200}px`,
|
height: `${$dndBounds?.height || 200}px`,
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
|
"--default-width": $dndBounds?.width || 400,
|
||||||
|
"--default-height": $dndBounds?.height || 200,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
static: true,
|
static: true,
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
import { writable } from "svelte/store"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extension of Svelte's built in "derived" stores, which the addition of deep
|
|
||||||
* comparison of non-primitives. Falls back to using shallow comparison for
|
|
||||||
* primitive types to avoid performance penalties.
|
|
||||||
* Useful for instances where a deep comparison is cheaper than an additional
|
|
||||||
* store invalidation.
|
|
||||||
* @param store the store to observer
|
|
||||||
* @param deriveValue the derivation function
|
|
||||||
* @returns {Writable<*>} a derived svelte store containing just the derived value
|
|
||||||
*/
|
|
||||||
export const computed = (store, deriveValue) => {
|
|
||||||
const initialValue = deriveValue(store)
|
|
||||||
const computedStore = writable(initialValue)
|
|
||||||
let lastKey = getKey(initialValue)
|
|
||||||
|
|
||||||
store.subscribe(state => {
|
|
||||||
const value = deriveValue(state)
|
|
||||||
const key = getKey(value)
|
|
||||||
if (key !== lastKey) {
|
|
||||||
lastKey = key
|
|
||||||
computedStore.set(value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return computedStore
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to serialise any value into a primitive which can be cheaply
|
|
||||||
// and shallowly compared
|
|
||||||
const getKey = value => {
|
|
||||||
if (value == null || typeof value !== "object") {
|
|
||||||
return value
|
|
||||||
} else {
|
|
||||||
return JSON.stringify(value)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -92,8 +92,12 @@ export const gridLayout = (node, metadata) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine default width and height of component
|
// Determine default width and height of component
|
||||||
let width = errored ? 500 : definition?.size?.width || 200
|
let width = styles["--default-width"] ?? definition?.size?.width ?? 200
|
||||||
let height = errored ? 60 : definition?.size?.height || 200
|
let height = styles["--default-height"] ?? definition?.size?.height ?? 200
|
||||||
|
if (errored) {
|
||||||
|
width = 500
|
||||||
|
height = 60
|
||||||
|
}
|
||||||
width += 2 * GridSpacing
|
width += 2 * GridSpacing
|
||||||
height += 2 * GridSpacing
|
height += 2 * GridSpacing
|
||||||
let vars = {
|
let vars = {
|
||||||
|
|
Loading…
Reference in New Issue