forked from tsai/budibase
31 changed files with 109 additions and 1026 deletions
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
|
|||
@ -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,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> |
|||
Loading…
Reference in new issue