@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.
Files changed (152) hide show
  1. package/LICENSE +375 -0
  2. package/README.md +19 -17
  3. package/dist/bbui.es.js +210 -0
  4. package/dist/bbui.es.js.map +1 -0
  5. package/package.json +71 -26
  6. package/src/ActionButton/ActionButton.svelte +102 -0
  7. package/src/ActionGroup/ActionGroup.svelte +26 -0
  8. package/src/ActionMenu/ActionMenu.svelte +44 -0
  9. package/src/Actions/ClickOutside.svench.svx +30 -0
  10. package/src/Actions/PositionDropdown.svench.svx +81 -0
  11. package/src/Actions/autoresize_textarea.js +14 -0
  12. package/src/Actions/click_outside.js +18 -0
  13. package/src/Actions/position_dropdown.js +66 -0
  14. package/src/Avatar/Avatar.svelte +62 -0
  15. package/src/Badge/Badge.svelte +29 -0
  16. package/src/Banner/Banner.svelte +72 -0
  17. package/src/Banner/BannerDisplay.svelte +31 -0
  18. package/src/Button/Button.svelte +114 -0
  19. package/src/Button/Button.svench +138 -0
  20. package/src/ButtonGroup/ButtonGroup.svelte +30 -0
  21. package/src/ClearButton/ClearButton.svelte +19 -0
  22. package/src/ColorPicker/ColorPicker.svelte +297 -0
  23. package/src/DetailSummary/DetailSummary.svelte +83 -0
  24. package/src/Divider/Divider.svelte +28 -0
  25. package/src/Drawer/Drawer.svelte +113 -0
  26. package/src/Drawer/Drawer.svench +42 -0
  27. package/src/Drawer/DrawerContent.svelte +46 -0
  28. package/src/Form/Checkbox.svelte +23 -0
  29. package/src/Form/Combobox.svelte +45 -0
  30. package/src/Form/Core/Checkbox.svelte +69 -0
  31. package/src/Form/Core/CheckboxGroup.svelte +68 -0
  32. package/src/Form/Core/Combobox.svelte +142 -0
  33. package/src/Form/Core/DatePicker.svelte +257 -0
  34. package/src/Form/Core/Dropzone.svelte +450 -0
  35. package/src/Form/Core/InputDropdown.svelte +228 -0
  36. package/src/Form/Core/Multiselect.svelte +90 -0
  37. package/src/Form/Core/Picker.svelte +259 -0
  38. package/src/Form/Core/PickerDropdown.svelte +436 -0
  39. package/src/Form/Core/RadioGroup.svelte +48 -0
  40. package/src/Form/Core/RichTextField.svelte +42 -0
  41. package/src/Form/Core/Search.svelte +105 -0
  42. package/src/Form/Core/Select.svelte +75 -0
  43. package/src/Form/Core/Slider.svelte +86 -0
  44. package/src/Form/Core/Stepper.svelte +172 -0
  45. package/src/Form/Core/Switch.svelte +37 -0
  46. package/src/Form/Core/TextArea.svelte +78 -0
  47. package/src/Form/Core/TextField.svelte +119 -0
  48. package/src/Form/Core/index.js +15 -0
  49. package/src/Form/DatePicker.svelte +39 -0
  50. package/src/Form/Dropzone.svelte +42 -0
  51. package/src/Form/Field.svelte +42 -0
  52. package/src/Form/FieldLabel.svelte +32 -0
  53. package/src/Form/Input.svelte +40 -45
  54. package/src/Form/InputDropdown.svelte +55 -0
  55. package/src/Form/Multiselect.svelte +40 -0
  56. package/src/Form/PickerDropdown.svelte +134 -0
  57. package/src/Form/RadioGroup.svelte +42 -0
  58. package/src/Form/RichTextField.svelte +36 -0
  59. package/src/Form/Search.svelte +36 -0
  60. package/src/Form/Select.svelte +48 -43
  61. package/src/Form/Slider.svelte +24 -0
  62. package/src/Form/Stepper.svelte +45 -0
  63. package/src/Form/TextArea.svelte +29 -44
  64. package/src/Form/Toggle.svelte +23 -0
  65. package/src/Icon/Icon.svelte +91 -0
  66. package/src/IconPicker/IconPicker.svelte +177 -0
  67. package/src/IconSideNav/IconSideNav.svelte +14 -0
  68. package/src/IconSideNav/IconSideNavItem.svelte +56 -0
  69. package/src/InlineAlert/InlineAlert.svelte +56 -0
  70. package/src/Label/Label.svelte +20 -0
  71. package/src/Layout/Layout.svelte +94 -0
  72. package/src/Layout/Page.svelte +32 -0
  73. package/src/Link/Link.svelte +24 -0
  74. package/src/List/List.svelte +28 -0
  75. package/src/List/ListItem.svelte +98 -0
  76. package/src/Markdown/MarkdownEditor.svelte +60 -0
  77. package/src/Markdown/MarkdownViewer.svelte +70 -0
  78. package/src/Markdown/SpectrumMDE.svelte +184 -0
  79. package/src/Menu/Item.svelte +96 -0
  80. package/src/Menu/Menu.svelte +7 -0
  81. package/src/Menu/Menu.svench +19 -0
  82. package/src/Menu/Section.svelte +10 -0
  83. package/src/Menu/Separator.svelte +1 -0
  84. package/src/Modal/Content.svelte +6 -0
  85. package/src/Modal/CustomContent.svelte +38 -0
  86. package/src/Modal/Modal.svelte +165 -0
  87. package/src/Modal/Modal.svench +117 -0
  88. package/src/Modal/ModalContent.svelte +192 -0
  89. package/src/Modal/QuizModal.svelte +54 -0
  90. package/src/Notification/Notification.svelte +70 -0
  91. package/src/Notification/NotificationDisplay.svelte +43 -0
  92. package/src/Pagination/Pagination.svelte +57 -0
  93. package/src/Popover/Popover.svelte +77 -0
  94. package/src/Popover/Popover.svench +121 -0
  95. package/src/ProgressBar/ProgressBar.svelte +54 -0
  96. package/src/ProgressCircle/ProgressCircle.svelte +62 -0
  97. package/src/SideNavigation/Item.svelte +47 -0
  98. package/src/SideNavigation/Navigation.svelte +12 -0
  99. package/src/StatusLight/StatusLight.svelte +80 -0
  100. package/src/Stores/Notifications.svench.svx +78 -0
  101. package/src/Stores/banner.js +37 -0
  102. package/src/Stores/notifications.js +84 -0
  103. package/src/Table/ArrayRenderer.svelte +17 -0
  104. package/src/Table/AttachmentRenderer.svelte +67 -0
  105. package/src/Table/BoldRenderer.svelte +15 -0
  106. package/src/Table/BooleanRenderer.svelte +42 -0
  107. package/src/Table/CellRenderer.svelte +69 -0
  108. package/src/Table/CodeRenderer.svelte +14 -0
  109. package/src/Table/DateTimeRenderer.svelte +29 -0
  110. package/src/Table/InternalRenderer.svelte +24 -0
  111. package/src/Table/RelationshipRenderer.svelte +40 -0
  112. package/src/Table/SelectEditRenderer.svelte +28 -0
  113. package/src/Table/StringRenderer.svelte +14 -0
  114. package/src/Table/Table.svelte +635 -0
  115. package/src/Table/index.js +1 -0
  116. package/src/Tabs/Tab.svelte +88 -0
  117. package/src/Tabs/Tabs.svelte +125 -0
  118. package/src/Tags/Tag.svelte +43 -0
  119. package/src/Tags/Tags.svelte +7 -0
  120. package/src/Tooltip/Tooltip.svelte +34 -0
  121. package/src/Tooltip/TooltipWrapper.svelte +60 -0
  122. package/src/TreeView/Item.svelte +41 -0
  123. package/src/TreeView/Tree.svelte +16 -0
  124. package/src/Typography/Body.svelte +21 -0
  125. package/src/Typography/Code.svelte +10 -0
  126. package/src/Typography/Detail.svelte +19 -0
  127. package/src/Typography/Heading.svelte +17 -0
  128. package/src/bbui.css +96 -0
  129. package/src/context.js +3 -0
  130. package/src/helpers.js +134 -0
  131. package/src/index.js +97 -11
  132. package/src/spectrum-icons-rollup.js +31 -0
  133. package/src/spectrum-icons-vite.js +31 -0
  134. package/dist/bundle.css +0 -7
  135. package/dist/bundle.css.map +0 -20
  136. package/dist/index.js +0 -1100
  137. package/dist/index.mjs +0 -1086
  138. package/src/Branding/Budibase-logo.svelte +0 -68
  139. package/src/Branding/Logo.svelte +0 -16
  140. package/src/Branding/Logo.svench +0 -8
  141. package/src/Form/Button.svelte +0 -131
  142. package/src/Form/Button.svench +0 -49
  143. package/src/Form/Input.svench +0 -8
  144. package/src/Form/Select.svench +0 -8
  145. package/src/Form/TextArea.svench +0 -8
  146. package/src/Links/Home.svelte +0 -49
  147. package/src/Links/Home.svench +0 -19
  148. package/src/List/Items/DetailSummary.svelte +0 -66
  149. package/src/List/Items/DetailSummary.svench +0 -15
  150. package/src/actions/autoresize_textarea.js +0 -14
  151. package/src/icons/Contribution.svelte +0 -14
  152. package/src/index.svench.svx +0 -35
@@ -0,0 +1,77 @@
1
+ <script>
2
+ import "@spectrum-css/popover/dist/index-vars.css"
3
+ import Portal from "svelte-portal"
4
+ import { createEventDispatcher } from "svelte"
5
+ import positionDropdown from "../Actions/position_dropdown"
6
+ import clickOutside from "../Actions/click_outside"
7
+
8
+ const dispatch = createEventDispatcher()
9
+
10
+ export let anchor
11
+ export let align = "right"
12
+ export let portalTarget
13
+ export let dataCy
14
+
15
+ export let direction = "bottom"
16
+ export let showTip = false
17
+
18
+ let tipSvg =
19
+ '<svg xmlns="http://www.w3.org/svg/2000" width="23" height="12" class="spectrum-Popover-tip" > <path class="spectrum-Popover-tip-triangle" d="M 0.7071067811865476 0 L 11.414213562373096 10.707106781186548 L 22.121320343559645 0" /> </svg>'
20
+
21
+ $: tooltipClasses = showTip
22
+ ? `spectrum-Popover--withTip spectrum-Popover--${direction}`
23
+ : ""
24
+
25
+ export const show = () => {
26
+ dispatch("open")
27
+ open = true
28
+ }
29
+
30
+ export const hide = () => {
31
+ dispatch("close")
32
+ open = false
33
+ }
34
+
35
+ let open = null
36
+
37
+ function handleEscape(e) {
38
+ if (open && e.key === "Escape") {
39
+ hide()
40
+ }
41
+ }
42
+ </script>
43
+
44
+ {#if open}
45
+ <Portal target={portalTarget}>
46
+ <div
47
+ tabindex="0"
48
+ use:positionDropdown={{ anchor, align }}
49
+ use:clickOutside={hide}
50
+ on:keydown={handleEscape}
51
+ class={"spectrum-Popover is-open " + (tooltipClasses || "")}
52
+ role="presentation"
53
+ data-cy={dataCy}
54
+ >
55
+ {#if showTip}
56
+ {@html tipSvg}
57
+ {/if}
58
+
59
+ <slot />
60
+ </div>
61
+ </Portal>
62
+ {/if}
63
+
64
+ <style>
65
+ .spectrum-Popover {
66
+ min-width: var(--spectrum-global-dimension-size-2000);
67
+ }
68
+ .spectrum-Popover.is-open.spectrum-Popover--withTip {
69
+ margin-top: var(--spacing-xs);
70
+ margin-left: var(--spacing-xl);
71
+ }
72
+ :global(.spectrum-Popover--bottom .spectrum-Popover-tip),
73
+ :global(.spectrum-Popover--top .spectrum-Popover-tip) {
74
+ left: 90%;
75
+ margin-left: calc(var(--spectrum-global-dimension-size-150) * -1);
76
+ }
77
+ </style>
@@ -0,0 +1,121 @@
1
+ <script>
2
+ import { View } from "svench";
3
+ import Popover from "./Popover.svelte";
4
+ import Button from "../Button/Button.svelte";
5
+ import TextButton from "../Button/TextButton.svelte";
6
+ import Icon from "../Icons/Icon.svelte";
7
+ import Input from "../Form/Input.svelte";
8
+ import Select from "../Form/Select.svelte";
9
+
10
+ let anchorRight;
11
+ let anchorLeft;
12
+ let dropdownRight;
13
+ let dropdownLeft;
14
+
15
+ const options = ["Column 1", "Column 2", "Super cool column"];
16
+ const option1s = ["Is", "Is not", "Contains" , "Does not contain"];
17
+
18
+ </script>
19
+
20
+ <style>
21
+ .button-group {
22
+ margin-top: var(--spacing-l);
23
+ display: flex;
24
+ justify-content: flex-end;
25
+ gap: var(--spacing-s);
26
+ }
27
+
28
+ h6 {
29
+ font-size: var(--font-size-m);
30
+ margin: 0 0 var(--spacing-l) 0;
31
+ font-weight: 600;
32
+ font-family: var(--font-sans);
33
+ }
34
+
35
+ .input-group-column {
36
+ display: flex;
37
+ flex-direction: column;
38
+ gap: var(--spacing-s);
39
+ }
40
+
41
+ .input-group-row {
42
+ display: grid;
43
+ grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];
44
+ gap: var(--spacing-s);
45
+ margin-bottom: var(--spacing-l);
46
+ align-items: center;
47
+ }
48
+
49
+ p {
50
+ margin:0;
51
+ font-size: var(--font-size-xs);
52
+ }
53
+ </style>
54
+
55
+ <View name="Simple popover">
56
+ <div bind:this={anchorLeft}>
57
+ <Button text on:click={dropdownLeft.show}>
58
+ <Icon name="view" />
59
+ Add View
60
+ </Button>
61
+ </div>
62
+ <Popover bind:this={dropdownLeft} anchor={anchorLeft} align="left">
63
+ <h6>Add New View</h6>
64
+ <Input thin placeholder="Enter your name" />
65
+ <div class="button-group">
66
+ <Button secondary on:click={() => alert('Clicked!')}>Cancel</Button>
67
+ <Button primary on:click={() => alert('Clicked!')}>Add New View</Button>
68
+ </div>
69
+ </Popover>
70
+ </View>
71
+
72
+ <View name="Stacked columns">
73
+ <div bind:this={anchorRight}>
74
+ <Button text on:click={dropdownRight.show}>
75
+ <Icon name="addrow" />
76
+ Add Row
77
+ </Button>
78
+ </div>
79
+ <Popover bind:this={dropdownRight} anchor={anchorRight}>
80
+ <h6>Add New Row</h6>
81
+ <div class="input-group-column">
82
+ <Input thin placeholder="Enter your string" />
83
+ <Input thin placeholder="Enter your string" />
84
+ <Input thin placeholder="Enter your string" />
85
+ </div>
86
+ <div class="button-group">
87
+ <Button secondary on:click={() => alert('Clicked!')}>Cancel</Button>
88
+ <Button primary on:click={() => alert('Clicked!')}>Add New Row</Button>
89
+ </div>
90
+ </Popover>
91
+ </View>
92
+
93
+ <View name="Multiple inputs in a row">
94
+ <div bind:this={anchorLeft}>
95
+ <Button text on:click={dropdownLeft.show}>
96
+ <Icon name="filter" />
97
+ Add Filter
98
+ </Button>
99
+ </div>
100
+ <Popover bind:this={dropdownLeft} anchor={anchorLeft} align="left">
101
+ <h6>Add New Filter</h6>
102
+ <div class="input-group-row">
103
+ <p>Where</p>
104
+ <Select secondary thin name="Test">
105
+ {#each options as option}
106
+ <option value={option}>{option}</option>
107
+ {/each}
108
+ </Select>
109
+ <Select secondary thin name="Test">
110
+ {#each option1s as option1}
111
+ <option value={option1}>{option1}</option>
112
+ {/each}
113
+ </Select>
114
+ <Input thin placeholder="Enter your name" />
115
+ <Button text on:click={() => alert('Clicked!')}>
116
+ <Icon name="close" />
117
+ </Button>
118
+ </div>
119
+ <Button text on:click={() => alert('Clicked!')}>Add Filter</Button>
120
+ </Popover>
121
+ </View>
@@ -0,0 +1,54 @@
1
+ <script>
2
+ import "@spectrum-css/progressbar/dist/index-vars.css"
3
+ import { tweened } from "svelte/motion"
4
+ import { cubicOut } from "svelte/easing"
5
+
6
+ export let value = false
7
+ export let easing = cubicOut
8
+ export let duration = 1000
9
+ export let width = false
10
+ export let sideLabel = false
11
+
12
+ export let size = "M"
13
+
14
+ const progress = tweened(0, {
15
+ duration: duration,
16
+ easing: easing,
17
+ })
18
+
19
+ $: if (value || value === 0) $progress = value
20
+ </script>
21
+
22
+ <div
23
+ class:spectrum-ProgressBar--indeterminate={!value && value !== 0}
24
+ class:spectrum-ProgressBar--sideLabel={sideLabel}
25
+ class="spectrum-ProgressBar spectrum-ProgressBar--size{size}"
26
+ value={$progress}
27
+ role="progressbar"
28
+ aria-valuenow={$progress}
29
+ aria-valuemin="0"
30
+ aria-valuemax="100"
31
+ style={width ? `width: ${width};` : ""}
32
+ >
33
+ {#if $$slots}
34
+ <div
35
+ class="spectrum-FieldLabel spectrum-ProgressBar-label spectrum-FieldLabel--size{size}"
36
+ >
37
+ <slot />
38
+ </div>
39
+ {/if}
40
+ {#if value || value === 0}
41
+ <div
42
+ class="spectrum-FieldLabel spectrum-ProgressBar-percentage spectrum-FieldLabel--size{size}"
43
+ >
44
+ {Math.round($progress)}%
45
+ </div>
46
+ {/if}
47
+ <div class="spectrum-ProgressBar-track">
48
+ <div
49
+ class="spectrum-ProgressBar-fill"
50
+ style={value || value === 0 ? `width: ${$progress}%` : ""}
51
+ />
52
+ </div>
53
+ <div class="spectrum-ProgressBar-label" hidden="" />
54
+ </div>
@@ -0,0 +1,62 @@
1
+ <script>
2
+ import "@spectrum-css/progresscircle/dist/index-vars.css"
3
+
4
+ export let size = "M"
5
+ function convertSize(size) {
6
+ switch (size) {
7
+ case "S":
8
+ return "small"
9
+ case "L":
10
+ return "large"
11
+ default:
12
+ return
13
+ }
14
+ }
15
+
16
+ export let value = null
17
+ export let minValue = 0
18
+ export let maxValue = 100
19
+
20
+ let subMask1Style
21
+ let subMask2Style
22
+ $: calculateSubMasks(value)
23
+
24
+ function calculateSubMasks(value) {
25
+ if (value) {
26
+ let percentage = ((value - minValue) / (maxValue - minValue)) * 100
27
+ let angle
28
+ if (percentage > 0 && percentage <= 50) {
29
+ angle = -180 + (percentage / 50) * 180
30
+ subMask1Style = `transform: rotate(${angle}deg);`
31
+ subMask2Style = "transform: rotate(-180deg);"
32
+ } else if (percentage > 50) {
33
+ angle = -180 + ((percentage - 50) / 50) * 180
34
+ subMask1Style = "transform: rotate(0deg);"
35
+ subMask2Style = `transform: rotate(${angle}deg);`
36
+ }
37
+ }
38
+ }
39
+
40
+ export let overBackground
41
+ </script>
42
+
43
+ <div
44
+ on:click
45
+ class:spectrum-ProgressCircle--indeterminate={value == null}
46
+ class:spectrum-ProgressCircle--overBackground={overBackground}
47
+ class="spectrum-ProgressCircle spectrum-ProgressCircle--{convertSize(size)}"
48
+ >
49
+ <div class="spectrum-ProgressCircle-track" />
50
+ <div class="spectrum-ProgressCircle-fills">
51
+ <div class="spectrum-ProgressCircle-fillMask1">
52
+ <div class="spectrum-ProgressCircle-fillSubMask1" style={subMask1Style}>
53
+ <div class="spectrum-ProgressCircle-fill" />
54
+ </div>
55
+ </div>
56
+ <div class="spectrum-ProgressCircle-fillMask2">
57
+ <div class="spectrum-ProgressCircle-fillSubMask2" style={subMask2Style}>
58
+ <div class="spectrum-ProgressCircle-fill" />
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </div>
@@ -0,0 +1,47 @@
1
+ <script>
2
+ import { getContext } from "svelte"
3
+ const multilevel = getContext("sidenav-type")
4
+ export let href = ""
5
+ export let external = false
6
+ export let heading = ""
7
+ export let icon = ""
8
+ export let selected = false
9
+ export let disabled = false
10
+ export let dataCy
11
+ </script>
12
+
13
+ <li
14
+ class="spectrum-SideNav-item"
15
+ class:is-selected={selected}
16
+ class:is-disabled={disabled}
17
+ on:click
18
+ data-cy={dataCy}
19
+ >
20
+ {#if heading}
21
+ <h2 class="spectrum-SideNav-heading" id="nav-heading-{heading}">
22
+ {heading}
23
+ </h2>
24
+ {/if}
25
+ <a
26
+ target={external ? "_blank" : ""}
27
+ {href}
28
+ class="spectrum-SideNav-itemLink"
29
+ aria-current="page"
30
+ >
31
+ {#if icon}
32
+ <svg
33
+ class="spectrum-Icon spectrum-Icon--sizeM spectrum-SideNav-itemIcon"
34
+ focusable="false"
35
+ aria-hidden="true"
36
+ >
37
+ <use xlink:href="#spectrum-icon-18-{icon}" />
38
+ </svg>
39
+ {/if}
40
+ <slot />
41
+ </a>
42
+ {#if multilevel && $$slots.subnav}
43
+ <ul class="spectrum-SideNav">
44
+ <slot name="subnav" />
45
+ </ul>
46
+ {/if}
47
+ </li>
@@ -0,0 +1,12 @@
1
+ <script>
2
+ import { setContext } from "svelte"
3
+ import "@spectrum-css/sidenav/dist/index-vars.css"
4
+ export let multilevel = false
5
+ setContext("sidenav-type", multilevel)
6
+ </script>
7
+
8
+ <nav>
9
+ <ul class="spectrum-SideNav" class:spectrum-SideNav--multiLevel={multilevel}>
10
+ <slot />
11
+ </ul>
12
+ </nav>
@@ -0,0 +1,80 @@
1
+ <script>
2
+ import "@spectrum-css/statuslight"
3
+
4
+ export let size = "M"
5
+ export let celery = false
6
+ export let yellow = false
7
+ export let fuchsia = false
8
+ export let indigo = false
9
+ export let seafoam = false
10
+ export let chartreuse = false
11
+ export let magenta = false
12
+ export let purple = false
13
+ export let neutral = false
14
+ export let info = false
15
+ export let positive = false
16
+ export let notice = false
17
+ export let negative = false
18
+ export let disabled = false
19
+ export let active = false
20
+ export let color = null
21
+ export let square = false
22
+ export let hoverable = false
23
+ </script>
24
+
25
+ <div
26
+ on:click
27
+ class="spectrum-StatusLight spectrum-StatusLight--size{size}"
28
+ class:custom={!!color}
29
+ class:square
30
+ class:hoverable
31
+ style={`--color: ${color};`}
32
+ class:spectrum-StatusLight--celery={celery}
33
+ class:spectrum-StatusLight--yellow={yellow}
34
+ class:spectrum-StatusLight--fuchsia={fuchsia}
35
+ class:spectrum-StatusLight--indigo={indigo}
36
+ class:spectrum-StatusLight--seafoam={seafoam}
37
+ class:spectrum-StatusLight--chartreuse={chartreuse}
38
+ class:spectrum-StatusLight--magenta={magenta}
39
+ class:spectrum-StatusLight--purple={purple}
40
+ class:spectrum-StatusLight--neutral={neutral}
41
+ class:spectrum-StatusLight--info={info}
42
+ class:spectrum-StatusLight--positive={positive}
43
+ class:spectrum-StatusLight--notice={notice}
44
+ class:spectrum-StatusLight--negative={negative}
45
+ class:spectrum-StatusLight--disabled={disabled}
46
+ class:spectrum-StatusLight--active={active}
47
+ class:withText={!!$$slots.default}
48
+ >
49
+ <slot />
50
+ </div>
51
+
52
+ <style>
53
+ .spectrum-StatusLight {
54
+ display: flex;
55
+ flex-direction: row;
56
+ justify-content: center;
57
+ align-items: center;
58
+ --spectrum-statuslight-info-text-gap: 4px;
59
+ min-height: 0;
60
+ padding-top: 0;
61
+ padding-bottom: 0;
62
+ transition: color ease-out 130ms;
63
+ }
64
+ .spectrum-StatusLight.withText::before {
65
+ margin-right: 10px;
66
+ }
67
+ .custom::before {
68
+ background: var(--color) !important;
69
+ }
70
+ .square::before {
71
+ width: 14px;
72
+ height: 14px;
73
+ border-radius: 4px;
74
+ margin: 0;
75
+ }
76
+ .hoverable:hover {
77
+ cursor: pointer;
78
+ color: var(--spectrum-global-color-gray-900);
79
+ }
80
+ </style>
@@ -0,0 +1,78 @@
1
+ <script>
2
+ import { flip } from 'svelte/animate';
3
+ import { fly } from "svelte/transition"
4
+ import { View } from "svench";
5
+ import { notifications } from "./notifications";
6
+
7
+ export let themes = {
8
+ danger: "#E26D69",
9
+ success: "#84C991",
10
+ warning: "#f0ad4e",
11
+ info: "#5bc0de",
12
+ default: "#aaaaaa",
13
+ }
14
+ </script>
15
+
16
+ ## Notification Store
17
+
18
+ This custom can be used to display toast messages. It has 5 different methods: `send`, `danger`, `warning`, `success`, `info`.
19
+
20
+
21
+ <View name="danger">
22
+ <button on:click={() => notifications.error('This is a danger!')}>Danger</button>
23
+ </View>
24
+ <View name="warning">
25
+ <button on:click={() => notifications.warning('This is a warning!')}>Warning</button>
26
+ </View>
27
+ <View name="success">
28
+ <button on:click={() => notifications.success('This is a success!')}>Success</button>
29
+ </View>
30
+ <View name="info">
31
+ <button on:click={() => notifications.info('This is an info toast!')}>Info</button>
32
+ </View>
33
+
34
+ <div class="notifications">
35
+ {#each $notifications as notification (notification.id)}
36
+ <div
37
+ animate:flip
38
+ class="toast"
39
+ style="background: {themes[notification.type]};"
40
+ transition:fly={{ y: -30 }}>
41
+ <div class="content">{notification.message}</div>
42
+ {#if notification.icon}<i class={notification.icon} />{/if}
43
+ </div>
44
+ {/each}
45
+ </div>
46
+
47
+ <style>
48
+ .notifications {
49
+ position: fixed;
50
+ top: 10px;
51
+ left: 0;
52
+ right: 0;
53
+ margin: 0 auto;
54
+ padding: 0;
55
+ z-index: 9999;
56
+ display: flex;
57
+ flex-direction: column;
58
+ justify-content: flex-start;
59
+ align-items: center;
60
+ pointer-events: none;
61
+ }
62
+
63
+ .toast {
64
+ flex: 0 0 auto;
65
+ margin-bottom: 10px;
66
+ border-radius: var(--border-radius-s);
67
+ /* The toasts now support being auto sized, so this static width could be removed */
68
+ width: 40vw;
69
+ }
70
+
71
+ .content {
72
+ padding: 10px;
73
+ display: block;
74
+ color: white;
75
+ font-weight: 500;
76
+ }
77
+ </style>
78
+
@@ -0,0 +1,37 @@
1
+ import { writable } from "svelte/store"
2
+
3
+ export function createBannerStore() {
4
+ const DEFAULT_CONFIG = {}
5
+
6
+ const banner = writable(DEFAULT_CONFIG)
7
+
8
+ const show = async (
9
+ // eslint-disable-next-line
10
+ config = { message, type, extraButtonText, extraButtonAction, onChange }
11
+ ) => {
12
+ banner.update(store => {
13
+ return {
14
+ ...store,
15
+ ...config,
16
+ }
17
+ })
18
+ }
19
+
20
+ const showStatus = async () => {
21
+ const config = {
22
+ message: "Some systems are experiencing issues",
23
+ type: "negative",
24
+ extraButtonText: "View Status",
25
+ extraButtonAction: () => window.open("https://status.budibase.com/"),
26
+ }
27
+
28
+ await show(config)
29
+ }
30
+
31
+ return {
32
+ subscribe: banner.subscribe,
33
+ showStatus,
34
+ }
35
+ }
36
+
37
+ export const banner = createBannerStore()
@@ -0,0 +1,84 @@
1
+ import { writable } from "svelte/store"
2
+
3
+ const NOTIFICATION_TIMEOUT = 3000
4
+
5
+ export const createNotificationStore = () => {
6
+ const timeoutIds = new Set()
7
+ const _notifications = writable([], () => {
8
+ return () => {
9
+ // clear all the timers
10
+ timeoutIds.forEach(timeoutId => {
11
+ clearTimeout(timeoutId)
12
+ })
13
+ _notifications.set([])
14
+ }
15
+ })
16
+ let block = false
17
+
18
+ const blockNotifications = (timeout = 1000) => {
19
+ block = true
20
+ setTimeout(() => (block = false), timeout)
21
+ }
22
+
23
+ const send = (
24
+ message,
25
+ {
26
+ type = "default",
27
+ icon = "",
28
+ autoDismiss = true,
29
+ action = null,
30
+ wide = false,
31
+ }
32
+ ) => {
33
+ if (block) {
34
+ return
35
+ }
36
+ let _id = id()
37
+ _notifications.update(state => {
38
+ return [
39
+ ...state,
40
+ {
41
+ id: _id,
42
+ type,
43
+ message,
44
+ icon,
45
+ dismissable: !autoDismiss,
46
+ action,
47
+ wide,
48
+ },
49
+ ]
50
+ })
51
+ if (autoDismiss) {
52
+ const timeoutId = setTimeout(() => {
53
+ dismissNotification(_id)
54
+ }, NOTIFICATION_TIMEOUT)
55
+ timeoutIds.add(timeoutId)
56
+ }
57
+ }
58
+
59
+ const dismissNotification = id => {
60
+ _notifications.update(state => {
61
+ return state.filter(n => n.id !== id)
62
+ })
63
+ }
64
+
65
+ const { subscribe } = _notifications
66
+
67
+ return {
68
+ subscribe,
69
+ send,
70
+ info: msg => send(msg, { type: "info", icon: "Info" }),
71
+ error: msg =>
72
+ send(msg, { type: "error", icon: "Alert", autoDismiss: false }),
73
+ warning: msg => send(msg, { type: "warning", icon: "Alert" }),
74
+ success: msg => send(msg, { type: "success", icon: "CheckmarkCircle" }),
75
+ blockNotifications,
76
+ dismiss: dismissNotification,
77
+ }
78
+ }
79
+
80
+ function id() {
81
+ return "_" + Math.random().toString(36).slice(2, 9)
82
+ }
83
+
84
+ export const notifications = createNotificationStore()
@@ -0,0 +1,17 @@
1
+ <script>
2
+ import "@spectrum-css/label/dist/index-vars.css"
3
+ import Badge from "../Badge/Badge.svelte"
4
+ export let value
5
+
6
+ const displayLimit = 5
7
+
8
+ $: badges = Array.isArray(value) ? value.slice(0, displayLimit) : []
9
+ $: leftover = (value?.length ?? 0) - badges.length
10
+ </script>
11
+
12
+ {#each badges as badge}
13
+ <Badge size="S" grey>{badge}</Badge>
14
+ {/each}
15
+ {#if leftover}
16
+ <div>+{leftover} more</div>
17
+ {/if}