Add full navigation settings panel in new design UI. Remove navigation theme settings from theme panel

This commit is contained in:
Andrew Kingston 2022-05-06 13:51:27 +01:00
parent 071dc5be4b
commit 3ada9a12c5
10 changed files with 181 additions and 57 deletions

View File

@ -56,3 +56,11 @@ export const BUDIBASE_INTERNAL_DB = "bb_internal"
export const APP_NAME_REGEX = /^[\w\s]+$/ export const APP_NAME_REGEX = /^[\w\s]+$/
// zero or more non-whitespace characters // zero or more non-whitespace characters
export const APP_URL_REGEX = /^\S*$/ export const APP_URL_REGEX = /^\S*$/
export const DefaultAppTheme = {
primaryColor: "var(--spectrum-global-color-blue-600)",
primaryColorHover: "var(--spectrum-global-color-blue-500)",
buttonBorderRadius: "16px",
navBackground: "var(--spectrum-global-color-gray-50)",
navTextColor: "var(--spectrum-global-color-gray-800)",
}

View File

@ -36,7 +36,7 @@ export const syncURLToState = options => {
let cachedRedirect = get(routify.redirect) let cachedRedirect = get(routify.redirect)
let cachedPage = get(routify.page) let cachedPage = get(routify.page)
let previousParamsHash = null let previousParamsHash = null
let debug = true let debug = false
const log = (...params) => debug && console.log(...params) const log = (...params) => debug && console.log(...params)
// Navigate to a certain URL // Navigate to a certain URL

View File

@ -17,10 +17,7 @@
routify, routify,
}) })
onDestroy(() => { onDestroy(stopSyncing)
console.log("============= stop syncing screen ID!")
stopSyncing()
})
</script> </script>
<div class="design"> <div class="design">

View File

@ -15,10 +15,7 @@
routify, routify,
}) })
onDestroy(() => { onDestroy(stopSyncing)
console.log("============= stop syncing component ID!")
stopSyncing()
})
</script> </script>
<slot /> <slot />

View File

@ -1,6 +1,6 @@
<script> <script>
import { Button, Drawer } from "@budibase/bbui" import { Button, Drawer } from "@budibase/bbui"
import NavigationDrawer from "./NavigationDrawer.svelte" import NavigationLinksDrawer from "./NavigationLinksDrawer.svelte"
import { cloneDeep } from "lodash/fp" import { cloneDeep } from "lodash/fp"
import { store } from "builderStore" import { store } from "builderStore"
@ -30,5 +30,5 @@
Configure the links in your navigation bar. Configure the links in your navigation bar.
</svelte:fragment> </svelte:fragment>
<Button cta slot="buttons" on:click={save}>Save</Button> <Button cta slot="buttons" on:click={save}>Save</Button>
<NavigationDrawer slot="body" bind:links /> <NavigationLinksDrawer slot="body" bind:links />
</Drawer> </Drawer>

View File

@ -1,7 +1,51 @@
<script> <script>
import NavigationPanel from "components/design/navigation/NavigationPanel.svelte" import NavigationPanel from "components/design/navigation/NavigationPanel.svelte"
import { Body, Layout } from "@budibase/bbui" import {
import NavigationEditor from "./_components/NavigationEditor.svelte" Body,
Layout,
Label,
ActionGroup,
ActionButton,
Checkbox,
Select,
ColorPicker,
Input,
notifications,
} from "@budibase/bbui"
import NavigationLinksEditor from "./_components/NavigationLinksEditor.svelte"
import { store } from "builderStore"
import { onMount } from "svelte"
import { DefaultAppTheme } from "constants"
const updateNavigation = async (key, value) => {
try {
let navigation = $store.navigation
navigation[key] = value
await store.actions.navigation.save(navigation)
} catch (error) {
notifications.error("Error updating navigation settings")
}
}
onMount(() => {
// Add navigation settings to old apps
let changed = false
if (!$store.navigation.navigation) {
$store.navigation.navigation = "Top"
changed = true
}
if (!$store.navigation.hideTitle && !$store.navigation.title) {
$store.navigation.title = $store.name
changed = true
}
if (!$store.navigation.width) {
$store.navigation.width = "Large"
changed = true
}
if (changed) {
store.actions.navigation.save($store.navigation)
}
})
</script> </script>
<NavigationPanel title="Navigation"> <NavigationPanel title="Navigation">
@ -13,6 +57,83 @@
You can hide and show your navigation for each screen in the screen You can hide and show your navigation for each screen in the screen
settings settings
</Body> </Body>
<NavigationEditor /> <NavigationLinksEditor />
<Layout noPadding gap="XS">
<Label>Position</Label>
<ActionGroup quiet>
<ActionButton
selected={$store.navigation.navigation === "Top"}
quiet={$store.navigation.navigation !== "Top"}
icon="PaddingTop"
on:click={() => updateNavigation("navigation", "Top")}
/>
<ActionButton
selected={$store.navigation.navigation === "Left"}
quiet={$store.navigation.navigation !== "Left"}
icon="PaddingLeft"
on:click={() => updateNavigation("navigation", "Left")}
/>
</ActionGroup>
</Layout>
{#if $store.navigation.navigation === "Top"}
<Checkbox
text="Sticky header"
value={$store.navigation.sticky}
on:change={e => updateNavigation("sticky", e.detail)}
/>
{/if}
<Layout noPadding gap="XS">
<Checkbox
text="Logo"
value={!$store.navigation.hideLogo}
on:change={e => updateNavigation("hideLogo", !e.detail)}
/>
{#if !$store.navigation.hideLogo}
<Input
value={$store.navigation.logoUrl}
on:change={e => updateNavigation("logoUrl", e.detail)}
placeholder="Add logo URL"
updateOnChange={false}
/>
{/if}
</Layout>
<Layout noPadding gap="XS">
<Checkbox
text="Title"
value={!$store.navigation.hideTitle}
on:change={e => updateNavigation("hideTitle", !e.detail)}
/>
{#if !$store.navigation.hideTitle}
<Input
value={$store.navigation.title}
on:change={e => updateNavigation("title", e.detail)}
placeholder="Add title"
updateOnChange={false}
/>
{/if}
</Layout>
<Select
label="Width"
options={["Max", "Large", "Medium", "Small"]}
plaveholder={null}
value={$store.navigation.navWidth}
on:change={e => updateNavigation("navWidth", e.detail)}
/>
<Layout noPadding gap="XS">
<Label>Background color</Label>
<ColorPicker
spectrumTheme={$store.theme}
value={$store.navigation.navBackground || DefaultAppTheme.navBackground}
on:change={e => updateNavigation("navBackground", e.detail)}
/>
</Layout>
<Layout noPadding gap="XS">
<Label>Text color</Label>
<ColorPicker
spectrumTheme={$store.theme}
value={$store.navigation.navTextColor || DefaultAppTheme.navTextColor}
on:change={e => updateNavigation("navTextColor", e.detail)}
/>
</Layout>
</Layout> </Layout>
</NavigationPanel> </NavigationPanel>

View File

@ -13,17 +13,10 @@
} from "@budibase/bbui" } from "@budibase/bbui"
import { store } from "builderStore" import { store } from "builderStore"
import AppThemeSelect from "./AppThemeSelect.svelte" import AppThemeSelect from "./AppThemeSelect.svelte"
import { DefaultAppTheme } from "constants"
let modal let modal
const defaultTheme = {
primaryColor: "var(--spectrum-global-color-blue-600)",
primaryColorHover: "var(--spectrum-global-color-blue-500)",
buttonBorderRadius: "16px",
navBackground: "var(--spectrum-global-color-gray-50)",
navTextColor: "var(--spectrum-global-color-gray-800)",
}
const buttonBorderRadiusOptions = [ const buttonBorderRadiusOptions = [
{ {
label: "None", label: "None",
@ -93,7 +86,7 @@
<Select <Select
placeholder={null} placeholder={null}
value={$store.customTheme?.buttonBorderRadius || value={$store.customTheme?.buttonBorderRadius ||
defaultTheme.buttonBorderRadius} DefaultAppTheme.buttonBorderRadius}
on:change={updateProperty("buttonBorderRadius")} on:change={updateProperty("buttonBorderRadius")}
options={buttonBorderRadiusOptions} options={buttonBorderRadiusOptions}
/> />
@ -103,7 +96,8 @@
<Label size="L">Accent color</Label> <Label size="L">Accent color</Label>
<ColorPicker <ColorPicker
spectrumTheme={$store.theme} spectrumTheme={$store.theme}
value={$store.customTheme?.primaryColor || defaultTheme.primaryColor} value={$store.customTheme?.primaryColor ||
DefaultAppTheme.primaryColor}
on:change={updateProperty("primaryColor")} on:change={updateProperty("primaryColor")}
/> />
</div> </div>
@ -112,27 +106,10 @@
<ColorPicker <ColorPicker
spectrumTheme={$store.theme} spectrumTheme={$store.theme}
value={$store.customTheme?.primaryColorHover || value={$store.customTheme?.primaryColorHover ||
defaultTheme.primaryColorHover} DefaultAppTheme.primaryColorHover}
on:change={updateProperty("primaryColorHover")} on:change={updateProperty("primaryColorHover")}
/> />
</div> </div>
<div class="setting">
<Label size="L">Navigation bar background color</Label>
<ColorPicker
spectrumTheme={$store.theme}
value={$store.customTheme?.navBackground ||
defaultTheme.navBackground}
on:change={updateProperty("navBackground")}
/>
</div>
<div class="setting">
<Label size="L">Navigation bar text color</Label>
<ColorPicker
spectrumTheme={$store.theme}
value={$store.customTheme?.navTextColor || defaultTheme.navTextColor}
on:change={updateProperty("navTextColor")}
/>
</div>
</Layout> </Layout>
<div slot="footer"> <div slot="footer">
<Button secondary quiet on:click={resetTheme}>Reset</Button> <Button secondary quiet on:click={resetTheme}>Reset</Button>

View File

@ -9,6 +9,7 @@
const component = getContext("component") const component = getContext("component")
const context = getContext("context") const context = getContext("context")
// Legacy props which must remain unchanged for backwards compatibility
export let title export let title
export let hideTitle = false export let hideTitle = false
export let logoUrl export let logoUrl
@ -18,12 +19,18 @@
export let links export let links
export let width = "Large" export let width = "Large"
const navigationClasses = { // New props from new design UI
export let navBackground
export let navTextColor
export let navWidth
export let pageWidth
const NavigationClasses = {
Top: "top", Top: "top",
Left: "left", Left: "left",
None: "none", None: "none",
} }
const widthClasses = { const WidthClasses = {
Max: "max", Max: "max",
Large: "l", Large: "l",
Medium: "m", Medium: "m",
@ -49,8 +56,15 @@
} }
$: validLinks = links?.filter(link => link.text && link.url) || [] $: validLinks = links?.filter(link => link.text && link.url) || []
$: typeClass = navigationClasses[navigation] || "none" $: typeClass = NavigationClasses[navigation] || NavigationClasses.None
$: widthClass = widthClasses[width] || "l" $: navWidthClass = WidthClasses[navWidth || width] || WidthClasses.Large
$: pageWidthClass = WidthClasses[pageWidth || width] || WidthClasses.Large
$: navStyle = getNavStyle(
navBackground,
navTextColor,
$context.device.width,
$context.device.height
)
let mobileOpen = false let mobileOpen = false
const isInternal = url => { const isInternal = url => {
@ -83,6 +97,17 @@
return navigation === "Top" ? "137px" : "0px" return navigation === "Top" ? "137px" : "0px"
} }
} }
const getNavStyle = (backgroundColor, textColor, width, height) => {
let style = `--width:${width}px;--height:${height}px;`
if (backgroundColor) {
style += `--navBackground: ${backgroundColor};`
}
if (textColor) {
style += `--navTextColor: ${textColor};`
}
return style
}
</script> </script>
<div <div
@ -96,9 +121,9 @@
class="nav-wrapper" class="nav-wrapper"
class:sticky class:sticky
class:hidden={isPeeking} class:hidden={isPeeking}
style={`--height:${$context.device.height}px; --width:${$context.device.width}px;`} style={navStyle}
> >
<div class="nav nav--{typeClass} size--{widthClass}"> <div class="nav nav--{typeClass} size--{navWidthClass}">
<div class="nav-header"> <div class="nav-header">
{#if validLinks?.length} {#if validLinks?.length}
<div class="burger"> <div class="burger">
@ -165,7 +190,7 @@
</div> </div>
{/if} {/if}
<div class="main-wrapper"> <div class="main-wrapper">
<div class="main size--{widthClass}"> <div class="main size--{pageWidthClass}">
<slot /> <slot />
</div> </div>
</div> </div>

View File

@ -47,18 +47,17 @@ const createScreenStore = () => {
} }
if (activeScreen?.showNavigation) { if (activeScreen?.showNavigation) {
navigationSettings = navigationSettings =
$builderStore.navigation || $appStore.application?.navigation $builderStore.navigation || $appStore.application?.navigation || {}
// Legacy - if this is a legacy screen without any navigation // Default navigation to top
// settings fall back to just showing the app title
if (!navigationSettings) {
navigationSettings = {
title: $appStore.application?.name,
}
}
if (!navigationSettings.navigation) { if (!navigationSettings.navigation) {
navigationSettings.navigation = "Top" navigationSettings.navigation = "Top"
} }
// Default title to app name
if (!navigationSettings.title && !navigationSettings.hideTitle) {
navigationSettings.title = $appStore.application?.name
}
} }
activeLayout = { activeLayout = {
_id: "layout", _id: "layout",