More BBUI types and tidy up
This commit is contained in:
parent
c77e4c4f09
commit
62500ea392
|
@ -1,16 +1,15 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import Icon from "./Icon.svelte"
|
||||
|
||||
import Tooltip from "../Tooltip/Tooltip.svelte"
|
||||
import { fade } from "svelte/transition"
|
||||
|
||||
export let icon
|
||||
export let background
|
||||
export let color
|
||||
export let size = "M"
|
||||
export let tooltip
|
||||
export let icon: string | undefined = undefined
|
||||
export let background: string | undefined = undefined
|
||||
export let color: string | undefined = undefined
|
||||
export let size: "XS" | "S" | "M" | "L" = "M"
|
||||
export let tooltip: string | undefined = undefined
|
||||
|
||||
let showTooltip = false
|
||||
let showTooltip: boolean = false
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import "@spectrum-css/popover/dist/index-vars.css"
|
||||
import clickOutside from "../Actions/click_outside"
|
||||
import { fly } from "svelte/transition"
|
||||
import Icon from "../Icon/Icon.svelte"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
|
||||
export let value
|
||||
export let size = "M"
|
||||
export let alignRight = false
|
||||
export let value: string | undefined
|
||||
export let size: "S" | "M" | "L" = "M"
|
||||
export let alignRight: boolean = false
|
||||
|
||||
let open = false
|
||||
let open: boolean = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const iconList = [
|
||||
interface IconCategory {
|
||||
label: string
|
||||
icons: string[]
|
||||
}
|
||||
|
||||
const iconList: IconCategory[] = [
|
||||
{
|
||||
label: "Icons",
|
||||
icons: [
|
||||
|
@ -45,12 +50,12 @@
|
|||
},
|
||||
]
|
||||
|
||||
const onChange = value => {
|
||||
const onChange = (value: string) => {
|
||||
dispatch("change", value)
|
||||
open = false
|
||||
}
|
||||
|
||||
const handleOutsideClick = event => {
|
||||
const handleOutsideClick = (event: MouseEvent) => {
|
||||
if (open) {
|
||||
event.stopPropagation()
|
||||
open = false
|
||||
|
@ -77,11 +82,11 @@
|
|||
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
|
||||
class:spectrum-Popover--align-right={alignRight}
|
||||
>
|
||||
{#each iconList as icon}
|
||||
{#each iconList as iconList}
|
||||
<div class="category">
|
||||
<div class="heading">{icon.label}</div>
|
||||
<div class="heading">{iconList.label}</div>
|
||||
<div class="icons">
|
||||
{#each icon.icons as icon}
|
||||
{#each iconList.icons as icon}
|
||||
<div
|
||||
on:click={() => {
|
||||
onChange(icon)
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
<div class="icon-side-nav">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.icon-side-nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: var(--spacing-s);
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
</style>
|
|
@ -1,58 +0,0 @@
|
|||
<script>
|
||||
import Icon from "../Icon/Icon.svelte"
|
||||
import Tooltip from "../Tooltip/Tooltip.svelte"
|
||||
import { fade } from "svelte/transition"
|
||||
|
||||
export let icon
|
||||
export let active = false
|
||||
export let tooltip
|
||||
|
||||
let showTooltip = false
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class="icon-side-nav-item"
|
||||
class:active
|
||||
on:mouseover={() => (showTooltip = true)}
|
||||
on:focus={() => (showTooltip = true)}
|
||||
on:mouseleave={() => (showTooltip = false)}
|
||||
on:click
|
||||
>
|
||||
<Icon name={icon} hoverable />
|
||||
{#if tooltip && showTooltip}
|
||||
<div class="tooltip" in:fade={{ duration: 130, delay: 250 }}>
|
||||
<Tooltip textWrapping direction="right" text={tooltip} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.icon-side-nav-item {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: background 130ms ease-out;
|
||||
}
|
||||
.icon-side-nav-item:hover :global(svg),
|
||||
.active :global(svg) {
|
||||
color: var(--spectrum-global-color-gray-900);
|
||||
}
|
||||
.active {
|
||||
background: var(--spectrum-global-color-gray-300);
|
||||
}
|
||||
.tooltip {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
left: calc(100% - 4px);
|
||||
top: 50%;
|
||||
white-space: nowrap;
|
||||
transform: translateY(-50%);
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
|
@ -1,19 +1,19 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import "@spectrum-css/inlinealert/dist/index-vars.css"
|
||||
import Button from "../Button/Button.svelte"
|
||||
|
||||
export let type = "info"
|
||||
export let header = ""
|
||||
export let message = ""
|
||||
export let onConfirm = undefined
|
||||
export let buttonText = ""
|
||||
export let cta = false
|
||||
export let type: "info" | "error" | "success" | "help" | "negative" = "info"
|
||||
export let header: string = ""
|
||||
export let message: string = ""
|
||||
export let onConfirm: (() => void) | undefined = undefined
|
||||
export let buttonText: string = ""
|
||||
export let cta: boolean = false
|
||||
|
||||
$: icon = selectIcon(type)
|
||||
// if newlines used, convert them to different elements
|
||||
$: split = message.split("\n")
|
||||
|
||||
function selectIcon(alertType) {
|
||||
function selectIcon(alertType: string): string {
|
||||
switch (alertType) {
|
||||
case "error":
|
||||
case "negative":
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import Input from "../Form/Input.svelte"
|
||||
import Icon from "../Icon/Icon.svelte"
|
||||
import { notifications } from "../Stores/notifications"
|
||||
|
||||
export let label = null
|
||||
export let value
|
||||
export let label: string | undefined = undefined
|
||||
export let value: string | undefined = undefined
|
||||
|
||||
const copyToClipboard = val => {
|
||||
const dummy = document.createElement("textarea")
|
||||
document.body.appendChild(dummy)
|
||||
dummy.value = val
|
||||
dummy.select()
|
||||
document.execCommand("copy")
|
||||
document.body.removeChild(dummy)
|
||||
notifications.success(`Copied to clipboard`)
|
||||
const copyToClipboard = (val: string | undefined) => {
|
||||
if (val) {
|
||||
const dummy = document.createElement("textarea")
|
||||
document.body.appendChild(dummy)
|
||||
dummy.value = val
|
||||
dummy.select()
|
||||
document.execCommand("copy")
|
||||
document.body.removeChild(dummy)
|
||||
notifications.success(`Copied to clipboard`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import "@spectrum-css/fieldlabel/dist/index-vars.css"
|
||||
import TooltipWrapper from "../Tooltip/TooltipWrapper.svelte"
|
||||
|
||||
export let size = "M"
|
||||
export let tooltip = ""
|
||||
export let muted = undefined
|
||||
export let size: "S" | "M" | "L" = "M"
|
||||
export let tooltip: string = ""
|
||||
export let muted: boolean | undefined = undefined
|
||||
</script>
|
||||
|
||||
<TooltipWrapper {tooltip} {size}>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<script>
|
||||
export let horizontal = false
|
||||
export let paddingX = "M"
|
||||
export let paddingY = "M"
|
||||
export let noPadding = false
|
||||
export let gap = "M"
|
||||
export let noGap = false
|
||||
export let alignContent = "normal"
|
||||
export let justifyItems = "stretch"
|
||||
<script lang="ts">
|
||||
export let horizontal: boolean = false
|
||||
export let paddingX: "S" | "M" | "L" | "XL" | "XXL" = "M"
|
||||
export let paddingY: "S" | "M" | "L" | "XL" | "XXL" = "M"
|
||||
export let noPadding: boolean = false
|
||||
export let gap: "XXS" | "XS" | "S" | "M" | "L" | "XL" = "M"
|
||||
export let noGap: boolean = false
|
||||
export let alignContent: string = "normal"
|
||||
export let justifyItems: string = "stretch"
|
||||
</script>
|
||||
|
||||
<div
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import { setContext } from "svelte"
|
||||
import clickOutside from "../Actions/click_outside"
|
||||
|
||||
export let wide = false
|
||||
export let narrow = false
|
||||
export let narrower = false
|
||||
export let noPadding = false
|
||||
export let wide: boolean = false
|
||||
export let narrow: boolean = false
|
||||
export let narrower: boolean = false
|
||||
export let noPadding: boolean = false
|
||||
|
||||
let sidePanelVisible = false
|
||||
let sidePanelVisible: boolean = false
|
||||
|
||||
setContext("side-panel", {
|
||||
open: () => (sidePanelVisible = true),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import Detail from "../Typography/Detail.svelte"
|
||||
|
||||
export let title = null
|
||||
export let title: string | null = null
|
||||
</script>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import SpectrumMDE from "./SpectrumMDE.svelte"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
|
||||
export let value = null
|
||||
export let height = null
|
||||
export let placeholder = null
|
||||
export let id = null
|
||||
export let fullScreenOffset = 0
|
||||
export let disabled = false
|
||||
export let readonly = false
|
||||
export let easyMDEOptions
|
||||
export let value: string | null = null
|
||||
export let height: string | null = null
|
||||
export let placeholder: string | null = null
|
||||
export let id: string | null = null
|
||||
export let fullScreenOffset: { x: string; y: string } | null = null
|
||||
export let disabled: boolean = false
|
||||
export let readonly: boolean = false
|
||||
export let easyMDEOptions: Record<string, any> = {}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let latestValue
|
||||
let mde
|
||||
let latestValue: string | null
|
||||
let mde: any
|
||||
|
||||
// Ensure the value is updated if the value prop changes outside the editor's
|
||||
// control
|
||||
|
@ -24,7 +24,7 @@
|
|||
mde?.togglePreview()
|
||||
}
|
||||
|
||||
const checkValue = val => {
|
||||
const checkValue = (val: string | null) => {
|
||||
if (mde && val !== latestValue) {
|
||||
mde.value(val)
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import SpectrumMDE from "./SpectrumMDE.svelte"
|
||||
|
||||
export let value
|
||||
export let height
|
||||
export let value: string | null = null
|
||||
export let height: string | null = null
|
||||
|
||||
let mde
|
||||
let mde: any
|
||||
|
||||
// Keep the value up to date
|
||||
$: mde && mde.value(value || "")
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import EasyMDE from "easymde"
|
||||
import "easymde/dist/easymde.min.css"
|
||||
import { onMount } from "svelte"
|
||||
|
||||
export let height = null
|
||||
export let scroll = true
|
||||
export let easyMDEOptions = null
|
||||
export let mde = null
|
||||
export let id = null
|
||||
export let fullScreenOffset = null
|
||||
export let disabled = false
|
||||
export let height: string | null = null
|
||||
export let scroll: boolean = true
|
||||
export let easyMDEOptions: Record<string, any> | null = null
|
||||
export let mde: EasyMDE | null = null
|
||||
export let id: string | null = null
|
||||
export let fullScreenOffset: { x: string; y: string } | null = null
|
||||
export let disabled: boolean = false
|
||||
|
||||
let element
|
||||
let element: HTMLTextAreaElement | undefined = undefined
|
||||
|
||||
onMount(() => {
|
||||
height = height || "200px"
|
||||
|
@ -27,13 +27,13 @@
|
|||
|
||||
// Revert the editor when we unmount
|
||||
return () => {
|
||||
mde.toTextArea()
|
||||
mde?.toTextArea()
|
||||
}
|
||||
})
|
||||
|
||||
$: styleString = getStyleString(fullScreenOffset)
|
||||
|
||||
const getStyleString = offset => {
|
||||
const getStyleString = (offset: { x?: string; y?: string } | null) => {
|
||||
let string = ""
|
||||
string += `--fullscreen-offset-x:${offset?.x || "0px"};`
|
||||
string += `--fullscreen-offset-y:${offset?.y || "0px"};`
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher, getContext } from "svelte"
|
||||
import Icon from "../Icon/Icon.svelte"
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const actionMenu = getContext("actionMenu")
|
||||
const actionMenu = getContext("actionMenu") as { hideAll: () => void }
|
||||
|
||||
export let icon = undefined
|
||||
export let disabled = undefined
|
||||
export let noClose = false
|
||||
export let keyBind = undefined
|
||||
export let icon: string | undefined = undefined
|
||||
export let disabled: boolean | undefined = undefined
|
||||
export let noClose: boolean = false
|
||||
export let keyBind: string | undefined = undefined
|
||||
|
||||
$: keys = getKeys(keyBind)
|
||||
|
||||
const getKeys = keyBind => {
|
||||
const getKeys = (keyBind: string | undefined): string[] => {
|
||||
let keys = keyBind?.split("+") || []
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
if (
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import "@spectrum-css/menu/dist/index-vars.css"
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
<script>
|
||||
import Menu from './Menu.svelte'
|
||||
import Separator from './Separator.svelte'
|
||||
import Section from './Section.svelte'
|
||||
import Item from './Item.svelte'
|
||||
</script>
|
||||
|
||||
<Menu>
|
||||
<Section heading="Section heading">
|
||||
<Item>Some Item 1</Item>
|
||||
<Item>Some Item 2</Item>
|
||||
<Item>Some Item 3</Item>
|
||||
</Section>
|
||||
<Separator />
|
||||
<Section heading="Section heading">
|
||||
<Item icon="SaveFloppy">Save</Item>
|
||||
<Item disabled icon="DataDownload">Download</Item>
|
||||
</Section>
|
||||
</Menu>
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
export let heading
|
||||
<script lang="ts">
|
||||
export let heading: string
|
||||
</script>
|
||||
|
||||
<li role="presentation">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import Input from "../Form/Input.svelte"
|
||||
|
||||
let value = ""
|
||||
let value: string = ""
|
||||
</script>
|
||||
|
||||
<Input label="Your Name" bind:value />
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import { getContext } from "svelte"
|
||||
import Context from "../context"
|
||||
|
||||
const { hide } = getContext(Context.Modal)
|
||||
const { hide } = getContext(Context.Modal) as { hide: () => void }
|
||||
|
||||
let count = 0
|
||||
const clicks = 5
|
||||
let count: number = 0
|
||||
const clicks: number = 5
|
||||
$: if (count === clicks) hide()
|
||||
$: remaining = clicks - count
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import "@spectrum-css/modal/dist/index-vars.css"
|
||||
import "@spectrum-css/underlay/dist/index-vars.css"
|
||||
import { createEventDispatcher, setContext, tick, onMount } from "svelte"
|
||||
|
@ -6,33 +6,37 @@
|
|||
import Portal from "svelte-portal"
|
||||
import Context from "../context"
|
||||
|
||||
export let fixed = false
|
||||
export let inline = false
|
||||
export let disableCancel = false
|
||||
export let autoFocus = true
|
||||
export let zIndex = 1001
|
||||
export let fixed: boolean = false
|
||||
export let inline: boolean = false
|
||||
export let disableCancel: boolean = false
|
||||
export let autoFocus: boolean = true
|
||||
export let zIndex: number = 1001
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
let visible = fixed || inline
|
||||
let modal
|
||||
const dispatch = createEventDispatcher<{
|
||||
show: void
|
||||
hide: void
|
||||
cancel: void
|
||||
}>()
|
||||
let visible: boolean = fixed || inline
|
||||
let modal: HTMLElement | undefined
|
||||
|
||||
$: dispatch(visible ? "show" : "hide")
|
||||
|
||||
export function show() {
|
||||
export function show(): void {
|
||||
if (visible) {
|
||||
return
|
||||
}
|
||||
visible = true
|
||||
}
|
||||
|
||||
export function hide() {
|
||||
export function hide(): void {
|
||||
if (!visible || fixed || inline) {
|
||||
return
|
||||
}
|
||||
visible = false
|
||||
}
|
||||
|
||||
export function toggle() {
|
||||
export function toggle(): void {
|
||||
if (visible) {
|
||||
hide()
|
||||
} else {
|
||||
|
@ -40,7 +44,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
export function cancel() {
|
||||
export function cancel(): void {
|
||||
if (!visible || disableCancel) {
|
||||
return
|
||||
}
|
||||
|
@ -48,31 +52,25 @@
|
|||
hide()
|
||||
}
|
||||
|
||||
function handleKey(e) {
|
||||
function handleKey(e: KeyboardEvent): void {
|
||||
if (visible && e.key === "Escape") {
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
|
||||
async function focusModal(node) {
|
||||
if (!autoFocus) {
|
||||
return
|
||||
}
|
||||
await tick()
|
||||
|
||||
// Try to focus first input
|
||||
const inputs = node.querySelectorAll("input")
|
||||
if (inputs?.length) {
|
||||
inputs[0].focus()
|
||||
}
|
||||
|
||||
// Otherwise try to focus confirmation button
|
||||
else if (modal) {
|
||||
const confirm = modal.querySelector(".confirm-wrap .spectrum-Button")
|
||||
if (confirm) {
|
||||
confirm.focus()
|
||||
function focusModal(node: HTMLElement): void {
|
||||
if (!autoFocus) return
|
||||
tick().then(() => {
|
||||
const inputs = node.querySelectorAll("input")
|
||||
if (inputs?.length) {
|
||||
inputs[0].focus()
|
||||
} else if (modal) {
|
||||
const confirm = modal.querySelector(".confirm-wrap .spectrum-Button")
|
||||
if (confirm) {
|
||||
;(confirm as HTMLElement).focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
setContext(Context.Modal, { show, hide, toggle, cancel })
|
||||
|
|
|
@ -1,116 +0,0 @@
|
|||
<script>
|
||||
import { View } from "svench";
|
||||
import Modal from "./Modal.svelte";
|
||||
import ModalContent from "./ModalContent.svelte";
|
||||
import Button from "../Button/Button.svelte";
|
||||
import Content from "./Content.svelte";
|
||||
import QuizModal from "./QuizModal.svelte";
|
||||
import CustomContent from "./CustomContent.svelte";
|
||||
|
||||
let modal1
|
||||
let modal2
|
||||
let modal3
|
||||
|
||||
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
||||
async function longTask() {
|
||||
await sleep(3000)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
p, span {
|
||||
font-size: var(--font-size-s);
|
||||
}
|
||||
|
||||
code {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
padding: var(--spacing-xs) var(--spacing-s);
|
||||
background-color: var(--grey-2);
|
||||
color: var(--red-dark);
|
||||
border-radius: var(--spacing-xs);
|
||||
}
|
||||
</style>
|
||||
|
||||
<h3>Modals</h3>
|
||||
<p>
|
||||
Modals provide a means to render content in front of everything else on a page.
|
||||
</p>
|
||||
<p>
|
||||
The modal module in BBUI exposes two
|
||||
separate components to provide this functionality; a <code>Modal</code> component to control visibility of content,
|
||||
and a <code>ModalContent</code> component to quickly construct the typical content - although this is optional.
|
||||
</p>
|
||||
<p>
|
||||
One of the common problems with modals and popups is stale state reappearing after hiding and showing the content
|
||||
again, since the state hasn't been garbage collected if a component controls its own visibility. This is handled for
|
||||
you when using the <code>Modal</code> component as it will fully unmount child components, properly resetting state
|
||||
every time it appears.
|
||||
</p>
|
||||
|
||||
<br/>
|
||||
<p>Use ModalContent to render typical modal content.</p>
|
||||
<View name="Simple Confirmation Modal">
|
||||
<Button primary on:click={modal1.show}>Delete Record</Button>
|
||||
<Modal bind:this={modal1}>
|
||||
<ModalContent title="Confirm Deletion" confirmText="Delete">
|
||||
<span>Are you sure you want to delete this record?</span>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</View>
|
||||
|
||||
<br/>
|
||||
<p>
|
||||
Width can be specified as a prop to a <code>Modal</code>. Any additional <code>ModalContent</code> props provided
|
||||
will be passed to the confirmation button.
|
||||
</p>
|
||||
<View name="Different Buttons and Width">
|
||||
<Button primary on:click={modal3.show}>Open Modal</Button>
|
||||
<Modal bind:this={modal3} width="250px">
|
||||
<ModalContent
|
||||
title="Confirmation Required"
|
||||
showCancelButton={false}
|
||||
showCloseIcon={false}
|
||||
confirmText="I'm sure!"
|
||||
green
|
||||
large
|
||||
wide
|
||||
>
|
||||
<span>Are you sure you want to do that?</span>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</View>
|
||||
|
||||
<br/>
|
||||
<p>Any content can be rendered inside a <code>Modal</code>. Use context to close the modal from your own components.</p>
|
||||
<View name="Custom Content">
|
||||
<Button primary on:click={modal1.show}>Open Modal</Button>
|
||||
<Modal bind:this={modal1} padding={false} border={false}>
|
||||
<CustomContent/>
|
||||
</Modal>
|
||||
</View>
|
||||
|
||||
<br/>
|
||||
<p>Async functions passed in as the onConfirm prop will make the modal wait until the callback is completed.</p>
|
||||
<View name="Async Callbacks">
|
||||
<Button primary on:click={modal2.show}>Long Task</Button>
|
||||
<Modal bind:this={modal2}>
|
||||
<ModalContent
|
||||
title="Perform Long Task"
|
||||
confirmText="Submit"
|
||||
onConfirm={longTask}
|
||||
>
|
||||
<span>Pressing submit will wait 3 seconds before finishing and disable the confirm button until it's done.</span>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</View>
|
||||
|
||||
<br/>
|
||||
<p>Returning false from a onConfirm callback will prevent the modal being closed.</p>
|
||||
<View name="Callback Failure Handling">
|
||||
<Button primary on:click={modal3.show}>Open Quiz</Button>
|
||||
<Modal bind:this={modal3}>
|
||||
<QuizModal />
|
||||
</Modal>
|
||||
</View>
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<script context="module">
|
||||
<script context="module" lang="ts">
|
||||
export const keepOpen = Symbol("keepOpen")
|
||||
</script>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import "@spectrum-css/dialog/dist/index-vars.css"
|
||||
import { getContext } from "svelte"
|
||||
import Button from "../Button/Button.svelte"
|
||||
|
@ -11,31 +11,36 @@
|
|||
import Context from "../context"
|
||||
import ProgressCircle from "../ProgressCircle/ProgressCircle.svelte"
|
||||
|
||||
export let title = undefined
|
||||
export let size = "S"
|
||||
export let cancelText = "Cancel"
|
||||
export let confirmText = "Confirm"
|
||||
export let showCancelButton = true
|
||||
export let showConfirmButton = true
|
||||
export let showCloseIcon = true
|
||||
export let onConfirm = undefined
|
||||
export let onCancel = undefined
|
||||
export let disabled = false
|
||||
export let showDivider = true
|
||||
export let title: string | undefined = undefined
|
||||
export let size: "S" | "M" | "L" | "XL" = "S"
|
||||
export let cancelText: string = "Cancel"
|
||||
export let confirmText: string = "Confirm"
|
||||
export let showCancelButton: boolean = true
|
||||
export let showConfirmButton: boolean = true
|
||||
export let showCloseIcon: boolean = true
|
||||
export let onConfirm: (() => Promise<any> | any) | undefined = undefined
|
||||
export let onCancel: (() => Promise<any> | any) | undefined = undefined
|
||||
export let disabled: boolean = false
|
||||
export let showDivider: boolean = true
|
||||
|
||||
export let showSecondaryButton = false
|
||||
export let secondaryButtonText = undefined
|
||||
export let secondaryAction = undefined
|
||||
export let secondaryButtonWarning = false
|
||||
export let custom = false
|
||||
export let showSecondaryButton: boolean = false
|
||||
export let secondaryButtonText: string | undefined = undefined
|
||||
export let secondaryAction: ((_e: Event) => Promise<any> | any) | undefined =
|
||||
undefined
|
||||
export let secondaryButtonWarning: boolean = false
|
||||
export let custom: boolean = false
|
||||
|
||||
const { hide, cancel } = getContext(Context.Modal)
|
||||
const { hide, cancel } = getContext(Context.Modal) as {
|
||||
hide: () => void
|
||||
cancel: () => void
|
||||
}
|
||||
|
||||
let loading = false
|
||||
let loading: boolean = false
|
||||
|
||||
let confirmDisabled: boolean
|
||||
$: confirmDisabled = disabled || loading
|
||||
|
||||
async function secondary(e) {
|
||||
async function secondary(e: Event): Promise<void> {
|
||||
loading = true
|
||||
if (!secondaryAction || (await secondaryAction(e)) !== keepOpen) {
|
||||
hide()
|
||||
|
@ -43,7 +48,7 @@
|
|||
loading = false
|
||||
}
|
||||
|
||||
export async function confirm() {
|
||||
export async function confirm(): Promise<void> {
|
||||
loading = true
|
||||
if (!onConfirm || (await onConfirm()) !== keepOpen) {
|
||||
hide()
|
||||
|
@ -51,7 +56,7 @@
|
|||
loading = false
|
||||
}
|
||||
|
||||
async function close() {
|
||||
async function close(): Promise<void> {
|
||||
loading = true
|
||||
if (!onCancel || (await onCancel()) !== keepOpen) {
|
||||
cancel()
|
||||
|
@ -90,7 +95,6 @@
|
|||
{/if}
|
||||
{/if}
|
||||
|
||||
<!-- TODO: Remove content-grid class once Layout components are in bbui -->
|
||||
<section class="spectrum-Dialog-content content-grid">
|
||||
<slot {loading} />
|
||||
</section>
|
||||
|
@ -102,7 +106,6 @@
|
|||
{#if showSecondaryButton && secondaryButtonText && secondaryAction}
|
||||
<div class="secondary-action">
|
||||
<Button
|
||||
group
|
||||
secondary
|
||||
warning={secondaryButtonWarning}
|
||||
on:click={secondary}>{secondaryButtonText}</Button
|
||||
|
@ -111,14 +114,13 @@
|
|||
{/if}
|
||||
|
||||
{#if showCancelButton}
|
||||
<Button group secondary on:click={close}>
|
||||
<Button secondary on:click={close}>
|
||||
{cancelText}
|
||||
</Button>
|
||||
{/if}
|
||||
{#if showConfirmButton}
|
||||
<span class="confirm-wrap">
|
||||
<Button
|
||||
group
|
||||
cta
|
||||
{...$$restProps}
|
||||
disabled={confirmDisabled}
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
<script>
|
||||
import ModalContent from "./ModalContent.svelte"
|
||||
import Input from "../Form/Input.svelte"
|
||||
|
||||
let modal
|
||||
let answer
|
||||
let error
|
||||
|
||||
export function show() {
|
||||
modal.show()
|
||||
}
|
||||
export function hide() {
|
||||
modal.hide
|
||||
}
|
||||
|
||||
function resetState() {
|
||||
answer = undefined
|
||||
error = undefined
|
||||
}
|
||||
|
||||
async function answerQuiz() {
|
||||
const correct = answer === "8"
|
||||
error = !correct
|
||||
return correct
|
||||
}
|
||||
</script>
|
||||
|
||||
<ModalContent
|
||||
title="Quick Maths"
|
||||
bind:this={modal}
|
||||
confirmText="Submit"
|
||||
onConfirm={answerQuiz}
|
||||
on:show={resetState}
|
||||
>
|
||||
{#if error}
|
||||
<p class="error">Wrong answer! Try again.</p>
|
||||
{/if}
|
||||
<p>What is 4 + 4?</p>
|
||||
<Input label="Answer" bind:value={answer} />
|
||||
</ModalContent>
|
||||
|
||||
<style>
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: var(--font-size-s);
|
||||
}
|
||||
p.error {
|
||||
color: #e26d69;
|
||||
background-color: #ffe6e6;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
|
@ -1,17 +1,17 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import { ActionButton } from "../"
|
||||
|
||||
import { createEventDispatcher } from "svelte"
|
||||
|
||||
export let type = "info"
|
||||
export let icon = "Info"
|
||||
export let message = ""
|
||||
export let dismissable = false
|
||||
export let actionMessage = null
|
||||
export let action = null
|
||||
export let wide = false
|
||||
export let type: string = "info"
|
||||
export let icon: string = "Info"
|
||||
export let message: string = ""
|
||||
export let dismissable: boolean = false
|
||||
export let actionMessage: string | null = null
|
||||
export let action: ((_dismiss: () => void) => void) | null = null
|
||||
export let wide: boolean = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const dispatch = createEventDispatcher<{ dismiss: void }>()
|
||||
</script>
|
||||
|
||||
<div class="spectrum-Toast spectrum-Toast--{type}" class:wide>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import "@spectrum-css/toast/dist/index-vars.css"
|
||||
import Portal from "svelte-portal"
|
||||
import { notifications } from "../Stores/notifications"
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import "@spectrum-css/pagination/dist/index-vars.css"
|
||||
import "@spectrum-css/actionbutton/dist/index-vars.css"
|
||||
import "@spectrum-css/typography/dist/index-vars.css"
|
||||
|
||||
export let page
|
||||
export let goToPrevPage
|
||||
export let goToNextPage
|
||||
export let hasPrevPage = true
|
||||
export let hasNextPage = true
|
||||
export let page: number
|
||||
export let goToPrevPage: () => void
|
||||
export let goToNextPage: () => void
|
||||
export let hasPrevPage: boolean = true
|
||||
export let hasNextPage: boolean = true
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<nav class="spectrum-Pagination spectrum-Pagination--explicit">
|
||||
<div
|
||||
href="#"
|
||||
class="spectrum-ActionButton spectrum-ActionButton--sizeM spectrum-ActionButton--quiet spectrum-Pagination-prevButton"
|
||||
on:click={hasPrevPage ? goToPrevPage : null}
|
||||
class:is-disabled={!hasPrevPage}
|
||||
|
@ -32,7 +31,6 @@
|
|||
Page {page}
|
||||
</span>
|
||||
<div
|
||||
href="#"
|
||||
class="spectrum-ActionButton spectrum-ActionButton--sizeM spectrum-ActionButton--quiet spectrum-Pagination-nextButton"
|
||||
on:click={hasNextPage ? goToNextPage : null}
|
||||
class:is-disabled={!hasNextPage}
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import "@spectrum-css/progressbar/dist/index-vars.css"
|
||||
|
||||
export let value = false
|
||||
export let duration = 1000
|
||||
export let width = false
|
||||
export let sideLabel = false
|
||||
export let hidePercentage = true
|
||||
export let color // red, green, default = blue
|
||||
export let size = "M"
|
||||
export let value: number | boolean = false
|
||||
export let duration: number = 1000
|
||||
export let width: string | boolean = false
|
||||
export let sideLabel: boolean = false
|
||||
export let hidePercentage: boolean = true
|
||||
export let color: "red" | "green" | undefined = undefined // red, green, default = blue
|
||||
export let size: string = "M"
|
||||
</script>
|
||||
|
||||
<div
|
||||
class:spectrum-ProgressBar--indeterminate={!value && value !== 0}
|
||||
class:spectrum-ProgressBar--sideLabel={sideLabel}
|
||||
class="spectrum-ProgressBar spectrum-ProgressBar--size{size}"
|
||||
{value}
|
||||
value={typeof value === "number" ? value : undefined}
|
||||
role="progressbar"
|
||||
aria-valuenow={value}
|
||||
aria-valuenow={typeof value === "number" ? value : undefined}
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
style={width ? `width: ${width};` : ""}
|
||||
style={width ? `width: ${typeof width === "string" ? width : ""};` : ""}
|
||||
>
|
||||
{#if $$slots}
|
||||
<div
|
||||
|
@ -32,7 +32,7 @@
|
|||
<div
|
||||
class="spectrum-FieldLabel spectrum-ProgressBar-percentage spectrum-FieldLabel--size{size}"
|
||||
>
|
||||
{Math.round(value)}%
|
||||
{Math.round(Number(value))}%
|
||||
</div>
|
||||
{/if}
|
||||
<div class="spectrum-ProgressBar-track">
|
||||
|
@ -40,7 +40,9 @@
|
|||
class="spectrum-ProgressBar-fill"
|
||||
class:color-green={color === "green"}
|
||||
class:color-red={color === "red"}
|
||||
style="width: {value}%; --duration: {duration}ms;"
|
||||
style="width: {typeof value === 'number'
|
||||
? value
|
||||
: 0}%; --duration: {duration}ms;"
|
||||
/>
|
||||
</div>
|
||||
<div class="spectrum-ProgressBar-label" hidden="" />
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import "@spectrum-css/progresscircle/dist/index-vars.css"
|
||||
|
||||
export let size = "M"
|
||||
function convertSize(size) {
|
||||
export let size: "S" | "M" | "L" = "M"
|
||||
function convertSize(size: "S" | "M" | "L"): string | undefined {
|
||||
switch (size) {
|
||||
case "S":
|
||||
return "small"
|
||||
|
@ -13,18 +13,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
export let value = null
|
||||
export let minValue = 0
|
||||
export let maxValue = 100
|
||||
export let value: number | null = null
|
||||
export let minValue: number = 0
|
||||
export let maxValue: number = 100
|
||||
|
||||
let subMask1Style
|
||||
let subMask2Style
|
||||
let subMask1Style: string | undefined
|
||||
let subMask2Style: string | undefined
|
||||
$: calculateSubMasks(value)
|
||||
|
||||
function calculateSubMasks(value) {
|
||||
function calculateSubMasks(value: number | null): void {
|
||||
if (value) {
|
||||
let percentage = ((value - minValue) / (maxValue - minValue)) * 100
|
||||
let angle
|
||||
let angle: number
|
||||
if (percentage > 0 && percentage <= 50) {
|
||||
angle = -180 + (percentage / 50) * 180
|
||||
subMask1Style = `transform: rotate(${angle}deg);`
|
||||
|
@ -37,7 +37,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
export let overBackground = false
|
||||
export let overBackground: boolean = false
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
|
|
|
@ -87,8 +87,6 @@ export { default as MarkdownEditor } from "./Markdown/MarkdownEditor.svelte"
|
|||
export { default as MarkdownViewer } from "./Markdown/MarkdownViewer.svelte"
|
||||
export { default as List } from "./List/List.svelte"
|
||||
export { default as ListItem } from "./List/ListItem.svelte"
|
||||
export { default as IconSideNav } from "./IconSideNav/IconSideNav.svelte"
|
||||
export { default as IconSideNavItem } from "./IconSideNav/IconSideNavItem.svelte"
|
||||
export { default as Accordion } from "./Accordion/Accordion.svelte"
|
||||
export { default as AbsTooltip } from "./Tooltip/AbsTooltip.svelte"
|
||||
|
||||
|
|
Loading…
Reference in New Issue