Add radio group spectrum component and update builder
This commit is contained in:
parent
3354aeff54
commit
431abb53ce
|
@ -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",
|
||||
|
|
|
@ -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>
|
|
@ -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"
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
|
@ -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() {}
|
||||
}
|
|
@ -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>
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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 ?? []}
|
||||
|
|
|
@ -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>
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue