budibase/packages/builder/src/components/userInterface/ComponentPropertiesPanel.sv...

214 lines
4.6 KiB
Svelte
Raw Normal View History

2020-01-21 15:50:35 +01:00
<script>
2020-02-03 10:50:30 +01:00
import PropsView from "./PropsView.svelte"
import { store } from "builderStore"
import IconButton from "components/common/IconButton.svelte"
2020-02-03 10:50:30 +01:00
import {
LayoutIcon,
PaintIcon,
TerminalIcon,
CircleIndicator,
EventsIcon,
} from "components/common/Icons/"
2020-02-03 10:50:30 +01:00
import CodeEditor from "./CodeEditor.svelte"
import LayoutEditor from "./LayoutEditor.svelte"
import EventsEditor from "./EventsEditor"
let current_view = "props"
let codeEditor
$: component = $store.currentComponentInfo
$: originalName = component.name
2020-02-26 10:43:38 +01:00
$: name =
$store.currentView === "detail"
? $store.currentPreviewItem.name
: component._component
2020-02-03 10:50:30 +01:00
$: description = component.description
$: components = $store.components
2020-02-26 10:43:38 +01:00
$: screen_props =
$store.currentFrontEndType === "page"
? getProps($store.currentPreviewItem, ["name", "favicon"])
: getProps($store.currentPreviewItem, ["name", "description", "route"])
2020-03-06 18:00:54 +01:00
2020-02-03 10:50:30 +01:00
const onStyleChanged = store.setComponentStyle
2020-02-26 10:43:38 +01:00
function getProps(obj, keys) {
return keys.map((key, i) => [key, obj[key], obj.props._id + i])
2020-02-26 10:43:38 +01:00
}
2020-01-21 15:50:35 +01:00
</script>
<div class="root">
2020-02-03 10:50:30 +01:00
<ul>
<li>
<button
class:selected={current_view === 'props'}
on:click={() => (current_view = 'props')}>
<PaintIcon />
</button>
</li>
<li>
<button
class:selected={current_view === 'layout'}
on:click={() => (current_view = 'layout')}>
<LayoutIcon />
</button>
</li>
2020-02-18 16:53:22 +01:00
{#if !component._component.startsWith('##')}
<li>
<button
class:selected={current_view === 'code'}
on:click={() => codeEditor && codeEditor.show()}>
{#if component._code && component._code.trim().length > 0}
<div class="button-indicator">
<CircleIndicator />
</div>
{/if}
<TerminalIcon />
</button>
</li>
<li>
<button
class:selected={current_view === 'events'}
on:click={() => (current_view = 'events')}>
<EventsIcon />
</button>
</li>
{/if}
2020-02-03 10:50:30 +01:00
</ul>
<div class="component-props-container">
{#if current_view === 'props'}
2020-02-26 10:43:38 +01:00
{#if $store.currentView === 'detail'}
{#each screen_props as [k, v, id] (id)}
<div class="detail-prop" for={k}>
<label>{k}:</label>
<input
id={k}
value={v}
2020-02-26 13:45:20 +01:00
on:input={({ target }) => store.setMetadataProp(k, target.value)} />
2020-02-26 10:43:38 +01:00
</div>
{/each}
2020-05-07 23:15:09 +02:00
<PropsView {component} {components} />
2020-02-26 10:43:38 +01:00
{:else}
2020-05-07 23:15:09 +02:00
<PropsView {component} {components} />
2020-02-26 10:43:38 +01:00
{/if}
{:else if current_view === 'layout'}
<LayoutEditor {onStyleChanged} {component} />
{:else if current_view === 'events'}
2020-05-07 23:15:09 +02:00
<EventsEditor {component} {components} />
{/if}
<CodeEditor
bind:this={codeEditor}
code={component._code}
onCodeChanged={store.setComponentCode} />
</div>
</div>
2020-01-21 15:50:35 +01:00
<style>
2020-02-26 10:43:38 +01:00
.detail-prop {
height: 40px;
margin-bottom: 15px;
display: grid;
grid-template-rows: 1fr;
grid-template-columns: 70px 1fr;
grid-gap: 10px;
}
.detail-prop label {
word-wrap: break-word;
font-size: 13px;
2020-02-26 10:43:38 +01:00
font-weight: 700;
color: #163057;
opacity: 0.6;
padding-top: 13px;
2020-02-26 10:43:38 +01:00
margin-bottom: 0;
}
input {
height: 30px;
padding-left: 8px;
padding-right: 8px;
border: 1px solid #dbdbdb;
border-radius: 2px;
opacity: 0.5;
}
input:focus {
outline: 0;
background-color: #fff;
color: #666;
border-color: #1e87f0;
}
2020-02-03 10:50:30 +01:00
.root {
2020-01-21 15:50:35 +01:00
height: 100%;
2020-04-17 11:45:53 +02:00
padding: 20px;
2020-01-21 15:50:35 +01:00
display: flex;
flex-direction: column;
2020-02-03 10:50:30 +01:00
}
2020-01-21 15:50:35 +01:00
2020-02-03 10:50:30 +01:00
.title > div:nth-child(1) {
2020-01-21 15:50:35 +01:00
grid-column-start: name;
color: var(--secondary100);
2020-02-03 10:50:30 +01:00
}
2020-01-21 15:50:35 +01:00
2020-02-03 10:50:30 +01:00
.title > div:nth-child(2) {
2020-01-21 15:50:35 +01:00
grid-column-start: actions;
2020-02-03 10:50:30 +01:00
}
2020-01-21 15:50:35 +01:00
2020-02-03 10:50:30 +01:00
.component-props-container {
margin-top: 10px;
2020-01-21 15:50:35 +01:00
flex: 1 1 auto;
2020-02-03 10:50:30 +01:00
}
2020-01-21 15:50:35 +01:00
2020-02-03 10:50:30 +01:00
ul {
2020-01-21 15:50:35 +01:00
list-style: none;
display: flex;
2020-03-24 11:56:48 +01:00
justify-content: space-between;
2020-01-21 15:50:35 +01:00
padding: 0;
2020-02-03 10:50:30 +01:00
}
2020-01-21 15:50:35 +01:00
2020-02-03 10:50:30 +01:00
li {
2020-01-21 15:50:35 +01:00
background: none;
2020-03-24 11:56:48 +01:00
border-radius: 3px;
2020-01-22 12:30:19 +01:00
width: 48px;
height: 48px;
2020-02-03 10:50:30 +01:00
}
2020-01-21 15:50:35 +01:00
2020-02-03 10:50:30 +01:00
li button {
2020-03-24 11:56:48 +01:00
width: 48px;
height: 48px;
2020-01-21 15:50:35 +01:00
background: none;
border: none;
2020-03-24 11:56:48 +01:00
border-radius: 3px;
padding: 7px;
2020-01-21 15:50:35 +01:00
outline: none;
cursor: pointer;
position: relative;
2020-02-03 10:50:30 +01:00
}
2020-01-21 15:50:35 +01:00
2020-03-24 11:56:48 +01:00
li:nth-last-child(1) {
margin-right: 0px;
background: none;
border-radius: 3px;
width: 48px;
height: 48px;
}
2020-02-03 10:50:30 +01:00
.selected {
2020-01-21 15:50:35 +01:00
color: var(--button-text);
2020-03-24 11:56:48 +01:00
background: #f9f9f9 !important;
width: 48px;
height: 48px;
2020-02-03 10:50:30 +01:00
}
2020-01-21 15:50:35 +01:00
2020-02-03 10:50:30 +01:00
.button-indicator {
position: absolute;
top: 8px;
right: 10px;
color: var(--button-text);
2020-02-03 10:50:30 +01:00
}
2020-01-21 15:50:35 +01:00
</style>