Add new typography settings, add new settings bar dropdowns, add settings bar to text components

This commit is contained in:
Andrew Kingston 2021-06-23 14:21:37 +01:00
parent 2dd5645aab
commit d0ba754a02
15 changed files with 448 additions and 315 deletions

View File

@ -8,6 +8,7 @@
import { capitalise } from "../utils/helpers" import { capitalise } from "../utils/helpers"
export let value export let value
export let size = "M"
let open = false let open = false
@ -110,7 +111,7 @@
<div class="container"> <div class="container">
<div <div
class="preview" class="preview size--{size || 'M'}"
style="background: {color};" style="background: {color};"
on:click={() => (open = true)} on:click={() => (open = true)}
/> />
@ -178,6 +179,18 @@
cursor: pointer; cursor: pointer;
box-shadow: 0 0 2px 2px var(--spectrum-global-color-gray-300); box-shadow: 0 0 2px 2px var(--spectrum-global-color-gray-300);
} }
.size--S {
width: 20px;
height: 20px;
}
.size--M {
width: 32px;
height: 32px;
}
.size--L {
width: 48px;
height: 48px;
}
.spectrum-Popover { .spectrum-Popover {
width: 210px; width: 210px;
z-index: 999; z-index: 999;

View File

@ -20,6 +20,7 @@
export let open = false export let open = false
export let readonly = false export let readonly = false
export let quiet = false export let quiet = false
export let autoWidth = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onClick = () => { const onClick = () => {
@ -41,7 +42,11 @@
aria-haspopup="listbox" aria-haspopup="listbox"
on:mousedown={onClick} on:mousedown={onClick}
> >
<span class="spectrum-Picker-label" class:is-placeholder={isPlaceholder}> <span
class="spectrum-Picker-label"
class:is-placeholder={isPlaceholder}
class:auto-width={autoWidth}
>
{fieldText} {fieldText}
</span> </span>
{#if error} {#if error}
@ -67,11 +72,12 @@
use:clickOutside={() => (open = false)} use:clickOutside={() => (open = false)}
transition:fly={{ y: -20, duration: 200 }} transition:fly={{ y: -20, duration: 200 }}
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open" class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
class:auto-width={autoWidth}
> >
<ul class="spectrum-Menu" role="listbox"> <ul class="spectrum-Menu" role="listbox">
{#if placeholderOption} {#if placeholderOption}
<li <li
class="spectrum-Menu-item" class="spectrum-Menu-item placeholder"
class:is-selected={isPlaceholder} class:is-selected={isPlaceholder}
role="option" role="option"
aria-selected="true" aria-selected="true"
@ -118,17 +124,28 @@
<style> <style>
.spectrum-Popover { .spectrum-Popover {
max-height: 240px; max-height: 240px;
width: 100%;
z-index: 999; z-index: 999;
top: 100%; top: 100%;
} }
.spectrum-Popover:not(.auto-width) {
width: 100%;
}
.spectrum-Popover.auto-width :global(.spectrum-Menu-itemLabel) {
white-space: nowrap;
}
.spectrum-Picker { .spectrum-Picker {
width: 100%; width: 100%;
} }
.spectrum-Picker-label { .spectrum-Picker-label:not(.auto-width) {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
width: 0; width: 0;
} }
.placeholder {
font-style: italic;
}
.spectrum-Picker-label.auto-width.is-placeholder {
padding-right: 2px;
}
</style> </style>

View File

@ -12,6 +12,7 @@
export let getOptionValue = option => option export let getOptionValue = option => option
export let readonly = false export let readonly = false
export let quiet = false export let quiet = false
export let autoWidth = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let open = false let open = false
@ -51,6 +52,7 @@
{readonly} {readonly}
{fieldText} {fieldText}
{options} {options}
{autoWidth}
{getOptionLabel} {getOptionLabel}
{getOptionValue} {getOptionValue}
isPlaceholder={value == null || value === ""} isPlaceholder={value == null || value === ""}

View File

@ -14,6 +14,7 @@
export let getOptionLabel = option => extractProperty(option, "label") export let getOptionLabel = option => extractProperty(option, "label")
export let getOptionValue = option => extractProperty(option, "value") export let getOptionValue = option => extractProperty(option, "value")
export let quiet = false export let quiet = false
export let autoWidth = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = e => {
@ -37,6 +38,7 @@
{value} {value}
{options} {options}
{placeholder} {placeholder}
{autoWidth}
{getOptionLabel} {getOptionLabel}
{getOptionValue} {getOptionValue}
on:change={onChange} on:change={onChange}

View File

@ -4,10 +4,13 @@
import iframeTemplate from "./iframeTemplate" import iframeTemplate from "./iframeTemplate"
import { Screen } from "builderStore/store/screenTemplates/utils/Screen" import { Screen } from "builderStore/store/screenTemplates/utils/Screen"
import { FrontendTypes } from "constants" import { FrontendTypes } from "constants"
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
let iframe let iframe
let layout let layout
let screen let screen
let confirmDeleteDialog
let idToDelete
// Create screen slot placeholder for use when a page is selected rather // Create screen slot placeholder for use when a page is selected rather
// than a screen // than a screen
@ -73,15 +76,26 @@
// Add listener for events sent by cliebt library in preview // Add listener for events sent by cliebt library in preview
iframe.contentWindow.addEventListener("bb-event", event => { iframe.contentWindow.addEventListener("bb-event", event => {
const { type, data } = event.detail const { type, data } = event.detail
if (type === "select-component") { if (type === "select-component" && data.id) {
store.actions.components.select({ _id: data.id }) store.actions.components.select({ _id: data.id })
} else if (type === "update-prop") { } else if (type === "update-prop") {
store.actions.components.updateProp(data.prop, data.value) store.actions.components.updateProp(data.prop, data.value)
} else if (type === "delete-component" && data.id) {
idToDelete = data.id
confirmDeleteDialog.show()
} else { } else {
console.log(data) console.log(data)
} }
}) })
}) })
const deleteComponent = () => {
store.actions.components.delete({ _id: idToDelete })
idToDelete = null
}
const cancelDeleteComponent = () => {
idToDelete = null
}
</script> </script>
<div class="component-container"> <div class="component-container">
@ -92,6 +106,14 @@
srcdoc={template} srcdoc={template}
/> />
</div> </div>
<ConfirmDialog
bind:this={confirmDeleteDialog}
title="Confirm Deletion"
body={`Are you sure you want to delete this component?`}
okText="Delete component"
onOk={deleteComponent}
onCancel={cancelDeleteComponent}
/>
<style> <style>
.component-container { .component-container {

View File

@ -1,6 +1,12 @@
<script> <script>
import { isEmpty } from "lodash/fp" import { isEmpty } from "lodash/fp"
import { Checkbox, Input, Select, DetailSummary } from "@budibase/bbui" import {
Checkbox,
Input,
Select,
DetailSummary,
ColorPicker,
} from "@budibase/bbui"
import { store } from "builderStore" import { store } from "builderStore"
import PropertyControl from "./PropertyControls/PropertyControl.svelte" import PropertyControl from "./PropertyControls/PropertyControl.svelte"
import LayoutSelect from "./PropertyControls/LayoutSelect.svelte" import LayoutSelect from "./PropertyControls/LayoutSelect.svelte"
@ -16,7 +22,6 @@
import EventsEditor from "./PropertyControls/EventsEditor" import EventsEditor from "./PropertyControls/EventsEditor"
import FilterEditor from "./PropertyControls/FilterEditor/FilterEditor.svelte" import FilterEditor from "./PropertyControls/FilterEditor/FilterEditor.svelte"
import { IconSelect } from "./PropertyControls/IconSelect" import { IconSelect } from "./PropertyControls/IconSelect"
import ColorPicker from "./PropertyControls/ColorPicker.svelte"
import StringFieldSelect from "./PropertyControls/StringFieldSelect.svelte" import StringFieldSelect from "./PropertyControls/StringFieldSelect.svelte"
import NumberFieldSelect from "./PropertyControls/NumberFieldSelect.svelte" import NumberFieldSelect from "./PropertyControls/NumberFieldSelect.svelte"
import OptionsFieldSelect from "./PropertyControls/OptionsFieldSelect.svelte" import OptionsFieldSelect from "./PropertyControls/OptionsFieldSelect.svelte"

View File

@ -1,85 +1,5 @@
import { Input, Select, ColorPicker } from "@budibase/bbui" import { Input, Select, ColorPicker } from "@budibase/bbui"
import FlatButtonGroup from "./PropertyControls/FlatButtonGroup" import FlatButtonGroup from "./PropertyControls/FlatButtonGroup"
// import Colorpicker from "./PropertyControls/ColorPicker.svelte"
export const layout = [
{
label: "Display",
key: "display",
control: Select,
options: [
{ label: "Block", value: "block" },
{ label: "Inline Block", value: "inline-block" },
{ label: "Flex", value: "flex" },
{ label: "Inline Flex", value: "inline-flex" },
],
},
{
label: "Direction",
key: "flex-direction",
control: FlatButtonGroup,
buttonProps: [
{ icon: "ri-arrow-right-line", padding: "0px 5px", value: "row" },
{ icon: "ri-arrow-left-line", padding: "0px 5px", value: "rowReverse" },
{ icon: "ri-arrow-down-line", padding: "0px 5px", value: "column" },
{
icon: "ri-arrow-up-line",
padding: "0px 5px",
value: "columnReverse",
},
{ icon: "ri-close-line", value: "" },
],
},
{
label: "Justify",
key: "justify-content",
control: Select,
options: [
{ label: "Flex Start", value: "flex-start" },
{ label: "Flex End", value: "flex-end" },
{ label: "Center", value: "center" },
{ label: "Space Between", value: "space-between" },
{ label: "Space Around", value: "space-around" },
{ label: "Space Evenly", value: "space-evenly" },
],
},
{
label: "Align",
key: "align-items",
control: Select,
options: [
{ label: "Flex Start", value: "flex-start" },
{ label: "Flex End", value: "flex-end" },
{ label: "Center", value: "center" },
{ label: "Baseline", value: "baseline" },
{ label: "Stretch", value: "stretch" },
],
},
{
label: "Wrap",
key: "flex-wrap",
control: Select,
options: [
{ label: "Wrap", value: "wrap" },
{ label: "No wrap", value: "nowrap" },
],
},
{
label: "Gap",
key: "gap",
control: Select,
options: [
{ label: "None", value: "0px" },
{ label: "4px", value: "4px" },
{ label: "8px", value: "8px" },
{ label: "16px", value: "16px" },
{ label: "20px", value: "20px" },
{ label: "32px", value: "32px" },
{ label: "48px", value: "48px" },
{ label: "64px", value: "64px" },
],
},
]
export const margin = { export const margin = {
label: "Margin", label: "Margin",
@ -274,116 +194,6 @@ export const size = {
], ],
} }
export const typography = [
{
label: "Font",
key: "font-family",
control: Select,
options: [
{ label: "Arial", value: "Arial" },
{ label: "Arial Black", value: "Arial Black" },
{ label: "Cursive", value: "Cursive" },
{ label: "Courier", value: "Courier" },
{ label: "Comic Sans MS", value: "Comic Sans MS" },
{ label: "Helvetica", value: "Helvetica" },
{ label: "Helvetica Neue", value: "Helvetica Neue" },
{ label: "Impact", value: "Impact" },
{ label: "Inter", value: "Inter" },
{ label: "Lucida Sans Unicode", value: "Lucida Sans Unicode" },
{ label: "Source Sans Pro", value: "Source Sans Pro" },
{ label: "Times New Roman", value: "Times New Roman" },
{ label: "Verdana", value: "Verdana" },
],
styleBindingProperty: "font-family",
},
{
label: "Weight",
key: "font-weight",
control: Select,
options: [
{ label: "200", value: "200" },
{ label: "300", value: "300" },
{ label: "400", value: "400" },
{ label: "500", value: "500" },
{ label: "600", value: "600" },
{ label: "700", value: "700" },
{ label: "800", value: "800" },
{ label: "900", value: "900" },
],
},
{
label: "size",
key: "font-size",
control: Select,
options: [
{ label: "8px", value: "8px" },
{ label: "10px", value: "10px" },
{ label: "12px", value: "12px" },
{ label: "14px", value: "14px" },
{ label: "16px", value: "16px" },
{ label: "18px", value: "18px" },
{ label: "20px", value: "20px" },
{ label: "24px", value: "24px" },
{ label: "32px", value: "32px" },
{ label: "48px", value: "48px" },
{ label: "60px", value: "60px" },
{ label: "72px", value: "72px" },
],
},
{
label: "Line H",
key: "line-height",
control: Select,
options: [
{ label: "1", value: "1" },
{ label: "1.25", value: "1.25" },
{ label: "1.5", value: "1.5" },
{ label: "1.75", value: "1.75" },
{ label: "2", value: "2" },
{ label: "4", value: "4" },
],
},
{
label: "Color",
key: "color",
control: ColorPicker,
},
{
label: "align",
key: "text-align",
control: FlatButtonGroup,
buttonProps: [
{ icon: "ri-align-left", padding: "0px 5px", value: "left" },
{ icon: "ri-align-center", padding: "0px 5px", value: "center" },
{ icon: "ri-align-right", padding: "0px 5px", value: "right" },
{ icon: "ri-align-justify", padding: "0px 5px", value: "justify" },
{ icon: "ri-close-line", value: "" },
],
},
{
label: "transform",
key: "text-transform",
control: FlatButtonGroup,
buttonProps: [
{ text: "BB", value: "uppercase" },
{ text: "Bb", value: "capitalize" },
{ text: "bb", value: "lowercase" },
{ icon: "ri-close-line", value: "" },
],
},
{
label: "Decoration",
key: "text-decoration-line",
control: Select,
options: [
{ label: "Underline", value: "underline" },
{ label: "Overline", value: "overline" },
{ label: "Line-through", value: "line-through" },
{ label: "Under Over", value: "underline overline" },
],
},
]
export const background = { export const background = {
label: "Background", label: "Background",
inline: true, inline: true,
@ -531,53 +341,4 @@ export const border = {
], ],
} }
export const transitions = [
{
label: "Property",
key: "transition-property",
control: Select,
options: [
{ label: "None", value: "none" },
{ label: "All", value: "all" },
{ label: "Background Color", value: "background color" },
{ label: "Color", value: "color" },
{ label: "Font Size", value: "font size" },
{ label: "Font Weight", value: "font weight" },
{ label: "Height", value: "height" },
{ label: "Margin", value: "margin" },
{ label: "Opacity", value: "opacity" },
{ label: "Padding", value: "padding" },
{ label: "Rotate", value: "rotate" },
{ label: "Shadow", value: "shadow" },
{ label: "Width", value: "width" },
],
},
{
label: "Duration",
key: "transition-duration",
control: Select,
placeholder: "sec",
options: [
{ label: "0.4s", value: "0.4s" },
{ label: "0.6s", value: "0.6s" },
{ label: "0.8s", value: "0.8s" },
{ label: "1s", value: "1s" },
{ label: "2s", value: "2s" },
{ label: "4s", value: "4s" },
],
},
{
label: "Ease",
key: "transition-timing-function",
control: Select,
options: [
{ label: "Linear", value: "linear" },
{ label: "Ease", value: "ease" },
{ label: "Ease in", value: "ease-in" },
{ label: "Ease out", value: "ease-out" },
{ label: "Ease in out", value: "ease-in-out" },
],
},
]
export const all = [margin] export const all = [margin]

View File

@ -1,6 +1,8 @@
<script> <script>
import { onMount, onDestroy } from "svelte" import { onMount, onDestroy } from "svelte"
import SettingsButton from "./SettingsButton.svelte" import SettingsButton from "./SettingsButton.svelte"
import SettingsColorPicker from "./SettingsColorPicker.svelte"
import SettingsPicker from "./SettingsPicker.svelte"
import { builderStore } from "../../store" import { builderStore } from "../../store"
import { domDebounce } from "../../utils/domDebounce" import { domDebounce } from "../../utils/domDebounce"
@ -87,6 +89,7 @@
> >
{#each settings as setting, idx} {#each settings as setting, idx}
{#if setting.type === "select"} {#if setting.type === "select"}
{#if setting.barStyle === "buttons"}
{#each setting.options as option} {#each setting.options as option}
<SettingsButton <SettingsButton
prop={setting.key} prop={setting.key}
@ -95,11 +98,35 @@
title={option.barTitle} title={option.barTitle}
/> />
{/each} {/each}
{:else}
<SettingsPicker
prop={setting.key}
options={setting.options}
label={setting.label}
/>
{/if} {/if}
{#if idx < settings.length - 1} {:else if setting.type === "boolean"}
<SettingsButton
prop={setting.key}
icon={setting.barIcon}
title={setting.barTitle}
bool
/>
{:else if setting.type === "color"}
<SettingsColorPicker prop={setting.key} />
{/if}
{#if setting.barSeparator !== false}
<div class="divider" /> <div class="divider" />
{/if} {/if}
{/each} {/each}
<SettingsButton
icon="Delete"
on:click={() => {
builderStore.actions.deleteComponent(
$builderStore.selectedComponent._id
)
}}
/>
</div> </div>
{/if} {/if}

View File

@ -1,6 +1,7 @@
<script> <script>
import { Icon } from "@budibase/bbui" import { Icon } from "@budibase/bbui"
import { builderStore } from "../../store" import { builderStore } from "../../store"
import { createEventDispatcher } from "svelte"
export let prop export let prop
export let value export let value
@ -9,6 +10,7 @@
export let rotate = false export let rotate = false
export let bool = false export let bool = false
const dispatch = createEventDispatcher()
$: currentValue = $builderStore.selectedComponent?.[prop] $: currentValue = $builderStore.selectedComponent?.[prop]
$: active = prop && (bool ? !!currentValue : currentValue === value) $: active = prop && (bool ? !!currentValue : currentValue === value)
</script> </script>
@ -22,6 +24,7 @@
const newValue = bool ? !currentValue : value const newValue = bool ? !currentValue : value
builderStore.actions.updateProp(prop, newValue) builderStore.actions.updateProp(prop, newValue)
} }
dispatch("click")
}} }}
> >
<Icon name={icon} size="S" /> <Icon name={icon} size="S" />

View File

@ -0,0 +1,26 @@
<script>
import { ColorPicker } from "@budibase/bbui"
import { builderStore } from "../../store"
export let prop
$: currentValue = $builderStore.selectedComponent?.[prop]
</script>
<div>
<ColorPicker
size="S"
value={currentValue}
on:change={e => {
if (prop) {
builderStore.actions.updateProp(prop, e.detail)
}
}}
/>
</div>
<style>
div {
padding: 0 4px;
}
</style>

View File

@ -0,0 +1,31 @@
<script>
import { Select } from "@budibase/bbui"
import { builderStore } from "../../store"
export let prop
export let options
export let label
$: currentValue = $builderStore.selectedComponent?.[prop]
</script>
<div>
<Select
quiet
autoWidth
placeholder={label}
{options}
value={currentValue}
on:change={e => {
if (prop) {
builderStore.actions.updateProp(prop, e.detail)
}
}}
/>
</div>
<style>
div {
padding: 0 4px;
}
</style>

View File

@ -56,13 +56,14 @@ const createBuilderStore = () => {
const actions = { const actions = {
selectComponent: id => { selectComponent: id => {
if (id) {
dispatchEvent("select-component", { id }) dispatchEvent("select-component", { id })
}
}, },
updateProp: (prop, value) => { updateProp: (prop, value) => {
dispatchEvent("update-prop", { prop, value }) dispatchEvent("update-prop", { prop, value })
}, },
deleteComponent: id => {
dispatchEvent("delete-component", { id })
},
} }
return { return {
...writableStore, ...writableStore,

View File

@ -4,7 +4,6 @@
"description": "This component is specific only to layouts", "description": "This component is specific only to layouts",
"icon": "Sandbox", "icon": "Sandbox",
"hasChildren": true, "hasChildren": true,
"styleable": true,
"styles": ["padding", "background"], "styles": ["padding", "background"],
"settings": [ "settings": [
{ {
@ -69,6 +68,7 @@
"label": "Direction", "label": "Direction",
"key": "direction", "key": "direction",
"showInBar": true, "showInBar": true,
"barStyle": "buttons",
"options": [ "options": [
{ {
"label": "Column", "label": "Column",
@ -90,6 +90,7 @@
"label": "Horiz. Align", "label": "Horiz. Align",
"key": "hAlign", "key": "hAlign",
"showInBar": true, "showInBar": true,
"barStyle": "buttons",
"options": [ "options": [
{ {
"label": "Left", "label": "Left",
@ -123,6 +124,7 @@
"label": "Vert. Align", "label": "Vert. Align",
"key": "vAlign", "key": "vAlign",
"showInBar": "true", "showInBar": "true",
"barStyle": "buttons",
"options": [ "options": [
{ {
"label": "Top", "label": "Top",
@ -156,6 +158,7 @@
"label": "Size", "label": "Size",
"key": "size", "key": "size",
"showInBar": true, "showInBar": true,
"barStyle": "buttons",
"options": [ "options": [
{ {
"label": "Shrink", "label": "Shrink",
@ -179,7 +182,6 @@
"description": "Add a section to your application", "description": "Add a section to your application",
"icon": "ColumnTwoB", "icon": "ColumnTwoB",
"hasChildren": true, "hasChildren": true,
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"showEmptyState": false, "showEmptyState": false,
"settings": [ "settings": [
@ -194,15 +196,13 @@
"screenslot": { "screenslot": {
"name": "Screenslot", "name": "Screenslot",
"icon": "WebPage", "icon": "WebPage",
"description": "Contains your app screens", "description": "Contains your app screens"
"styleable": true
}, },
"button": { "button": {
"name": "Button", "name": "Button",
"description": "A basic html button that is ready for styling", "description": "A basic html button that is ready for styling",
"icon": "Button", "icon": "Button",
"illegalChildren": ["section"], "illegalChildren": ["section"],
"styleable": true,
"settings": [ "settings": [
{ {
"type": "text", "type": "text",
@ -239,7 +239,6 @@
"name": "Repeater", "name": "Repeater",
"description": "A configurable data list that attaches to your backend tables.", "description": "A configurable data list that attaches to your backend tables.",
"icon": "ViewList", "icon": "ViewList",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"hasChildren": true, "hasChildren": true,
"settings": [ "settings": [
@ -268,7 +267,6 @@
"name": "Stacked List", "name": "Stacked List",
"icon": "TaskList", "icon": "TaskList",
"description": "A basic card component that can contain content and actions.", "description": "A basic card component that can contain content and actions.",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -298,7 +296,6 @@
"name": "Vertical Card", "name": "Vertical Card",
"description": "A basic card component that can contain content and actions.", "description": "A basic card component that can contain content and actions.",
"icon": "ViewColumn", "icon": "ViewColumn",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -359,13 +356,93 @@
"name": "Paragraph", "name": "Paragraph",
"description": "A component for displaying paragraph text.", "description": "A component for displaying paragraph text.",
"icon": "TextParagraph", "icon": "TextParagraph",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"showSettingsBar": true,
"settings": [ "settings": [
{ {
"type": "text", "type": "text",
"label": "Text", "label": "Text",
"key": "text" "key": "text"
},
{
"type": "select",
"label": "Size",
"key": "size",
"defaultValue": "Medium",
"showInBar": true,
"barStyle": "picker",
"options": [{
"label": "Small",
"value": "S"
}, {
"label": "Medium",
"value": "M"
}, {
"label": "Large",
"value": "L"
}]
},
{
"type": "color",
"label": "Color",
"key": "color",
"showInBar": true,
"barSeparator": false
},
{
"type": "boolean",
"label": "Bold",
"key": "bold",
"showInBar": true,
"barIcon": "TagBold",
"barTitle": "Bold text",
"barSeparator": false
},
{
"type": "boolean",
"label": "Italic",
"key": "italic",
"showInBar": true,
"barIcon": "TagItalic",
"barTitle": "Italic text",
"barSeparator": false
},
{
"type": "boolean",
"label": "Underline",
"key": "underline",
"showInBar": true,
"barIcon": "TagUnderline",
"barTitle": "Underline text"
},
{
"type": "select",
"label": "Alignment",
"key": "align",
"defaultValue": "left",
"showInBar": true,
"barStyle": "buttons",
"options": [{
"label": "Left",
"value": "left",
"barIcon": "TextAlignLeft",
"barTitle": "Align left"
}, {
"label": "Center",
"value": "center",
"barIcon": "TextAlignCenter",
"barTitle": "Align center"
}, {
"label": "Right",
"value": "right",
"barIcon": "TextAlignRight",
"barTitle": "Align right"
}, {
"label": "Justify",
"value": "justify",
"barIcon": "TextAlignJustify",
"barTitle": "Justify text"
}]
} }
] ]
}, },
@ -373,8 +450,8 @@
"name": "Headline", "name": "Headline",
"icon": "TextBold", "icon": "TextBold",
"description": "A component for displaying heading text", "description": "A component for displaying heading text",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"showSettingsBar": true,
"settings": [ "settings": [
{ {
"type": "text", "type": "text",
@ -383,10 +460,83 @@
}, },
{ {
"type": "select", "type": "select",
"key": "type", "label": "Size",
"label": "Type", "key": "size",
"options": ["h1", "h2", "h3", "h4", "h5", "h6"], "defaultValue": "Medium",
"defaultValue": "h1" "showInBar": true,
"barStyle": "picker",
"options": [{
"label": "Small",
"value": "S"
}, {
"label": "Medium",
"value": "M"
}, {
"label": "Large",
"value": "L"
}]
},
{
"type": "color",
"label": "Color",
"key": "color",
"showInBar": true,
"barSeparator": false
},
{
"type": "boolean",
"label": "Bold",
"key": "bold",
"showInBar": true,
"barIcon": "TagBold",
"barTitle": "Bold text",
"barSeparator": false
},
{
"type": "boolean",
"label": "Italic",
"key": "italic",
"showInBar": true,
"barIcon": "TagItalic",
"barTitle": "Italic text",
"barSeparator": false
},
{
"type": "boolean",
"label": "Underline",
"key": "underline",
"showInBar": true,
"barIcon": "TagUnderline",
"barTitle": "Underline text"
},
{
"type": "select",
"label": "Alignment",
"key": "align",
"defaultValue": "left",
"showInBar": true,
"barStyle": "buttons",
"options": [{
"label": "Left",
"value": "left",
"barIcon": "TextAlignLeft",
"barTitle": "Align left"
}, {
"label": "Center",
"value": "center",
"barIcon": "TextAlignCenter",
"barTitle": "Align center"
}, {
"label": "Right",
"value": "right",
"barIcon": "TextAlignRight",
"barTitle": "Align right"
}, {
"label": "Justify",
"value": "justify",
"barIcon": "TextAlignJustify",
"barTitle": "Justify text"
}]
} }
] ]
}, },
@ -394,7 +544,6 @@
"name": "Image", "name": "Image",
"description": "A basic component for displaying images", "description": "A basic component for displaying images",
"icon": "Image", "icon": "Image",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -408,7 +557,6 @@
"name": "Background Image", "name": "Background Image",
"description": "A background image", "description": "A background image",
"icon": "Images", "icon": "Images",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -466,7 +614,6 @@
"name": "Icon", "name": "Icon",
"description": "A basic component for displaying icons", "description": "A basic component for displaying icons",
"icon": "Bell", "icon": "Bell",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -514,7 +661,6 @@
"name": "Nav Bar", "name": "Nav Bar",
"description": "A component for handling the navigation within your app.", "description": "A component for handling the navigation within your app.",
"icon": "BreadcrumbNavigation", "icon": "BreadcrumbNavigation",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"hasChildren": true, "hasChildren": true,
"settings": [ "settings": [
@ -535,7 +681,6 @@
"name": "Link", "name": "Link",
"description": "A basic link component for internal and external links", "description": "A basic link component for internal and external links",
"icon": "Link", "icon": "Link",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -565,7 +710,6 @@
"name": "Horizontal Card", "name": "Horizontal Card",
"description": "A basic card component that can contain content and actions.", "description": "A basic card component that can contain content and actions.",
"icon": "ViewRow", "icon": "ViewRow",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -638,7 +782,6 @@
"name": "Stat Card", "name": "Stat Card",
"description": "A card component for displaying numbers.", "description": "A card component for displaying numbers.",
"icon": "Card", "icon": "Card",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -665,7 +808,6 @@
"name": "Embed", "name": "Embed",
"icon": "Code", "icon": "Code",
"description": "Embed content from 3rd party sources", "description": "Embed content from 3rd party sources",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -1228,7 +1370,6 @@
"form": { "form": {
"name": "Form", "name": "Form",
"icon": "Form", "icon": "Form",
"styleable": true,
"hasChildren": true, "hasChildren": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"actions": [ "actions": [
@ -1301,7 +1442,6 @@
"fieldgroup": { "fieldgroup": {
"name": "Field Group", "name": "Field Group",
"icon": "Group", "icon": "Group",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"hasChildren": true, "hasChildren": true,
"settings": [ "settings": [
@ -1330,7 +1470,6 @@
"stringfield": { "stringfield": {
"name": "Text Field", "name": "Text Field",
"icon": "Text", "icon": "Text",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -1359,7 +1498,6 @@
"numberfield": { "numberfield": {
"name": "Number Field", "name": "Number Field",
"icon": "123", "icon": "123",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -1388,7 +1526,6 @@
"passwordfield": { "passwordfield": {
"name": "Password Field", "name": "Password Field",
"icon": "LockClosed", "icon": "LockClosed",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -1417,7 +1554,6 @@
"optionsfield": { "optionsfield": {
"name": "Options Picker", "name": "Options Picker",
"icon": "ViewList", "icon": "ViewList",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -1447,7 +1583,6 @@
"booleanfield": { "booleanfield": {
"name": "Checkbox", "name": "Checkbox",
"icon": "Checkmark", "icon": "Checkmark",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -1476,7 +1611,6 @@
"longformfield": { "longformfield": {
"name": "Rich Text", "name": "Rich Text",
"icon": "TextParagraph", "icon": "TextParagraph",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -1506,7 +1640,6 @@
"datetimefield": { "datetimefield": {
"name": "Date Picker", "name": "Date Picker",
"icon": "DateInput", "icon": "DateInput",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -1541,7 +1674,6 @@
"attachmentfield": { "attachmentfield": {
"name": "Attachment", "name": "Attachment",
"icon": "Attach", "icon": "Attach",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -1565,7 +1697,6 @@
"relationshipfield": { "relationshipfield": {
"name": "Relationship Picker", "name": "Relationship Picker",
"icon": "TaskList", "icon": "TaskList",
"styleable": true,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"settings": [ "settings": [
{ {
@ -1595,7 +1726,6 @@
"name": "Data Provider", "name": "Data Provider",
"info": "Pagination is only available for data stored in internal tables.", "info": "Pagination is only available for data stored in internal tables.",
"icon": "Data", "icon": "Data",
"styleable": false,
"illegalChildren": ["section"], "illegalChildren": ["section"],
"hasChildren": true, "hasChildren": true,
"settings": [ "settings": [
@ -1740,7 +1870,6 @@
"daterangepicker": { "daterangepicker": {
"name": "Date Range", "name": "Date Range",
"icon": "Date", "icon": "Date",
"styleable": true,
"hasChildren": false, "hasChildren": false,
"info": "Your data provider will be automatically filtered to the given date range.", "info": "Your data provider will be automatically filtered to the given date range.",
"settings": [ "settings": [

View File

@ -4,41 +4,83 @@
const { styleable, builderStore } = getContext("sdk") const { styleable, builderStore } = getContext("sdk")
const component = getContext("component") const component = getContext("component")
export let type
export let text export let text
export let color
export let align
export let bold
export let italic
export let underline
export let size
$: placeholder = $builderStore.inBuilder && !text $: placeholder = $builderStore.inBuilder && !text
$: componentText = $builderStore.inBuilder $: componentText = $builderStore.inBuilder
? text || "Placeholder text" ? text || "Placeholder text"
: text || "" : text || ""
// Add color styles to main styles object, otherwise the styleable helper
// overrides the color when it's passed as inline style.
$: styles = {
...$component.styles,
normal: {
...$component.styles?.normal,
color,
},
}
</script> </script>
{#if type === "h1"} <h1
<h1 class:placeholder use:styleable={$component.styles}>{componentText}</h1> use:styleable={styles}
{:else if type === "h2"} class:placeholder
<h2 class:placeholder use:styleable={$component.styles}>{componentText}</h2> class:bold
{:else if type === "h3"} class:italic
<h3 class:placeholder use:styleable={$component.styles}>{componentText}</h3> class:underline
{:else if type === "h4"} class="align--{align || 'left'} size--{size || 'M'}"
<h4 class:placeholder use:styleable={$component.styles}>{componentText}</h4> >
{:else if type === "h5"} {#if bold}
<h5 class:placeholder use:styleable={$component.styles}>{componentText}</h5> <strong>{componentText}</strong>
{:else if type === "h6"} {:else}
<h6 class:placeholder use:styleable={$component.styles}>{componentText}</h6> {componentText}
{/if} {/if}
</h1>
<style> <style>
h1, h1 {
h2, display: inline-block;
h3,
h4,
h5,
h6 {
white-space: pre-wrap; white-space: pre-wrap;
font-weight: 600;
} }
.placeholder { .placeholder {
font-style: italic; font-style: italic;
color: var(--grey-6); color: var(--grey-6);
} }
.bold {
font-weight: 700;
}
.italic {
font-style: italic;
}
.underline {
text-decoration: underline;
}
.size--S {
font-size: 18px;
}
.size--M {
font-size: 22px;
}
.size--L {
font-size: 28px;
}
.align--left {
text-align: left;
}
.align--center {
text-align: center;
}
.align--right {
text-align: right;
}
.align-justify {
text-align: justify;
}
</style> </style>

View File

@ -5,14 +5,37 @@
const component = getContext("component") const component = getContext("component")
export let text export let text
export let color
export let align
export let bold
export let italic
export let underline
export let size
$: placeholder = $builderStore.inBuilder && !text $: placeholder = $builderStore.inBuilder && !text
$: componentText = $builderStore.inBuilder $: componentText = $builderStore.inBuilder
? text || "Placeholder text" ? text || "Placeholder text"
: text || "" : text || ""
// Add color styles to main styles object, otherwise the styleable helper
// overrides the color when it's passed as inline style.
$: styles = {
...$component.styles,
normal: {
...$component.styles?.normal,
color,
},
}
</script> </script>
<p use:styleable={$component.styles} class:placeholder> <p
use:styleable={styles}
class:placeholder
class:bold
class:italic
class:underline
class="align--{align || 'left'} size--{size || 'M'}"
>
{componentText} {componentText}
</p> </p>
@ -21,9 +44,38 @@
display: inline-block; display: inline-block;
white-space: pre-wrap; white-space: pre-wrap;
} }
.placeholder { .placeholder {
font-style: italic; font-style: italic;
color: var(--grey-6); color: var(--grey-6);
} }
.bold {
font-weight: 600;
}
.italic {
font-style: italic;
}
.underline {
text-decoration: underline;
}
.size--S {
font-size: 14px;
}
.size--M {
font-size: 16px;
}
.size--L {
font-size: 18px;
}
.align--left {
text-align: left;
}
.align--center {
text-align: center;
}
.align--right {
text-align: right;
}
.align-justify {
text-align: justify;
}
</style> </style>