@budibase/bbui 1.3.0 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +375 -0
- package/README.md +19 -17
- package/dist/bbui.es.js +210 -0
- package/dist/bbui.es.js.map +1 -0
- package/package.json +71 -26
- package/src/ActionButton/ActionButton.svelte +102 -0
- package/src/ActionGroup/ActionGroup.svelte +26 -0
- package/src/ActionMenu/ActionMenu.svelte +44 -0
- package/src/Actions/ClickOutside.svench.svx +30 -0
- package/src/Actions/PositionDropdown.svench.svx +81 -0
- package/src/Actions/autoresize_textarea.js +14 -0
- package/src/Actions/click_outside.js +18 -0
- package/src/Actions/position_dropdown.js +66 -0
- package/src/Avatar/Avatar.svelte +62 -0
- package/src/Badge/Badge.svelte +29 -0
- package/src/Banner/Banner.svelte +72 -0
- package/src/Banner/BannerDisplay.svelte +31 -0
- package/src/Button/Button.svelte +114 -0
- package/src/Button/Button.svench +138 -0
- package/src/ButtonGroup/ButtonGroup.svelte +30 -0
- package/src/ClearButton/ClearButton.svelte +19 -0
- package/src/ColorPicker/ColorPicker.svelte +297 -0
- package/src/DetailSummary/DetailSummary.svelte +83 -0
- package/src/Divider/Divider.svelte +28 -0
- package/src/Drawer/Drawer.svelte +113 -0
- package/src/Drawer/Drawer.svench +42 -0
- package/src/Drawer/DrawerContent.svelte +46 -0
- package/src/Form/Checkbox.svelte +23 -0
- package/src/Form/Combobox.svelte +45 -0
- package/src/Form/Core/Checkbox.svelte +69 -0
- package/src/Form/Core/CheckboxGroup.svelte +68 -0
- package/src/Form/Core/Combobox.svelte +142 -0
- package/src/Form/Core/DatePicker.svelte +257 -0
- package/src/Form/Core/Dropzone.svelte +450 -0
- package/src/Form/Core/InputDropdown.svelte +228 -0
- package/src/Form/Core/Multiselect.svelte +90 -0
- package/src/Form/Core/Picker.svelte +259 -0
- package/src/Form/Core/PickerDropdown.svelte +436 -0
- package/src/Form/Core/RadioGroup.svelte +48 -0
- package/src/Form/Core/RichTextField.svelte +42 -0
- package/src/Form/Core/Search.svelte +105 -0
- package/src/Form/Core/Select.svelte +75 -0
- package/src/Form/Core/Slider.svelte +86 -0
- package/src/Form/Core/Stepper.svelte +172 -0
- package/src/Form/Core/Switch.svelte +37 -0
- package/src/Form/Core/TextArea.svelte +78 -0
- package/src/Form/Core/TextField.svelte +119 -0
- package/src/Form/Core/index.js +15 -0
- package/src/Form/DatePicker.svelte +39 -0
- package/src/Form/Dropzone.svelte +42 -0
- package/src/Form/Field.svelte +42 -0
- package/src/Form/FieldLabel.svelte +32 -0
- package/src/Form/Input.svelte +40 -45
- package/src/Form/InputDropdown.svelte +55 -0
- package/src/Form/Multiselect.svelte +40 -0
- package/src/Form/PickerDropdown.svelte +134 -0
- package/src/Form/RadioGroup.svelte +42 -0
- package/src/Form/RichTextField.svelte +36 -0
- package/src/Form/Search.svelte +36 -0
- package/src/Form/Select.svelte +48 -43
- package/src/Form/Slider.svelte +24 -0
- package/src/Form/Stepper.svelte +45 -0
- package/src/Form/TextArea.svelte +29 -44
- package/src/Form/Toggle.svelte +23 -0
- package/src/Icon/Icon.svelte +91 -0
- package/src/IconPicker/IconPicker.svelte +177 -0
- package/src/IconSideNav/IconSideNav.svelte +14 -0
- package/src/IconSideNav/IconSideNavItem.svelte +56 -0
- package/src/InlineAlert/InlineAlert.svelte +56 -0
- package/src/Label/Label.svelte +20 -0
- package/src/Layout/Layout.svelte +94 -0
- package/src/Layout/Page.svelte +32 -0
- package/src/Link/Link.svelte +24 -0
- package/src/List/List.svelte +28 -0
- package/src/List/ListItem.svelte +98 -0
- package/src/Markdown/MarkdownEditor.svelte +60 -0
- package/src/Markdown/MarkdownViewer.svelte +70 -0
- package/src/Markdown/SpectrumMDE.svelte +184 -0
- package/src/Menu/Item.svelte +96 -0
- package/src/Menu/Menu.svelte +7 -0
- package/src/Menu/Menu.svench +19 -0
- package/src/Menu/Section.svelte +10 -0
- package/src/Menu/Separator.svelte +1 -0
- package/src/Modal/Content.svelte +6 -0
- package/src/Modal/CustomContent.svelte +38 -0
- package/src/Modal/Modal.svelte +165 -0
- package/src/Modal/Modal.svench +117 -0
- package/src/Modal/ModalContent.svelte +192 -0
- package/src/Modal/QuizModal.svelte +54 -0
- package/src/Notification/Notification.svelte +70 -0
- package/src/Notification/NotificationDisplay.svelte +43 -0
- package/src/Pagination/Pagination.svelte +57 -0
- package/src/Popover/Popover.svelte +77 -0
- package/src/Popover/Popover.svench +121 -0
- package/src/ProgressBar/ProgressBar.svelte +54 -0
- package/src/ProgressCircle/ProgressCircle.svelte +62 -0
- package/src/SideNavigation/Item.svelte +47 -0
- package/src/SideNavigation/Navigation.svelte +12 -0
- package/src/StatusLight/StatusLight.svelte +80 -0
- package/src/Stores/Notifications.svench.svx +78 -0
- package/src/Stores/banner.js +37 -0
- package/src/Stores/notifications.js +84 -0
- package/src/Table/ArrayRenderer.svelte +17 -0
- package/src/Table/AttachmentRenderer.svelte +67 -0
- package/src/Table/BoldRenderer.svelte +15 -0
- package/src/Table/BooleanRenderer.svelte +42 -0
- package/src/Table/CellRenderer.svelte +69 -0
- package/src/Table/CodeRenderer.svelte +14 -0
- package/src/Table/DateTimeRenderer.svelte +29 -0
- package/src/Table/InternalRenderer.svelte +24 -0
- package/src/Table/RelationshipRenderer.svelte +40 -0
- package/src/Table/SelectEditRenderer.svelte +28 -0
- package/src/Table/StringRenderer.svelte +14 -0
- package/src/Table/Table.svelte +635 -0
- package/src/Table/index.js +1 -0
- package/src/Tabs/Tab.svelte +88 -0
- package/src/Tabs/Tabs.svelte +125 -0
- package/src/Tags/Tag.svelte +43 -0
- package/src/Tags/Tags.svelte +7 -0
- package/src/Tooltip/Tooltip.svelte +34 -0
- package/src/Tooltip/TooltipWrapper.svelte +60 -0
- package/src/TreeView/Item.svelte +41 -0
- package/src/TreeView/Tree.svelte +16 -0
- package/src/Typography/Body.svelte +21 -0
- package/src/Typography/Code.svelte +10 -0
- package/src/Typography/Detail.svelte +19 -0
- package/src/Typography/Heading.svelte +17 -0
- package/src/bbui.css +96 -0
- package/src/context.js +3 -0
- package/src/helpers.js +134 -0
- package/src/index.js +97 -11
- package/src/spectrum-icons-rollup.js +31 -0
- package/src/spectrum-icons-vite.js +31 -0
- package/dist/bundle.css +0 -7
- package/dist/bundle.css.map +0 -20
- package/dist/index.js +0 -1100
- package/dist/index.mjs +0 -1086
- package/src/Branding/Budibase-logo.svelte +0 -68
- package/src/Branding/Logo.svelte +0 -16
- package/src/Branding/Logo.svench +0 -8
- package/src/Form/Button.svelte +0 -131
- package/src/Form/Button.svench +0 -49
- package/src/Form/Input.svench +0 -8
- package/src/Form/Select.svench +0 -8
- package/src/Form/TextArea.svench +0 -8
- package/src/Links/Home.svelte +0 -49
- package/src/Links/Home.svench +0 -19
- package/src/List/Items/DetailSummary.svelte +0 -66
- package/src/List/Items/DetailSummary.svench +0 -15
- package/src/actions/autoresize_textarea.js +0 -14
- package/src/icons/Contribution.svelte +0 -14
- package/src/index.svench.svx +0 -35
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import "@spectrum-css/modal/dist/index-vars.css"
|
|
3
|
+
import "@spectrum-css/underlay/dist/index-vars.css"
|
|
4
|
+
import { createEventDispatcher, setContext, tick } from "svelte"
|
|
5
|
+
import { fade, fly } from "svelte/transition"
|
|
6
|
+
import Portal from "svelte-portal"
|
|
7
|
+
import Context from "../context"
|
|
8
|
+
|
|
9
|
+
export let fixed = false
|
|
10
|
+
export let inline = false
|
|
11
|
+
|
|
12
|
+
const dispatch = createEventDispatcher()
|
|
13
|
+
let visible = fixed || inline
|
|
14
|
+
let modal
|
|
15
|
+
|
|
16
|
+
$: dispatch(visible ? "show" : "hide")
|
|
17
|
+
|
|
18
|
+
export function show() {
|
|
19
|
+
if (visible) {
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
visible = true
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function hide() {
|
|
26
|
+
if (!visible || fixed || inline) {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
visible = false
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function cancel() {
|
|
33
|
+
if (!visible) {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
dispatch("cancel")
|
|
37
|
+
hide()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function handleKey(e) {
|
|
41
|
+
if (visible && e.key === "Escape") {
|
|
42
|
+
cancel()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function focusModal(node) {
|
|
47
|
+
await tick()
|
|
48
|
+
|
|
49
|
+
// Try to focus first input
|
|
50
|
+
const inputs = node.querySelectorAll("input")
|
|
51
|
+
if (inputs?.length) {
|
|
52
|
+
inputs[0].focus()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Otherwise try to focus confirmation button
|
|
56
|
+
else if (modal) {
|
|
57
|
+
const confirm = modal.querySelector(".confirm-wrap .spectrum-Button")
|
|
58
|
+
if (confirm) {
|
|
59
|
+
confirm.focus()
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
setContext(Context.Modal, { show, hide, cancel })
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<svelte:window on:keydown={handleKey} />
|
|
68
|
+
|
|
69
|
+
{#if inline}
|
|
70
|
+
{#if visible}
|
|
71
|
+
<div use:focusModal bind:this={modal} class="spectrum-Modal inline is-open">
|
|
72
|
+
<slot />
|
|
73
|
+
</div>
|
|
74
|
+
{/if}
|
|
75
|
+
{:else}
|
|
76
|
+
<!--
|
|
77
|
+
We cannot conditionally render the portal as this leads to a missing
|
|
78
|
+
insertion point when using nested modals. Therefore we just conditionally
|
|
79
|
+
render the content of the portal.
|
|
80
|
+
It still breaks the modal animation, but its better than soft bricking the
|
|
81
|
+
screen.
|
|
82
|
+
-->
|
|
83
|
+
<Portal target=".modal-container">
|
|
84
|
+
{#if visible}
|
|
85
|
+
<div class="spectrum-Underlay is-open" on:mousedown|self={cancel}>
|
|
86
|
+
<div
|
|
87
|
+
class="background"
|
|
88
|
+
in:fade={{ duration: 200 }}
|
|
89
|
+
out:fade|local={{ duration: 200 }}
|
|
90
|
+
/>
|
|
91
|
+
<div class="modal-wrapper" on:mousedown|self={cancel}>
|
|
92
|
+
<div class="modal-inner-wrapper" on:mousedown|self={cancel}>
|
|
93
|
+
<slot name="outside" />
|
|
94
|
+
<div
|
|
95
|
+
use:focusModal
|
|
96
|
+
bind:this={modal}
|
|
97
|
+
class="spectrum-Modal is-open"
|
|
98
|
+
in:fly={{ y: 30, duration: 200 }}
|
|
99
|
+
out:fly|local={{ y: 30, duration: 200 }}
|
|
100
|
+
>
|
|
101
|
+
<slot />
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
{/if}
|
|
107
|
+
</Portal>
|
|
108
|
+
{/if}
|
|
109
|
+
|
|
110
|
+
<style>
|
|
111
|
+
.spectrum-Underlay {
|
|
112
|
+
display: flex;
|
|
113
|
+
flex-direction: row;
|
|
114
|
+
justify-content: center;
|
|
115
|
+
align-items: center;
|
|
116
|
+
z-index: 999;
|
|
117
|
+
overflow: auto;
|
|
118
|
+
overflow-x: hidden;
|
|
119
|
+
background: transparent;
|
|
120
|
+
}
|
|
121
|
+
.background {
|
|
122
|
+
background: var(--modal-background, rgba(0, 0, 0, 0.75));
|
|
123
|
+
position: fixed;
|
|
124
|
+
top: 0;
|
|
125
|
+
left: 0;
|
|
126
|
+
height: 100vh;
|
|
127
|
+
width: 100vw;
|
|
128
|
+
opacity: 0.65;
|
|
129
|
+
pointer-events: none;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.modal-wrapper {
|
|
133
|
+
flex: 1 1 auto;
|
|
134
|
+
display: flex;
|
|
135
|
+
flex-direction: row;
|
|
136
|
+
-moz-box-pack: center;
|
|
137
|
+
justify-content: center;
|
|
138
|
+
align-items: flex-start;
|
|
139
|
+
max-height: 100%;
|
|
140
|
+
}
|
|
141
|
+
.modal-inner-wrapper {
|
|
142
|
+
flex: 1 1 auto;
|
|
143
|
+
display: flex;
|
|
144
|
+
flex-direction: row;
|
|
145
|
+
-moz-box-pack: center;
|
|
146
|
+
justify-content: center;
|
|
147
|
+
align-items: flex-start;
|
|
148
|
+
width: 0;
|
|
149
|
+
position: relative;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.spectrum-Modal {
|
|
153
|
+
overflow: visible;
|
|
154
|
+
max-height: none;
|
|
155
|
+
margin: 40px 0;
|
|
156
|
+
transform: none;
|
|
157
|
+
--spectrum-dialog-confirm-border-radius: var(
|
|
158
|
+
--spectrum-global-dimension-size-100
|
|
159
|
+
);
|
|
160
|
+
max-width: 100%;
|
|
161
|
+
}
|
|
162
|
+
:global(.spectrum--lightest .spectrum-Modal.inline) {
|
|
163
|
+
border: var(--border-light);
|
|
164
|
+
}
|
|
165
|
+
</style>
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { View } from "svench";
|
|
3
|
+
import Modal from "./Modal.svelte";
|
|
4
|
+
import ModalContent from "./ModalContent.svelte";
|
|
5
|
+
import Button from "../Button/Button.svelte";
|
|
6
|
+
import Content from "./Content.svelte";
|
|
7
|
+
import QuizModal from "./QuizModal.svelte";
|
|
8
|
+
import CustomContent from "./CustomContent.svelte";
|
|
9
|
+
|
|
10
|
+
let modal1
|
|
11
|
+
let modal2
|
|
12
|
+
let modal3
|
|
13
|
+
|
|
14
|
+
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
|
15
|
+
async function longTask() {
|
|
16
|
+
await sleep(3000)
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<style>
|
|
21
|
+
p, span {
|
|
22
|
+
font-family: var(--font-sans);
|
|
23
|
+
font-size: var(--font-size-s);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
code {
|
|
27
|
+
display: inline-block;
|
|
28
|
+
box-sizing: border-box;
|
|
29
|
+
padding: var(--spacing-xs) var(--spacing-s);
|
|
30
|
+
background-color: var(--grey-2);
|
|
31
|
+
color: var(--red-dark);
|
|
32
|
+
border-radius: var(--spacing-xs);
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
35
|
+
|
|
36
|
+
<h3>Modals</h3>
|
|
37
|
+
<p>
|
|
38
|
+
Modals provide a means to render content in front of everything else on a page.
|
|
39
|
+
</p>
|
|
40
|
+
<p>
|
|
41
|
+
The modal module in BBUI exposes two
|
|
42
|
+
separate components to provide this functionality; a <code>Modal</code> component to control visibility of content,
|
|
43
|
+
and a <code>ModalContent</code> component to quickly construct the typical content - although this is optional.
|
|
44
|
+
</p>
|
|
45
|
+
<p>
|
|
46
|
+
One of the common problems with modals and popups is stale state reappearing after hiding and showing the content
|
|
47
|
+
again, since the state hasn't been garbage collected if a component controls its own visibility. This is handled for
|
|
48
|
+
you when using the <code>Modal</code> component as it will fully unmount child components, properly resetting state
|
|
49
|
+
every time it appears.
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
<br/>
|
|
53
|
+
<p>Use ModalContent to render typical modal content.</p>
|
|
54
|
+
<View name="Simple Confirmation Modal">
|
|
55
|
+
<Button primary on:click={modal1.show}>Delete Record</Button>
|
|
56
|
+
<Modal bind:this={modal1}>
|
|
57
|
+
<ModalContent title="Confirm Deletion" confirmText="Delete">
|
|
58
|
+
<span>Are you sure you want to delete this record?</span>
|
|
59
|
+
</ModalContent>
|
|
60
|
+
</Modal>
|
|
61
|
+
</View>
|
|
62
|
+
|
|
63
|
+
<br/>
|
|
64
|
+
<p>
|
|
65
|
+
Width can be specified as a prop to a <code>Modal</code>. Any additional <code>ModalContent</code> props provided
|
|
66
|
+
will be passed to the confirmation button.
|
|
67
|
+
</p>
|
|
68
|
+
<View name="Different Buttons and Width">
|
|
69
|
+
<Button primary on:click={modal3.show}>Open Modal</Button>
|
|
70
|
+
<Modal bind:this={modal3} width="250px">
|
|
71
|
+
<ModalContent
|
|
72
|
+
title="Confirmation Required"
|
|
73
|
+
showCancelButton={false}
|
|
74
|
+
showCloseIcon={false}
|
|
75
|
+
confirmText="I'm sure!"
|
|
76
|
+
green
|
|
77
|
+
large
|
|
78
|
+
wide
|
|
79
|
+
>
|
|
80
|
+
<span>Are you sure you want to do that?</span>
|
|
81
|
+
</ModalContent>
|
|
82
|
+
</Modal>
|
|
83
|
+
</View>
|
|
84
|
+
|
|
85
|
+
<br/>
|
|
86
|
+
<p>Any content can be rendered inside a <code>Modal</code>. Use context to close the modal from your own components.</p>
|
|
87
|
+
<View name="Custom Content">
|
|
88
|
+
<Button primary on:click={modal1.show}>Open Modal</Button>
|
|
89
|
+
<Modal bind:this={modal1} padding={false} border={false}>
|
|
90
|
+
<CustomContent/>
|
|
91
|
+
</Modal>
|
|
92
|
+
</View>
|
|
93
|
+
|
|
94
|
+
<br/>
|
|
95
|
+
<p>Async functions passed in as the onConfirm prop will make the modal wait until the callback is completed.</p>
|
|
96
|
+
<View name="Async Callbacks">
|
|
97
|
+
<Button primary on:click={modal2.show}>Long Task</Button>
|
|
98
|
+
<Modal bind:this={modal2}>
|
|
99
|
+
<ModalContent
|
|
100
|
+
title="Perform Long Task"
|
|
101
|
+
confirmText="Submit"
|
|
102
|
+
onConfirm={longTask}
|
|
103
|
+
>
|
|
104
|
+
<span>Pressing submit will wait 3 seconds before finishing and disable the confirm button until it's done.</span>
|
|
105
|
+
</ModalContent>
|
|
106
|
+
</Modal>
|
|
107
|
+
</View>
|
|
108
|
+
|
|
109
|
+
<br/>
|
|
110
|
+
<p>Returning false from a onConfirm callback will prevent the modal being closed.</p>
|
|
111
|
+
<View name="Callback Failure Handling">
|
|
112
|
+
<Button primary on:click={modal3.show}>Open Quiz</Button>
|
|
113
|
+
<Modal bind:this={modal3}>
|
|
114
|
+
<QuizModal />
|
|
115
|
+
</Modal>
|
|
116
|
+
</View>
|
|
117
|
+
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import "@spectrum-css/dialog/dist/index-vars.css"
|
|
3
|
+
import { getContext } from "svelte"
|
|
4
|
+
import Button from "../Button/Button.svelte"
|
|
5
|
+
import Divider from "../Divider/Divider.svelte"
|
|
6
|
+
import Icon from "../Icon/Icon.svelte"
|
|
7
|
+
import Context from "../context"
|
|
8
|
+
import ProgressCircle from "../ProgressCircle/ProgressCircle.svelte"
|
|
9
|
+
|
|
10
|
+
export let title = undefined
|
|
11
|
+
export let size = "S"
|
|
12
|
+
export let cancelText = "Cancel"
|
|
13
|
+
export let confirmText = "Confirm"
|
|
14
|
+
export let showCancelButton = true
|
|
15
|
+
export let showConfirmButton = true
|
|
16
|
+
export let showCloseIcon = true
|
|
17
|
+
export let onConfirm = undefined
|
|
18
|
+
export let onCancel = undefined
|
|
19
|
+
export let disabled = false
|
|
20
|
+
export let showDivider = true
|
|
21
|
+
|
|
22
|
+
export let showSecondaryButton = false
|
|
23
|
+
export let secondaryButtonText = undefined
|
|
24
|
+
export let secondaryAction = undefined
|
|
25
|
+
export let secondaryButtonWarning = false
|
|
26
|
+
export let dataCy = null
|
|
27
|
+
|
|
28
|
+
const { hide, cancel } = getContext(Context.Modal)
|
|
29
|
+
let loading = false
|
|
30
|
+
$: confirmDisabled = disabled || loading
|
|
31
|
+
|
|
32
|
+
async function secondary() {
|
|
33
|
+
loading = true
|
|
34
|
+
if (!secondaryAction || (await secondaryAction()) !== false) {
|
|
35
|
+
hide()
|
|
36
|
+
}
|
|
37
|
+
loading = false
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function confirm() {
|
|
41
|
+
loading = true
|
|
42
|
+
if (!onConfirm || (await onConfirm()) !== false) {
|
|
43
|
+
hide()
|
|
44
|
+
}
|
|
45
|
+
loading = false
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function close() {
|
|
49
|
+
loading = true
|
|
50
|
+
if (!onCancel || (await onCancel()) !== false) {
|
|
51
|
+
cancel()
|
|
52
|
+
}
|
|
53
|
+
loading = false
|
|
54
|
+
}
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<div
|
|
58
|
+
class="spectrum-Dialog"
|
|
59
|
+
class:spectrum-Dialog--small={size === "S"}
|
|
60
|
+
class:spectrum-Dialog--medium={size === "M"}
|
|
61
|
+
class:spectrum-Dialog--large={size === "L"}
|
|
62
|
+
class:spectrum-Dialog--extraLarge={size === "XL"}
|
|
63
|
+
style="position: relative;"
|
|
64
|
+
role="dialog"
|
|
65
|
+
tabindex="-1"
|
|
66
|
+
aria-modal="true"
|
|
67
|
+
data-cy={dataCy}
|
|
68
|
+
>
|
|
69
|
+
<div class="spectrum-Dialog-grid">
|
|
70
|
+
{#if title || $$slots.header}
|
|
71
|
+
<h1
|
|
72
|
+
class="spectrum-Dialog-heading spectrum-Dialog-heading--noHeader"
|
|
73
|
+
class:noDivider={!showDivider}
|
|
74
|
+
class:header-spacing={$$slots.header}
|
|
75
|
+
>
|
|
76
|
+
{#if title}
|
|
77
|
+
{title}
|
|
78
|
+
{:else if $$slots.header}
|
|
79
|
+
<slot name="header" />
|
|
80
|
+
{/if}
|
|
81
|
+
</h1>
|
|
82
|
+
{#if showDivider}
|
|
83
|
+
<Divider size="M" />
|
|
84
|
+
{/if}
|
|
85
|
+
{/if}
|
|
86
|
+
|
|
87
|
+
<!-- TODO: Remove content-grid class once Layout components are in bbui -->
|
|
88
|
+
<section class="spectrum-Dialog-content content-grid">
|
|
89
|
+
<slot />
|
|
90
|
+
</section>
|
|
91
|
+
{#if showCancelButton || showConfirmButton}
|
|
92
|
+
<div
|
|
93
|
+
class="spectrum-ButtonGroup spectrum-Dialog-buttonGroup spectrum-Dialog-buttonGroup--noFooter"
|
|
94
|
+
>
|
|
95
|
+
<slot name="footer" />
|
|
96
|
+
|
|
97
|
+
{#if showSecondaryButton && secondaryButtonText && secondaryAction}
|
|
98
|
+
<div class="secondary-action">
|
|
99
|
+
<Button
|
|
100
|
+
group
|
|
101
|
+
secondary
|
|
102
|
+
warning={secondaryButtonWarning}
|
|
103
|
+
on:click={secondary}>{secondaryButtonText}</Button
|
|
104
|
+
>
|
|
105
|
+
</div>
|
|
106
|
+
{/if}
|
|
107
|
+
|
|
108
|
+
{#if showCancelButton}
|
|
109
|
+
<Button group secondary newStyles on:click={close}>
|
|
110
|
+
{cancelText}
|
|
111
|
+
</Button>
|
|
112
|
+
{/if}
|
|
113
|
+
{#if showConfirmButton}
|
|
114
|
+
<span class="confirm-wrap">
|
|
115
|
+
<Button
|
|
116
|
+
group
|
|
117
|
+
cta
|
|
118
|
+
{...$$restProps}
|
|
119
|
+
disabled={confirmDisabled}
|
|
120
|
+
on:click={confirm}
|
|
121
|
+
>
|
|
122
|
+
{#if loading}
|
|
123
|
+
<ProgressCircle overBackground={true} size="S" />
|
|
124
|
+
{/if}
|
|
125
|
+
{#if !loading}
|
|
126
|
+
{confirmText}
|
|
127
|
+
{/if}
|
|
128
|
+
</Button>
|
|
129
|
+
</span>
|
|
130
|
+
{/if}
|
|
131
|
+
</div>
|
|
132
|
+
{/if}
|
|
133
|
+
{#if showCloseIcon}
|
|
134
|
+
<div class="close-icon">
|
|
135
|
+
<Icon hoverable name="Close" on:click={cancel} />
|
|
136
|
+
</div>
|
|
137
|
+
{/if}
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
|
|
141
|
+
<style>
|
|
142
|
+
.spectrum-Dialog--extraLarge {
|
|
143
|
+
width: 1000px;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.content-grid {
|
|
147
|
+
display: grid;
|
|
148
|
+
position: relative;
|
|
149
|
+
gap: var(--spacing-xl);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.spectrum-Dialog-content {
|
|
153
|
+
overflow: visible;
|
|
154
|
+
}
|
|
155
|
+
.spectrum-Dialog-heading {
|
|
156
|
+
font-family: var(--font-sans);
|
|
157
|
+
}
|
|
158
|
+
.spectrum-Dialog-heading.noDivider {
|
|
159
|
+
margin-bottom: 12px;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.spectrum-Dialog-buttonGroup {
|
|
163
|
+
gap: var(--spectrum-global-dimension-static-size-200);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.close-icon {
|
|
167
|
+
position: absolute;
|
|
168
|
+
top: 15px;
|
|
169
|
+
right: 15px;
|
|
170
|
+
font-size: var(--font-size-m);
|
|
171
|
+
}
|
|
172
|
+
.close-icon :global(svg) {
|
|
173
|
+
margin-right: 0;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.header-spacing {
|
|
177
|
+
display: flex;
|
|
178
|
+
justify-content: space-between;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.secondary-action {
|
|
182
|
+
margin-right: auto;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.spectrum-Dialog-buttonGroup {
|
|
186
|
+
padding-left: 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.confirm-wrap :global(.spectrum-Button-label) {
|
|
190
|
+
display: contents;
|
|
191
|
+
}
|
|
192
|
+
</style>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import ModalContent from "./ModalContent.svelte"
|
|
3
|
+
import Input from "../Form/Input.svelte"
|
|
4
|
+
|
|
5
|
+
let modal
|
|
6
|
+
let answer
|
|
7
|
+
let error
|
|
8
|
+
|
|
9
|
+
export function show() {
|
|
10
|
+
modal.show()
|
|
11
|
+
}
|
|
12
|
+
export function hide() {
|
|
13
|
+
modal.hide
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function resetState() {
|
|
17
|
+
answer = undefined
|
|
18
|
+
error = undefined
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function answerQuiz() {
|
|
22
|
+
const correct = answer === "8"
|
|
23
|
+
error = !correct
|
|
24
|
+
return correct
|
|
25
|
+
}
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<ModalContent
|
|
29
|
+
title="Quick Maths"
|
|
30
|
+
bind:this={modal}
|
|
31
|
+
confirmText="Submit"
|
|
32
|
+
onConfirm={answerQuiz}
|
|
33
|
+
on:show={resetState}
|
|
34
|
+
>
|
|
35
|
+
{#if error}
|
|
36
|
+
<p class="error">Wrong answer! Try again.</p>
|
|
37
|
+
{/if}
|
|
38
|
+
<p>What is 4 + 4?</p>
|
|
39
|
+
<Input label="Answer" bind:value={answer} />
|
|
40
|
+
</ModalContent>
|
|
41
|
+
|
|
42
|
+
<style>
|
|
43
|
+
p {
|
|
44
|
+
margin: 0;
|
|
45
|
+
font-family: var(--font-sans);
|
|
46
|
+
font-size: var(--font-size-s);
|
|
47
|
+
}
|
|
48
|
+
p.error {
|
|
49
|
+
color: #e26d69;
|
|
50
|
+
background-color: #ffe6e6;
|
|
51
|
+
padding: 8px;
|
|
52
|
+
border-radius: 4px;
|
|
53
|
+
}
|
|
54
|
+
</style>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { ActionButton } from "../"
|
|
3
|
+
|
|
4
|
+
import { createEventDispatcher } from "svelte"
|
|
5
|
+
|
|
6
|
+
export let type = "info"
|
|
7
|
+
export let icon = "Info"
|
|
8
|
+
export let message = ""
|
|
9
|
+
export let dismissable = false
|
|
10
|
+
export let actionMessage = null
|
|
11
|
+
export let action = null
|
|
12
|
+
export let wide = false
|
|
13
|
+
|
|
14
|
+
const dispatch = createEventDispatcher()
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<div class="spectrum-Toast spectrum-Toast--{type}" class:wide>
|
|
18
|
+
{#if icon}
|
|
19
|
+
<svg
|
|
20
|
+
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Toast-typeIcon"
|
|
21
|
+
focusable="false"
|
|
22
|
+
aria-hidden="true"
|
|
23
|
+
>
|
|
24
|
+
<use xlink:href="#spectrum-icon-18-{icon}" />
|
|
25
|
+
</svg>
|
|
26
|
+
{/if}
|
|
27
|
+
<div class="spectrum-Toast-body" class:actionBody={!!action}>
|
|
28
|
+
<div class="spectrum-Toast-content">{message || ""}</div>
|
|
29
|
+
{#if action}
|
|
30
|
+
<ActionButton quiet emphasized on:click={action}>
|
|
31
|
+
<div style="color: white; font-weight: 600;">{actionMessage}</div>
|
|
32
|
+
</ActionButton>
|
|
33
|
+
{/if}
|
|
34
|
+
</div>
|
|
35
|
+
{#if dismissable}
|
|
36
|
+
<div class="spectrum-Toast-buttons">
|
|
37
|
+
<button
|
|
38
|
+
class="spectrum-ClearButton spectrum-ClearButton--overBackground spectrum-ClearButton--sizeM"
|
|
39
|
+
on:click={() => dispatch("dismiss")}
|
|
40
|
+
>
|
|
41
|
+
<div class="spectrum-ClearButton-fill">
|
|
42
|
+
<svg
|
|
43
|
+
class="spectrum-ClearButton-icon spectrum-Icon spectrum-UIIcon-Cross100"
|
|
44
|
+
focusable="false"
|
|
45
|
+
aria-hidden="true"
|
|
46
|
+
>
|
|
47
|
+
<use xlink:href="#spectrum-css-icon-Cross100" />
|
|
48
|
+
</svg>
|
|
49
|
+
</div>
|
|
50
|
+
</button>
|
|
51
|
+
</div>
|
|
52
|
+
{/if}
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<style>
|
|
56
|
+
.spectrum-Toast {
|
|
57
|
+
pointer-events: all;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.wide {
|
|
61
|
+
width: 100%;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.actionBody {
|
|
65
|
+
justify-content: space-between;
|
|
66
|
+
display: flex;
|
|
67
|
+
width: 100%;
|
|
68
|
+
align-items: center;
|
|
69
|
+
}
|
|
70
|
+
</style>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import "@spectrum-css/toast/dist/index-vars.css"
|
|
3
|
+
import Portal from "svelte-portal"
|
|
4
|
+
import { notifications } from "../Stores/notifications"
|
|
5
|
+
import Notification from "./Notification.svelte"
|
|
6
|
+
import { fly } from "svelte/transition"
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<Portal target=".modal-container">
|
|
10
|
+
<div class="notifications">
|
|
11
|
+
{#each $notifications as { type, icon, message, id, dismissable, action, wide } (id)}
|
|
12
|
+
<div transition:fly={{ y: 30 }}>
|
|
13
|
+
<Notification
|
|
14
|
+
{type}
|
|
15
|
+
{icon}
|
|
16
|
+
{message}
|
|
17
|
+
{dismissable}
|
|
18
|
+
{action}
|
|
19
|
+
{wide}
|
|
20
|
+
on:dismiss={() => notifications.dismiss(id)}
|
|
21
|
+
/>
|
|
22
|
+
</div>
|
|
23
|
+
{/each}
|
|
24
|
+
</div>
|
|
25
|
+
</Portal>
|
|
26
|
+
|
|
27
|
+
<style>
|
|
28
|
+
.notifications {
|
|
29
|
+
position: fixed;
|
|
30
|
+
bottom: 40px;
|
|
31
|
+
left: 0;
|
|
32
|
+
right: 0;
|
|
33
|
+
margin: 0 auto;
|
|
34
|
+
padding: 0;
|
|
35
|
+
z-index: 9999;
|
|
36
|
+
display: flex;
|
|
37
|
+
flex-direction: column;
|
|
38
|
+
justify-content: flex-start;
|
|
39
|
+
align-items: center;
|
|
40
|
+
pointer-events: none;
|
|
41
|
+
gap: 10px;
|
|
42
|
+
}
|
|
43
|
+
</style>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import "@spectrum-css/pagination/dist/index-vars.css"
|
|
3
|
+
import "@spectrum-css/actionbutton/dist/index-vars.css"
|
|
4
|
+
import "@spectrum-css/typography/dist/index-vars.css"
|
|
5
|
+
|
|
6
|
+
export let page
|
|
7
|
+
export let goToPrevPage
|
|
8
|
+
export let goToNextPage
|
|
9
|
+
export let hasPrevPage = true
|
|
10
|
+
export let hasNextPage = true
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<nav class="spectrum-Pagination spectrum-Pagination--explicit">
|
|
14
|
+
<div
|
|
15
|
+
href="#"
|
|
16
|
+
class="spectrum-ActionButton spectrum-ActionButton--sizeM spectrum-ActionButton--quiet spectrum-Pagination-prevButton"
|
|
17
|
+
on:click={hasPrevPage ? goToPrevPage : null}
|
|
18
|
+
class:is-disabled={!hasPrevPage}
|
|
19
|
+
>
|
|
20
|
+
<svg
|
|
21
|
+
class="spectrum-Icon spectrum-UIIcon-ChevronLeft100"
|
|
22
|
+
focusable="false"
|
|
23
|
+
aria-hidden="true"
|
|
24
|
+
aria-label="ChevronLeft"
|
|
25
|
+
>
|
|
26
|
+
<use xlink:href="#spectrum-css-icon-Chevron100" />
|
|
27
|
+
</svg>
|
|
28
|
+
</div>
|
|
29
|
+
<span class="spectrum-Body--secondary spectrum-Pagination-counter">
|
|
30
|
+
Page {page}
|
|
31
|
+
</span>
|
|
32
|
+
<div
|
|
33
|
+
href="#"
|
|
34
|
+
class="spectrum-ActionButton spectrum-ActionButton--sizeM spectrum-ActionButton--quiet spectrum-Pagination-nextButton"
|
|
35
|
+
on:click={hasNextPage ? goToNextPage : null}
|
|
36
|
+
class:is-disabled={!hasNextPage}
|
|
37
|
+
>
|
|
38
|
+
<svg
|
|
39
|
+
class="spectrum-Icon spectrum-UIIcon-ChevronRight100"
|
|
40
|
+
focusable="false"
|
|
41
|
+
aria-hidden="true"
|
|
42
|
+
aria-label="ChevronLeft"
|
|
43
|
+
>
|
|
44
|
+
<use xlink:href="#spectrum-css-icon-Chevron100" />
|
|
45
|
+
</svg>
|
|
46
|
+
</div>
|
|
47
|
+
</nav>
|
|
48
|
+
|
|
49
|
+
<style>
|
|
50
|
+
.spectrum-Pagination-counter {
|
|
51
|
+
margin-left: 0;
|
|
52
|
+
user-select: none;
|
|
53
|
+
}
|
|
54
|
+
.is-disabled:hover {
|
|
55
|
+
cursor: initial;
|
|
56
|
+
}
|
|
57
|
+
</style>
|