Add radio group spectrum component and update builder

This commit is contained in:
Andrew Kingston 2021-04-16 14:30:33 +01:00
parent 3354aeff54
commit 431abb53ce
31 changed files with 109 additions and 1026 deletions

View File

@ -53,6 +53,7 @@
"@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/table": "^3.0.1",
"@spectrum-css/tabs": "^3.0.1",
"@spectrum-css/textfield": "^3.0.1",

View File

@ -1,67 +0,0 @@
<script>
import { View } from "svench";
import Checkbox from "./Checkbox.svelte";
let checked = false
let menu = [
{text: 'Cookies and cream', checked: false},
{text: 'Mint choc chip', checked: false},
{text: 'Raspberry ripple', checked: true}
];
</script>
<View name="Single checkbox">
<Checkbox bind:checked value="value">
<label for="value">One single checkbox with text</label>
</Checkbox>
</View>
<View name="Single disabled checkbox">
<Checkbox disabled checked value="value">
<label for="someOtherValue">A disabled checkbox</label>
</Checkbox>
</View>
<View name="No text">
<Checkbox bind:checked value="somevalue" />
</View>
## Multiple checkboxes
Use an array and an each block to use multiple checkboxes
```svelte
<script>
let menu = [
{text: 'Cookies and cream', checked: false},
{text: 'Mint choc chip', checked: false},
{text: 'Raspberry ripple', checked: true}
];
</script>
{#each menu as {text, checked}}
<Checkbox value={text} bind:checked>
<label for={text}>{text}</label>
</Checkbox>
{/each}
```
<View name="Multiple checkboxes">
<div class="container">
{#each menu as {text, checked}}
<Checkbox value={text} bind:checked>
<label for={text}>{text}</label>
</Checkbox>
{/each}
</div>
</View>
<style>
label {
display: grid;
place-items: center;
}
.container {
display: grid;
grid-gap: 10px;
}
</style>

View File

@ -5,7 +5,7 @@
export let value = false
export let error = null
export let fieldId = null
export let id = null
export let text = null
export let disabled = false
@ -24,7 +24,7 @@
on:change={onChange}
type="checkbox"
class="spectrum-Checkbox-input"
id={fieldId} />
{id} />
<span class="spectrum-Checkbox-box">
<svg
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark"

View File

@ -3,7 +3,7 @@
import { createEventDispatcher } from "svelte"
export let value = []
export let fieldId = null
export let id = null
export let placeholder = null
export let disabled = false
export let error = null
@ -69,7 +69,7 @@
</script>
<Picker
{fieldId}
{id}
{error}
{disabled}
{fieldText}

View File

@ -4,7 +4,7 @@
import "@spectrum-css/menu/dist/index-vars.css"
import { fly } from "svelte/transition"
export let fieldId = null
export let id = null
export let disabled = false
export let error = null
export let fieldText = ""
@ -19,7 +19,7 @@
</script>
<button
id={fieldId}
{id}
class="spectrum-Picker spectrum-Picker--sizeM"
{disabled}
class:is-invalid={!!error}

View File

@ -0,0 +1,36 @@
<script>
import "@spectrum-css/fieldgroup/dist/index-vars.css"
import "@spectrum-css/radio/dist/index-vars.css"
import { createEventDispatcher } from "svelte"
export let direction = "vertical"
export let value = null
export let options = []
export let error = null
export let disabled = false
export let getOptionLabel = option => option
export let getOptionValue = option => option
const dispatch = createEventDispatcher()
const onChange = e => dispatch("change", e.target.value)
</script>
<div class={`spectrum-FieldGroup spectrum-FieldGroup--${direction}`}>
{#if options && Array.isArray(options)}
{#each options as option}
<div
class="spectrum-Radio spectrum-FieldGroup-item spectrum-Radio--emphasized"
class:is-invalid={!!error}>
<input
on:change={onChange}
bind:group={value}
value={getOptionValue(option)}
type="radio"
class="spectrum-Radio-input"
{disabled} />
<span class="spectrum-Radio-button" />
<label class="spectrum-Radio-label">{getOptionLabel(option)}</label>
</div>
{/each}
{/if}
</div>

View File

@ -3,7 +3,7 @@
import Picker from "./Picker.svelte"
export let value = null
export let fieldId = null
export let id = null
export let placeholder = "Choose an option"
export let disabled = false
export let error = null
@ -39,7 +39,7 @@
<Picker
bind:open
{fieldId}
{id}
{error}
{disabled}
{fieldText}

View File

@ -3,7 +3,7 @@
import { createEventDispatcher } from "svelte"
export let value = ""
export let placeholder = ""
export let placeholder = null
export let type = "text"
export let disabled = false
export let error = null

View File

@ -2,3 +2,4 @@ export { default as CoreTextField } from "./TextField.svelte"
export { default as CoreSelect } from "./Select.svelte"
export { default as CoreMultiselect } from "./Multiselect.svelte"
export { default as CoreCheckbox } from "./Checkbox.svelte"
export { default as CoreRadioGroup } from "./RadioGroup.svelte"

View File

@ -1,57 +0,0 @@
<script>
import { View } from "svench";
import Select from "./Select.svelte";
import DataList from "./DataList.svelte";
import Spacer from "../Spacer/Spacer.svelte"
const options = ["Chocolate", "Vanilla", "Strawberry Cheesecake"];
</script>
<View name="default">
<DataList name="Test" label="Flavour">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</DataList>
</View>
<View name="secondary">
<DataList secondary name="Test" label="Flavour">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</DataList>
</View>
<View name="outline">
<DataList outline name="Test" label="Flavour">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</DataList>
</View>
<View name="disabled">
<DataList disabled name="Test" label="Flavour">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</DataList>
</View>
<View name="thin">
<DataList thin name="Test" label="Flavour">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</DataList>
</View>
<View name="extraThin">
<DataList extraThin name="Test" label="Flavour">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</DataList>
</View>

View File

@ -1,62 +0,0 @@
<script>
import { View } from "svench";
import Input from "./Input.svelte";
import Button from "../Button/Button.svelte";
</script>
<View name="default">
<Input placeholder="Enter your name" label="Name" />
</View>
<View name="presentation">
<Input presentation placeholder="Enter your name" label="Name" />
</View>
<View name="outline">
<Input outline placeholder="Enter your name" label="Name" />
</View>
<View name="disabled">
<Input disabled placeholder="Enter your name" label="Name" />
</View>
<View name="disabled with value">
<Input value="Some text" disabled placeholder="Enter your name" label="Name" />
</View>
<View name="thin">
<Input thin placeholder="Enter your name" label="Name" />
</View>
<View name="extraThin">
<Input extraThin placeholder="Enter your name" label="Name" />
</View>
<View name="large">
<Input large placeholder="Enter your name" label="Name" />
</View>
<View name="border">
<Input border presentation placeholder="Enter your name" label="Name" />
</View>
<View name="number">
<Input type="number" placeholder="Enter your age" label="Age" />
</View>
<View name="with edit buttons">
<Input
thin
edit
placeholder="Enter your name"
label="Name"
on:save={console.log} />
</View>
<View name="with error message">
<Input
placeholder="Enter your name"
label="Name"
error="This is an error message!"
on:save={console.log} />
</View>

View File

@ -1,63 +0,0 @@
<script>
import { View } from "svench";
import Multiselect from "./Multiselect.svelte";
const options = ["Red", "Blue", "Yellow", "Green", "Pink", "Very long color name to show text wrapping"];
</script>
<View name="default">
<Multiselect name="Test" label="Colours" placeholder="Choose some colours">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Multiselect>
</View>
<View name="right aligned">
<div class="max-width">
<Multiselect align="right" name="Test" label="Colours" placeholder="Choose some colours">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Multiselect>
</div>
</View>
<View name="secondary">
<Multiselect name="Test" label="Colours" secondary placeholder="Choose some colours">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Multiselect>
</View>
<View name="outline">
<Multiselect name="Test" label="Colours" outline placeholder="Choose some colours">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Multiselect>
</View>
<View name="disabled">
<Multiselect name="Test" label="Colours" disabled placeholder="Choose some colours">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Multiselect>
</View>
<View name="extraThin">
<Multiselect name="Test" label="Colours" extraThin placeholder="Choose some colours">
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Multiselect>
</View>
<style>
.max-width {
align-self: flex-end;
max-width: 150px;
}
</style>

View File

@ -1,140 +0,0 @@
<script>
import { createEventDispatcher } from "svelte"
const dispatch = createEventDispatcher()
export let value
export let group
export let name
export let disabled = false
function handleChange() {
if (disabled) return
group = value
dispatch("change", group)
}
</script>
<div class="container">
<input
{disabled}
on:change={handleChange}
{value}
bind:group
type="radio"
{name}
class="checkbox"
id={value} />
<div class="checkbox-container" on:click={handleChange}>
<div class:disabled class="check-div" class:checked={group === value}>
<div class="tick_mark" />
</div>
</div>
<slot />
</div>
<style>
.container {
display: flex;
gap: var(--spacing-s);
}
.checkbox-container {
position: relative;
z-index: 0;
}
.checkbox {
display: none;
}
.check-div {
position: relative;
width: 20px;
height: 20px;
background-color: var(--grey-2);
cursor: pointer;
transition: 0.2s ease transform, 0.2s ease background-color,
0.2s ease box-shadow;
overflow: hidden;
border-radius: 4px;
}
.check-div:before {
content: "";
position: absolute;
top: 50%;
right: 0;
left: 0;
width: 12px;
height: 12px;
margin: 0 auto;
background-color: var(--background);
transform: translateY(-50%);
transition: 0.2s ease width, 0.2s ease height;
border-radius: 2px;
}
.check-div:active {
transform: translateY(-50%) scale(0.9);
}
.tick_mark {
position: absolute;
top: 50%;
left: 6px;
width: 5px;
height: 4px;
margin: 0 auto;
transform: rotateZ(-40deg);
}
.tick_mark:before,
.tick_mark:after {
content: "";
position: absolute;
background-color: var(--ink);
border-radius: 2px;
opacity: 0;
transition: 0.2s ease transform, 0.2s ease opacity;
}
.tick_mark:before {
left: 0;
bottom: 0;
width: 2px;
height: 6px;
box-shadow: -2px 0 5px rgba(0, 0, 0, 0.23);
transform: translateY(-68px);
}
.tick_mark:after {
left: 0;
bottom: 0;
width: 12px;
height: 2px;
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.23);
transform: translateX(78px);
}
.check-div.disabled:active {
transform: none;
}
.checked {
background-color: var(--grey-2);
}
.checked.disabled {
background-color: var(--grey-5);
}
.checked:before {
width: 0;
height: 0;
}
.checked .tick_mark:before,
.checked .tick_mark:after {
transform: translate(0);
opacity: 1;
}
</style>

View File

@ -1,64 +0,0 @@
<script>
import { View } from "svench";
import Radio from "./Radio.svelte";
let selected = 'Cookies and cream'
let selected2 = 'Mint choc chip'
let menu = [
'Cookies and cream',
'Mint choc chip',
'Raspberry ripple'
];
</script>
## Multiple checkboxes
Use an array and an each block to use the radio button.
```svelte
<script>
let selected = 'Cookies and cream'
let selected2 = 'Cookies and cream'
let menu = [
'Cookies and cream',
'Mint choc chip',
'Raspberry ripple'
];
</script>
{#each menu as flavour}
<Radio name="Ice Cream Flavour" value={flavour} bind:group={selected} label={flavour} showLabel/>
{/each}
```
<View name="Multiple radio buttons">
<div class="container">
{#each menu as flavour}
<Radio name="Ice Cream Flavour" value={flavour} bind:group={selected}>
<label for={flavour}>{flavour}</label>
</Radio>
{/each}
</div>
</View>
<View name="Disabled Radio inputs">
<div class="container">
{#each menu as flavour}
<Radio disabled name="Ice Cream Flavour" value={flavour} bind:group={selected2}>
<label for={flavour}>{flavour}</label>
</Radio>
{/each}
</div>
</View>
<style>
label {
display: grid;
place-items: center;
}
.container {
display: grid;
grid-gap: 10px;
}
</style>

View File

@ -0,0 +1,37 @@
<script>
import Field from "./Field.svelte"
import RadioGroup from "./Core/RadioGroup.svelte"
import { createEventDispatcher } from "svelte"
export let value = null
export let label = undefined
export let disabled = false
export let labelPosition = "above"
export let error = null
export let options = []
export let getOptionLabel = option => extractProperty(option, "label")
export let getOptionValue = option => extractProperty(option, "value")
const dispatch = createEventDispatcher()
const onChange = e => {
dispatch("change", e.detail)
value = e.detail
}
const extractProperty = (value, property) => {
if (value && typeof value === "object") {
return value[property]
}
return value
}
</script>
<Field {label} {labelPosition} {disabled} {error}>
<RadioGroup
{error}
{disabled}
{value}
{options}
{getOptionLabel}
{getOptionValue}
on:change={onChange} />
</Field>

View File

@ -1,40 +0,0 @@
<script>
import { View } from "svench";
import RichText from "./RichText.svelte";
const options = { placeholder: "this is not the default value!" };
let value;
</script>
### Rich Text Component
This component uses the QuillJS library to add Rich Text editing functionality.
It exposes a <code>content</code> variable that you can bind to in order to get Markdown out of the component.
As well as the content you can also pass in an option object that looks like so:
```js
let options = {
modules: {
toolbar: [
[{ header: [1, 2, 3, false] }],
['bold', 'italic', 'underline', 'strike']
]
},
placeholder: 'Type something...',
theme: 'snow'
}
```
<View name="default">
<RichText bind:value />
</View>
<View name="passing in Markdown">
<RichText value="# This is an h1 heading!" />
</View>
<View name="passing in custom options">
<RichText {options} />
</View>

View File

@ -1,62 +0,0 @@
<script>
import { View } from "svench";
import Select from "./Select.svelte";
import Spacer from "../Spacer/Spacer.svelte"
const options = ["Chocolate", "Vanilla", "Strawberry Cheesecake"];
</script>
<View name="default">
<Select name="Test" label="Flavour">
<option value="">Choose an option</option>
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Select>
</View>
<View name="secondary">
<Select secondary name="Test" label="Flavour">
<option value="">Choose an option</option>
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Select>
</View>
<View name="outline">
<Select outline name="Test" label="Flavour">
<option value="">Choose an option</option>
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Select>
</View>
<View name="disabled">
<Select disabled name="Test" label="Flavour">
<option value="">Choose an option</option>
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Select>
</View>
<View name="thin">
<Select thin name="Test" label="Flavour">
<option value="">Choose an option</option>
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Select>
</View>
<View name="extraThin">
<Select extraThin name="Test" label="Flavour">
<option value="">Choose an option</option>
{#each options as option}
<option value={option}>{option}</option>
{/each}
</Select>
</View>

View File

@ -1,26 +0,0 @@
<script>
import { View } from "svench";
import Slider from "./Slider.svelte";
</script>
<View name="default">
<Slider label=Quantity value="50" />
</View>
<View name="show value">
<Slider label="Quantity" value="50" showValue />
</View>
<View name="show range">
<Slider label="Quantity" value="25" showValue showRange min="0" max="100" />
</View>
<View name="custom min and max">
<Slider label="Quantity" value="350" showValue showRange min="50" max="500" />
</View>
<View name="custom step">
<Slider label="Quantity" value="25" step="25" showValue showRange min="0" max="100" />
</View>

View File

@ -1,30 +0,0 @@
<script>
import { View } from "svench";
import TextArea from "./TextArea.svelte";
import Button from "../Button/Button.svelte";
</script>
<View name="default">
<TextArea placeholder="Enter your email text" label="Email Body" />
</View>
<View name="disabled">
<TextArea disabled placeholder="Enter your email text" label="Email Body" />
</View>
<View name="no label">
<TextArea placeholder="Enter your email text" />
</View>
<View name="thin">
<TextArea thin placeholder="Enter your email text" label="Email Body" />
</View>
<View name="extraThin">
<TextArea extraThin placeholder="Enter your email text" label="Email Body" />
</View>
<View name="with buttons">
<TextArea edit placeholder="Enter your email text" label="Email Body" />
</View>

View File

@ -1,21 +0,0 @@
<script>
import { View } from "svench";
import Toggle from "./Toggle.svelte";
</script>
<View name="default">
<Toggle />
</View>
<View name="checked with text">
<Toggle text="Display on mobile?" />
</View>
<View name="thin">
<Toggle text="Display on mobile?" thin />
</View>
<View name="disabled">
<Toggle disabled={true} />
</View>

View File

@ -14,7 +14,7 @@ export { default as ActionMenu } from "./ActionMenu/ActionMenu.svelte"
export { default as Button } from "./Button/Button.svelte"
export { default as Icon, iconOptions, directions } from "./Icons/Icon.svelte"
export { default as Toggle } from "./Form/Toggle.svelte"
export { default as Radio } from "./Form/Radio.svelte"
export { default as RadioGroup } from "./Form/RadioGroup.svelte"
export { default as Checkbox } from "./Form/Checkbox.svelte"
export { default as Home } from "./Links/Home.svelte"
export { default as DetailSummary } from "./List/Items/DetailSummary.svelte"
@ -49,7 +49,6 @@ export { default as Heading } from "./Typography/Heading.svelte"
export { default as Detail } from "./Typography/Detail.svelte"
export { default as Code } from "./Typography/Code.svelte"
// Core form components to be used elsewhere (standard components)
export * from "./Form/Core"

View File

@ -156,6 +156,11 @@
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.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/radio/-/radio-3.0.2.tgz#9c1386894920bbed604e4e174fbbd45d9d762152"
integrity sha512-0TDdzC9omNXnpKHEXNuuGeXdNh4x8jvTKVUqMRLb7vY4hY94hAdt6X01NBqka+jzK35HxGzpDdPADAz62yZLPQ==
"@spectrum-css/table@^3.0.1":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/table/-/table-3.0.2.tgz#c666743d569fef81ddc8810fac8cda53b315f8d7"

View File

@ -1,171 +0,0 @@
<script>
import { onMount, onDestroy } from "svelte"
import { Modal, ModalContent } from "@budibase/bbui"
import CreateEditColumn from "../modals/CreateEditColumn.svelte"
import { FIELDS } from "constants/backend"
const SORT_ICON_MAP = {
asc: "ri-arrow-down-fill",
desc: "ri-arrow-up-fill",
}
export let field
export let displayName
export let column
export let enableSorting = true
export let showColumnMenu
export let progressSort
export let editable
let menuButton
let sortDirection = ""
let modal
let hovered
let filterActive
function toggleMenu() {
showColumnMenu(menuButton)
}
function onSort(event) {
progressSort(event.shiftKey)
}
function showModal() {
modal.show()
}
function setSort() {
sortDirection = column.getSort()
}
function setFilterActive(e) {
filterActive = e.column.filterActive
}
onMount(() => {
column.addEventListener("sortChanged", setSort)
column.addEventListener("filterActiveChanged", setFilterActive)
})
onDestroy(() => {
column.removeEventListener("sortChanged", setSort)
column.removeEventListener("filterActiveChanged", setFilterActive)
})
$: type = FIELDS[field?.type?.toUpperCase()]?.name
</script>
<header
on:click={onSort}
data-cy="table-header"
on:mouseover={() => (hovered = true)}
on:mouseleave={() => (hovered = false)}>
<div class="column-header">
<div class="column-header-text">
<div class="column-header-name">
{displayName}
{#if field.autocolumn}<i class="auto ri-magic-fill" />{/if}
</div>
{#if type}
<div class="column-header-type">{type}</div>
{/if}
</div>
<i class={`${SORT_ICON_MAP[sortDirection]} icon`} />
</div>
<Modal bind:this={modal}>
<ModalContent
size="large"
showCancelButton={false}
showConfirmButton={false}
title={`Edit Column: ${field.name}`}>
<CreateEditColumn onClosed={modal.hide} {field} />
</ModalContent>
</Modal>
<section class:show={hovered || filterActive}>
{#if editable && hovered}
<span on:click|stopPropagation={showModal}>
<i class="ri-pencil-line icon" />
</span>
{/if}
<span on:click|stopPropagation={toggleMenu} bind:this={menuButton}>
<i class="ri-filter-line icon" class:active={filterActive} />
</span>
</section>
</header>
<style>
header {
font-family: Inter;
font-weight: 600;
display: flex;
justify-content: space-between;
height: 100%;
width: 100%;
align-items: center;
color: var(--ink);
}
section {
opacity: 0;
transition: 0.3s all;
}
section.show {
opacity: 1;
}
.column-header {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: var(--spacing-s);
}
.column-header-text {
flex: 1 1 auto;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
gap: var(--spacing-xs);
}
.column-header-name {
white-space: normal !important;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
}
.column-header-type {
font-size: var(--font-size-xs);
color: var(--grey-6);
}
.icon {
transition: 0.2s all;
font-size: var(--font-size-m);
font-weight: 500;
}
.auto {
font-size: 9px;
transition: none;
position: relative;
margin-left: 2px;
top: -3px;
color: var(--grey-6);
}
.icon:hover {
color: var(--blue);
}
.icon.active,
.icon:hover {
color: var(--blue);
}
</style>

View File

@ -1,35 +0,0 @@
import TableHeader from "./TableHeader.svelte"
export default class TableHeaderWrapper {
constructor() {}
init(params) {
this.agParams = params
this.container = document.createElement("div")
this.container.style.height = "100%"
this.container.style.width = "100%"
this.headerComponent = new TableHeader({
target: this.container,
props: params,
})
this.gui = this.container
}
// can get called more than once, you should return the HTML element
getGui() {
return this.gui
}
// gets called when a new Column Definition has been set for this header
refresh(params) {
this.agParams = params
this.headerComponent = new TableHeader({
target: this.container,
props: params,
})
}
// optional method, gets called once, when component is destroyed
destroy() {}
}

View File

@ -1,27 +0,0 @@
<script>
import Spinner from "components/common/Spinner.svelte"
import { fade } from "svelte/transition"
import Logo from "/assets/bb-logo.svg"
</script>
<div class="ag-overlay-loading-center loading-container">
<div transition:fade class="loading-overlay">
<img height="30" width="30" src={Logo} alt="Budibase icon" />
<span> Loading Your Data </span>
<Spinner size="12" />
</div>
</div>
<style>
.loading-overlay {
display: flex;
align-items: center;
font-family: var(--font-sans);
font-weight: 500;
color: var(--ink);
}
.loading-overlay > * {
margin-right: var(--spacing-m);
}
</style>

View File

@ -1,17 +0,0 @@
import LoadingOverlay from "./LoadingOverlay.svelte"
export default class LoadingOverlayWrapper {
init(params) {
this.gui = document.createElement("div")
new LoadingOverlay({
target: this.gui,
props: {
params,
},
})
}
getGui() {
return this.gui
}
}

View File

@ -1,5 +1,12 @@
<script>
import { Input, Button, Label, Select, Toggle, Radio } from "@budibase/bbui"
import {
Input,
Button,
Label,
Select,
Toggle,
RadioGroup,
} from "@budibase/bbui"
import { cloneDeep } from "lodash/fp"
import { tables } from "stores/backend"
@ -242,26 +249,15 @@
getOptionLabel={table => table.name}
getOptionValue={table => table._id} />
{#if relationshipOptions && relationshipOptions.length > 0}
<div>
<Label grey extraSmall>Define the relationship</Label>
<div class="radio-buttons">
{#each relationshipOptions as { value, name }}
<Radio
<RadioGroup
disabled={originalName}
name="Relationship type"
{value}
bind:group={field.relationshipType}>
<div class="radio-button-labels">
<label for={value}>{name.split('→')[0]}</label>
<label class="rel-type-center" for={value}>→</label>
<label for={value}>{name.split('→')[1]}</label>
</div>
</Radio>
{/each}
</div>
</div>
label="Define the relationship"
bind:value={field.relationshipType}
options={relationshipOptions}
getOptionLabel={option => option.name}
getOptionValue={option => option.value} />
{/if}
<Input label={`Column Name in Other Table`} bind:value={field.fieldName} />
<Input label={`Column name in other table`} bind:value={field.fieldName} />
{:else if field.type === AUTO_COL}
<Select
label="Auto Column Type"

View File

@ -24,7 +24,7 @@
value={$fieldState.value}
disabled={$fieldState.disabled}
error={$fieldState.error}
fieldId={$fieldState.fieldId}
id={$fieldState.fieldId}
on:change={e => fieldApi.setValue(e.detail)}
{text} />
{/if}

View File

@ -23,7 +23,7 @@
{#if fieldState}
<CoreSelect
value={$fieldState.value}
fieldId={$fieldState.fieldId}
id={$fieldState.fieldId}
disabled={$fieldState.disabled}
error={$fieldState.error}
options={fieldSchema?.constraints?.inclusion ?? []}

View File

@ -1,110 +0,0 @@
<script>
import "@spectrum-css/picker/dist/index-vars.css"
import "@spectrum-css/popover/dist/index-vars.css"
import "@spectrum-css/menu/dist/index-vars.css"
import { fly } from "svelte/transition"
export let fieldState
export let fieldText = ""
export let isPlaceholder = false
export let placeholderOption = null
export let options = []
export let isOptionSelected = () => false
export let onSelectOption = () => {}
export let getOptionLabel = option => option
export let getOptionValue = option => option
export let open = false
</script>
{#if fieldState}
<button
id={$fieldState.fieldId}
class="spectrum-Picker spectrum-Picker--sizeM"
disabled={$fieldState.disabled}
class:is-invalid={!$fieldState.valid}
class:is-open={open}
aria-haspopup="listbox"
on:click={() => (open = true)}>
<span class="spectrum-Picker-label" class:is-placeholder={isPlaceholder}>
{fieldText}
</span>
{#if !$fieldState.valid}
<svg
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Picker-validationIcon"
focusable="false"
aria-hidden="true"
aria-label="Folder">
<use xlink:href="#spectrum-icon-18-Alert" />
</svg>
{/if}
<svg
class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon"
focusable="false"
aria-hidden="true">
<use xlink:href="#spectrum-css-icon-Chevron100" />
</svg>
</button>
{#if open}
<div class="overlay" on:mousedown|self={() => (open = false)} />
<div
transition:fly={{ y: -20, duration: 200 }}
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open">
<ul class="spectrum-Menu" role="listbox">
{#if placeholderOption}
<li
class="spectrum-Menu-item"
class:is-selected={isPlaceholder}
role="option"
aria-selected="true"
tabindex="0"
on:click={() => onSelectOption(null)}>
<span class="spectrum-Menu-itemLabel">{placeholderOption}</span>
<svg
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
focusable="false"
aria-hidden="true">
<use xlink:href="#spectrum-css-icon-Checkmark100" />
</svg>
</li>
{/if}
{#each options as option}
<li
class="spectrum-Menu-item"
class:is-selected={isOptionSelected(getOptionValue(option))}
role="option"
aria-selected="true"
tabindex="0"
on:click={() => onSelectOption(getOptionValue(option))}>
<span
class="spectrum-Menu-itemLabel">{getOptionLabel(option)}</span>
<svg
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
focusable="false"
aria-hidden="true">
<use xlink:href="#spectrum-css-icon-Checkmark100" />
</svg>
</li>
{/each}
</ul>
</div>
{/if}
{/if}
<style>
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 999;
}
.spectrum-Popover {
max-height: 240px;
width: 100%;
z-index: 999;
}
.spectrum-Picker {
width: 100%;
}
</style>

View File

@ -75,7 +75,7 @@
{options}
value={multiselect ? multiValue : singleValue}
on:change={multiselect ? multiHandler : singleHandler}
fieldId={$fieldState.fieldId}
id={$fieldState.fieldId}
disabled={$fieldState.disabled}
error={$fieldState.error}
getOptionLabel={getDisplayName}