Merge pull request #1701 from Budibase/interactive-layouts
Interactive builder preview and friendly containers
This commit is contained in:
commit
17f69c6e34
|
@ -5,6 +5,7 @@
|
|||
|
||||
export let disabled = false
|
||||
export let align = "left"
|
||||
export let portalTarget
|
||||
|
||||
let anchor
|
||||
let dropdown
|
||||
|
@ -32,7 +33,7 @@
|
|||
<div use:getAnchor on:click={openMenu}>
|
||||
<slot name="control" />
|
||||
</div>
|
||||
<Popover bind:this={dropdown} {anchor} {align}>
|
||||
<Popover bind:this={dropdown} {anchor} {align} {portalTarget}>
|
||||
<Menu>
|
||||
<slot />
|
||||
</Menu>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
export let anchor
|
||||
export let align = "right"
|
||||
export let portalTarget
|
||||
|
||||
export const show = () => {
|
||||
dispatch("open")
|
||||
|
@ -30,7 +31,7 @@
|
|||
</script>
|
||||
|
||||
{#if open}
|
||||
<Portal>
|
||||
<Portal target={portalTarget}>
|
||||
<div
|
||||
tabindex="0"
|
||||
use:positionDropdown={{ anchor, align }}
|
||||
|
|
|
@ -29,7 +29,7 @@ context("Create Bindings", () => {
|
|||
// The builder preview pages don't have a real URL, so all we can do
|
||||
// is check that we were able to bind to the property, and that the
|
||||
// component exists on the page
|
||||
cy.getComponent(componentId).should("have.text", "")
|
||||
cy.getComponent(componentId).should("have.text", "Placeholder text")
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -6,9 +6,5 @@ export default {
|
|||
}
|
||||
|
||||
const createScreen = () => {
|
||||
return new Screen()
|
||||
.mainType("div")
|
||||
.component("@budibase/standard-components/container")
|
||||
.instanceName("New Screen")
|
||||
.json()
|
||||
return new Screen().instanceName("New Screen").json()
|
||||
}
|
||||
|
|
|
@ -28,8 +28,10 @@ function generateTitleContainer(table, formId) {
|
|||
|
||||
const createScreen = table => {
|
||||
const screen = new Screen()
|
||||
.component("@budibase/standard-components/container")
|
||||
.instanceName(`${table.name} - New`)
|
||||
.customProps({
|
||||
hAlign: "center",
|
||||
})
|
||||
.route(newRowUrl(table))
|
||||
|
||||
const form = makeMainForm()
|
||||
|
|
|
@ -149,9 +149,11 @@ const createScreen = table => {
|
|||
provider.addChild(repeater)
|
||||
|
||||
return new Screen()
|
||||
.component("@budibase/standard-components/container")
|
||||
.instanceName(`${table.name} - Detail`)
|
||||
.route(rowDetailUrl(table))
|
||||
.customProps({
|
||||
hAlign: "center",
|
||||
})
|
||||
.addChild(provider)
|
||||
.json()
|
||||
}
|
||||
|
|
|
@ -56,14 +56,15 @@ function generateTitleContainer(table) {
|
|||
.text(table.name)
|
||||
|
||||
return new Component("@budibase/standard-components/container")
|
||||
.type("div")
|
||||
.normalStyle({
|
||||
display: "flex",
|
||||
"flex-direction": "row",
|
||||
"justify-content": "space-between",
|
||||
"align-items": "center",
|
||||
"margin-bottom": "32px",
|
||||
})
|
||||
.customProps({
|
||||
direction: "row",
|
||||
hAlign: "stretch",
|
||||
vAlign: "middle",
|
||||
size: "shrink",
|
||||
})
|
||||
.instanceName("Title Container")
|
||||
.addChild(heading)
|
||||
.addChild(newButton)
|
||||
|
@ -79,7 +80,8 @@ const createScreen = table => {
|
|||
tableId: table._id,
|
||||
type: "table",
|
||||
},
|
||||
paginate: false,
|
||||
paginate: true,
|
||||
limit: 8,
|
||||
})
|
||||
|
||||
const spectrumTable = new Component("@budibase/standard-components/table")
|
||||
|
@ -126,7 +128,6 @@ const createScreen = table => {
|
|||
background: "white",
|
||||
"border-radius": "0.5rem",
|
||||
"box-shadow": "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
||||
margin: "auto",
|
||||
"margin-top": "20px",
|
||||
"border-width": "2px",
|
||||
"border-color": "rgba(0, 0, 0, 0.1)",
|
||||
|
@ -137,13 +138,17 @@ const createScreen = table => {
|
|||
"padding-left": "48px",
|
||||
"margin-bottom": "20px",
|
||||
})
|
||||
.type("div")
|
||||
.customProps({
|
||||
direction: "column",
|
||||
hAlign: "stretch",
|
||||
vAlign: "top",
|
||||
size: "shrink",
|
||||
})
|
||||
.instanceName("Container")
|
||||
.addChild(generateTitleContainer(table))
|
||||
.addChild(provider)
|
||||
|
||||
return new Screen()
|
||||
.component("@budibase/standard-components/container")
|
||||
.route(rowListUrl(table))
|
||||
.instanceName(`${table.name} - List`)
|
||||
.addChild(mainContainer)
|
||||
|
|
|
@ -8,7 +8,7 @@ export class Screen extends BaseStructure {
|
|||
layoutId: "layout_private_master",
|
||||
props: {
|
||||
_id: uuid(),
|
||||
_component: "",
|
||||
_component: "@budibase/standard-components/container",
|
||||
_styles: {
|
||||
normal: {},
|
||||
hover: {},
|
||||
|
@ -17,6 +17,10 @@ export class Screen extends BaseStructure {
|
|||
},
|
||||
_children: [],
|
||||
_instanceName: "",
|
||||
direction: "column",
|
||||
hAlign: "stretch",
|
||||
vAlign: "top",
|
||||
size: "grow",
|
||||
},
|
||||
routing: {
|
||||
route: "",
|
||||
|
@ -41,11 +45,6 @@ export class Screen extends BaseStructure {
|
|||
return this
|
||||
}
|
||||
|
||||
mainType(type) {
|
||||
this._json.type = type
|
||||
return this
|
||||
}
|
||||
|
||||
route(route) {
|
||||
this._json.routing.route = route
|
||||
return this
|
||||
|
@ -60,4 +59,11 @@ export class Screen extends BaseStructure {
|
|||
this._json.props._instanceName = name
|
||||
return this
|
||||
}
|
||||
|
||||
customProps(props) {
|
||||
for (let key of Object.keys(props)) {
|
||||
this._json.props[key] = props[key]
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,13 +35,11 @@ export function makeLinkComponent(tableName) {
|
|||
|
||||
export function makeMainForm() {
|
||||
return new Component("@budibase/standard-components/form")
|
||||
.type("div")
|
||||
.normalStyle({
|
||||
width: "700px",
|
||||
padding: "0px",
|
||||
"border-radius": "0.5rem",
|
||||
"box-shadow": "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
||||
margin: "auto",
|
||||
"margin-top": "20px",
|
||||
"padding-top": "48px",
|
||||
"padding-bottom": "48px",
|
||||
|
@ -79,11 +77,16 @@ export function makeBreadcrumbContainer(tableName, text, capitalise = false) {
|
|||
.instanceName("Identifier")
|
||||
|
||||
return new Component("@budibase/standard-components/container")
|
||||
.type("div")
|
||||
.normalStyle({
|
||||
"font-size": "14px",
|
||||
color: "#757575",
|
||||
})
|
||||
.customProps({
|
||||
direction: "row",
|
||||
hAlign: "left",
|
||||
vAlign: "middle",
|
||||
size: "shrink",
|
||||
})
|
||||
.instanceName("Breadcrumbs")
|
||||
.addChild(link)
|
||||
.addChild(arrowText)
|
||||
|
@ -149,15 +152,16 @@ export function makeTitleContainer(title) {
|
|||
.text(title)
|
||||
|
||||
return new Component("@budibase/standard-components/container")
|
||||
.type("div")
|
||||
.normalStyle({
|
||||
display: "flex",
|
||||
"flex-direction": "row",
|
||||
"justify-content": "space-between",
|
||||
"align-items": "center",
|
||||
"margin-top": "32px",
|
||||
"margin-bottom": "32px",
|
||||
})
|
||||
.customProps({
|
||||
direction: "row",
|
||||
hAlign: "stretch",
|
||||
vAlign: "middle",
|
||||
size: "shrink",
|
||||
})
|
||||
.instanceName("Title Container")
|
||||
.addChild(heading)
|
||||
}
|
||||
|
|
|
@ -70,9 +70,16 @@
|
|||
{ once: true }
|
||||
)
|
||||
|
||||
// Add listener to select components
|
||||
iframe.contentWindow.addEventListener("bb-select-component", data => {
|
||||
store.actions.components.select({ _id: data.detail })
|
||||
// Add listener for events sent by cliebt library in preview
|
||||
iframe.contentWindow.addEventListener("bb-event", event => {
|
||||
const { type, data } = event.detail
|
||||
if (type === "select-component") {
|
||||
store.actions.components.select({ _id: data.id })
|
||||
} else if (type === "update-prop") {
|
||||
store.actions.components.updateProp(data.prop, data.value)
|
||||
} else {
|
||||
console.log(data)
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
@ -94,12 +101,12 @@
|
|||
overflow: hidden;
|
||||
margin: auto;
|
||||
height: 100%;
|
||||
background-color: white;
|
||||
}
|
||||
.component-container iframe {
|
||||
border: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -14,10 +14,14 @@ export default `
|
|||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
body {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
*,
|
||||
|
|
|
@ -194,7 +194,6 @@
|
|||
padding: var(--spacing-l) 40px var(--spacing-xl) 40px;
|
||||
}
|
||||
.preview-content {
|
||||
background: var(--background);
|
||||
box-shadow: 0 0 12px rgba(0, 0, 0, 0.05);
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
|
|
@ -18,13 +18,14 @@
|
|||
"dev:builder": "rollup -cw"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "^0.9.46",
|
||||
"@budibase/standard-components": "^0.9.46",
|
||||
"@budibase/string-templates": "^0.9.46",
|
||||
"regexparam": "^1.3.0",
|
||||
"shortid": "^2.2.15",
|
||||
"svelte-spa-router": "^3.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@budibase/standard-components": "^0.9.46",
|
||||
"@rollup/plugin-commonjs": "^18.0.0",
|
||||
"@rollup/plugin-node-resolve": "^11.2.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
builderStore,
|
||||
} from "../store"
|
||||
import { TableNames, ActionTypes } from "../constants"
|
||||
import SettingsBar from "./preview/SettingsBar.svelte"
|
||||
import SelectionIndicator from "./preview/SelectionIndicator.svelte"
|
||||
import HoverIndicator from "./preview/HoverIndicator.svelte"
|
||||
|
||||
// Provide contexts
|
||||
setContext("sdk", SDK)
|
||||
|
@ -54,18 +57,46 @@
|
|||
</script>
|
||||
|
||||
{#if dataLoaded && $screenStore.activeLayout}
|
||||
<div lang="en" dir="ltr" class="spectrum spectrum--medium spectrum--light">
|
||||
<div
|
||||
id="spectrum-root"
|
||||
lang="en"
|
||||
dir="ltr"
|
||||
class="spectrum spectrum--medium spectrum--light"
|
||||
>
|
||||
<Provider key="user" data={$authStore} {actions}>
|
||||
<Component definition={$screenStore.activeLayout.props} />
|
||||
<div id="app-root">
|
||||
<Component instance={$screenStore.activeLayout.props} />
|
||||
</div>
|
||||
<NotificationDisplay />
|
||||
<!-- Key block needs to be outside the if statement or it breaks -->
|
||||
{#key $builderStore.selectedComponentId}
|
||||
{#if $builderStore.inBuilder}
|
||||
<SettingsBar />
|
||||
{/if}
|
||||
{/key}
|
||||
<!--
|
||||
We don't want to key these by componentID as they control their own
|
||||
re-mounting to avoid flashes.
|
||||
-->
|
||||
{#if $builderStore.inBuilder}
|
||||
<SelectionIndicator />
|
||||
<HoverIndicator />
|
||||
{/if}
|
||||
</Provider>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
div {
|
||||
background: transparent;
|
||||
#spectrum-root {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app-root {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
import { enrichProps, propsAreSame } from "../utils/componentProps"
|
||||
import { builderStore } from "../store"
|
||||
import { hashString } from "../utils/hash"
|
||||
import Manifest from "@budibase/standard-components/manifest.json"
|
||||
import { Placeholder } from "@budibase/standard-components"
|
||||
|
||||
export let definition = {}
|
||||
export let instance = {}
|
||||
|
||||
// Props that will be passed to the component instance
|
||||
let componentProps
|
||||
|
@ -23,25 +25,39 @@
|
|||
|
||||
// Get contexts
|
||||
const context = getContext("context")
|
||||
const insideScreenslot = !!getContext("screenslot")
|
||||
|
||||
// Create component context
|
||||
const componentStore = writable({})
|
||||
setContext("component", componentStore)
|
||||
|
||||
// Extract component definition info
|
||||
$: constructor = getComponentConstructor(definition._component)
|
||||
$: children = definition._children || []
|
||||
$: id = definition._id
|
||||
$: updateComponentProps(definition, $context)
|
||||
$: styles = definition._styles
|
||||
$: transition = definition._transition
|
||||
// Extract component instance info
|
||||
$: constructor = getComponentConstructor(instance._component)
|
||||
$: definition = getComponentDefinition(instance._component)
|
||||
$: children = instance._children || []
|
||||
$: id = instance._id
|
||||
$: name = instance._instanceName
|
||||
$: empty =
|
||||
!children.length &&
|
||||
definition?.hasChildren &&
|
||||
definition?.showEmptyState !== false &&
|
||||
$builderStore.inBuilder
|
||||
$: updateComponentProps(instance, $context)
|
||||
$: selected =
|
||||
$builderStore.inBuilder &&
|
||||
$builderStore.selectedComponentId === instance._id
|
||||
$: interactive = $builderStore.previewType === "layout" || insideScreenslot
|
||||
|
||||
// Update component context
|
||||
$: componentStore.set({
|
||||
id,
|
||||
children: children.length,
|
||||
styles: { ...styles, id },
|
||||
transition,
|
||||
styles: { ...instance._styles, id, empty, interactive },
|
||||
empty,
|
||||
transition: instance._transition,
|
||||
selected,
|
||||
props: componentProps,
|
||||
name,
|
||||
})
|
||||
|
||||
// Gets the component constructor for the specified component
|
||||
|
@ -54,14 +70,20 @@
|
|||
return ComponentLibrary[name]
|
||||
}
|
||||
|
||||
const getComponentDefinition = component => {
|
||||
const prefix = "@budibase/standard-components/"
|
||||
const type = component?.replace(prefix, "")
|
||||
return type ? Manifest[type] : null
|
||||
}
|
||||
|
||||
// Enriches any string component props using handlebars
|
||||
const updateComponentProps = (definition, context) => {
|
||||
const updateComponentProps = (instance, context) => {
|
||||
// Record the timestamp so we can reference it after enrichment
|
||||
latestUpdateTime = Date.now()
|
||||
const enrichmentTime = latestUpdateTime
|
||||
|
||||
// Enrich props with context
|
||||
const enrichedProps = enrichProps(definition, context)
|
||||
const enrichedProps = enrichProps(instance, context)
|
||||
|
||||
// Abandon this update if a newer update has started
|
||||
if (enrichmentTime !== latestUpdateTime) {
|
||||
|
@ -94,14 +116,29 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
{#if constructor && componentProps}
|
||||
<div
|
||||
class={`component ${id}`}
|
||||
data-type={interactive ? "component" : ""}
|
||||
data-id={id}
|
||||
data-name={name}
|
||||
>
|
||||
{#key propsHash}
|
||||
<svelte:component this={constructor} {...componentProps}>
|
||||
{#if children.length}
|
||||
{#each children as child (child._id)}
|
||||
<svelte:self definition={child} />
|
||||
{/each}
|
||||
{/if}
|
||||
</svelte:component>
|
||||
{#if constructor && componentProps}
|
||||
<svelte:component this={constructor} {...componentProps}>
|
||||
{#if children.length}
|
||||
{#each children as child (child._id)}
|
||||
<svelte:self instance={child} />
|
||||
{/each}
|
||||
{:else if empty}
|
||||
<Placeholder />
|
||||
{/if}
|
||||
</svelte:component>
|
||||
{/if}
|
||||
{/key}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.component {
|
||||
display: contents;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import { setContext, getContext } from "svelte"
|
||||
import Router from "svelte-spa-router"
|
||||
import { routeStore } from "../store"
|
||||
import Screen from "./Screen.svelte"
|
||||
import { onMount } from "svelte"
|
||||
|
||||
const { styleable } = getContext("sdk")
|
||||
const component = getContext("component")
|
||||
setContext("screenslot", true)
|
||||
|
||||
// Only wrap this as an array to take advantage of svelte keying,
|
||||
// to ensure the svelte-spa-router is fully remounted when route config
|
||||
|
@ -41,5 +41,6 @@
|
|||
<style>
|
||||
div {
|
||||
position: relative;
|
||||
overflow-x: auto;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -22,6 +22,6 @@
|
|||
<!-- Ensure to fully remount when screen changes -->
|
||||
{#key screenDefinition?._id}
|
||||
<Provider key="url" data={params}>
|
||||
<Component definition={screenDefinition} />
|
||||
<Component instance={screenDefinition} />
|
||||
</Provider>
|
||||
{/key}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<script>
|
||||
import { onMount, onDestroy } from "svelte"
|
||||
import IndicatorSet from "./IndicatorSet.svelte"
|
||||
import { builderStore } from "../../store"
|
||||
|
||||
let componentId
|
||||
$: zIndex = componentId === $builderStore.selectedComponentId ? 900 : 920
|
||||
|
||||
const onMouseOver = e => {
|
||||
const element = e.target.closest("[data-type='component']")
|
||||
const newId = element?.dataset?.id
|
||||
if (newId !== componentId) {
|
||||
componentId = newId
|
||||
}
|
||||
}
|
||||
|
||||
const onMouseLeave = () => {
|
||||
componentId = null
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
document.addEventListener("mouseover", onMouseOver)
|
||||
document.body.addEventListener("mouseleave", onMouseLeave)
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
document.removeEventListener("mouseover", onMouseOver)
|
||||
document.body.removeEventListener("mouseleave", onMouseLeave)
|
||||
})
|
||||
</script>
|
||||
|
||||
<IndicatorSet {componentId} color="rgb(120, 170, 244)" transition {zIndex} />
|
|
@ -0,0 +1,61 @@
|
|||
<script>
|
||||
import { fade } from "svelte/transition"
|
||||
|
||||
export let top
|
||||
export let left
|
||||
export let width
|
||||
export let height
|
||||
export let text
|
||||
export let color
|
||||
export let zIndex
|
||||
export let transition = false
|
||||
</script>
|
||||
|
||||
<div
|
||||
in:fade={{
|
||||
delay: transition ? 50 : 0,
|
||||
duration: transition ? 130 : 0,
|
||||
}}
|
||||
out:fade={{ duration: transition ? 130 : 0 }}
|
||||
class="indicator"
|
||||
style="top: {top}px; left: {left}px; width: {width}px; height: {height}px; --color: {color}; --zIndex: {zIndex};"
|
||||
>
|
||||
{#if text}
|
||||
<div class="text" class:flipped={top < 22}>
|
||||
{text}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.indicator {
|
||||
position: fixed;
|
||||
z-index: var(--zIndex);
|
||||
border: 2px solid var(--color);
|
||||
pointer-events: none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.text {
|
||||
background-color: var(--color);
|
||||
color: white;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -2px;
|
||||
height: 20px;
|
||||
padding: 0 8px 2px 8px;
|
||||
transform: translateY(-100%);
|
||||
font-size: 11px;
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
.flipped {
|
||||
transform: translateY(0%);
|
||||
top: -2px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,118 @@
|
|||
<script>
|
||||
import { onMount, onDestroy } from "svelte"
|
||||
import Indicator from "./Indicator.svelte"
|
||||
import { domDebounce } from "../../utils/domDebounce"
|
||||
|
||||
export let componentId
|
||||
export let color
|
||||
export let transition
|
||||
export let zIndex
|
||||
|
||||
let indicators = []
|
||||
let interval
|
||||
let text
|
||||
$: visibleIndicators = indicators.filter(x => x.visible)
|
||||
|
||||
let updating = false
|
||||
let observers = []
|
||||
let callbackCount = 0
|
||||
let nextIndicators = []
|
||||
|
||||
const createIntersectionCallback = idx => entries => {
|
||||
if (callbackCount >= observers.length) {
|
||||
return
|
||||
}
|
||||
nextIndicators[idx].visible = entries[0].isIntersecting
|
||||
if (++callbackCount === observers.length) {
|
||||
indicators = nextIndicators
|
||||
updating = false
|
||||
}
|
||||
}
|
||||
|
||||
const updatePosition = () => {
|
||||
if (updating) {
|
||||
return
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if (!componentId) {
|
||||
indicators = []
|
||||
return
|
||||
}
|
||||
|
||||
// Reset state
|
||||
updating = true
|
||||
callbackCount = 0
|
||||
observers.forEach(o => o.disconnect())
|
||||
observers = []
|
||||
nextIndicators = []
|
||||
|
||||
// Determine next set of indicators
|
||||
const parents = document.getElementsByClassName(componentId)
|
||||
if (parents.length) {
|
||||
text = parents[0].dataset.name
|
||||
}
|
||||
|
||||
// Batch reads to minimize reflow
|
||||
const scrollX = window.scrollX
|
||||
const scrollY = window.scrollY
|
||||
|
||||
// Extract valid children
|
||||
// Sanity limit of 100 active indicators
|
||||
const children = Array.from(parents)
|
||||
.map(parent => parent?.childNodes?.[0])
|
||||
.filter(child => child != null)
|
||||
.slice(0, 100)
|
||||
|
||||
// If there aren't any nodes then reset
|
||||
if (!children.length) {
|
||||
indicators = []
|
||||
updating = false
|
||||
}
|
||||
|
||||
children.forEach((child, idx) => {
|
||||
const callback = createIntersectionCallback(idx)
|
||||
const threshold = children.length > 1 ? 1 : 0
|
||||
const observer = new IntersectionObserver(callback, { threshold })
|
||||
observer.observe(child)
|
||||
observers.push(observer)
|
||||
|
||||
const elBounds = child.getBoundingClientRect()
|
||||
nextIndicators.push({
|
||||
top: elBounds.top + scrollY - 2,
|
||||
left: elBounds.left + scrollX - 2,
|
||||
width: elBounds.width + 4,
|
||||
height: elBounds.height + 4,
|
||||
visible: false,
|
||||
})
|
||||
})
|
||||
}
|
||||
const debouncedUpdate = domDebounce(updatePosition)
|
||||
|
||||
onMount(() => {
|
||||
debouncedUpdate()
|
||||
interval = setInterval(debouncedUpdate, 100)
|
||||
document.addEventListener("scroll", debouncedUpdate, true)
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
clearInterval(interval)
|
||||
document.removeEventListener("scroll", debouncedUpdate, true)
|
||||
observers.forEach(o => o.disconnect())
|
||||
})
|
||||
</script>
|
||||
|
||||
{#key componentId}
|
||||
{#each visibleIndicators as indicator, idx}
|
||||
<Indicator
|
||||
top={indicator.top}
|
||||
left={indicator.left}
|
||||
width={indicator.width}
|
||||
height={indicator.height}
|
||||
text={idx === 0 ? text : null}
|
||||
{transition}
|
||||
{zIndex}
|
||||
{color}
|
||||
/>
|
||||
{/each}
|
||||
{/key}
|
|
@ -0,0 +1,11 @@
|
|||
<script>
|
||||
import { builderStore } from "../../store"
|
||||
import IndicatorSet from "./IndicatorSet.svelte"
|
||||
</script>
|
||||
|
||||
<IndicatorSet
|
||||
componentId={$builderStore.selectedComponentId}
|
||||
color="rgb(66, 133, 244)"
|
||||
zIndex="910"
|
||||
transition
|
||||
/>
|
|
@ -0,0 +1,131 @@
|
|||
<script>
|
||||
import { onMount, onDestroy } from "svelte"
|
||||
import SettingsButton from "./SettingsButton.svelte"
|
||||
import { builderStore } from "../../store"
|
||||
import { domDebounce } from "../../utils/domDebounce"
|
||||
|
||||
const verticalOffset = 28
|
||||
const horizontalOffset = 2
|
||||
|
||||
let top = 0
|
||||
let left = 0
|
||||
let interval
|
||||
let self
|
||||
let measured = false
|
||||
|
||||
$: definition = $builderStore.selectedComponentDefinition
|
||||
$: showBar = definition?.showSettingsBar
|
||||
$: settings = definition?.settings?.filter(setting => setting.showInBar) ?? []
|
||||
|
||||
const updatePosition = () => {
|
||||
if (!showBar) {
|
||||
return
|
||||
}
|
||||
const id = $builderStore.selectedComponentId
|
||||
const parent = document.getElementsByClassName(id)?.[0]
|
||||
const element = parent?.childNodes?.[0]
|
||||
if (element && self) {
|
||||
// Batch reads to minimize reflow
|
||||
const elBounds = element.getBoundingClientRect()
|
||||
const width = self.offsetWidth
|
||||
const height = self.offsetHeight
|
||||
const { scrollX, scrollY, innerWidth } = window
|
||||
|
||||
// Vertically, always render above unless no room, then render inside
|
||||
let newTop = elBounds.top + scrollY - verticalOffset - height
|
||||
if (newTop < 0) {
|
||||
newTop = elBounds.top + scrollY + verticalOffset
|
||||
}
|
||||
|
||||
// Horizontally, try to center first.
|
||||
// Failing that, render to left edge of component.
|
||||
// Failing that, render to right edge of component,
|
||||
// Failing that, render to window left edge and accept defeat.
|
||||
let elCenter = elBounds.left + scrollX + elBounds.width / 2
|
||||
let newLeft = elCenter - width / 2
|
||||
if (newLeft < 0 || newLeft + width > innerWidth) {
|
||||
newLeft = elBounds.left + scrollX - horizontalOffset
|
||||
if (newLeft < 0 || newLeft + width > innerWidth) {
|
||||
newLeft = elBounds.right + scrollX - width + horizontalOffset
|
||||
if (newLeft < 0 || newLeft + width > innerWidth) {
|
||||
newLeft = horizontalOffset
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only update state when things changes to minimize renders
|
||||
if (Math.round(newTop) !== Math.round(top)) {
|
||||
top = newTop
|
||||
}
|
||||
if (Math.round(newLeft) !== Math.round(left)) {
|
||||
left = newLeft
|
||||
}
|
||||
|
||||
measured = true
|
||||
}
|
||||
}
|
||||
const debouncedUpdate = domDebounce(updatePosition)
|
||||
|
||||
onMount(() => {
|
||||
debouncedUpdate()
|
||||
interval = setInterval(debouncedUpdate, 100)
|
||||
document.addEventListener("scroll", debouncedUpdate, true)
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
clearInterval(interval)
|
||||
document.removeEventListener("scroll", debouncedUpdate, true)
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if showBar}
|
||||
<div
|
||||
class="bar"
|
||||
style="top: {top}px; left: {left}px;"
|
||||
bind:this={self}
|
||||
class:visible={measured}
|
||||
>
|
||||
{#each settings as setting, idx}
|
||||
{#if setting.type === "select"}
|
||||
{#each setting.options as option}
|
||||
<SettingsButton
|
||||
prop={setting.key}
|
||||
value={option.value}
|
||||
icon={option.barIcon}
|
||||
title={option.barTitle}
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
{#if idx < settings.length - 1}
|
||||
<div class="divider" />
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.bar {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
z-index: 930;
|
||||
padding: 6px 8px;
|
||||
opacity: 0;
|
||||
flex-direction: row;
|
||||
background: var(--background);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 4px;
|
||||
box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.2);
|
||||
gap: 2px;
|
||||
transition: opacity 0.13s ease-in-out;
|
||||
}
|
||||
.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
.divider {
|
||||
flex: 0 0 1px;
|
||||
align-self: stretch;
|
||||
margin: 0 4px;
|
||||
background-color: var(--spectrum-global-color-gray-300);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,50 @@
|
|||
<script>
|
||||
import { Icon } from "@budibase/bbui"
|
||||
import { builderStore } from "../../store"
|
||||
|
||||
export let prop
|
||||
export let value
|
||||
export let icon
|
||||
export let title
|
||||
export let rotate = false
|
||||
export let bool = false
|
||||
|
||||
$: currentValue = $builderStore.selectedComponent?.[prop]
|
||||
$: active = prop && (bool ? !!currentValue : currentValue === value)
|
||||
</script>
|
||||
|
||||
<div
|
||||
{title}
|
||||
class:rotate
|
||||
class:active
|
||||
on:click={() => {
|
||||
if (prop) {
|
||||
const newValue = bool ? !currentValue : value
|
||||
builderStore.actions.updateProp(prop, newValue)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon name={icon} size="S" />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
padding: 6px;
|
||||
border-radius: 2px;
|
||||
color: var(--spectrum-global-color-gray-700);
|
||||
display: flex;
|
||||
transition: color 0.13s ease-in-out, background-color 0.13s ease-in-out;
|
||||
}
|
||||
div:hover {
|
||||
background-color: var(--spectrum-global-color-gray-200);
|
||||
cursor: pointer;
|
||||
}
|
||||
.active,
|
||||
.active:hover {
|
||||
background-color: rgba(13, 102, 208, 0.1);
|
||||
color: var(--spectrum-global-color-blue-600);
|
||||
}
|
||||
.rotate {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
</style>
|
|
@ -1,4 +1,32 @@
|
|||
import { writable } from "svelte/store"
|
||||
import { writable, derived } from "svelte/store"
|
||||
import Manifest from "@budibase/standard-components/manifest.json"
|
||||
|
||||
const dispatchEvent = (type, data) => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("bb-event", {
|
||||
detail: { type, data },
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const findComponentById = (component, componentId) => {
|
||||
if (!component || !componentId) {
|
||||
return null
|
||||
}
|
||||
if (component._id === componentId) {
|
||||
return component
|
||||
}
|
||||
if (!component._children?.length) {
|
||||
return null
|
||||
}
|
||||
for (let child of component._children) {
|
||||
const result = findComponentById(child, componentId)
|
||||
if (result) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const createBuilderStore = () => {
|
||||
const initialState = {
|
||||
|
@ -10,18 +38,35 @@ const createBuilderStore = () => {
|
|||
previewId: null,
|
||||
previewType: null,
|
||||
}
|
||||
const store = writable(initialState)
|
||||
const writableStore = writable(initialState)
|
||||
const derivedStore = derived(writableStore, $state => {
|
||||
// Derive the selected component instance and definition
|
||||
const { layout, screen, previewType, selectedComponentId } = $state
|
||||
const asset = previewType === "layout" ? layout : screen
|
||||
const component = findComponentById(asset?.props, selectedComponentId)
|
||||
const prefix = "@budibase/standard-components/"
|
||||
const type = component?._component?.replace(prefix, "")
|
||||
const definition = type ? Manifest[type] : null
|
||||
return {
|
||||
...$state,
|
||||
selectedComponent: component,
|
||||
selectedComponentDefinition: definition,
|
||||
}
|
||||
})
|
||||
|
||||
const actions = {
|
||||
selectComponent: id => {
|
||||
if (id) {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("bb-select-component", { detail: id })
|
||||
)
|
||||
dispatchEvent("select-component", { id })
|
||||
}
|
||||
},
|
||||
updateProp: (prop, value) => {
|
||||
dispatchEvent("update-prop", { prop, value })
|
||||
},
|
||||
}
|
||||
return {
|
||||
...store,
|
||||
...writableStore,
|
||||
subscribe: derivedStore.subscribe,
|
||||
actions,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
export const domDebounce = callback => {
|
||||
let active = false
|
||||
return e => {
|
||||
if (!active) {
|
||||
window.requestAnimationFrame(() => {
|
||||
callback(e)
|
||||
active = false
|
||||
})
|
||||
active = true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,25 +14,6 @@ const buildStyleString = (styleObject, customStyles) => {
|
|||
return str + (customStyles || "")
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies styles to enrich the builder preview.
|
||||
* Applies styles to highlight the selected component, and allows pointer
|
||||
* events for any selectable components (overriding the blanket ban on pointer
|
||||
* events in the iframe HTML).
|
||||
*/
|
||||
const addBuilderPreviewStyles = (node, styleString, componentId) => {
|
||||
if (componentId === get(builderStore).selectedComponentId) {
|
||||
const style = window.getComputedStyle(node)
|
||||
const property = style?.display === "table-row" ? "outline" : "border"
|
||||
return (
|
||||
styleString +
|
||||
`;${property}: 2px solid #4285f4 !important; border-radius: 4px !important;`
|
||||
)
|
||||
} else {
|
||||
return styleString
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Svelte action to apply correct component styles.
|
||||
* This also applies handlers for selecting components from the builder preview.
|
||||
|
@ -44,9 +25,17 @@ export const styleable = (node, styles = {}) => {
|
|||
|
||||
// Creates event listeners and applies initial styles
|
||||
const setupStyles = (newStyles = {}) => {
|
||||
// Use empty state styles as base styles if required, but let them, get
|
||||
// overridden by any user specified styles
|
||||
let baseStyles = {}
|
||||
if (newStyles.empty) {
|
||||
baseStyles.border = "2px dashed var(--grey-5)"
|
||||
baseStyles.padding = "var(--spacing-l)"
|
||||
}
|
||||
|
||||
const componentId = newStyles.id
|
||||
const customStyles = newStyles.custom || ""
|
||||
const normalStyles = newStyles.normal || {}
|
||||
const normalStyles = { ...baseStyles, ...newStyles.normal }
|
||||
const hoverStyles = {
|
||||
...normalStyles,
|
||||
...(newStyles.hover || {}),
|
||||
|
@ -54,7 +43,7 @@ export const styleable = (node, styles = {}) => {
|
|||
|
||||
// Applies a style string to a DOM node
|
||||
const applyStyles = styleString => {
|
||||
node.style = addBuilderPreviewStyles(node, styleString, componentId)
|
||||
node.style = styleString
|
||||
node.dataset.componentId = componentId
|
||||
}
|
||||
|
||||
|
@ -71,7 +60,9 @@ export const styleable = (node, styles = {}) => {
|
|||
// Handler to select a component in the builder when clicking it in the
|
||||
// builder preview
|
||||
selectComponent = event => {
|
||||
builderStore.actions.selectComponent(componentId)
|
||||
if (newStyles.interactive) {
|
||||
builderStore.actions.selectComponent(componentId)
|
||||
}
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
return false
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@budibase/bbui@^0.9.35":
|
||||
version "0.9.35"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.35.tgz#7a201c0d56cd3efb212a7adff99bbe2b6c9b7613"
|
||||
integrity sha512-xgzeDXE+Lv7T1x6f2O8f9l8YOusMBVV1Ar9jf/4sERHxLNJCJNokkLI9GAWTc7HnSp78Kb98kZ9M+/mcEkIXyw==
|
||||
"@budibase/bbui@^0.9.46":
|
||||
version "0.9.46"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.46.tgz#3109666b618daa65b29d1c7c45549420c62e6489"
|
||||
integrity sha512-PRW8kR9+QrMiom6hVzisMYd268dj03ojC0ruzEkDhKMONg2I021ST62hzKXdb7zh5LgoYXtapmM9qsKwoHfkPg==
|
||||
dependencies:
|
||||
"@adobe/spectrum-css-workflow-icons" "^1.2.1"
|
||||
"@spectrum-css/actionbutton" "^1.0.1"
|
||||
|
@ -76,10 +76,10 @@
|
|||
svelte-flatpickr "^3.1.0"
|
||||
svelte-portal "^1.0.0"
|
||||
|
||||
"@budibase/handlebars-helpers@^0.11.3":
|
||||
version "0.11.3"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/handlebars-helpers/-/handlebars-helpers-0.11.3.tgz#b6e5c91b83e8906e7d7ff10ddde277a3d561016e"
|
||||
integrity sha512-MS1ptZEYq8o9J3tNLM7cZ2RGSSJIer4GiMIUHtbBI3sC9UKqZebao1JYNfmZKpNjntuqhZKgjqc5GfnVIEjsYQ==
|
||||
"@budibase/handlebars-helpers@^0.11.4":
|
||||
version "0.11.4"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/handlebars-helpers/-/handlebars-helpers-0.11.4.tgz#8acfa2ee84134f7be4b2906e710fce6d25c5d000"
|
||||
integrity sha512-AJNJYlJnxZmn9QJ8tBl8nrm4YxbwHP4AR0pbiVGK+EoOylkNBlUnZ/QDL1VyqM5fTkAE/Z2IZVLKrrG3kxuWLA==
|
||||
dependencies:
|
||||
arr-flatten "^1.1.0"
|
||||
array-sort "^0.1.4"
|
||||
|
@ -108,12 +108,12 @@
|
|||
to-gfm-code-block "^0.1.1"
|
||||
year "^0.2.1"
|
||||
|
||||
"@budibase/standard-components@^0.9.35":
|
||||
version "0.9.35"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/standard-components/-/standard-components-0.9.35.tgz#5b2c2844c47324dbb6e563f30cd53ca19cd5baa8"
|
||||
integrity sha512-HMmFXyLiMEPKTn8as5mq4wNwFviPdhoaSkfwFqVr/LD9nEX5Ti2+6ZCL/EGjIZXwPXcN6wnJ4wqfmK9q6pb84g==
|
||||
"@budibase/standard-components@^0.9.46":
|
||||
version "0.9.46"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/standard-components/-/standard-components-0.9.46.tgz#a31a253ca51a2029c3aaf5d8aca5c953358e1d67"
|
||||
integrity sha512-QjW4tukMw4Xa477wGTle2UPz85ygodQ3KG+WEdPAWKq7j0IDv0Fad0oDmWtzLvGxxB+AiRbEnM6T1QV6X1ItCA==
|
||||
dependencies:
|
||||
"@budibase/bbui" "^0.9.35"
|
||||
"@budibase/bbui" "^0.9.46"
|
||||
"@spectrum-css/page" "^3.0.1"
|
||||
"@spectrum-css/vars" "^3.0.1"
|
||||
apexcharts "^3.22.1"
|
||||
|
@ -121,12 +121,12 @@
|
|||
svelte-apexcharts "^1.0.2"
|
||||
svelte-flatpickr "^3.1.0"
|
||||
|
||||
"@budibase/string-templates@^0.9.35":
|
||||
version "0.9.35"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-0.9.35.tgz#5f5d114f65e8acf4eb0856c544fcdc27263f3bc9"
|
||||
integrity sha512-puPUxnCHUp3+VZi8HYoFe+ruHC8/m0q5F1SdhRZtNLpjwBkgXNun7e+hegF/y7lkxVz/rR76Ufmyza31Mliv9w==
|
||||
"@budibase/string-templates@^0.9.46":
|
||||
version "0.9.46"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-0.9.46.tgz#e43f87513977879a892ae52f3941d3320cb9ff88"
|
||||
integrity sha512-yOVS7Y/QLATj31QuBu8KP78Oyzhs60V09JEQKa7n4vRP8TBemcev/LFShln8Iiv70YZSpdJviguQuJ6Ow0aUNA==
|
||||
dependencies:
|
||||
"@budibase/handlebars-helpers" "^0.11.3"
|
||||
"@budibase/handlebars-helpers" "^0.11.4"
|
||||
dayjs "^1.10.4"
|
||||
handlebars "^4.7.6"
|
||||
handlebars-utils "^1.0.6"
|
||||
|
|
|
@ -23,9 +23,8 @@ const EMPTY_LAYOUT = {
|
|||
"justify-content": "flex-start",
|
||||
"align-items": "stretch",
|
||||
"max-width": "100%",
|
||||
"margin-left": "20px",
|
||||
"margin-right": "20px",
|
||||
width: "1400px",
|
||||
padding: "20px",
|
||||
},
|
||||
hover: {},
|
||||
active: {},
|
||||
|
@ -34,24 +33,19 @@ const EMPTY_LAYOUT = {
|
|||
_children: [],
|
||||
},
|
||||
],
|
||||
type: "div",
|
||||
_styles: {
|
||||
active: {},
|
||||
hover: {},
|
||||
normal: {
|
||||
display: "flex",
|
||||
"flex-direction": "column",
|
||||
"align-items": "center",
|
||||
"justify-content": "flex-start",
|
||||
"margin-right": "auto",
|
||||
"margin-left": "auto",
|
||||
"min-height": "100%",
|
||||
"background-image": "#f5f5f5",
|
||||
},
|
||||
selected: {},
|
||||
},
|
||||
className: "",
|
||||
onLoad: [],
|
||||
direction: "column",
|
||||
hAlign: "center",
|
||||
vAlign: "top",
|
||||
size: "grow",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -72,10 +66,6 @@ const BASE_LAYOUTS = [
|
|||
_component: "@budibase/standard-components/container",
|
||||
_styles: {
|
||||
normal: {
|
||||
display: "flex",
|
||||
"flex-direction": "row",
|
||||
"justify-content": "flex-start",
|
||||
"align-items": "flex-start",
|
||||
background: "#fff",
|
||||
width: "100%",
|
||||
"box-shadow": "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
||||
|
@ -84,9 +74,6 @@ const BASE_LAYOUTS = [
|
|||
active: {},
|
||||
selected: {},
|
||||
},
|
||||
className: "",
|
||||
onLoad: [],
|
||||
type: "div",
|
||||
_instanceName: "Header",
|
||||
_children: [
|
||||
{
|
||||
|
@ -95,8 +82,6 @@ const BASE_LAYOUTS = [
|
|||
_styles: {
|
||||
normal: {
|
||||
"max-width": "1400px",
|
||||
"margin-left": "auto",
|
||||
"margin-right": "auto",
|
||||
padding: "20px",
|
||||
"font-weight": "400",
|
||||
"font-size": "16px",
|
||||
|
@ -143,6 +128,10 @@ const BASE_LAYOUTS = [
|
|||
],
|
||||
},
|
||||
],
|
||||
direction: "row",
|
||||
hAlign: "center",
|
||||
vAlign: "middle",
|
||||
size: "shrink",
|
||||
},
|
||||
{
|
||||
_id: "7fcf11e4-6f5b-4085-8e0d-9f3d44c98967",
|
||||
|
@ -155,8 +144,6 @@ const BASE_LAYOUTS = [
|
|||
"justify-content": "flex-start",
|
||||
"align-items": "stretch",
|
||||
"max-width": "100%",
|
||||
"margin-left": "20px",
|
||||
"margin-right": "20px",
|
||||
width: "1400px",
|
||||
padding: "20px",
|
||||
},
|
||||
|
@ -167,24 +154,19 @@ const BASE_LAYOUTS = [
|
|||
_children: [],
|
||||
},
|
||||
],
|
||||
type: "div",
|
||||
_styles: {
|
||||
active: {},
|
||||
hover: {},
|
||||
normal: {
|
||||
display: "flex",
|
||||
"flex-direction": "column",
|
||||
"align-items": "center",
|
||||
"justify-content": "flex-start",
|
||||
"margin-right": "auto",
|
||||
"margin-left": "auto",
|
||||
"min-height": "100%",
|
||||
background: "#f5f5f5",
|
||||
},
|
||||
selected: {},
|
||||
},
|
||||
className: "",
|
||||
onLoad: [],
|
||||
direction: "column",
|
||||
hAlign: "center",
|
||||
vAlign: "top",
|
||||
size: "grow",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -209,8 +191,6 @@ const BASE_LAYOUTS = [
|
|||
"justify-content": "flex-start",
|
||||
"align-items": "stretch",
|
||||
"max-width": "100%",
|
||||
"margin-left": "20px",
|
||||
"margin-right": "20px",
|
||||
width: "1400px",
|
||||
padding: "20px",
|
||||
},
|
||||
|
@ -221,24 +201,19 @@ const BASE_LAYOUTS = [
|
|||
_children: [],
|
||||
},
|
||||
],
|
||||
type: "div",
|
||||
_styles: {
|
||||
active: {},
|
||||
hover: {},
|
||||
normal: {
|
||||
display: "flex",
|
||||
"flex-direction": "column",
|
||||
"align-items": "center",
|
||||
"justify-content": "center",
|
||||
"margin-right": "auto",
|
||||
"margin-left": "auto",
|
||||
"min-height": "100%",
|
||||
background: "#f5f5f5",
|
||||
},
|
||||
selected: {},
|
||||
},
|
||||
className: "",
|
||||
onLoad: [],
|
||||
direction: "column",
|
||||
hAlign: "center",
|
||||
vAlign: "top",
|
||||
size: "grow",
|
||||
},
|
||||
},
|
||||
]
|
||||
|
|
|
@ -9,19 +9,12 @@ exports.createHomeScreen = () => ({
|
|||
_id: "d834fea2-1b3e-4320-ab34-f9009f5ecc59",
|
||||
_component: "@budibase/standard-components/container",
|
||||
_styles: {
|
||||
normal: {
|
||||
flex: "1 1 auto",
|
||||
display: "flex",
|
||||
"flex-direction": "column",
|
||||
"justify-content": "flex-start",
|
||||
"align-items": "stretch",
|
||||
},
|
||||
normal: {},
|
||||
hover: {},
|
||||
active: {},
|
||||
selected: {},
|
||||
},
|
||||
_transition: "fade",
|
||||
type: "div",
|
||||
_children: [
|
||||
{
|
||||
_id: "ef60083f-4a02-4df3-80f3-a0d3d16847e7",
|
||||
|
@ -41,6 +34,10 @@ exports.createHomeScreen = () => ({
|
|||
},
|
||||
],
|
||||
_instanceName: "Home",
|
||||
direction: "column",
|
||||
hAlign: "stretch",
|
||||
vAlign: "top",
|
||||
size: "grow",
|
||||
},
|
||||
routing: {
|
||||
route: "/",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,7 +6,117 @@
|
|||
"hasChildren": true,
|
||||
"styleable": true,
|
||||
"transitionable": true,
|
||||
"settings": []
|
||||
"showSettingsBar": true,
|
||||
"settings": [
|
||||
{
|
||||
"type": "select",
|
||||
"label": "Direction",
|
||||
"key": "direction",
|
||||
"showInBar": true,
|
||||
"options": [
|
||||
{
|
||||
"label": "Column",
|
||||
"value": "column",
|
||||
"barIcon": "ViewRow",
|
||||
"barTitle": "Column layout"
|
||||
},
|
||||
{
|
||||
"label": "Row",
|
||||
"value": "row",
|
||||
"barIcon": "ViewColumn",
|
||||
"barTitle": "Row layout"
|
||||
}
|
||||
],
|
||||
"defaultValue": "column"
|
||||
},
|
||||
{
|
||||
"type": "select",
|
||||
"label": "Horiz. Align",
|
||||
"key": "hAlign",
|
||||
"showInBar": true,
|
||||
"options": [
|
||||
{
|
||||
"label": "Left",
|
||||
"value": "left",
|
||||
"barIcon": "AlignLeft",
|
||||
"barTitle": "Align left"
|
||||
},
|
||||
{
|
||||
"label": "Center",
|
||||
"value": "center",
|
||||
"barIcon": "AlignCenter",
|
||||
"barTitle": "Align center"
|
||||
},
|
||||
{
|
||||
"label": "Right",
|
||||
"value": "right",
|
||||
"barIcon": "AlignRight",
|
||||
"barTitle": "Align right"
|
||||
},
|
||||
{
|
||||
"label": "Stretch",
|
||||
"value": "stretch",
|
||||
"barIcon": "MoveLeftRight",
|
||||
"barTitle": "Align stretched horizontally"
|
||||
}
|
||||
],
|
||||
"defaultValue": "stretch"
|
||||
},
|
||||
{
|
||||
"type": "select",
|
||||
"label": "Vert. Align",
|
||||
"key": "vAlign",
|
||||
"showInBar": "true",
|
||||
"options": [
|
||||
{
|
||||
"label": "Top",
|
||||
"value": "top",
|
||||
"barIcon": "AlignTop",
|
||||
"barTitle": "Align top"
|
||||
},
|
||||
{
|
||||
"label": "Middle",
|
||||
"value": "middle",
|
||||
"barIcon": "AlignMiddle",
|
||||
"barTitle": "Align middle"
|
||||
},
|
||||
{
|
||||
"label": "Bottom",
|
||||
"value": "bottom",
|
||||
"barIcon": "AlignBottom",
|
||||
"barTitle": "Align bottom"
|
||||
},
|
||||
{
|
||||
"label": "Stretch",
|
||||
"value": "stretch",
|
||||
"barIcon": "MoveUpDown",
|
||||
"barTitle": "Align stretched vertically"
|
||||
}
|
||||
],
|
||||
"defaultValue": "top"
|
||||
},
|
||||
{
|
||||
"type": "select",
|
||||
"label": "Size",
|
||||
"key": "size",
|
||||
"showInBar": true,
|
||||
"options": [
|
||||
{
|
||||
"label": "Shrink",
|
||||
"value": "shrink",
|
||||
"barIcon": "Minimize",
|
||||
"barTitle": "Shrink container"
|
||||
},
|
||||
{
|
||||
"label": "Grow",
|
||||
"value": "grow",
|
||||
"barIcon": "Maximize",
|
||||
"barTitle": "Grow container"
|
||||
}
|
||||
],
|
||||
"defaultValue": "shrink"
|
||||
}
|
||||
]
|
||||
},
|
||||
"screenslot": {
|
||||
"name": "Screenslot",
|
||||
|
@ -53,7 +163,7 @@
|
|||
"type": "text",
|
||||
"label": "Empty Text",
|
||||
"key": "noRowsMessage",
|
||||
"defaultValue": "No rows found."
|
||||
"defaultValue": "No rows found"
|
||||
},
|
||||
{
|
||||
"type": "filter",
|
||||
|
@ -1438,6 +1548,7 @@
|
|||
"icon": "Table",
|
||||
"styleable": true,
|
||||
"hasChildren": true,
|
||||
"showEmptyState": false,
|
||||
"settings": [
|
||||
{
|
||||
"type": "dataProvider",
|
||||
|
|
|
@ -1,13 +1,87 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
|
||||
const { styleable, transition } = getContext("sdk")
|
||||
const { styleable, transition, builderStore } = getContext("sdk")
|
||||
const component = getContext("component")
|
||||
|
||||
export let direction
|
||||
export let hAlign
|
||||
export let vAlign
|
||||
export let size
|
||||
|
||||
$: directionClass = direction ? `valid-container direction-${direction}` : ""
|
||||
$: hAlignClass = hAlign ? `hAlign-${hAlign}` : ""
|
||||
$: vAlignClass = vAlign ? `vAlign-${vAlign}` : ""
|
||||
$: sizeClass = size ? `size-${size}` : ""
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={[directionClass, hAlignClass, vAlignClass, sizeClass].join(" ")}
|
||||
in:transition={{ type: $component.transition }}
|
||||
use:styleable={$component.styles}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.valid-container {
|
||||
display: flex;
|
||||
max-width: 100%;
|
||||
}
|
||||
.valid-container :global([data-type="component"] > *) {
|
||||
max-width: 100%;
|
||||
}
|
||||
.direction-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
.direction-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Grow containers inside a row need 0 width 0 so that they ignore content */
|
||||
/* The nested selector for data-type is the wrapper around all components */
|
||||
.direction-row :global(> [data-type="component"] > .size-grow) {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.size-shrink {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
.size-grow {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.direction-row.hAlign-left,
|
||||
.direction-column.vAlign-top {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.direction-row.hAlign-center,
|
||||
.direction-column.vAlign-middle {
|
||||
justify-content: center;
|
||||
}
|
||||
.direction-row.hAlign-right,
|
||||
.direction-column.vAlign-bottom {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.direction-row.hAlign-stretch,
|
||||
.direction-column.vAlign-stretch {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.direction-row.vAlign-top,
|
||||
.direction-column.hAlign-left {
|
||||
align-items: flex-start;
|
||||
}
|
||||
.direction-row.vAlign-middle,
|
||||
.direction-column.hAlign-center {
|
||||
align-items: center;
|
||||
}
|
||||
.direction-row.vAlign-bottom,
|
||||
.direction-column.hAlign-right {
|
||||
align-items: flex-end;
|
||||
}
|
||||
.direction-row.vAlign-stretch,
|
||||
.direction-column.hAlign-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
luceneSort,
|
||||
luceneLimit,
|
||||
} from "./lucene"
|
||||
import Placeholder from "./Placeholder.svelte"
|
||||
|
||||
export let dataSource
|
||||
export let filter
|
||||
|
@ -22,7 +23,8 @@
|
|||
let loading = false
|
||||
|
||||
// Loading flag for the initial load
|
||||
let loaded = false
|
||||
// Mark as loaded if we have no datasource so we don't stall forever
|
||||
let loaded = !dataSource
|
||||
let schemaLoaded = false
|
||||
|
||||
// Provider state
|
||||
|
@ -87,6 +89,7 @@
|
|||
// bindings, but are used internally by other components
|
||||
id: $component?.id,
|
||||
state: { query },
|
||||
loaded,
|
||||
}
|
||||
|
||||
const getSortType = (schema, sortColumn) => {
|
||||
|
@ -231,7 +234,11 @@
|
|||
<ProgressCircle />
|
||||
</div>
|
||||
{:else}
|
||||
<slot />
|
||||
{#if !$component.children}
|
||||
<Placeholder />
|
||||
{:else}
|
||||
<slot />
|
||||
{/if}
|
||||
{#if paginate && internalTable}
|
||||
<div class="pagination">
|
||||
<Pagination
|
||||
|
|
|
@ -1,25 +1,30 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
|
||||
const { styleable } = getContext("sdk")
|
||||
const { styleable, builderStore } = getContext("sdk")
|
||||
const component = getContext("component")
|
||||
|
||||
export let type
|
||||
export let text = ""
|
||||
export let text
|
||||
|
||||
$: placeholder = $builderStore.inBuilder && !text
|
||||
$: componentText = $builderStore.inBuilder
|
||||
? text || "Placeholder text"
|
||||
: text || ""
|
||||
</script>
|
||||
|
||||
{#if type === "h1"}
|
||||
<h1 use:styleable={$component.styles}>{text}</h1>
|
||||
<h1 class:placeholder use:styleable={$component.styles}>{componentText}</h1>
|
||||
{:else if type === "h2"}
|
||||
<h2 use:styleable={$component.styles}>{text}</h2>
|
||||
<h2 class:placeholder use:styleable={$component.styles}>{componentText}</h2>
|
||||
{:else if type === "h3"}
|
||||
<h3 use:styleable={$component.styles}>{text}</h3>
|
||||
<h3 class:placeholder use:styleable={$component.styles}>{componentText}</h3>
|
||||
{:else if type === "h4"}
|
||||
<h4 use:styleable={$component.styles}>{text}</h4>
|
||||
<h4 class:placeholder use:styleable={$component.styles}>{componentText}</h4>
|
||||
{:else if type === "h5"}
|
||||
<h5 use:styleable={$component.styles}>{text}</h5>
|
||||
<h5 class:placeholder use:styleable={$component.styles}>{componentText}</h5>
|
||||
{:else if type === "h6"}
|
||||
<h6 use:styleable={$component.styles}>{text}</h6>
|
||||
<h6 class:placeholder use:styleable={$component.styles}>{componentText}</h6>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
|
@ -31,4 +36,9 @@
|
|||
h6 {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
font-style: italic;
|
||||
color: var(--grey-6);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -65,15 +65,11 @@
|
|||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav__menu > * {
|
||||
margin-right: 16px;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
:global(.nav__menu > a) {
|
||||
font-size: 1.5em;
|
||||
text-decoration: none;
|
||||
margin-right: 16px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
|
||||
const { builderStore } = getContext("sdk")
|
||||
const component = getContext("component")
|
||||
|
||||
export let text = $component.name || "Placeholder"
|
||||
</script>
|
||||
|
||||
{#if $builderStore.inBuilder}
|
||||
<div>
|
||||
{text}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
div {
|
||||
color: var(--grey-6);
|
||||
font-size: var(--font-size-s);
|
||||
}
|
||||
</style>
|
|
@ -1,5 +1,6 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import Placeholder from "./Placeholder.svelte"
|
||||
|
||||
export let dataProvider
|
||||
export let noRowsMessage
|
||||
|
@ -9,37 +10,32 @@
|
|||
const context = getContext("context")
|
||||
|
||||
$: rows = dataProvider?.rows ?? []
|
||||
$: loaded = dataProvider?.loaded ?? false
|
||||
$: loaded = dataProvider?.loaded ?? true
|
||||
</script>
|
||||
|
||||
<div use:styleable={$component.styles}>
|
||||
{#if rows.length > 0}
|
||||
{#if $component.children === 0 && $builderStore.inBuilder}
|
||||
<p><i class="ri-image-line" />Add some components to display.</p>
|
||||
{:else}
|
||||
{#each rows as row}
|
||||
<Provider data={row}>
|
||||
<slot />
|
||||
</Provider>
|
||||
{/each}
|
||||
{/if}
|
||||
{#if $component.empty}
|
||||
<Placeholder />
|
||||
{:else if rows.length > 0}
|
||||
{#each rows as row}
|
||||
<Provider data={row}>
|
||||
<slot />
|
||||
</Provider>
|
||||
{/each}
|
||||
{:else if loaded && noRowsMessage}
|
||||
<p><i class="ri-list-check-2" />{noRowsMessage}</p>
|
||||
<div class="noRows"><i class="ri-list-check-2" />{noRowsMessage}</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
p {
|
||||
margin: 0 var(--spacing-m);
|
||||
background-color: var(--grey-2);
|
||||
.noRows {
|
||||
color: var(--grey-6);
|
||||
font-size: var(--font-size-s);
|
||||
padding: var(--spacing-l);
|
||||
border-radius: var(--border-radius-s);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
p i {
|
||||
.noRows i {
|
||||
margin-bottom: var(--spacing-m);
|
||||
font-size: 1.5rem;
|
||||
color: var(--grey-5);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
export let imageUrl = ""
|
||||
export let heading = ""
|
||||
export let subheading = ""
|
||||
export let destinationUrl = ""
|
||||
export let destinationUrl = "/"
|
||||
|
||||
$: showImage = !!imageUrl
|
||||
</script>
|
||||
|
|
|
@ -1,17 +1,29 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
|
||||
const { styleable } = getContext("sdk")
|
||||
const { styleable, builderStore } = getContext("sdk")
|
||||
const component = getContext("component")
|
||||
|
||||
export let text = ""
|
||||
export let text
|
||||
|
||||
$: placeholder = $builderStore.inBuilder && !text
|
||||
$: componentText = $builderStore.inBuilder
|
||||
? text || "Placeholder text"
|
||||
: text || ""
|
||||
</script>
|
||||
|
||||
<p use:styleable={$component.styles}>{text}</p>
|
||||
<p use:styleable={$component.styles} class:placeholder>
|
||||
{componentText}
|
||||
</p>
|
||||
|
||||
<style>
|
||||
p {
|
||||
display: inline-block;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
font-style: italic;
|
||||
color: var(--grey-6);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import { chart } from "svelte-apexcharts"
|
||||
import Placeholder from "../Placeholder.svelte"
|
||||
|
||||
const { styleable, builderStore } = getContext("sdk")
|
||||
const component = getContext("component")
|
||||
|
@ -11,8 +12,8 @@
|
|||
{#if options}
|
||||
<div use:chart={options} use:styleable={$component.styles} />
|
||||
{:else if $builderStore.inBuilder}
|
||||
<div class="placeholder" use:styleable={$component.styles}>
|
||||
Use the settings panel to build your chart.
|
||||
<div use:styleable={$component.styles}>
|
||||
<Placeholder text="Use the settings panel to build your chart" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
@ -24,7 +25,4 @@
|
|||
div :global(.apexcharts-yaxis-label, .apexcharts-xaxis-label) {
|
||||
fill: #aaa;
|
||||
}
|
||||
div.placeholder {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import Placeholder from "./Placeholder.svelte"
|
||||
import Placeholder from "../Placeholder.svelte"
|
||||
import FieldGroupFallback from "./FieldGroupFallback.svelte"
|
||||
import { getContext } from "svelte"
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
|||
<FieldGroupFallback>
|
||||
<div class="spectrum-Form-item" use:styleable={$component.styles}>
|
||||
<label
|
||||
class:hidden={!label}
|
||||
for={$fieldState?.fieldId}
|
||||
class={`spectrum-FieldLabel spectrum-FieldLabel--sizeM spectrum-Form-itemLabel ${labelPositionClass}`}
|
||||
>
|
||||
|
@ -43,15 +44,15 @@
|
|||
</label>
|
||||
<div class="spectrum-Form-itemField">
|
||||
{#if !formContext}
|
||||
<Placeholder>Form components need to be wrapped in a Form</Placeholder>
|
||||
<Placeholder text="Form components need to be wrapped in a form" />
|
||||
{:else if !fieldState}
|
||||
<Placeholder>
|
||||
Add the Field setting to start using your component
|
||||
</Placeholder>
|
||||
<Placeholder
|
||||
text="Add the Field setting to start using your component"
|
||||
/>
|
||||
{:else if fieldSchema?.type && fieldSchema?.type !== type}
|
||||
<Placeholder>
|
||||
This Field setting is the wrong data type for this component
|
||||
</Placeholder>
|
||||
<Placeholder
|
||||
text="This Field setting is the wrong data type for this component"
|
||||
/>
|
||||
{:else}
|
||||
<slot />
|
||||
{#if $fieldState.error}
|
||||
|
@ -66,6 +67,9 @@
|
|||
label {
|
||||
white-space: nowrap;
|
||||
}
|
||||
label.hidden {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.spectrum-Form-itemField {
|
||||
position: relative;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
<script>
|
||||
import { setContext, getContext, onMount } from "svelte"
|
||||
import { writable, get } from "svelte/store"
|
||||
import { createValidatorFromConstraints } from "./validation"
|
||||
import { generateID } from "../helpers"
|
||||
import { getContext } from "svelte"
|
||||
import InnerForm from "./InnerForm.svelte"
|
||||
|
||||
export let dataSource
|
||||
export let theme
|
||||
|
@ -10,14 +8,7 @@
|
|||
export let disabled = false
|
||||
export let actionType = "Create"
|
||||
|
||||
const component = getContext("component")
|
||||
const context = getContext("context")
|
||||
const { styleable, API, Provider, ActionTypes } = getContext("sdk")
|
||||
|
||||
let loaded = false
|
||||
let schema
|
||||
let table
|
||||
let fieldMap = {}
|
||||
|
||||
// Returns the closes data context which isn't a built in context
|
||||
const getInitialValues = (type, dataSource, context) => {
|
||||
|
@ -41,167 +32,19 @@
|
|||
return closestContext
|
||||
}
|
||||
|
||||
// Use the closest data context as the initial form values
|
||||
const initialValues = getInitialValues(actionType, dataSource, $context)
|
||||
|
||||
// Form state contains observable data about the form
|
||||
const formState = writable({ values: initialValues, errors: {}, valid: true })
|
||||
|
||||
// Form API contains functions to control the form
|
||||
const formApi = {
|
||||
registerField: (field, defaultValue = null, fieldDisabled = false) => {
|
||||
if (!field) {
|
||||
return
|
||||
}
|
||||
|
||||
// Auto columns are always disabled
|
||||
const isAutoColumn = !!schema?.[field]?.autocolumn
|
||||
|
||||
// Create validation function based on field schema
|
||||
const constraints = schema?.[field]?.constraints
|
||||
const validate = createValidatorFromConstraints(constraints, field, table)
|
||||
|
||||
// Construct field object
|
||||
fieldMap[field] = {
|
||||
fieldState: makeFieldState(
|
||||
field,
|
||||
defaultValue,
|
||||
disabled || fieldDisabled || isAutoColumn
|
||||
),
|
||||
fieldApi: makeFieldApi(field, defaultValue, validate),
|
||||
fieldSchema: schema?.[field] ?? {},
|
||||
}
|
||||
|
||||
// Set initial value
|
||||
const initialValue = get(fieldMap[field].fieldState).value
|
||||
formState.update(state => ({
|
||||
...state,
|
||||
values: {
|
||||
...state.values,
|
||||
[field]: initialValue,
|
||||
},
|
||||
}))
|
||||
|
||||
return fieldMap[field]
|
||||
},
|
||||
validate: () => {
|
||||
const fields = Object.keys(fieldMap)
|
||||
fields.forEach(field => {
|
||||
const { fieldApi } = fieldMap[field]
|
||||
fieldApi.validate()
|
||||
})
|
||||
return get(formState).valid
|
||||
},
|
||||
}
|
||||
|
||||
// Provide both form API and state to children
|
||||
setContext("form", { formApi, formState, dataSource })
|
||||
|
||||
// Action context to pass to children
|
||||
$: actions = [{ type: ActionTypes.ValidateForm, callback: formApi.validate }]
|
||||
|
||||
// Creates an API for a specific field
|
||||
const makeFieldApi = (field, defaultValue, validate) => {
|
||||
const setValue = (value, skipCheck = false) => {
|
||||
const { fieldState } = fieldMap[field]
|
||||
|
||||
// Skip if the value is the same
|
||||
if (!skipCheck && get(fieldState).value === value) {
|
||||
return
|
||||
}
|
||||
|
||||
const newValue = value == null ? defaultValue : value
|
||||
const newError = validate ? validate(newValue) : null
|
||||
|
||||
// Update field state
|
||||
fieldState.update(state => {
|
||||
state.value = newValue
|
||||
state.error = newError
|
||||
return state
|
||||
})
|
||||
|
||||
// Update form state
|
||||
formState.update(state => {
|
||||
state.values = { ...state.values, [field]: newValue }
|
||||
if (newError) {
|
||||
state.errors = { ...state.errors, [field]: newError }
|
||||
} else {
|
||||
delete state.errors[field]
|
||||
}
|
||||
state.valid = Object.keys(state.errors).length === 0
|
||||
return state
|
||||
})
|
||||
|
||||
return !newError
|
||||
}
|
||||
return {
|
||||
setValue,
|
||||
validate: () => {
|
||||
const { fieldState } = fieldMap[field]
|
||||
setValue(get(fieldState).value, true)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Creates observable state data about a specific field
|
||||
const makeFieldState = (field, defaultValue, fieldDisabled) => {
|
||||
return writable({
|
||||
field,
|
||||
fieldId: `id-${generateID()}`,
|
||||
value: initialValues[field] ?? defaultValue,
|
||||
error: null,
|
||||
disabled: fieldDisabled,
|
||||
})
|
||||
}
|
||||
|
||||
// Fetches the form schema from this form's dataSource, if one exists
|
||||
const fetchSchema = async () => {
|
||||
if (!dataSource?.tableId) {
|
||||
schema = {}
|
||||
table = null
|
||||
} else {
|
||||
table = await API.fetchTableDefinition(dataSource?.tableId)
|
||||
if (table) {
|
||||
if (dataSource?.type === "query") {
|
||||
schema = {}
|
||||
const params = table.parameters || []
|
||||
params.forEach(param => {
|
||||
schema[param.name] = { ...param, type: "string" }
|
||||
})
|
||||
} else {
|
||||
schema = table.schema || {}
|
||||
}
|
||||
}
|
||||
}
|
||||
loaded = true
|
||||
}
|
||||
|
||||
// Load the form schema on mount
|
||||
onMount(fetchSchema)
|
||||
$: initialValues = getInitialValues(actionType, dataSource, $context)
|
||||
$: resetKey = JSON.stringify(initialValues)
|
||||
</script>
|
||||
|
||||
<Provider
|
||||
{actions}
|
||||
data={{ ...$formState.values, tableId: dataSource?.tableId }}
|
||||
>
|
||||
<div
|
||||
lang="en"
|
||||
dir="ltr"
|
||||
use:styleable={$component.styles}
|
||||
class={`spectrum ${size || "spectrum--medium"} ${
|
||||
theme || "spectrum--light"
|
||||
}`}
|
||||
{#key resetKey}
|
||||
<InnerForm
|
||||
{dataSource}
|
||||
{theme}
|
||||
{size}
|
||||
{disabled}
|
||||
{actionType}
|
||||
{initialValues}
|
||||
>
|
||||
{#if loaded}
|
||||
<slot />
|
||||
{/if}
|
||||
</div>
|
||||
</Provider>
|
||||
|
||||
<style>
|
||||
div {
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
background-color: var(--spectrum-alias-background-color-secondary);
|
||||
}
|
||||
</style>
|
||||
<slot />
|
||||
</InnerForm>
|
||||
{/key}
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
<script>
|
||||
import { setContext, getContext, onMount } from "svelte"
|
||||
import { writable, get } from "svelte/store"
|
||||
import { createValidatorFromConstraints } from "./validation"
|
||||
import { generateID } from "../helpers"
|
||||
|
||||
export let dataSource
|
||||
export let theme
|
||||
export let size
|
||||
export let disabled = false
|
||||
export let actionType = "Create"
|
||||
export let initialValues
|
||||
|
||||
const component = getContext("component")
|
||||
const context = getContext("context")
|
||||
const { styleable, API, Provider, ActionTypes } = getContext("sdk")
|
||||
|
||||
let loaded = false
|
||||
let schema
|
||||
let table
|
||||
let fieldMap = {}
|
||||
|
||||
// Form state contains observable data about the form
|
||||
const formState = writable({ values: initialValues, errors: {}, valid: true })
|
||||
|
||||
// Form API contains functions to control the form
|
||||
const formApi = {
|
||||
registerField: (field, defaultValue = null, fieldDisabled = false) => {
|
||||
if (!field) {
|
||||
return
|
||||
}
|
||||
|
||||
// Auto columns are always disabled
|
||||
const isAutoColumn = !!schema?.[field]?.autocolumn
|
||||
|
||||
// Create validation function based on field schema
|
||||
const constraints = schema?.[field]?.constraints
|
||||
const validate = createValidatorFromConstraints(constraints, field, table)
|
||||
|
||||
// Construct field object
|
||||
fieldMap[field] = {
|
||||
fieldState: makeFieldState(
|
||||
field,
|
||||
defaultValue,
|
||||
disabled || fieldDisabled || isAutoColumn
|
||||
),
|
||||
fieldApi: makeFieldApi(field, defaultValue, validate),
|
||||
fieldSchema: schema?.[field] ?? {},
|
||||
}
|
||||
|
||||
// Set initial value
|
||||
const initialValue = get(fieldMap[field].fieldState).value
|
||||
formState.update(state => ({
|
||||
...state,
|
||||
values: {
|
||||
...state.values,
|
||||
[field]: initialValue,
|
||||
},
|
||||
}))
|
||||
|
||||
return fieldMap[field]
|
||||
},
|
||||
validate: () => {
|
||||
const fields = Object.keys(fieldMap)
|
||||
fields.forEach(field => {
|
||||
const { fieldApi } = fieldMap[field]
|
||||
fieldApi.validate()
|
||||
})
|
||||
return get(formState).valid
|
||||
},
|
||||
}
|
||||
|
||||
// Provide both form API and state to children
|
||||
setContext("form", { formApi, formState, dataSource })
|
||||
|
||||
// Action context to pass to children
|
||||
const actions = [
|
||||
{ type: ActionTypes.ValidateForm, callback: formApi.validate },
|
||||
]
|
||||
|
||||
// Creates an API for a specific field
|
||||
const makeFieldApi = (field, defaultValue, validate) => {
|
||||
const setValue = (value, skipCheck = false) => {
|
||||
const { fieldState } = fieldMap[field]
|
||||
|
||||
// Skip if the value is the same
|
||||
if (!skipCheck && get(fieldState).value === value) {
|
||||
return
|
||||
}
|
||||
|
||||
const newValue = value == null ? defaultValue : value
|
||||
const newError = validate ? validate(newValue) : null
|
||||
|
||||
// Update field state
|
||||
fieldState.update(state => {
|
||||
state.value = newValue
|
||||
state.error = newError
|
||||
return state
|
||||
})
|
||||
|
||||
// Update form state
|
||||
formState.update(state => {
|
||||
state.values = { ...state.values, [field]: newValue }
|
||||
if (newError) {
|
||||
state.errors = { ...state.errors, [field]: newError }
|
||||
} else {
|
||||
delete state.errors[field]
|
||||
}
|
||||
state.valid = Object.keys(state.errors).length === 0
|
||||
return state
|
||||
})
|
||||
|
||||
return !newError
|
||||
}
|
||||
return {
|
||||
setValue,
|
||||
validate: () => {
|
||||
const { fieldState } = fieldMap[field]
|
||||
setValue(get(fieldState).value, true)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Creates observable state data about a specific field
|
||||
const makeFieldState = (field, defaultValue, fieldDisabled) => {
|
||||
return writable({
|
||||
field,
|
||||
fieldId: `id-${generateID()}`,
|
||||
value: initialValues[field] ?? defaultValue,
|
||||
error: null,
|
||||
disabled: fieldDisabled,
|
||||
})
|
||||
}
|
||||
|
||||
// Fetches the form schema from this form's dataSource, if one exists
|
||||
const fetchSchema = async () => {
|
||||
if (!dataSource?.tableId) {
|
||||
schema = {}
|
||||
table = null
|
||||
} else {
|
||||
table = await API.fetchTableDefinition(dataSource?.tableId)
|
||||
if (table) {
|
||||
if (dataSource?.type === "query") {
|
||||
schema = {}
|
||||
const params = table.parameters || []
|
||||
params.forEach(param => {
|
||||
schema[param.name] = { ...param, type: "string" }
|
||||
})
|
||||
} else {
|
||||
schema = table.schema || {}
|
||||
}
|
||||
}
|
||||
}
|
||||
loaded = true
|
||||
}
|
||||
|
||||
// Load the form schema on mount
|
||||
onMount(fetchSchema)
|
||||
</script>
|
||||
|
||||
<Provider
|
||||
{actions}
|
||||
data={{ ...$formState.values, tableId: dataSource?.tableId }}
|
||||
>
|
||||
<div
|
||||
lang="en"
|
||||
dir="ltr"
|
||||
use:styleable={$component.styles}
|
||||
class={`spectrum ${size || "spectrum--medium"} ${
|
||||
theme || "spectrum--light"
|
||||
}`}
|
||||
>
|
||||
{#if loaded}
|
||||
<slot />
|
||||
{/if}
|
||||
</div>
|
||||
</Provider>
|
||||
|
||||
<style>
|
||||
div {
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
background-color: var(--spectrum-alias-background-color-secondary);
|
||||
}
|
||||
</style>
|
|
@ -1,30 +0,0 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
const { builderStore } = getContext("sdk")
|
||||
</script>
|
||||
|
||||
{#if $builderStore.inBuilder}
|
||||
<div>
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
div {
|
||||
height: var(
|
||||
--spectrum-alias-item-height-m,
|
||||
var(--spectrum-global-dimension-size-400)
|
||||
);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
color: var(--spectrum-global-color-gray-600);
|
||||
font-size: var(
|
||||
--spectrum-alias-item-text-size-m,
|
||||
var(--spectrum-global-dimension-font-size-100)
|
||||
);
|
||||
font-style: var(--spectrum-global-font-style-italic, italic);
|
||||
font-weight: var(--spectrum-global-font-weight-regular, 400);
|
||||
}
|
||||
</style>
|
|
@ -8,30 +8,6 @@ export const capitalise = string => {
|
|||
return string.substring(0, 1).toUpperCase() + string.substring(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Svelte action to set CSS variables on a DOM node.
|
||||
*
|
||||
* @param node
|
||||
* @param props
|
||||
*/
|
||||
export const cssVars = (node, props) => {
|
||||
Object.entries(props).forEach(([key, value]) => {
|
||||
node.style.setProperty(`--${key}`, value)
|
||||
})
|
||||
|
||||
return {
|
||||
update(new_props) {
|
||||
Object.entries(new_props).forEach(([key, value]) => {
|
||||
node.style.setProperty(`--${key}`, value)
|
||||
delete props[key]
|
||||
})
|
||||
|
||||
Object.keys(props).forEach(name => node.style.removeProperty(`--${name}`))
|
||||
props = new_props
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a short random ID.
|
||||
* This is "nanoid" but rollup was derping attempting to bundle it, so the
|
||||
|
|
|
@ -10,6 +10,10 @@ import "@spectrum-css/page/dist/index-vars.css"
|
|||
import loadSpectrumIcons from "@budibase/bbui/spectrum-icons-rollup.js"
|
||||
loadSpectrumIcons()
|
||||
|
||||
// Non user-facing components
|
||||
export { default as Placeholder } from "./Placeholder.svelte"
|
||||
|
||||
// User facing components
|
||||
export { default as container } from "./Container.svelte"
|
||||
export { default as dataprovider } from "./DataProvider.svelte"
|
||||
export { default as screenslot } from "./ScreenSlot.svelte"
|
||||
|
|
|
@ -2,6 +2,59 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@adobe/spectrum-css-workflow-icons@^1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@adobe/spectrum-css-workflow-icons/-/spectrum-css-workflow-icons-1.2.1.tgz#7e2cb3fcfb5c8b12d7275afafbb6ec44913551b4"
|
||||
integrity sha512-uVgekyBXnOVkxp+CUssjN/gefARtudZC8duEn1vm0lBQFwGRZFlDEzU1QC+aIRWCrD1Z8OgRpmBYlSZ7QS003w==
|
||||
|
||||
"@budibase/bbui@^0.9.41":
|
||||
version "0.9.45"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.45.tgz#c37e84ffbf99daf0ebaa5c19b9109e7222463591"
|
||||
integrity sha512-+wojKap0kieYoeCqhah1V9EswVbR+Pg1k9Nlw1n/zTsuGtjA0kUH652yKjz7zNzZgFm+s5oYS1CoPieIMehhSw==
|
||||
dependencies:
|
||||
"@adobe/spectrum-css-workflow-icons" "^1.2.1"
|
||||
"@spectrum-css/actionbutton" "^1.0.1"
|
||||
"@spectrum-css/actiongroup" "^1.0.1"
|
||||
"@spectrum-css/avatar" "^3.0.2"
|
||||
"@spectrum-css/button" "^3.0.1"
|
||||
"@spectrum-css/buttongroup" "^3.0.2"
|
||||
"@spectrum-css/checkbox" "^3.0.2"
|
||||
"@spectrum-css/dialog" "^3.0.1"
|
||||
"@spectrum-css/divider" "^1.0.1"
|
||||
"@spectrum-css/dropzone" "^3.0.2"
|
||||
"@spectrum-css/fieldgroup" "^3.0.2"
|
||||
"@spectrum-css/fieldlabel" "^3.0.1"
|
||||
"@spectrum-css/icon" "^3.0.1"
|
||||
"@spectrum-css/illustratedmessage" "^3.0.2"
|
||||
"@spectrum-css/inputgroup" "^3.0.2"
|
||||
"@spectrum-css/label" "^2.0.10"
|
||||
"@spectrum-css/link" "^3.1.1"
|
||||
"@spectrum-css/menu" "^3.0.1"
|
||||
"@spectrum-css/modal" "^3.0.1"
|
||||
"@spectrum-css/pagination" "^3.0.3"
|
||||
"@spectrum-css/picker" "^1.0.1"
|
||||
"@spectrum-css/popover" "^3.0.1"
|
||||
"@spectrum-css/progressbar" "^1.0.2"
|
||||
"@spectrum-css/progresscircle" "^1.0.2"
|
||||
"@spectrum-css/radio" "^3.0.2"
|
||||
"@spectrum-css/search" "^3.0.2"
|
||||
"@spectrum-css/sidenav" "^3.0.2"
|
||||
"@spectrum-css/statuslight" "^3.0.2"
|
||||
"@spectrum-css/switch" "^1.0.2"
|
||||
"@spectrum-css/table" "^3.0.1"
|
||||
"@spectrum-css/tabs" "^3.0.1"
|
||||
"@spectrum-css/tags" "^3.0.2"
|
||||
"@spectrum-css/textfield" "^3.0.1"
|
||||
"@spectrum-css/toast" "^3.0.1"
|
||||
"@spectrum-css/tooltip" "^3.0.3"
|
||||
"@spectrum-css/treeview" "^3.0.2"
|
||||
"@spectrum-css/typography" "^3.0.1"
|
||||
"@spectrum-css/underlay" "^2.0.9"
|
||||
"@spectrum-css/vars" "^3.0.1"
|
||||
dayjs "^1.10.4"
|
||||
svelte-flatpickr "^3.1.0"
|
||||
svelte-portal "^1.0.0"
|
||||
|
||||
"@rollup/pluginutils@^4.1.0":
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.0.tgz#0dcc61c780e39257554feb7f77207dceca13c838"
|
||||
|
@ -10,31 +63,218 @@
|
|||
estree-walker "^2.0.1"
|
||||
picomatch "^2.2.2"
|
||||
|
||||
"@spectrum-css/page@^3.0.1":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/page/-/page-3.0.1.tgz#5e1c3dd5b1a1ee591f9d636b75f03665f542d846"
|
||||
integrity sha512-LAlKF8km5BlsGPpZ2SNtwKOQIHn1lz0X93aczGZVZceOg73O4gyeoT5cx4vi1z+KtBRY5VMDWx3XgGtUwwjqwA==
|
||||
dependencies:
|
||||
"@spectrum-css/vars" "^3.0.1"
|
||||
"@spectrum-css/actionbutton@^1.0.1":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/actionbutton/-/actionbutton-1.0.3.tgz#8f7342a69b303c5acdcfa0a59f5e9267b9f3cb30"
|
||||
integrity sha512-P9qoCPSiZ1SB6ZYqK5hub0vGty00YYqonQE0KTjtb1i+T1nYR/87vWqVPERx9j63uhgZncjwFYaThTvRqye7eQ==
|
||||
|
||||
"@spectrum-css/vars@^3.0.1":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-3.0.1.tgz#561fd69098f896a647242dd8d6108af603bfa31e"
|
||||
integrity sha512-l4oRcCOqInChYXZN6OQhpe3isk6l4OE6Ys8cgdlsiKp53suNoQxyyd9p/eGRbCjZgH3xQ8nK0t4DHa7QYC0S6w==
|
||||
"@spectrum-css/actiongroup@^1.0.1":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/actiongroup/-/actiongroup-1.0.3.tgz#4713ce65e6f5c72c404a7b638fbc3b4fd7e3874f"
|
||||
integrity sha512-NlB9Q4ZlWixXxymoPIYG6g2hkwAGKFodHWPFfxHD8ddkjXWRB9G2akUP7cfsJ4DcYn4VisUORCOYQwqDiSmboQ==
|
||||
|
||||
"@spectrum-css/avatar@^3.0.2":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/avatar/-/avatar-3.0.2.tgz#4f1826223eae330e64b6d3cc899e9bc2e98dac95"
|
||||
integrity sha512-wEczvSqxttTWSiL3cOvXV/RmGRwSkw2w6+slcHhnf0kb7ovymMM+9oz8vvEpEsSeo5u598bc+7ktrKFpAd6soQ==
|
||||
|
||||
"@spectrum-css/button@^3.0.1":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/button/-/button-3.0.3.tgz#2df1efaab6c7e0b3b06cb4b59e1eae59c7f1fc84"
|
||||
integrity sha512-6CnLPqqtaU/PcSSIGeGRi0iFIIxIUByYLKFO6zn5NEUc12KQ28dJ4PLwB6WBa0L8vRoAGlnWWH2ZZweTijbXgg==
|
||||
|
||||
"@spectrum-css/buttongroup@^3.0.2":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/buttongroup/-/buttongroup-3.0.3.tgz#719d868845ac9d2c4f939c1b9f6044507902d5aa"
|
||||
integrity sha512-eXl8U4QWMWXqyTu654FdQdEGnmczgOYlpIFSHyCMVjhtPqZp2xwnLFiGh6LKw+bLio6eeOZ0L+vpk1GcoYqgkw==
|
||||
|
||||
"@spectrum-css/checkbox@^3.0.2":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/checkbox/-/checkbox-3.0.3.tgz#8577067fc8b97e4609f92bd242364937a533a7bb"
|
||||
integrity sha512-QVG9uMHq+lh70Dh6mDNnY+vEvNz2p7VC6xgLfDYfijp2qeiqYPq72fQK6p/SiyqPk96ZACzNRwgeROU6Xf6Wgg==
|
||||
|
||||
"@spectrum-css/dialog@^3.0.1":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/dialog/-/dialog-3.0.3.tgz#7715a4ea435e753afb623d99ca5917ed1bcd6f34"
|
||||
integrity sha512-AhmKgfRIVyTe3ABiJ8lLUQL34VB/H6fN16na2LlbDRJvyRMzkdN1Xf2i6U3f4OMd3qQ8Gm5xat4BvMxIQPBAUQ==
|
||||
|
||||
"@spectrum-css/divider@^1.0.1":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/divider/-/divider-1.0.3.tgz#639e2ebaa0834efa40f42397668bbd5c153ea385"
|
||||
integrity sha512-Zy4Rn40w8UtzMh3wx/U9+CepSCpm1aOCGftHgWDub0XZuVTzh0c1WwyzTuLCx2Hf21z5VRGNiDh8bGEEzSbtNA==
|
||||
dependencies:
|
||||
"@spectrum-css/vars" "^3.0.2"
|
||||
|
||||
"@spectrum-css/dropzone@^3.0.2":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/dropzone/-/dropzone-3.0.3.tgz#aee71697a2c195947599d7541b858c3c198741dc"
|
||||
integrity sha512-ujrswdtB6bHigklyHsm6zomFd6rUnKJ3xVVRjroVF4+ouK4DxK5tX0iVd0EW6AOfOjx4Cc28uyFot3fpxp+MQw==
|
||||
|
||||
"@spectrum-css/fieldgroup@^3.0.2":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/fieldgroup/-/fieldgroup-3.0.3.tgz#85d85da048d08200f25ceab378026dd2b11e0bb2"
|
||||
integrity sha512-wXUXTXN1CPnR7M4Ltd+3uh7BfcNGUV1+Xe0/h0tCpq/j+S2Sd4xo7/pUMdU19sIDrAAtpEFp1tt+nouHcU5HGQ==
|
||||
|
||||
"@spectrum-css/fieldlabel@^3.0.1":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/fieldlabel/-/fieldlabel-3.0.3.tgz#f73c04d20734d4718ffb620dc46458904685b449"
|
||||
integrity sha512-nEvIkEXCD5n4fW67Unq6Iu7VXoauEd/JGpfTY02VsC5p4FJLnwKfPDbJUuUsqClAxqw7nAsmXVKtn4zQFf5yPQ==
|
||||
|
||||
"@spectrum-css/icon@^3.0.1":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/icon/-/icon-3.0.3.tgz#5c612822380927087aebd526855d82ed2c3e2cba"
|
||||
integrity sha512-hyloKOejPCXhP3MBNsm3SjR9j8xT1R1S19p32KW/0Qhj+VMUtfyEPmevyFptpn7wcovQccdl/vZVIVDuML/imw==
|
||||
|
||||
"@spectrum-css/illustratedmessage@^3.0.2":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/illustratedmessage/-/illustratedmessage-3.0.2.tgz#6a480be98b027e050b086e7899e40d87adb0a8c0"
|
||||
integrity sha512-dqnE8X27bGcO0HN8+dYx8O4o0dNNIAqeivOzDHhe2El+V4dTzMrNIerF6G0NLm3GjVf6XliwmitsZK+K6FmbtA==
|
||||
|
||||
"@spectrum-css/inputgroup@^3.0.2":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/inputgroup/-/inputgroup-3.0.3.tgz#00c9a370ddc2c55cf0f37dd6069faa9501fd7eb5"
|
||||
integrity sha512-FqRJTiLL7jiGfzDVXWUGVLqHryJjCcqQIrqAi+Tq0oenapzsBe2qc/zIrKgh2wtMI+NTIBLXTECvij3L1HlqAg==
|
||||
|
||||
"@spectrum-css/label@^2.0.10":
|
||||
version "2.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/label/-/label-2.0.10.tgz#2368651d7636a19385b5d300cdf6272db1916001"
|
||||
integrity sha512-xCbtEiQkZIlLdWFikuw7ifDCC21DOC/KMgVrrVJHXFc4KRQe9LTZSqmGF3tovm+CSq1adE59mYoTbojVQ9YuEQ==
|
||||
|
||||
"@spectrum-css/link@^3.1.1":
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/link/-/link-3.1.3.tgz#b0e560a7e0acdb4a2b329b6669696aa3438f5993"
|
||||
integrity sha512-8Pmy5d73MwKcATTPaj+fSrZYnIw7GmfX40AvpC1xx5LauOxsbUb4AVNp1kn2H8rrOBmxF7czyhoBBhEiv66QUg==
|
||||
|
||||
"@spectrum-css/menu@^3.0.1":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/menu/-/menu-3.0.3.tgz#46a9b221bb5f470a2f8a934bdfd512d84d2fdc4d"
|
||||
integrity sha512-qKA9J/MrikNKIpCEHsAazG2vY3im5tjGCmo6p9Pdnu8/aQMsiuZDHZayukeCttJUZkrb9guDVL9OIHlK5RZvcQ==
|
||||
|
||||
"@spectrum-css/modal@^3.0.1":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/modal/-/modal-3.0.2.tgz#58b6621cab65f90788d310374f40df1f7090473f"
|
||||
integrity sha512-YnIivJhoaao7Otu+HV7sgebPyFbO6sd/oMvTN/Rb2wwgnaMnIIuIRdGandSrcgotN2uNgs+P0knG6mv/xA1/dg==
|
||||
|
||||
"@spectrum-css/page@^3.0.1":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/page/-/page-3.0.2.tgz#8f0c03d25f5565fb13115541a8fcaf0e1d3a8ee0"
|
||||
integrity sha512-lCXWjonLwYBg8FHUEkiFX0Mmfk+9Uivgvxq0DTulPlWrJcULTwjaOiY28/YBz7Fy1wuv/0KORbkPRALpYldBZg==
|
||||
dependencies:
|
||||
"@spectrum-css/vars" "^3.0.2"
|
||||
|
||||
"@spectrum-css/pagination@^3.0.3":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/pagination/-/pagination-3.0.3.tgz#b204c3ada384c4af751a354bc428346d82eeea65"
|
||||
integrity sha512-OJ/v9GeNXJOZ9Yr9LDBYPrR2NCiLOWP9wANT/a5sqFuugRnQbn/HYMnRp9TBxwpDY6ihaPo0T/wi7kLiAJFdDw==
|
||||
|
||||
"@spectrum-css/picker@^1.0.1":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/picker/-/picker-1.0.3.tgz#21379bcf8ae94277deeb6ad65dcd9e2bbfacb487"
|
||||
integrity sha512-oHLGxBx5BwVCSGo7/T1C9PTHX1+/5AmVjyLiTJ4UoIdSJmOERw9YcRZbcGZgBJNWbxcjr4TyGtwj1EcSjEy97w==
|
||||
|
||||
"@spectrum-css/popover@^3.0.1":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/popover/-/popover-3.0.3.tgz#6fb69873474fb968afb738eacb9e121f93e83a09"
|
||||
integrity sha512-KvmXv4TV19FBx39KfmgVlDYtvtBqv/8RRK7RRLDDHGViTxZtShjVsVpwIgfkfgn4iJztCnXpWzFqRXWUu2XCpQ==
|
||||
|
||||
"@spectrum-css/progressbar@^1.0.2":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/progressbar/-/progressbar-1.0.3.tgz#f70bcc38a2a21cff2f422ec825724ebbb9455e67"
|
||||
integrity sha512-vJHplefUuy8+NjCw1X7fLbqHVGNVBpvGFXNAeaIj4SFf4ygxiUq/5c9iRhhsCQixEsJlfD/b7BnGXU7BUDkr6Q==
|
||||
|
||||
"@spectrum-css/progresscircle@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/progresscircle/-/progresscircle-1.0.2.tgz#258ea9170fb70f795edda03e38a61d93bef4487c"
|
||||
integrity sha512-JLULpyzjIY95lzlWR1yE1gv4l1K6p+scQ+edmuZZUHBzwM3pUtkvHJmUlA9TYdResUYW6Uka60VRdY6lZ8gnFQ==
|
||||
|
||||
"@spectrum-css/radio@^3.0.2":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/radio/-/radio-3.0.3.tgz#25c3bc5e9c30a8a8ae728717b7c7fb736cdae640"
|
||||
integrity sha512-LaLGfz/eGNR2iyqouXYILIA+pKRqF769iPdwM0REm5RpWvMQDD7rPZ/kWlg18owjaFsyllEp25gEjmhRJIIVOw==
|
||||
|
||||
"@spectrum-css/search@^3.0.2":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/search/-/search-3.0.3.tgz#3415dc106aca0d5dd996e87084a1b47c2b95a882"
|
||||
integrity sha512-kdLpKTt0obljuhS1q1tukujRlvSs8sBwij76D4Qp8KpMzwePfZyvv1kYzuWPNZfTeISxWsmyZ6Wxd1uvzjn+UA==
|
||||
|
||||
"@spectrum-css/sidenav@^3.0.2":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/sidenav/-/sidenav-3.0.3.tgz#132141fbd2500a927c312fa4e1d712c438b3d597"
|
||||
integrity sha512-cQ+CgwjxGftrcc79i1XnGd66QTl7H7zopSU0UTV4Qq7hvqfrjjWxfZ6b+3tezrrhNlDope1ff9o8sm67PsPXtg==
|
||||
|
||||
"@spectrum-css/statuslight@^3.0.2":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/statuslight/-/statuslight-3.0.2.tgz#dc54b6cd113413dcdb909c486b5d7bae60db65c5"
|
||||
integrity sha512-xodB8g8vGJH20XmUj9ZsPlM1jHrGeRbvmVXkz0q7YvQrYAhim8pP3W+XKKZAletPFAuu8cmUOc6SWn6i4X4z6w==
|
||||
|
||||
"@spectrum-css/switch@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/switch/-/switch-1.0.2.tgz#f0b4c69271964573e02b08e90998096e49e1de44"
|
||||
integrity sha512-zqmHpgWPNg1gEwdUNFYV3CBX5JaeALfIqcJIxE0FLZqr9d1C4+oLE0ItIFzt1bwr4bFAOmkEpvtiY+amluzGxQ==
|
||||
|
||||
"@spectrum-css/table@^3.0.1":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/table/-/table-3.0.3.tgz#7f7f19905ef3275cbf907ce3a5818e63c30b2caf"
|
||||
integrity sha512-nxwzVjLPsXoY/v4sdxOVYLcC+cEbGgJyLcLclT5LT9MGSbngFeUMJzzVR4EvehzuN4dH7hrATG7Mbuq29Mf0Hg==
|
||||
|
||||
"@spectrum-css/tabs@^3.0.1":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/tabs/-/tabs-3.0.3.tgz#51dd6f168c897b0fdc3a7e9f901df7bd2288b4fc"
|
||||
integrity sha512-iLP1I72bJWz9APdQB1jiw+pOv5a7N+hYOCJvRoc56Us/hJKVzowkyGRe3uH+8v36nCG9bHxiAQNLoU8eXisVrg==
|
||||
|
||||
"@spectrum-css/tags@^3.0.2":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/tags/-/tags-3.0.3.tgz#fc76d2735cdc442de91b7eb3bee49a928c0767ac"
|
||||
integrity sha512-SL8vPxVDfWcY5VdIuyl0TImEXcOU1I7yCyXkk7MudMwfnYs81FaIyY32hFV9OHj0Tz/36UzRzc7AVMSuRQ53pw==
|
||||
|
||||
"@spectrum-css/textfield@^3.0.1":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/textfield/-/textfield-3.0.2.tgz#907f62d2dc82852dd6236a820be99e252b531631"
|
||||
integrity sha512-nkFgAb0cP4jUodkUBErMNfyF78jJLtgL1Mrr9/rvGpGobo10IAbb8zZY4CkZ64o8XmMy/85+wZTKcx+KHatqpg==
|
||||
|
||||
"@spectrum-css/toast@^3.0.1":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/toast/-/toast-3.0.3.tgz#97c1527384707600832ecda35643ed304615250f"
|
||||
integrity sha512-CjLeaMs+cjUXojCCRtbj0YkD2BoZW16kjj2o5omkEpUTjA34IJ8xJ1a+CCtDILWekhXvN0MBN4sbumcnwcnx8w==
|
||||
|
||||
"@spectrum-css/tooltip@^3.0.3":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/tooltip/-/tooltip-3.0.3.tgz#26b8ca3b3d30e29630244d85eb4fc11d0c841281"
|
||||
integrity sha512-ztRF7WW1FzyNavXBRc+80z67UoOrY9wl3cMYsVD3MpDnyxdzP8cjza1pCcolKBaFqRTcQKkxKw3GWtGICRKR5A==
|
||||
|
||||
"@spectrum-css/treeview@^3.0.2":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/treeview/-/treeview-3.0.3.tgz#aeda5175158b9f8d7529cb2b394428eb2a428046"
|
||||
integrity sha512-D5gGzZC/KtRArdx86Mesc9+99W9nTbUOeyYGqoJoAfJSOttoT6Tk5CrDvlCmAqjKf5rajemAkGri1ChqvUIwkw==
|
||||
|
||||
"@spectrum-css/typography@^3.0.1":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/typography/-/typography-3.0.2.tgz#ea3ca0a60e18064527819d48c8c4364cab4fcd38"
|
||||
integrity sha512-5ZOLmQe0edzsDMyhghUd4hBb5uxGsFrxzf+WasfcUw9klSfTsRZ09n1BsaaWbgrLjlMQ+EEHS46v5VNo0Ms2CA==
|
||||
|
||||
"@spectrum-css/underlay@^2.0.9":
|
||||
version "2.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/underlay/-/underlay-2.0.10.tgz#8b75b646605a311850f6620caa18d4996cd64ed7"
|
||||
integrity sha512-PmsmkzeGD/rY4pp3ILXHt9w8BW7uaEqXe08hQRS7rGki7wqCpG4mE0/8N3yEcA3QxWQclmG9gdkg5uz6wMmYzA==
|
||||
|
||||
"@spectrum-css/vars@^3.0.1", "@spectrum-css/vars@^3.0.2":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-3.0.2.tgz#ea9062c3c98dfc6ba59e5df14a03025ad8969999"
|
||||
integrity sha512-vzS9KqYXot4J3AEER/u618MXWAS+IoMvYMNrOoscKiLLKYQWenaueakUWulFonToPd/9vIpqtdbwxznqrK5qDw==
|
||||
|
||||
"@sveltejs/vite-plugin-svelte@^1.0.0-next.5":
|
||||
version "1.0.0-next.5"
|
||||
resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.5.tgz#8cf608f7a3c33dfa5b648397aae1ba90e6a4883f"
|
||||
integrity sha512-RVjafsqziWwnQm8VEy2y0qNaugNDvRd8tTaCt9rjgQkqaS/BDiyDCluXxA28PRC+ddZjvwUeq9k+0EfbLVObfg==
|
||||
version "1.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.10.tgz#15526067ea2edd334420b1e14602e29b370be25e"
|
||||
integrity sha512-ImvxbhPePm2hWNTKBSA3LHAYGwiEjHjvvgfPLXm4R87sfZ+BMXql9jBmDpzUC/URBLT4BB3Jxos/i523qkJBHg==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^4.1.0"
|
||||
chalk "^4.1.0"
|
||||
chalk "^4.1.1"
|
||||
debug "^4.3.2"
|
||||
hash-sum "^2.0.0"
|
||||
require-relative "^0.8.7"
|
||||
slash "^3.0.0"
|
||||
slash "^4.0.0"
|
||||
source-map "^0.7.3"
|
||||
svelte-hmr "^0.13.3"
|
||||
svelte-hmr "^0.14.2"
|
||||
|
||||
ansi-styles@^4.1.0:
|
||||
version "4.3.0"
|
||||
|
@ -44,9 +284,9 @@ ansi-styles@^4.1.0:
|
|||
color-convert "^2.0.1"
|
||||
|
||||
apexcharts@^3.19.2, apexcharts@^3.22.1:
|
||||
version "3.26.0"
|
||||
resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.26.0.tgz#a78abc108b2e1b3086a738f0ec7c98e292f4a14b"
|
||||
integrity sha512-zdYHs3k3tgmCn1BpYLj7rhGEndBYF33Pq1+g0ora37xAr+3act5CJrpdXM2jx2boVUyXgavoSp6sa8WpK7RkSA==
|
||||
version "3.27.1"
|
||||
resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.27.1.tgz#b0e6dd3b3ace028f29b32fcd88e19a2420a18089"
|
||||
integrity sha512-2pfw3pxeWhI0ap5lfxyfGNGoGScfEwfc8XnTpbnzgRdr1AOH5JJN9hh3MvfwrC9TQQfJYC2TZc8P/q9qXUj1bQ==
|
||||
dependencies:
|
||||
svg.draggable.js "^2.2.2"
|
||||
svg.easing.js "^2.0.0"
|
||||
|
@ -55,10 +295,10 @@ apexcharts@^3.19.2, apexcharts@^3.22.1:
|
|||
svg.resize.js "^1.4.3"
|
||||
svg.select.js "^3.0.1"
|
||||
|
||||
chalk@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
|
||||
integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
|
||||
chalk@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad"
|
||||
integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
|
||||
dependencies:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
@ -80,7 +320,7 @@ colorette@^1.2.2:
|
|||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
|
||||
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
|
||||
|
||||
dayjs@^1.10.5:
|
||||
dayjs@^1.10.4, dayjs@^1.10.5:
|
||||
version "1.10.5"
|
||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.5.tgz#5600df4548fc2453b3f163ebb2abbe965ccfb986"
|
||||
integrity sha512-BUFis41ikLz+65iH6LHQCDm4YPMj5r1YFLdupPIyM4SGcXMmtiLQ7U37i+hGS8urIuqe7I/ou3IS1jVc4nbN4g==
|
||||
|
@ -92,10 +332,10 @@ debug@^4.3.2:
|
|||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
esbuild@^0.9.3:
|
||||
version "0.9.7"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.9.7.tgz#ea0d639cbe4b88ec25fbed4d6ff00c8d788ef70b"
|
||||
integrity sha512-VtUf6aQ89VTmMLKrWHYG50uByMF4JQlVysb8dmg6cOgW8JnFCipmz7p+HNBl+RR3LLCuBxFGVauAe2wfnF9bLg==
|
||||
esbuild@^0.12.5:
|
||||
version "0.12.8"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.8.tgz#ac90da77cb3bfbf49ab815200bcef7ffe1a3348f"
|
||||
integrity sha512-sx/LwlP/SWTGsd9G4RlOPrXnIihAJ2xwBUmzoqe2nWwbXORMQWtAGNJNYLBJJqa3e9PWvVzxdrtyFZJcr7D87g==
|
||||
|
||||
estree-walker@^2.0.1:
|
||||
version "2.0.2"
|
||||
|
@ -135,9 +375,9 @@ hash-sum@^2.0.0:
|
|||
integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==
|
||||
|
||||
is-core-module@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a"
|
||||
integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1"
|
||||
integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
|
@ -146,29 +386,29 @@ ms@2.1.2:
|
|||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
nanoid@^3.1.22:
|
||||
version "3.1.22"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844"
|
||||
integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==
|
||||
nanoid@^3.1.23:
|
||||
version "3.1.23"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
|
||||
integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
|
||||
|
||||
path-parse@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
||||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
picomatch@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
|
||||
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
||||
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
|
||||
|
||||
postcss@^8.2.1:
|
||||
version "8.2.9"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.9.tgz#fd95ff37b5cee55c409b3fdd237296ab4096fba3"
|
||||
integrity sha512-b+TmuIL4jGtCHtoLi+G/PisuIl9avxs8IZMSmlABRwNz5RLUUACrC+ws81dcomz1nRezm5YPdXiMEzBEKgYn+Q==
|
||||
postcss@^8.3.0:
|
||||
version "8.3.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f"
|
||||
integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==
|
||||
dependencies:
|
||||
colorette "^1.2.2"
|
||||
nanoid "^3.1.22"
|
||||
source-map "^0.6.1"
|
||||
nanoid "^3.1.23"
|
||||
source-map-js "^0.6.2"
|
||||
|
||||
require-relative@^0.8.7:
|
||||
version "0.8.7"
|
||||
|
@ -184,21 +424,21 @@ resolve@^1.19.0:
|
|||
path-parse "^1.0.6"
|
||||
|
||||
rollup@^2.38.5:
|
||||
version "2.44.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.44.0.tgz#8da324d1c4fd12beef9ae6e12f4068265b6d95eb"
|
||||
integrity sha512-rGSF4pLwvuaH/x4nAS+zP6UNn5YUDWf/TeEU5IoXSZKBbKRNTCI3qMnYXKZgrC0D2KzS2baiOZt1OlqhMu5rnQ==
|
||||
version "2.51.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.51.1.tgz#87bcd4095fe79b14c9bec0edc7ffa44e4827f793"
|
||||
integrity sha512-8xfDbAtBleXotb6qKEHWuo/jkn94a9dVqGc7Rwl3sqspCVlnCfbRek7ldhCARSi7h32H0xR4QThm1t9zHN+3uw==
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.1"
|
||||
|
||||
slash@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||
slash@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"
|
||||
integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
|
||||
|
||||
source-map@^0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
source-map-js@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
|
||||
integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
|
||||
|
||||
source-map@^0.7.3:
|
||||
version "0.7.3"
|
||||
|
@ -220,16 +460,21 @@ svelte-apexcharts@^1.0.2:
|
|||
apexcharts "^3.19.2"
|
||||
|
||||
svelte-flatpickr@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/svelte-flatpickr/-/svelte-flatpickr-3.1.0.tgz#ad83588430dbd55196a1a258b8ba27e7f9c1ee37"
|
||||
integrity sha512-zKyV+ukeVuJ8CW0Ing3T19VSekc4bPkou/5Riutt1yATrLvSsanNqcgqi7Q5IePvIoOF9GJ5OtHvn1qK9Wx9BQ==
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/svelte-flatpickr/-/svelte-flatpickr-3.1.1.tgz#c79da72a4acab252ed39bac8168f30f79db3ff80"
|
||||
integrity sha512-z/sV/AMTqyybeWPCjoWYUOyuMmu9qX2c2f2cRqYos9K9sM5L3CqagtvfVy7GZQrnEYe+K7l/gGDCAyxJNp2+gA==
|
||||
dependencies:
|
||||
flatpickr "^4.5.2"
|
||||
|
||||
svelte-hmr@^0.13.3:
|
||||
version "0.13.3"
|
||||
resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.13.3.tgz#fba5739b477ea44caf70e542a24a4352bee2b897"
|
||||
integrity sha512-gagW62pLQ2lULmvNA3pIZu9pBCYOaGu3rQikUOv6Nokz5VxUgT9/mQLfMxj9phDEKHCg/lgr3i6PkqZDbO9P2Q==
|
||||
svelte-hmr@^0.14.2:
|
||||
version "0.14.4"
|
||||
resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.4.tgz#b7ef2bfeef23916e0e912828c50645ca572ac355"
|
||||
integrity sha512-kItFF7vqzStckSigoFmMnxJpTOdB9TWnQAW6Js+yAB4277tLbJIIE5KBlGHNmJNpA7MguqidsPB27Uw5UzQPCA==
|
||||
|
||||
svelte-portal@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/svelte-portal/-/svelte-portal-1.0.0.tgz#36a47c5578b1a4d9b4dc60fa32a904640ec4cdd3"
|
||||
integrity sha512-nHf+DS/jZ6jjnZSleBMSaZua9JlG5rZv9lOGKgJuaZStfevtjIlUJrkLc3vbV8QdBvPPVmvcjTlazAzfKu0v3Q==
|
||||
|
||||
svelte@^3.38.2:
|
||||
version "3.38.2"
|
||||
|
@ -292,12 +537,12 @@ svg.select.js@^3.0.1:
|
|||
svg.js "^2.6.5"
|
||||
|
||||
vite@^2.1.5:
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-2.1.5.tgz#4857da441c62f7982c83cbd5f42a00330f20c9c1"
|
||||
integrity sha512-tYU5iaYeUgQYvK/CNNz3tiJ8vYqPWfCE9IQ7K0iuzYovWw7lzty7KRYGWwV3CQPh0NKxWjOczAqiJsCL0Xb+Og==
|
||||
version "2.3.7"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-2.3.7.tgz#3023892419367465e1af1739578f8663d04243b2"
|
||||
integrity sha512-Y0xRz11MPYu/EAvzN94+FsOZHbSvO6FUvHv127CyG7mV6oDoay2bw+g5y9wW3Blf8OY3chaz3nc/DcRe1IQ3Nw==
|
||||
dependencies:
|
||||
esbuild "^0.9.3"
|
||||
postcss "^8.2.1"
|
||||
esbuild "^0.12.5"
|
||||
postcss "^8.3.0"
|
||||
resolve "^1.19.0"
|
||||
rollup "^2.38.5"
|
||||
optionalDependencies:
|
||||
|
|
Loading…
Reference in New Issue