Moved screen settings/theme into the new rightpanel structure. Refactord the color picker to help with positioning. Removed dead home link
This commit is contained in:
parent
1d0ab398cd
commit
d94fe7c2eb
|
@ -32,11 +32,10 @@ export default function positionDropdown(element, opts) {
|
||||||
left: null,
|
left: null,
|
||||||
top: null,
|
top: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine vertical styles
|
// Determine vertical styles
|
||||||
if (align === "right-outside") {
|
if (align === "right-outside") {
|
||||||
styles.top = anchorBounds.top
|
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.top = anchorBounds.top - elementBounds.height - offset
|
||||||
styles.maxHeight = maxHeight || 240
|
styles.maxHeight = maxHeight || 240
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
|
import Popover from "../Popover/Popover.svelte"
|
||||||
|
import Layout from "../Layout/Layout.svelte"
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import "@spectrum-css/popover/dist/index-vars.css"
|
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 Icon from "../Icon/Icon.svelte"
|
||||||
import Input from "../Form/Input.svelte"
|
import Input from "../Form/Input.svelte"
|
||||||
import { capitalise } from "../helpers"
|
import { capitalise } from "../helpers"
|
||||||
|
@ -10,9 +10,11 @@
|
||||||
export let value
|
export let value
|
||||||
export let size = "M"
|
export let size = "M"
|
||||||
export let spectrumTheme
|
export let spectrumTheme
|
||||||
export let alignRight = false
|
export let offset
|
||||||
|
export let align
|
||||||
|
|
||||||
let open = false
|
let dropdown
|
||||||
|
let preview
|
||||||
|
|
||||||
$: customValue = getCustomValue(value)
|
$: customValue = getCustomValue(value)
|
||||||
$: checkColor = getCheckColor(value)
|
$: checkColor = getCheckColor(value)
|
||||||
|
@ -82,7 +84,7 @@
|
||||||
|
|
||||||
const onChange = value => {
|
const onChange = value => {
|
||||||
dispatch("change", value)
|
dispatch("change", value)
|
||||||
open = false
|
dropdown.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCustomValue = value => {
|
const getCustomValue = value => {
|
||||||
|
@ -119,30 +121,25 @@
|
||||||
|
|
||||||
return "var(--spectrum-global-color-static-gray-900)"
|
return "var(--spectrum-global-color-static-gray-900)"
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOutsideClick = event => {
|
|
||||||
if (open) {
|
|
||||||
event.stopPropagation()
|
|
||||||
open = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="container">
|
<div
|
||||||
<div class="preview size--{size || 'M'}" on:click={() => (open = true)}>
|
bind:this={preview}
|
||||||
<div
|
class="preview size--{size || 'M'}"
|
||||||
class="fill {spectrumTheme || ''}"
|
on:click={() => {
|
||||||
style={value ? `background: ${value};` : ""}
|
dropdown.toggle()
|
||||||
class:placeholder={!value}
|
}}
|
||||||
/>
|
>
|
||||||
</div>
|
<div
|
||||||
{#if open}
|
class="fill {spectrumTheme || ''}"
|
||||||
<div
|
style={value ? `background: ${value};` : ""}
|
||||||
use:clickOutside={handleOutsideClick}
|
class:placeholder={!value}
|
||||||
transition:fly|local={{ y: -20, duration: 200 }}
|
/>
|
||||||
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
|
</div>
|
||||||
class:spectrum-Popover--align-right={alignRight}
|
|
||||||
>
|
<Popover bind:this={dropdown} anchor={preview} maxHeight={320} {offset} {align}>
|
||||||
|
<Layout paddingX="XL" paddingY="L">
|
||||||
|
<div class="container">
|
||||||
{#each categories as category}
|
{#each categories as category}
|
||||||
<div class="category">
|
<div class="category">
|
||||||
<div class="heading">{category.label}</div>
|
<div class="heading">{category.label}</div>
|
||||||
|
@ -187,8 +184,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
</Layout>
|
||||||
</div>
|
</Popover>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.container {
|
.container {
|
||||||
|
@ -248,20 +245,6 @@
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 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 {
|
.colors {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
|
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
|
||||||
|
@ -297,7 +280,11 @@
|
||||||
.category--custom .heading {
|
.category--custom .heading {
|
||||||
margin-bottom: var(--spacing-xs);
|
margin-bottom: var(--spacing-xs);
|
||||||
}
|
}
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--spacing-xl);
|
||||||
|
}
|
||||||
.spectrum-wrapper {
|
.spectrum-wrapper {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,14 @@
|
||||||
open = false
|
open = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const toggle = () => {
|
||||||
|
if (!open) {
|
||||||
|
show()
|
||||||
|
} else {
|
||||||
|
hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleOutsideClick = e => {
|
const handleOutsideClick = e => {
|
||||||
if (open) {
|
if (open) {
|
||||||
// Stop propagation if the source is the anchor
|
// Stop propagation if the source is the anchor
|
||||||
|
|
|
@ -16,6 +16,6 @@
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.pane {
|
.pane {
|
||||||
padding: 13px;
|
padding: var(--spacing-l);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
<ColorPicker
|
<ColorPicker
|
||||||
value={column.background}
|
value={column.background}
|
||||||
on:change={e => (column.background = e.detail)}
|
on:change={e => (column.background = e.detail)}
|
||||||
alignRight
|
|
||||||
spectrumTheme={$store.theme}
|
spectrumTheme={$store.theme}
|
||||||
/>
|
/>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
@ -51,7 +50,6 @@
|
||||||
<ColorPicker
|
<ColorPicker
|
||||||
value={column.color}
|
value={column.color}
|
||||||
on:change={e => (column.color = e.detail)}
|
on:change={e => (column.color = e.detail)}
|
||||||
alignRight
|
|
||||||
spectrumTheme={$store.theme}
|
spectrumTheme={$store.theme}
|
||||||
/>
|
/>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -38,12 +38,6 @@
|
||||||
active={$isActive("./components")}
|
active={$isActive("./components")}
|
||||||
on:click={() => $goto("./components")}
|
on:click={() => $goto("./components")}
|
||||||
/>
|
/>
|
||||||
<IconSideNavItem
|
|
||||||
icon="Brush"
|
|
||||||
tooltip="Theme"
|
|
||||||
active={$isActive("./theme")}
|
|
||||||
on:click={() => $goto("./theme")}
|
|
||||||
/>
|
|
||||||
<IconSideNavItem
|
<IconSideNavItem
|
||||||
icon="Link"
|
icon="Link"
|
||||||
tooltip="Navigation"
|
tooltip="Navigation"
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Nav Setting
|
||||||
|
/design/:screen/navigation
|
||||||
|
|
||||||
|
Current screen setting paths
|
||||||
|
/design/:screen/screens
|
||||||
|
/design/:screen/theme
|
||||||
|
|
||||||
|
-->
|
||||||
|
<script>
|
||||||
|
import Pane from "components/design/Pane.svelte"
|
||||||
|
import { get } from "svelte/store"
|
||||||
|
import { Helpers } from "@budibase/bbui"
|
||||||
|
import {
|
||||||
|
Input,
|
||||||
|
Layout,
|
||||||
|
Button,
|
||||||
|
Toggle,
|
||||||
|
Checkbox,
|
||||||
|
Banner,
|
||||||
|
Select,
|
||||||
|
notifications,
|
||||||
|
} from "@budibase/bbui"
|
||||||
|
import PropertyControl from "components/design/settings/controls/PropertyControl.svelte"
|
||||||
|
import RoleSelect from "components/design/settings/controls/RoleSelect.svelte"
|
||||||
|
import { selectedScreen, store } from "builderStore"
|
||||||
|
import sanitizeUrl from "builderStore/store/screenTemplates/utils/sanitizeUrl"
|
||||||
|
import { goto } from "@roxi/routify"
|
||||||
|
import ButtonActionEditor from "components/design/settings/controls/ButtonActionEditor/ButtonActionEditor.svelte"
|
||||||
|
import { getBindableProperties } from "builderStore/dataBinding"
|
||||||
|
|
||||||
|
$: bindings = getBindableProperties($selectedScreen, null)
|
||||||
|
|
||||||
|
let errors = {}
|
||||||
|
|
||||||
|
const routeTaken = url => {
|
||||||
|
const roleId = get(selectedScreen).routing.roleId || "BASIC"
|
||||||
|
return get(store).screens.some(
|
||||||
|
screen =>
|
||||||
|
screen.routing.route.toLowerCase() === url.toLowerCase() &&
|
||||||
|
screen.routing.roleId === roleId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const roleTaken = roleId => {
|
||||||
|
const url = get(selectedScreen).routing.route
|
||||||
|
return get(store).screens.some(
|
||||||
|
screen =>
|
||||||
|
screen.routing.route.toLowerCase() === url.toLowerCase() &&
|
||||||
|
screen.routing.roleId === roleId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const setScreenSetting = async (setting, value) => {
|
||||||
|
const { key, parser, validate } = setting
|
||||||
|
|
||||||
|
// Parse value if required
|
||||||
|
if (parser) {
|
||||||
|
value = parser(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate value if required and determine errors
|
||||||
|
if (validate) {
|
||||||
|
const error = validate(value)
|
||||||
|
errors = {
|
||||||
|
...errors,
|
||||||
|
[key]: error,
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errors = {
|
||||||
|
...errors,
|
||||||
|
[key]: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update screen setting
|
||||||
|
try {
|
||||||
|
await store.actions.screens.updateSetting(get(selectedScreen), key, value)
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
notifications.error("Error saving screen settings")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: screenSettings = [
|
||||||
|
{
|
||||||
|
key: "routing.homeScreen",
|
||||||
|
control: Checkbox,
|
||||||
|
props: {
|
||||||
|
text: "Set as home screen",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "routing.route",
|
||||||
|
label: "Route",
|
||||||
|
control: Input,
|
||||||
|
parser: val => {
|
||||||
|
if (!val.startsWith("/")) {
|
||||||
|
val = "/" + val
|
||||||
|
}
|
||||||
|
return sanitizeUrl(val)
|
||||||
|
},
|
||||||
|
validate: route => {
|
||||||
|
const existingRoute = get(selectedScreen).routing.route
|
||||||
|
if (route !== existingRoute && routeTaken(route)) {
|
||||||
|
return "That URL is already in use for this role"
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "routing.roleId",
|
||||||
|
label: "Access",
|
||||||
|
control: RoleSelect,
|
||||||
|
validate: role => {
|
||||||
|
const existingRole = get(selectedScreen).routing.roleId
|
||||||
|
if (role !== existingRole && roleTaken(role)) {
|
||||||
|
return "That role is already in use for this URL"
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "onLoad",
|
||||||
|
label: "On screen load",
|
||||||
|
control: ButtonActionEditor,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "showNavigation",
|
||||||
|
label: "Navigation",
|
||||||
|
control: Toggle,
|
||||||
|
props: {
|
||||||
|
text: "Show nav",
|
||||||
|
disabled: !!$selectedScreen.layoutId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "width",
|
||||||
|
label: "Width",
|
||||||
|
control: Select,
|
||||||
|
props: {
|
||||||
|
options: ["Extra small", "Small", "Medium", "Large", "Max"],
|
||||||
|
placeholder: "Default",
|
||||||
|
disabled: !!$selectedScreen.layoutId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const removeCustomLayout = async () => {
|
||||||
|
return store.actions.screens.removeCustomLayout(get(selectedScreen))
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Pane title="General">
|
||||||
|
<Layout gap="S" noPadding>
|
||||||
|
{#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}
|
||||||
|
<span class="screen-settings">
|
||||||
|
{#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}
|
||||||
|
</span>
|
||||||
|
<Button secondary on:click={() => $goto("../components")}>
|
||||||
|
View components
|
||||||
|
</Button>
|
||||||
|
</Layout>
|
||||||
|
</Pane>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.screen-settings {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
.screen-settings :global(.property-control) {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,98 @@
|
||||||
|
<script>
|
||||||
|
import Pane from "components/design/Pane.svelte"
|
||||||
|
import {
|
||||||
|
Layout,
|
||||||
|
Label,
|
||||||
|
ColorPicker,
|
||||||
|
notifications,
|
||||||
|
Icon,
|
||||||
|
Body,
|
||||||
|
} from "@budibase/bbui"
|
||||||
|
import { store } from "builderStore"
|
||||||
|
import { get } from "svelte/store"
|
||||||
|
import { DefaultAppTheme } from "constants"
|
||||||
|
|
||||||
|
//These were shifted technically the /theme url is unnecessary
|
||||||
|
import AppThemeSelect from "./theme/AppThemeSelect.svelte"
|
||||||
|
import ButtonRoundnessSelect from "./theme/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>
|
||||||
|
|
||||||
|
<Pane title="Theme">
|
||||||
|
<div class="info">
|
||||||
|
<div class="infoHeader">
|
||||||
|
<Icon name="InfoOutline" size="S" />
|
||||||
|
<Body size="XS">CHANGES WILL APPLY TO ALL SCREENS</Body>
|
||||||
|
</div>
|
||||||
|
<Body size="S">
|
||||||
|
Your navigation is configured for all the screens within your app.
|
||||||
|
</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>
|
||||||
|
</Pane>
|
||||||
|
|
||||||
|
<!-- Add this to its own component -->
|
||||||
|
<style>
|
||||||
|
.infoHeader {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoHeader :global(svg) {
|
||||||
|
margin-right: 5px;
|
||||||
|
color: var(--grey-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoHeader :global(p) {
|
||||||
|
color: var(--grey-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
background-color: var(--background-alt);
|
||||||
|
padding: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<script>
|
||||||
|
import RightPanel from "components/design/RightPanel.svelte"
|
||||||
|
import GeneralPane from "./GeneralPane.svelte"
|
||||||
|
import ThemePane from "./ThemePane.svelte"
|
||||||
|
|
||||||
|
import { selectedScreen } from "builderStore"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<RightPanel
|
||||||
|
title={$selectedScreen.routing.route}
|
||||||
|
icon={$selectedScreen.routing.route === "/" ? "Home" : "WebPage"}
|
||||||
|
>
|
||||||
|
<GeneralPane />
|
||||||
|
<ThemePane />
|
||||||
|
</RightPanel>
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { selectedScreen } from "builderStore"
|
import { selectedScreen } from "builderStore"
|
||||||
import ScreenListPanel from "./_components/ScreenListPanel.svelte"
|
import ScreenListPanel from "./_components/ScreenListPanel.svelte"
|
||||||
import ScreenSettingsPanel from "./_components/ScreenSettingsPanel.svelte"
|
import ScreenSettingsPanel from "./_components/ScreenSettingsPanel/index.svelte"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ScreenListPanel />
|
<ScreenListPanel />
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
<script>
|
|
||||||
import Panel from "components/design/Panel.svelte"
|
|
||||||
import { Body, Layout } from "@budibase/bbui"
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Panel borderLeft title="Theme" icon="InfoOutline" wide>
|
|
||||||
<Layout paddingX="L" paddingY="XL">
|
|
||||||
<Body size="S">
|
|
||||||
Your theme is set across all the screens within your app.
|
|
||||||
</Body>
|
|
||||||
</Layout>
|
|
||||||
</Panel>
|
|
|
@ -1,55 +0,0 @@
|
||||||
<script>
|
|
||||||
import Panel from "components/design/Panel.svelte"
|
|
||||||
import { Layout, Label, ColorPicker, notifications } 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"
|
|
||||||
|
|
||||||
$: 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>
|
|
||||||
|
|
||||||
<Panel title="Theme" borderRight>
|
|
||||||
<Layout paddingX="L" paddingY="XL" gap="S">
|
|
||||||
<Layout noPadding gap="XS">
|
|
||||||
<Label>Theme</Label>
|
|
||||||
<AppThemeSelect />
|
|
||||||
</Layout>
|
|
||||||
<Layout noPadding gap="XS">
|
|
||||||
<Label>Button roundness</Label>
|
|
||||||
<ButtonRoundnessSelect
|
|
||||||
{customTheme}
|
|
||||||
on:change={e => update("buttonBorderRadius", e.detail)}
|
|
||||||
/>
|
|
||||||
</Layout>
|
|
||||||
<Layout noPadding gap="XS">
|
|
||||||
<Label>Accent color</Label>
|
|
||||||
<ColorPicker
|
|
||||||
spectrumTheme={$store.theme}
|
|
||||||
value={customTheme.primaryColor || DefaultAppTheme.primaryColor}
|
|
||||||
on:change={e => update("primaryColor", e.detail)}
|
|
||||||
/>
|
|
||||||
</Layout>
|
|
||||||
<Layout noPadding gap="XS">
|
|
||||||
<Label>Accent color (hover)</Label>
|
|
||||||
<ColorPicker
|
|
||||||
spectrumTheme={$store.theme}
|
|
||||||
value={customTheme.primaryColorHover ||
|
|
||||||
DefaultAppTheme.primaryColorHover}
|
|
||||||
on:change={e => update("primaryColorHover", e.detail)}
|
|
||||||
/>
|
|
||||||
</Layout>
|
|
||||||
</Layout>
|
|
||||||
</Panel>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<script>
|
|
||||||
import ThemeSettingsPanel from "./_components/ThemeSettingsPanel.svelte"
|
|
||||||
import ThemeInfoPanel from "./_components/ThemeInfoPanel.svelte"
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ThemeSettingsPanel />
|
|
||||||
<ThemeInfoPanel />
|
|
|
@ -298,12 +298,7 @@ async function performAppCreate(ctx: UserCtx) {
|
||||||
title: name,
|
title: name,
|
||||||
navWidth: "Large",
|
navWidth: "Large",
|
||||||
navBackground: "var(--spectrum-global-color-gray-100)",
|
navBackground: "var(--spectrum-global-color-gray-100)",
|
||||||
links: [
|
links: [],
|
||||||
{
|
|
||||||
url: "/home",
|
|
||||||
text: "Home",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
theme: "spectrum--light",
|
theme: "spectrum--light",
|
||||||
customTheme: {
|
customTheme: {
|
||||||
|
|
Loading…
Reference in New Issue