Add global data bindings for mobile and tablet device sizes
This commit is contained in:
parent
ec83a77ce9
commit
47ca925003
|
@ -17,7 +17,13 @@ export const getBindableProperties = (asset, componentId) => {
|
|||
const contextBindings = getContextBindings(asset, componentId)
|
||||
const userBindings = getUserBindings()
|
||||
const urlBindings = getUrlBindings(asset)
|
||||
return [...contextBindings, ...userBindings, ...urlBindings]
|
||||
const deviceBindings = getDeviceBindings()
|
||||
return [
|
||||
...deviceBindings,
|
||||
...urlBindings,
|
||||
...contextBindings,
|
||||
...userBindings,
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,6 +227,27 @@ const getUserBindings = () => {
|
|||
return bindings
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all device bindings that are globally available.
|
||||
*/
|
||||
const getDeviceBindings = () => {
|
||||
let bindings = []
|
||||
if (get(store).clientFeatures?.deviceAwareness) {
|
||||
const safeDevice = makePropSafe("device")
|
||||
bindings.push({
|
||||
type: "context",
|
||||
runtimeBinding: `${safeDevice}.${makePropSafe("mobile")}`,
|
||||
readableBinding: `Device.Mobile`,
|
||||
})
|
||||
bindings.push({
|
||||
type: "context",
|
||||
runtimeBinding: `${safeDevice}.${makePropSafe("tablet")}`,
|
||||
readableBinding: `Device.Tablet`,
|
||||
})
|
||||
}
|
||||
return bindings
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all bindable properties from URL parameters.
|
||||
*/
|
||||
|
|
|
@ -35,6 +35,7 @@ const INITIAL_FRONTEND_STATE = {
|
|||
clientFeatures: {
|
||||
spectrumThemes: false,
|
||||
intelligentLoading: false,
|
||||
deviceAwareness: false,
|
||||
},
|
||||
currentFrontEndType: "none",
|
||||
selectedScreenId: "",
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
</section>
|
||||
{#if filteredColumns?.length}
|
||||
<section>
|
||||
<div class="heading">Columns</div>
|
||||
<div class="heading">Bindable Values</div>
|
||||
<ul>
|
||||
{#each filteredColumns as { readableBinding }}
|
||||
<li
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
import NotificationDisplay from "./NotificationDisplay.svelte"
|
||||
import ConfirmationDisplay from "./ConfirmationDisplay.svelte"
|
||||
import PeekScreenDisplay from "./PeekScreenDisplay.svelte"
|
||||
import Provider from "./Provider.svelte"
|
||||
import SDK from "../sdk"
|
||||
import {
|
||||
createContextStore,
|
||||
|
@ -16,12 +15,13 @@
|
|||
builderStore,
|
||||
appStore,
|
||||
} from "../store"
|
||||
import { TableNames, ActionTypes } from "../constants"
|
||||
import SettingsBar from "./preview/SettingsBar.svelte"
|
||||
import SelectionIndicator from "./preview/SelectionIndicator.svelte"
|
||||
import HoverIndicator from "./preview/HoverIndicator.svelte"
|
||||
import { Layout, Heading, Body } from "@budibase/bbui"
|
||||
import ErrorSVG from "../../../builder/assets/error.svg"
|
||||
import UserBindingsProvider from "./UserBindingsProvider.svelte"
|
||||
import DeviceBindingsProvider from "./DeviceBindingsProvider.svelte"
|
||||
|
||||
// Provide contexts
|
||||
setContext("sdk", SDK)
|
||||
|
@ -41,16 +41,6 @@
|
|||
}
|
||||
})
|
||||
|
||||
// Register this as a refreshable datasource so that user changes cause
|
||||
// the user object to be refreshed
|
||||
$: actions = [
|
||||
{
|
||||
type: ActionTypes.RefreshDatasource,
|
||||
callback: () => authStore.actions.fetchUser(),
|
||||
metadata: { dataSource: { type: "table", tableId: TableNames.USERS } },
|
||||
},
|
||||
]
|
||||
|
||||
// Handle no matching route - this is likely a permission error
|
||||
$: {
|
||||
if (dataLoaded && $routeStore.routerLoaded && !$routeStore.activeRoute) {
|
||||
|
@ -93,30 +83,32 @@
|
|||
</Layout>
|
||||
</div>
|
||||
{:else if $screenStore.activeLayout}
|
||||
<Provider key="user" data={$authStore} {actions}>
|
||||
<div id="app-root" class:preview={$builderStore.inBuilder}>
|
||||
{#key $screenStore.activeLayout._id}
|
||||
<Component instance={$screenStore.activeLayout.props} />
|
||||
<UserBindingsProvider>
|
||||
<DeviceBindingsProvider>
|
||||
<div id="app-root" class:preview={$builderStore.inBuilder}>
|
||||
{#key $screenStore.activeLayout._id}
|
||||
<Component instance={$screenStore.activeLayout.props} />
|
||||
{/key}
|
||||
</div>
|
||||
<NotificationDisplay />
|
||||
<ConfirmationDisplay />
|
||||
<PeekScreenDisplay />
|
||||
<!-- Key block needs to be outside the if statement or it breaks -->
|
||||
{#key $builderStore.selectedComponentId}
|
||||
{#if $builderStore.inBuilder}
|
||||
<SettingsBar />
|
||||
{/if}
|
||||
{/key}
|
||||
</div>
|
||||
<NotificationDisplay />
|
||||
<ConfirmationDisplay />
|
||||
<PeekScreenDisplay />
|
||||
<!-- Key block needs to be outside the if statement or it breaks -->
|
||||
{#key $builderStore.selectedComponentId}
|
||||
<!--
|
||||
We don't want to key these by componentID as they control their own
|
||||
re-mounting to avoid flashes.
|
||||
-->
|
||||
{#if $builderStore.inBuilder}
|
||||
<SettingsBar />
|
||||
<SelectionIndicator />
|
||||
<HoverIndicator />
|
||||
{/if}
|
||||
{/key}
|
||||
<!--
|
||||
We don't want to key these by componentID as they control their own
|
||||
re-mounting to avoid flashes.
|
||||
-->
|
||||
{#if $builderStore.inBuilder}
|
||||
<SelectionIndicator />
|
||||
<HoverIndicator />
|
||||
{/if}
|
||||
</Provider>
|
||||
</DeviceBindingsProvider>
|
||||
</UserBindingsProvider>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<script>
|
||||
import Provider from "./Provider.svelte"
|
||||
import { onMount } from "svelte"
|
||||
|
||||
const tabletBreakpoint = 768
|
||||
const desktopBreakpoint = 1280
|
||||
|
||||
let screenWidth = window.innerWidth
|
||||
const resizeObserver = new ResizeObserver(entries => {
|
||||
if (entries?.[0]) {
|
||||
screenWidth = entries[0].contentRect?.width
|
||||
}
|
||||
})
|
||||
$: mobile = screenWidth && screenWidth < tabletBreakpoint
|
||||
$: tablet =
|
||||
screenWidth &&
|
||||
screenWidth >= tabletBreakpoint &&
|
||||
screenWidth < desktopBreakpoint
|
||||
$: data = { mobile, tablet }
|
||||
|
||||
onMount(() => {
|
||||
const doc = document.documentElement
|
||||
resizeObserver.observe(doc)
|
||||
|
||||
return () => {
|
||||
resizeObserver.unobserve(doc)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<Provider key="device" {data}>
|
||||
<slot />
|
||||
</Provider>
|
|
@ -0,0 +1,19 @@
|
|||
<script>
|
||||
import Provider from "./Provider.svelte"
|
||||
import { authStore } from "../store"
|
||||
import { ActionTypes, TableNames } from "../constants"
|
||||
|
||||
// Register this as a refreshable datasource so that user changes cause
|
||||
// the user object to be refreshed
|
||||
$: actions = [
|
||||
{
|
||||
type: ActionTypes.RefreshDatasource,
|
||||
callback: () => authStore.actions.fetchUser(),
|
||||
metadata: { dataSource: { type: "table", tableId: TableNames.USERS } },
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<Provider key="user" data={$authStore} {actions}>
|
||||
<slot />
|
||||
</Provider>
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"features": {
|
||||
"spectrumThemes": true,
|
||||
"intelligentLoading": true
|
||||
"intelligentLoading": true,
|
||||
"deviceAwareness": true
|
||||
},
|
||||
"layout": {
|
||||
"name": "Layout",
|
||||
|
|
Loading…
Reference in New Issue