@budibase/bbui 3.5.2 → 3.6.0
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/dist/bbui.mjs +14368 -16206
- package/package.json +2 -2
- package/src/ActionMenu/ActionMenu.svelte +14 -13
- package/src/Avatar/Avatar.svelte +1 -1
- package/src/ColorPicker/ColorPicker.svelte +66 -34
- package/src/Form/Core/File.svelte +27 -21
- package/src/Form/Core/Multiselect.svelte +1 -1
- package/src/Form/Core/TextArea.svelte +49 -17
- package/src/Form/DatePicker.svelte +1 -1
- package/src/Form/File.svelte +14 -15
- package/src/Form/Multiselect.svelte +15 -14
- package/src/Form/Select.svelte +6 -9
- package/src/Form/TextArea.svelte +15 -6
- package/src/Form/Toggle.svelte +2 -2
- package/src/Icon/Icon.svelte +1 -1
- package/src/Icon/IconAvatar.svelte +7 -8
- package/src/IconPicker/IconPicker.svelte +16 -11
- package/src/InlineAlert/InlineAlert.svelte +10 -10
- package/src/Input/CopyInput.svelte +13 -11
- package/src/Label/Label.svelte +4 -4
- package/src/Layout/Layout.svelte +14 -9
- package/src/Layout/Page.svelte +6 -6
- package/src/List/List.svelte +2 -2
- package/src/List/ListItem.svelte +2 -2
- package/src/Markdown/MarkdownEditor.svelte +12 -12
- package/src/Markdown/MarkdownViewer.svelte +5 -4
- package/src/Markdown/SpectrumMDE.svelte +11 -11
- package/src/Menu/Item.svelte +7 -7
- package/src/Menu/Menu.svelte +1 -1
- package/src/Menu/Section.svelte +2 -2
- package/src/Modal/Content.svelte +2 -2
- package/src/Modal/CustomContent.svelte +4 -4
- package/src/Modal/Modal.svelte +36 -33
- package/src/Modal/ModalContent.svelte +33 -31
- package/src/Notification/Notification.svelte +9 -9
- package/src/Notification/NotificationDisplay.svelte +1 -1
- package/src/Pagination/Pagination.svelte +6 -8
- package/src/ProgressBar/ProgressBar.svelte +15 -14
- package/src/ProgressCircle/ProgressCircle.svelte +11 -11
- package/src/Tooltip/TooltipWrapper.svelte +1 -1
- package/src/bbui.css +10 -0
- package/src/context.d.ts +8 -0
- package/src/index.ts +0 -3
- package/src/types/actionMenu.ts +3 -0
- package/src/Form/PickerDropdown.svelte +0 -132
- package/src/IconSideNav/IconSideNav.svelte +0 -14
- package/src/IconSideNav/IconSideNavItem.svelte +0 -58
- package/src/Menu/Menu.svench +0 -19
- package/src/Modal/Modal.svench +0 -116
- package/src/Modal/QuizModal.svelte +0 -53
- package/src/Stores/Notifications.svench.svx +0 -78
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
<script>
|
|
1
|
+
<script lang="ts">
|
|
2
2
|
import { ActionButton } from "../"
|
|
3
3
|
|
|
4
4
|
import { createEventDispatcher } from "svelte"
|
|
5
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
|
|
6
|
+
export let type: string = "info"
|
|
7
|
+
export let icon: string = "Info"
|
|
8
|
+
export let message: string = ""
|
|
9
|
+
export let dismissable: boolean = false
|
|
10
|
+
export let actionMessage: string | null = null
|
|
11
|
+
export let action: ((_dismiss: () => void) => void) | null = null
|
|
12
|
+
export let wide: boolean = false
|
|
13
13
|
|
|
14
|
-
const dispatch = createEventDispatcher()
|
|
14
|
+
const dispatch = createEventDispatcher<{ dismiss: void }>()
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
17
|
<div class="spectrum-Toast spectrum-Toast--{type}" class:wide>
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
<script>
|
|
1
|
+
<script lang="ts">
|
|
2
2
|
import "@spectrum-css/pagination/dist/index-vars.css"
|
|
3
3
|
import "@spectrum-css/actionbutton/dist/index-vars.css"
|
|
4
4
|
import "@spectrum-css/typography/dist/index-vars.css"
|
|
5
5
|
|
|
6
|
-
export let page
|
|
7
|
-
export let goToPrevPage
|
|
8
|
-
export let goToNextPage
|
|
9
|
-
export let hasPrevPage = true
|
|
10
|
-
export let hasNextPage = true
|
|
6
|
+
export let page: number
|
|
7
|
+
export let goToPrevPage: () => void
|
|
8
|
+
export let goToNextPage: () => void
|
|
9
|
+
export let hasPrevPage: boolean = true
|
|
10
|
+
export let hasNextPage: boolean = true
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
13
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
14
14
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
15
15
|
<nav class="spectrum-Pagination spectrum-Pagination--explicit">
|
|
16
16
|
<div
|
|
17
|
-
href="#"
|
|
18
17
|
class="spectrum-ActionButton spectrum-ActionButton--sizeM spectrum-ActionButton--quiet spectrum-Pagination-prevButton"
|
|
19
18
|
on:click={hasPrevPage ? goToPrevPage : null}
|
|
20
19
|
class:is-disabled={!hasPrevPage}
|
|
@@ -32,7 +31,6 @@
|
|
|
32
31
|
Page {page}
|
|
33
32
|
</span>
|
|
34
33
|
<div
|
|
35
|
-
href="#"
|
|
36
34
|
class="spectrum-ActionButton spectrum-ActionButton--sizeM spectrum-ActionButton--quiet spectrum-Pagination-nextButton"
|
|
37
35
|
on:click={hasNextPage ? goToNextPage : null}
|
|
38
36
|
class:is-disabled={!hasNextPage}
|
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
<script>
|
|
1
|
+
<script lang="ts">
|
|
2
2
|
import "@spectrum-css/progressbar/dist/index-vars.css"
|
|
3
3
|
|
|
4
|
-
export let value = false
|
|
5
|
-
export let duration = 1000
|
|
6
|
-
export let width = false
|
|
7
|
-
export let sideLabel = false
|
|
8
|
-
export let hidePercentage = true
|
|
9
|
-
export let color // red, green, default = blue
|
|
10
|
-
export let size = "M"
|
|
4
|
+
export let value: number | boolean = false
|
|
5
|
+
export let duration: number = 1000
|
|
6
|
+
export let width: string | boolean = false
|
|
7
|
+
export let sideLabel: boolean = false
|
|
8
|
+
export let hidePercentage: boolean = true
|
|
9
|
+
export let color: "red" | "green" | undefined = undefined // red, green, default = blue
|
|
10
|
+
export let size: string = "M"
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
13
|
<div
|
|
14
14
|
class:spectrum-ProgressBar--indeterminate={!value && value !== 0}
|
|
15
15
|
class:spectrum-ProgressBar--sideLabel={sideLabel}
|
|
16
16
|
class="spectrum-ProgressBar spectrum-ProgressBar--size{size}"
|
|
17
|
-
{value}
|
|
18
17
|
role="progressbar"
|
|
19
|
-
aria-valuenow={value}
|
|
18
|
+
aria-valuenow={typeof value === "number" ? value : undefined}
|
|
20
19
|
aria-valuemin="0"
|
|
21
20
|
aria-valuemax="100"
|
|
22
|
-
style={width ? `width: ${width};` : ""}
|
|
21
|
+
style={width ? `width: ${typeof width === "string" ? width : ""};` : ""}
|
|
23
22
|
>
|
|
24
23
|
{#if $$slots}
|
|
25
24
|
<div
|
|
@@ -32,7 +31,7 @@
|
|
|
32
31
|
<div
|
|
33
32
|
class="spectrum-FieldLabel spectrum-ProgressBar-percentage spectrum-FieldLabel--size{size}"
|
|
34
33
|
>
|
|
35
|
-
{Math.round(value)}%
|
|
34
|
+
{Math.round(Number(value))}%
|
|
36
35
|
</div>
|
|
37
36
|
{/if}
|
|
38
37
|
<div class="spectrum-ProgressBar-track">
|
|
@@ -40,10 +39,12 @@
|
|
|
40
39
|
class="spectrum-ProgressBar-fill"
|
|
41
40
|
class:color-green={color === "green"}
|
|
42
41
|
class:color-red={color === "red"}
|
|
43
|
-
style="width: {value
|
|
42
|
+
style="width: {typeof value === 'number'
|
|
43
|
+
? value
|
|
44
|
+
: 0}%; --duration: {duration}ms;"
|
|
44
45
|
/>
|
|
45
46
|
</div>
|
|
46
|
-
<div class="spectrum-ProgressBar-label" hidden=
|
|
47
|
+
<div class="spectrum-ProgressBar-label" hidden={false} />
|
|
47
48
|
</div>
|
|
48
49
|
|
|
49
50
|
<style>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
<script>
|
|
1
|
+
<script lang="ts">
|
|
2
2
|
import "@spectrum-css/progresscircle/dist/index-vars.css"
|
|
3
3
|
|
|
4
|
-
export let size = "M"
|
|
5
|
-
function convertSize(size) {
|
|
4
|
+
export let size: "S" | "M" | "L" = "M"
|
|
5
|
+
function convertSize(size: "S" | "M" | "L"): string | undefined {
|
|
6
6
|
switch (size) {
|
|
7
7
|
case "S":
|
|
8
8
|
return "small"
|
|
@@ -13,18 +13,18 @@
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export let value = null
|
|
17
|
-
export let minValue = 0
|
|
18
|
-
export let maxValue = 100
|
|
16
|
+
export let value: number | null = null
|
|
17
|
+
export let minValue: number = 0
|
|
18
|
+
export let maxValue: number = 100
|
|
19
19
|
|
|
20
|
-
let subMask1Style
|
|
21
|
-
let subMask2Style
|
|
20
|
+
let subMask1Style: string | undefined
|
|
21
|
+
let subMask2Style: string | undefined
|
|
22
22
|
$: calculateSubMasks(value)
|
|
23
23
|
|
|
24
|
-
function calculateSubMasks(value) {
|
|
24
|
+
function calculateSubMasks(value: number | null): void {
|
|
25
25
|
if (value) {
|
|
26
26
|
let percentage = ((value - minValue) / (maxValue - minValue)) * 100
|
|
27
|
-
let angle
|
|
27
|
+
let angle: number
|
|
28
28
|
if (percentage > 0 && percentage <= 50) {
|
|
29
29
|
angle = -180 + (percentage / 50) * 180
|
|
30
30
|
subMask1Style = `transform: rotate(${angle}deg);`
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
export let overBackground = false
|
|
40
|
+
export let overBackground: boolean = false
|
|
41
41
|
</script>
|
|
42
42
|
|
|
43
43
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
package/src/bbui.css
CHANGED
|
@@ -11,6 +11,16 @@
|
|
|
11
11
|
--bb-forest-green: #053835;
|
|
12
12
|
--bb-beige: #f6efea;
|
|
13
13
|
|
|
14
|
+
/* Custom spectrum additions */
|
|
15
|
+
--spectrum-global-color-static-red-1200: #740000;
|
|
16
|
+
--spectrum-global-color-static-orange-1200: #612300;
|
|
17
|
+
--spectrum-global-color-static-yellow-1200: #483300;
|
|
18
|
+
--spectrum-global-color-static-green-1200: #053f27;
|
|
19
|
+
--spectrum-global-color-static-seafoam-1200: #123c3a;
|
|
20
|
+
--spectrum-global-color-static-blue-1200: #003571;
|
|
21
|
+
--spectrum-global-color-static-indigo-1200: #262986;
|
|
22
|
+
--spectrum-global-color-static-magenta-1200: #700037;
|
|
23
|
+
|
|
14
24
|
--grey-1: #fafafa;
|
|
15
25
|
--grey-2: #f5f5f5;
|
|
16
26
|
--grey-3: #eeeeee;
|
package/src/context.d.ts
ADDED
package/src/index.ts
CHANGED
|
@@ -17,7 +17,6 @@ export { default as Toggle } from "./Form/Toggle.svelte"
|
|
|
17
17
|
export { default as RadioGroup } from "./Form/RadioGroup.svelte"
|
|
18
18
|
export { default as Checkbox } from "./Form/Checkbox.svelte"
|
|
19
19
|
export { default as InputDropdown } from "./Form/InputDropdown.svelte"
|
|
20
|
-
export { default as PickerDropdown } from "./Form/PickerDropdown.svelte"
|
|
21
20
|
export { default as EnvDropdown } from "./Form/EnvDropdown.svelte"
|
|
22
21
|
export { default as Multiselect } from "./Form/Multiselect.svelte"
|
|
23
22
|
export { default as Search } from "./Form/Search.svelte"
|
|
@@ -87,8 +86,6 @@ export { default as MarkdownEditor } from "./Markdown/MarkdownEditor.svelte"
|
|
|
87
86
|
export { default as MarkdownViewer } from "./Markdown/MarkdownViewer.svelte"
|
|
88
87
|
export { default as List } from "./List/List.svelte"
|
|
89
88
|
export { default as ListItem } from "./List/ListItem.svelte"
|
|
90
|
-
export { default as IconSideNav } from "./IconSideNav/IconSideNav.svelte"
|
|
91
|
-
export { default as IconSideNavItem } from "./IconSideNav/IconSideNavItem.svelte"
|
|
92
89
|
export { default as Accordion } from "./Accordion/Accordion.svelte"
|
|
93
90
|
export { default as AbsTooltip } from "./Tooltip/AbsTooltip.svelte"
|
|
94
91
|
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import Field from "./Field.svelte"
|
|
3
|
-
import PickerDropdown from "./Core/PickerDropdown.svelte"
|
|
4
|
-
import { createEventDispatcher } from "svelte"
|
|
5
|
-
|
|
6
|
-
export let primaryValue = null
|
|
7
|
-
export let secondaryValue = null
|
|
8
|
-
export let inputType = "text"
|
|
9
|
-
export let label = null
|
|
10
|
-
export let labelPosition = "above"
|
|
11
|
-
export let secondaryPlaceholder = null
|
|
12
|
-
export let autocomplete
|
|
13
|
-
export let placeholder = null
|
|
14
|
-
export let disabled = false
|
|
15
|
-
export let readonly = false
|
|
16
|
-
export let error = null
|
|
17
|
-
export let getSecondaryOptionLabel = option =>
|
|
18
|
-
extractProperty(option, "label")
|
|
19
|
-
export let getSecondaryOptionValue = option =>
|
|
20
|
-
extractProperty(option, "value")
|
|
21
|
-
export let getSecondaryOptionColour = () => {}
|
|
22
|
-
export let getSecondaryOptionIcon = () => {}
|
|
23
|
-
export let quiet = false
|
|
24
|
-
export let autofocus
|
|
25
|
-
export let primaryOptions = []
|
|
26
|
-
export let secondaryOptions = []
|
|
27
|
-
export let searchTerm
|
|
28
|
-
export let showClearIcon = true
|
|
29
|
-
export let helpText = null
|
|
30
|
-
|
|
31
|
-
let primaryLabel
|
|
32
|
-
let secondaryLabel
|
|
33
|
-
const dispatch = createEventDispatcher()
|
|
34
|
-
|
|
35
|
-
$: secondaryFieldText = getSecondaryFieldText(
|
|
36
|
-
secondaryValue,
|
|
37
|
-
secondaryOptions,
|
|
38
|
-
secondaryPlaceholder
|
|
39
|
-
)
|
|
40
|
-
$: secondaryFieldIcon = getSecondaryFieldAttribute(
|
|
41
|
-
getSecondaryOptionIcon,
|
|
42
|
-
secondaryValue,
|
|
43
|
-
secondaryOptions
|
|
44
|
-
)
|
|
45
|
-
$: secondaryFieldColour = getSecondaryFieldAttribute(
|
|
46
|
-
getSecondaryOptionColour,
|
|
47
|
-
secondaryValue,
|
|
48
|
-
secondaryOptions
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
const getSecondaryFieldAttribute = (getAttribute, value, options) => {
|
|
52
|
-
// Wait for options to load if there is a value but no options
|
|
53
|
-
|
|
54
|
-
if (!options?.length) {
|
|
55
|
-
return ""
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const index = options.findIndex(
|
|
59
|
-
(option, idx) => getSecondaryOptionValue(option, idx) === value
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
return index !== -1 ? getAttribute(options[index], index) : null
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const getSecondaryFieldText = (value, options, placeholder) => {
|
|
66
|
-
// Always use placeholder if no value
|
|
67
|
-
if (value == null || value === "") {
|
|
68
|
-
return placeholder || "Choose an option"
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return getSecondaryFieldAttribute(getSecondaryOptionLabel, value, options)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const onPickPrimary = e => {
|
|
75
|
-
primaryLabel = e?.detail?.label || null
|
|
76
|
-
primaryValue = e?.detail?.value || null
|
|
77
|
-
dispatch("pickprimary", e?.detail?.value || {})
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const onPickSecondary = e => {
|
|
81
|
-
secondaryValue = e.detail
|
|
82
|
-
dispatch("picksecondary", e.detail)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const extractProperty = (value, property) => {
|
|
86
|
-
if (value && typeof value === "object") {
|
|
87
|
-
return value[property]
|
|
88
|
-
}
|
|
89
|
-
return value
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const updateSearchTerm = e => {
|
|
93
|
-
searchTerm = e.detail
|
|
94
|
-
}
|
|
95
|
-
</script>
|
|
96
|
-
|
|
97
|
-
<Field {helpText} {label} {labelPosition} {error}>
|
|
98
|
-
<PickerDropdown
|
|
99
|
-
{searchTerm}
|
|
100
|
-
{autocomplete}
|
|
101
|
-
{error}
|
|
102
|
-
{disabled}
|
|
103
|
-
{readonly}
|
|
104
|
-
{placeholder}
|
|
105
|
-
{inputType}
|
|
106
|
-
{quiet}
|
|
107
|
-
{autofocus}
|
|
108
|
-
{primaryOptions}
|
|
109
|
-
{secondaryOptions}
|
|
110
|
-
{getSecondaryOptionLabel}
|
|
111
|
-
{getSecondaryOptionValue}
|
|
112
|
-
{getSecondaryOptionIcon}
|
|
113
|
-
{getSecondaryOptionColour}
|
|
114
|
-
{secondaryFieldText}
|
|
115
|
-
{secondaryFieldIcon}
|
|
116
|
-
{secondaryFieldColour}
|
|
117
|
-
{primaryValue}
|
|
118
|
-
{secondaryValue}
|
|
119
|
-
{primaryLabel}
|
|
120
|
-
{secondaryLabel}
|
|
121
|
-
{showClearIcon}
|
|
122
|
-
on:pickprimary={onPickPrimary}
|
|
123
|
-
on:picksecondary={onPickSecondary}
|
|
124
|
-
on:search={updateSearchTerm}
|
|
125
|
-
on:click
|
|
126
|
-
on:input
|
|
127
|
-
on:blur
|
|
128
|
-
on:focus
|
|
129
|
-
on:keyup
|
|
130
|
-
on:closed
|
|
131
|
-
/>
|
|
132
|
-
</Field>
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import Icon from "../Icon/Icon.svelte"
|
|
3
|
-
import Tooltip from "../Tooltip/Tooltip.svelte"
|
|
4
|
-
import { fade } from "svelte/transition"
|
|
5
|
-
|
|
6
|
-
export let icon
|
|
7
|
-
export let active = false
|
|
8
|
-
export let tooltip
|
|
9
|
-
|
|
10
|
-
let showTooltip = false
|
|
11
|
-
</script>
|
|
12
|
-
|
|
13
|
-
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
14
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
15
|
-
<div
|
|
16
|
-
class="icon-side-nav-item"
|
|
17
|
-
class:active
|
|
18
|
-
on:mouseover={() => (showTooltip = true)}
|
|
19
|
-
on:focus={() => (showTooltip = true)}
|
|
20
|
-
on:mouseleave={() => (showTooltip = false)}
|
|
21
|
-
on:click
|
|
22
|
-
>
|
|
23
|
-
<Icon name={icon} hoverable />
|
|
24
|
-
{#if tooltip && showTooltip}
|
|
25
|
-
<div class="tooltip" in:fade={{ duration: 130, delay: 250 }}>
|
|
26
|
-
<Tooltip textWrapping direction="right" text={tooltip} />
|
|
27
|
-
</div>
|
|
28
|
-
{/if}
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
<style>
|
|
32
|
-
.icon-side-nav-item {
|
|
33
|
-
width: 36px;
|
|
34
|
-
height: 36px;
|
|
35
|
-
display: grid;
|
|
36
|
-
place-items: center;
|
|
37
|
-
border-radius: 4px;
|
|
38
|
-
position: relative;
|
|
39
|
-
cursor: pointer;
|
|
40
|
-
transition: background 130ms ease-out;
|
|
41
|
-
}
|
|
42
|
-
.icon-side-nav-item:hover :global(svg),
|
|
43
|
-
.active :global(svg) {
|
|
44
|
-
color: var(--spectrum-global-color-gray-900);
|
|
45
|
-
}
|
|
46
|
-
.active {
|
|
47
|
-
background: var(--spectrum-global-color-gray-300);
|
|
48
|
-
}
|
|
49
|
-
.tooltip {
|
|
50
|
-
position: absolute;
|
|
51
|
-
pointer-events: none;
|
|
52
|
-
left: calc(100% - 4px);
|
|
53
|
-
top: 50%;
|
|
54
|
-
white-space: nowrap;
|
|
55
|
-
transform: translateY(-50%);
|
|
56
|
-
z-index: 1;
|
|
57
|
-
}
|
|
58
|
-
</style>
|
package/src/Menu/Menu.svench
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import Menu from './Menu.svelte'
|
|
3
|
-
import Separator from './Separator.svelte'
|
|
4
|
-
import Section from './Section.svelte'
|
|
5
|
-
import Item from './Item.svelte'
|
|
6
|
-
</script>
|
|
7
|
-
|
|
8
|
-
<Menu>
|
|
9
|
-
<Section heading="Section heading">
|
|
10
|
-
<Item>Some Item 1</Item>
|
|
11
|
-
<Item>Some Item 2</Item>
|
|
12
|
-
<Item>Some Item 3</Item>
|
|
13
|
-
</Section>
|
|
14
|
-
<Separator />
|
|
15
|
-
<Section heading="Section heading">
|
|
16
|
-
<Item icon="SaveFloppy">Save</Item>
|
|
17
|
-
<Item disabled icon="DataDownload">Download</Item>
|
|
18
|
-
</Section>
|
|
19
|
-
</Menu>
|
package/src/Modal/Modal.svench
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
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-size: var(--font-size-s);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
code {
|
|
26
|
-
display: inline-block;
|
|
27
|
-
box-sizing: border-box;
|
|
28
|
-
padding: var(--spacing-xs) var(--spacing-s);
|
|
29
|
-
background-color: var(--grey-2);
|
|
30
|
-
color: var(--red-dark);
|
|
31
|
-
border-radius: var(--spacing-xs);
|
|
32
|
-
}
|
|
33
|
-
</style>
|
|
34
|
-
|
|
35
|
-
<h3>Modals</h3>
|
|
36
|
-
<p>
|
|
37
|
-
Modals provide a means to render content in front of everything else on a page.
|
|
38
|
-
</p>
|
|
39
|
-
<p>
|
|
40
|
-
The modal module in BBUI exposes two
|
|
41
|
-
separate components to provide this functionality; a <code>Modal</code> component to control visibility of content,
|
|
42
|
-
and a <code>ModalContent</code> component to quickly construct the typical content - although this is optional.
|
|
43
|
-
</p>
|
|
44
|
-
<p>
|
|
45
|
-
One of the common problems with modals and popups is stale state reappearing after hiding and showing the content
|
|
46
|
-
again, since the state hasn't been garbage collected if a component controls its own visibility. This is handled for
|
|
47
|
-
you when using the <code>Modal</code> component as it will fully unmount child components, properly resetting state
|
|
48
|
-
every time it appears.
|
|
49
|
-
</p>
|
|
50
|
-
|
|
51
|
-
<br/>
|
|
52
|
-
<p>Use ModalContent to render typical modal content.</p>
|
|
53
|
-
<View name="Simple Confirmation Modal">
|
|
54
|
-
<Button primary on:click={modal1.show}>Delete Record</Button>
|
|
55
|
-
<Modal bind:this={modal1}>
|
|
56
|
-
<ModalContent title="Confirm Deletion" confirmText="Delete">
|
|
57
|
-
<span>Are you sure you want to delete this record?</span>
|
|
58
|
-
</ModalContent>
|
|
59
|
-
</Modal>
|
|
60
|
-
</View>
|
|
61
|
-
|
|
62
|
-
<br/>
|
|
63
|
-
<p>
|
|
64
|
-
Width can be specified as a prop to a <code>Modal</code>. Any additional <code>ModalContent</code> props provided
|
|
65
|
-
will be passed to the confirmation button.
|
|
66
|
-
</p>
|
|
67
|
-
<View name="Different Buttons and Width">
|
|
68
|
-
<Button primary on:click={modal3.show}>Open Modal</Button>
|
|
69
|
-
<Modal bind:this={modal3} width="250px">
|
|
70
|
-
<ModalContent
|
|
71
|
-
title="Confirmation Required"
|
|
72
|
-
showCancelButton={false}
|
|
73
|
-
showCloseIcon={false}
|
|
74
|
-
confirmText="I'm sure!"
|
|
75
|
-
green
|
|
76
|
-
large
|
|
77
|
-
wide
|
|
78
|
-
>
|
|
79
|
-
<span>Are you sure you want to do that?</span>
|
|
80
|
-
</ModalContent>
|
|
81
|
-
</Modal>
|
|
82
|
-
</View>
|
|
83
|
-
|
|
84
|
-
<br/>
|
|
85
|
-
<p>Any content can be rendered inside a <code>Modal</code>. Use context to close the modal from your own components.</p>
|
|
86
|
-
<View name="Custom Content">
|
|
87
|
-
<Button primary on:click={modal1.show}>Open Modal</Button>
|
|
88
|
-
<Modal bind:this={modal1} padding={false} border={false}>
|
|
89
|
-
<CustomContent/>
|
|
90
|
-
</Modal>
|
|
91
|
-
</View>
|
|
92
|
-
|
|
93
|
-
<br/>
|
|
94
|
-
<p>Async functions passed in as the onConfirm prop will make the modal wait until the callback is completed.</p>
|
|
95
|
-
<View name="Async Callbacks">
|
|
96
|
-
<Button primary on:click={modal2.show}>Long Task</Button>
|
|
97
|
-
<Modal bind:this={modal2}>
|
|
98
|
-
<ModalContent
|
|
99
|
-
title="Perform Long Task"
|
|
100
|
-
confirmText="Submit"
|
|
101
|
-
onConfirm={longTask}
|
|
102
|
-
>
|
|
103
|
-
<span>Pressing submit will wait 3 seconds before finishing and disable the confirm button until it's done.</span>
|
|
104
|
-
</ModalContent>
|
|
105
|
-
</Modal>
|
|
106
|
-
</View>
|
|
107
|
-
|
|
108
|
-
<br/>
|
|
109
|
-
<p>Returning false from a onConfirm callback will prevent the modal being closed.</p>
|
|
110
|
-
<View name="Callback Failure Handling">
|
|
111
|
-
<Button primary on:click={modal3.show}>Open Quiz</Button>
|
|
112
|
-
<Modal bind:this={modal3}>
|
|
113
|
-
<QuizModal />
|
|
114
|
-
</Modal>
|
|
115
|
-
</View>
|
|
116
|
-
|
|
@@ -1,53 +0,0 @@
|
|
|
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-size: var(--font-size-s);
|
|
46
|
-
}
|
|
47
|
-
p.error {
|
|
48
|
-
color: #e26d69;
|
|
49
|
-
background-color: #ffe6e6;
|
|
50
|
-
padding: 8px;
|
|
51
|
-
border-radius: 4px;
|
|
52
|
-
}
|
|
53
|
-
</style>
|