Merge pull request #11296 from Budibase/screen-theme-rightpanel
Screen Settings/Theme UI updated and moved
This commit is contained in:
commit
d0854c2fec
|
@ -32,11 +32,10 @@ export default function positionDropdown(element, opts) {
|
|||
left: null,
|
||||
top: null,
|
||||
}
|
||||
|
||||
// Determine vertical styles
|
||||
if (align === "right-outside") {
|
||||
styles.top = anchorBounds.top
|
||||
} else if (window.innerHeight - anchorBounds.bottom < 100) {
|
||||
} else if (window.innerHeight - anchorBounds.bottom < (maxHeight || 100)) {
|
||||
styles.top = anchorBounds.top - elementBounds.height - offset
|
||||
styles.maxHeight = maxHeight || 240
|
||||
} else {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script>
|
||||
import Popover from "../Popover/Popover.svelte"
|
||||
import Layout from "../Layout/Layout.svelte"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import "@spectrum-css/popover/dist/index-vars.css"
|
||||
import clickOutside from "../Actions/click_outside"
|
||||
import { fly } from "svelte/transition"
|
||||
import Icon from "../Icon/Icon.svelte"
|
||||
import Input from "../Form/Input.svelte"
|
||||
import { capitalise } from "../helpers"
|
||||
|
@ -10,9 +10,11 @@
|
|||
export let value
|
||||
export let size = "M"
|
||||
export let spectrumTheme
|
||||
export let alignRight = false
|
||||
export let offset
|
||||
export let align
|
||||
|
||||
let open = false
|
||||
let dropdown
|
||||
let preview
|
||||
|
||||
$: customValue = getCustomValue(value)
|
||||
$: checkColor = getCheckColor(value)
|
||||
|
@ -82,7 +84,7 @@
|
|||
|
||||
const onChange = value => {
|
||||
dispatch("change", value)
|
||||
open = false
|
||||
dropdown.hide()
|
||||
}
|
||||
|
||||
const getCustomValue = value => {
|
||||
|
@ -119,30 +121,25 @@
|
|||
|
||||
return "var(--spectrum-global-color-static-gray-900)"
|
||||
}
|
||||
|
||||
const handleOutsideClick = event => {
|
||||
if (open) {
|
||||
event.stopPropagation()
|
||||
open = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="preview size--{size || 'M'}" on:click={() => (open = true)}>
|
||||
<div
|
||||
class="fill {spectrumTheme || ''}"
|
||||
style={value ? `background: ${value};` : ""}
|
||||
class:placeholder={!value}
|
||||
/>
|
||||
</div>
|
||||
{#if open}
|
||||
<div
|
||||
use:clickOutside={handleOutsideClick}
|
||||
transition:fly|local={{ y: -20, duration: 200 }}
|
||||
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
|
||||
class:spectrum-Popover--align-right={alignRight}
|
||||
>
|
||||
<div
|
||||
bind:this={preview}
|
||||
class="preview size--{size || 'M'}"
|
||||
on:click={() => {
|
||||
dropdown.toggle()
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class="fill {spectrumTheme || ''}"
|
||||
style={value ? `background: ${value};` : ""}
|
||||
class:placeholder={!value}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Popover bind:this={dropdown} anchor={preview} maxHeight={320} {offset} {align}>
|
||||
<Layout paddingX="XL" paddingY="L">
|
||||
<div class="container">
|
||||
{#each categories as category}
|
||||
<div class="category">
|
||||
<div class="heading">{category.label}</div>
|
||||
|
@ -187,8 +184,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</Layout>
|
||||
</Popover>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
|
@ -248,20 +245,6 @@
|
|||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
.spectrum-Popover {
|
||||
width: 210px;
|
||||
z-index: 999;
|
||||
top: 100%;
|
||||
padding: var(--spacing-l) var(--spacing-xl);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
gap: var(--spacing-xl);
|
||||
}
|
||||
.spectrum-Popover--align-right {
|
||||
right: 0;
|
||||
}
|
||||
.colors {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
|
||||
|
@ -297,7 +280,11 @@
|
|||
.category--custom .heading {
|
||||
margin-bottom: var(--spacing-xs);
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-xl);
|
||||
}
|
||||
.spectrum-wrapper {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,14 @@
|
|||
open = false
|
||||
}
|
||||
|
||||
export const toggle = () => {
|
||||
if (!open) {
|
||||
show()
|
||||
} else {
|
||||
hide()
|
||||
}
|
||||
}
|
||||
|
||||
const handleOutsideClick = e => {
|
||||
if (open) {
|
||||
// Stop propagation if the source is the anchor
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
<ColorPicker
|
||||
value={column.background}
|
||||
on:change={e => (column.background = e.detail)}
|
||||
alignRight
|
||||
spectrumTheme={$store.theme}
|
||||
/>
|
||||
</Layout>
|
||||
|
@ -51,7 +50,6 @@
|
|||
<ColorPicker
|
||||
value={column.color}
|
||||
on:change={e => (column.color = e.detail)}
|
||||
alignRight
|
||||
spectrumTheme={$store.theme}
|
||||
/>
|
||||
</Layout>
|
||||
|
|
|
@ -64,10 +64,8 @@
|
|||
<Detail>Customize</Detail>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="infoHeader">
|
||||
<Icon name="InfoOutline" />
|
||||
<Body size="S">These settings apply to all screens</Body>
|
||||
</div>
|
||||
<Icon name="InfoOutline" size="S" />
|
||||
<Body size="S">These settings apply to all screens</Body>
|
||||
</div>
|
||||
<div class="configureLinks">
|
||||
<LinksEditor />
|
||||
|
@ -210,22 +208,14 @@
|
|||
.info {
|
||||
background-color: var(--background-alt);
|
||||
padding: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.infoHeader {
|
||||
display: flex;
|
||||
margin-bottom: 5px;
|
||||
border-radius: 4px;
|
||||
gap: 4px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.infoHeader :global(svg) {
|
||||
.info :global(svg) {
|
||||
margin-right: 5px;
|
||||
color: var(--grey-6);
|
||||
}
|
||||
|
||||
.infoHeader :global(p) {
|
||||
color: var(--grey-7);
|
||||
color: var(--spectrum-global-color-gray-600);
|
||||
}
|
||||
|
||||
.configureLinks :global(button) {
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<script>
|
||||
import { notifications } from "@budibase/bbui"
|
||||
import { store } from "builderStore"
|
||||
import { Constants } from "@budibase/frontend-core"
|
||||
|
||||
const onChangeTheme = async theme => {
|
||||
try {
|
||||
await store.actions.theme.save(`spectrum--${theme}`)
|
||||
} catch (error) {
|
||||
notifications.error("Error updating theme")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
{#each Constants.Themes as theme}
|
||||
<div
|
||||
class="theme"
|
||||
class:selected={`spectrum--${theme.class}` === $store.theme}
|
||||
on:click={() => onChangeTheme(theme.class)}
|
||||
>
|
||||
<div
|
||||
style="background: {theme.preview}"
|
||||
class="color spectrum--{theme.class}"
|
||||
/>
|
||||
{theme.name}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
.color {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50px;
|
||||
background: var(--spectrum-global-color-gray-200);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.theme {
|
||||
border-radius: 4px;
|
||||
padding: var(--spacing-s) var(--spacing-m);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: var(--spacing-xl);
|
||||
transition: background 130ms ease-out;
|
||||
font-weight: 600;
|
||||
color: var(--spectrum-global-color-gray-900);
|
||||
}
|
||||
.theme:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
.theme.selected,
|
||||
.theme:hover {
|
||||
background: var(--spectrum-global-color-gray-50);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,38 @@
|
|||
<script>
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import { Slider, Button } from "@budibase/bbui"
|
||||
|
||||
export let customTheme
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const options = ["0", "4px", "8px", "16px"]
|
||||
|
||||
$: index = options.indexOf(customTheme.buttonBorderRadius) ?? 2
|
||||
|
||||
const onChange = async e => {
|
||||
dispatch("change", options[e.detail])
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<Slider min={0} max={3} step={1} value={index} on:change={onChange} />
|
||||
<div class="button" style="--radius: {customTheme.buttonBorderRadius};">
|
||||
<Button primary>Button</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
gap: var(--spacing-xl);
|
||||
}
|
||||
.container :global(.spectrum-Form-item) {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.button :global(.spectrum-Button) {
|
||||
border-radius: var(--radius) !important;
|
||||
}
|
||||
</style>
|
|
@ -1,10 +1,8 @@
|
|||
<script>
|
||||
import Panel from "components/design/Panel.svelte"
|
||||
import { get } from "svelte/store"
|
||||
import { Helpers } from "@budibase/bbui"
|
||||
import {
|
||||
Input,
|
||||
Layout,
|
||||
Checkbox,
|
||||
Banner,
|
||||
Select,
|
||||
|
@ -133,33 +131,24 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<Panel
|
||||
title={$selectedScreen.routing.route}
|
||||
icon={$selectedScreen.routing.route === "/" ? "Home" : "WebPage"}
|
||||
borderLeft
|
||||
wide
|
||||
>
|
||||
<Layout gap="S" paddingX="L" paddingY="XL">
|
||||
{#if $selectedScreen.layoutId}
|
||||
<Banner
|
||||
type="warning"
|
||||
extraButtonText="Detach custom layout"
|
||||
extraButtonAction={removeCustomLayout}
|
||||
showCloseButton={false}
|
||||
>
|
||||
This screen uses a custom layout, which is deprecated
|
||||
</Banner>
|
||||
{/if}
|
||||
{#each screenSettings as setting (setting.key)}
|
||||
<PropertyControl
|
||||
control={setting.control}
|
||||
label={setting.label}
|
||||
key={setting.key}
|
||||
value={Helpers.deepGet($selectedScreen, setting.key)}
|
||||
onChange={val => setScreenSetting(setting, val)}
|
||||
props={{ ...setting.props, error: errors[setting.key] }}
|
||||
{bindings}
|
||||
/>
|
||||
{/each}
|
||||
</Layout>
|
||||
</Panel>
|
||||
{#if $selectedScreen.layoutId}
|
||||
<Banner
|
||||
type="warning"
|
||||
extraButtonText="Detach custom layout"
|
||||
extraButtonAction={removeCustomLayout}
|
||||
showCloseButton={false}
|
||||
>
|
||||
This screen uses a custom layout, which is deprecated
|
||||
</Banner>
|
||||
{/if}
|
||||
{#each screenSettings as setting (setting.key)}
|
||||
<PropertyControl
|
||||
control={setting.control}
|
||||
label={setting.label}
|
||||
key={setting.key}
|
||||
value={Helpers.deepGet($selectedScreen, setting.key)}
|
||||
onChange={val => setScreenSetting(setting, val)}
|
||||
props={{ ...setting.props, error: errors[setting.key] }}
|
||||
{bindings}
|
||||
/>
|
||||
{/each}
|
|
@ -0,0 +1,78 @@
|
|||
<script>
|
||||
import {
|
||||
Layout,
|
||||
Label,
|
||||
ColorPicker,
|
||||
notifications,
|
||||
Icon,
|
||||
Body,
|
||||
} from "@budibase/bbui"
|
||||
import { store } from "builderStore"
|
||||
import { get } from "svelte/store"
|
||||
import { DefaultAppTheme } from "constants"
|
||||
import AppThemeSelect from "./AppThemeSelect.svelte"
|
||||
import ButtonRoundnessSelect from "./ButtonRoundnessSelect.svelte"
|
||||
import PropertyControl from "components/design/settings/controls/PropertyControl.svelte"
|
||||
|
||||
$: customTheme = $store.customTheme || {}
|
||||
|
||||
const update = async (property, value) => {
|
||||
try {
|
||||
store.actions.customTheme.save({
|
||||
...get(store).customTheme,
|
||||
[property]: value,
|
||||
})
|
||||
} catch (error) {
|
||||
notifications.error("Error updating custom theme")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="info">
|
||||
<Icon name="InfoOutline" size="S" />
|
||||
<Body size="S">These settings apply to all screens</Body>
|
||||
</div>
|
||||
<Layout noPadding gap="S">
|
||||
<Layout noPadding gap="XS">
|
||||
<AppThemeSelect />
|
||||
</Layout>
|
||||
<Layout noPadding gap="XS">
|
||||
<Label>Button roundness</Label>
|
||||
<ButtonRoundnessSelect
|
||||
{customTheme}
|
||||
on:change={e => update("buttonBorderRadius", e.detail)}
|
||||
/>
|
||||
</Layout>
|
||||
<PropertyControl
|
||||
label="Accent color"
|
||||
control={ColorPicker}
|
||||
value={customTheme.primaryColor || DefaultAppTheme.primaryColor}
|
||||
onChange={val => update("primaryColor", val)}
|
||||
props={{
|
||||
spectrumTheme: $store.theme,
|
||||
}}
|
||||
/>
|
||||
<PropertyControl
|
||||
label="Hover"
|
||||
control={ColorPicker}
|
||||
value={customTheme.primaryColorHover || DefaultAppTheme.primaryColorHover}
|
||||
onChange={val => update("primaryColorHover", val)}
|
||||
props={{
|
||||
spectrumTheme: $store.theme,
|
||||
}}
|
||||
/>
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
.info {
|
||||
background-color: var(--background-alt);
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
border-radius: 4px;
|
||||
gap: 4px;
|
||||
}
|
||||
.info :global(svg) {
|
||||
margin-right: 5px;
|
||||
color: var(--spectrum-global-color-gray-600);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,51 @@
|
|||
<script>
|
||||
import GeneralPanel from "./GeneralPanel.svelte"
|
||||
import ThemePanel from "./ThemePanel.svelte"
|
||||
import { selectedScreen } from "builderStore"
|
||||
import Panel from "components/design/Panel.svelte"
|
||||
import { capitalise } from "helpers"
|
||||
import { ActionButton, Layout } from "@budibase/bbui"
|
||||
|
||||
let activeTab = "general"
|
||||
const tabs = ["general", "theme"]
|
||||
</script>
|
||||
|
||||
<Panel
|
||||
title={$selectedScreen.routing.route}
|
||||
icon={$selectedScreen.routing.route === "/" ? "Home" : "WebPage"}
|
||||
borderLeft
|
||||
wide
|
||||
>
|
||||
<div slot="panel-header-content">
|
||||
<div class="settings-tabs">
|
||||
{#each tabs as tab}
|
||||
<ActionButton
|
||||
size="M"
|
||||
quiet
|
||||
selected={activeTab === tab}
|
||||
on:click={() => {
|
||||
activeTab = tab
|
||||
}}
|
||||
>
|
||||
{capitalise(tab)}
|
||||
</ActionButton>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<Layout gap="S" paddingX="L" paddingY="XL">
|
||||
{#if activeTab === "theme"}
|
||||
<ThemePanel />
|
||||
{:else}
|
||||
<GeneralPanel />
|
||||
{/if}
|
||||
</Layout>
|
||||
</Panel>
|
||||
|
||||
<style>
|
||||
.settings-tabs {
|
||||
display: flex;
|
||||
gap: var(--spacing-s);
|
||||
padding: 0 var(--spacing-l);
|
||||
padding-bottom: var(--spacing-l);
|
||||
}
|
||||
</style>
|
|
@ -6,7 +6,7 @@
|
|||
import { findComponent } from "builderStore/componentUtils"
|
||||
import ComponentSettingsPanel from "./_components/Component/ComponentSettingsPanel.svelte"
|
||||
import NavigationPanel from "./_components/Navigation/index.svelte"
|
||||
import ScreenSettingsPanel from "./_components/Screen/SettingsPanel.svelte"
|
||||
import ScreenSettingsPanel from "./_components/Screen/index.svelte"
|
||||
|
||||
$: componentId = $store.selectedComponentId
|
||||
$: store.actions.websocket.selectResource(componentId)
|
||||
|
|
|
@ -281,12 +281,7 @@ async function performAppCreate(ctx: UserCtx) {
|
|||
title: name,
|
||||
navWidth: "Large",
|
||||
navBackground: "var(--spectrum-global-color-gray-100)",
|
||||
links: [
|
||||
{
|
||||
url: "/home",
|
||||
text: "Home",
|
||||
},
|
||||
],
|
||||
links: [],
|
||||
},
|
||||
theme: "spectrum--light",
|
||||
customTheme: {
|
||||
|
|
Loading…
Reference in New Issue