@budibase/bbui 1.4.0 → 1.4.2

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 (154) hide show
  1. package/LICENSE +375 -0
  2. package/README.md +19 -17
  3. package/dist/bbui.es.js +14 -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 +75 -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 +41 -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 +60 -0
  70. package/src/Label/Label.svelte +29 -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 +190 -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 +78 -0
  94. package/src/Popover/Popover.svench +121 -0
  95. package/src/ProgressBar/ProgressBar.svelte +67 -0
  96. package/src/ProgressCircle/ProgressCircle.svelte +62 -0
  97. package/src/SideNavigation/Item.svelte +61 -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 +65 -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 +130 -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 +98 -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/Switcher/Switcher.svelte +0 -39
  151. package/src/Switcher/Switcher.svench +0 -25
  152. package/src/actions/autoresize_textarea.js +0 -14
  153. package/src/icons/Contribution.svelte +0 -14
  154. package/src/index.svench.svx +0 -35
@@ -0,0 +1,83 @@
1
+ <script>
2
+ import Icon from "../Icon/Icon.svelte"
3
+ import { createEventDispatcher } from "svelte"
4
+
5
+ export let name
6
+ export let show = false
7
+ export let collapsible = true
8
+
9
+ const dispatch = createEventDispatcher()
10
+ const onHeaderClick = () => {
11
+ if (!collapsible) {
12
+ return
13
+ }
14
+ show = !show
15
+ if (show) {
16
+ dispatch("open")
17
+ }
18
+ }
19
+ </script>
20
+
21
+ <div class="property-group-container">
22
+ <div class="property-group-name" on:click={onHeaderClick}>
23
+ <div class="name">{name}</div>
24
+ {#if collapsible}
25
+ <Icon size="S" name={show ? "Remove" : "Add"} />
26
+ {/if}
27
+ </div>
28
+ <div class="property-panel" class:show={show || !collapsible}>
29
+ <slot />
30
+ </div>
31
+ </div>
32
+
33
+ <style>
34
+ .property-group-container {
35
+ display: flex;
36
+ flex-direction: column;
37
+ justify-content: flex-start;
38
+ align-items: stretch;
39
+ border-bottom: var(--border-light);
40
+ }
41
+
42
+ .property-group-name {
43
+ cursor: pointer;
44
+ display: flex;
45
+ flex-flow: row nowrap;
46
+ flex-direction: row;
47
+ justify-content: space-between;
48
+ align-items: center;
49
+ padding: var(--spacing-m) var(--spacing-xl);
50
+ color: var(--spectrum-global-color-gray-600);
51
+ transition: color 130ms ease-in-out;
52
+ }
53
+ .property-group-name:hover {
54
+ color: var(--spectrum-global-color-gray-900);
55
+ }
56
+
57
+ .name {
58
+ text-align: left;
59
+ font-size: var(--font-size-s);
60
+ font-weight: 600;
61
+ letter-spacing: 0.14px;
62
+ flex: 1 1 auto;
63
+ overflow: hidden;
64
+ text-overflow: ellipsis;
65
+ text-transform: uppercase;
66
+ white-space: nowrap;
67
+ user-select: none;
68
+ }
69
+
70
+ .property-panel {
71
+ display: none;
72
+ padding: var(--spacing-s) var(--spacing-xl) var(--spacing-xl)
73
+ var(--spacing-xl);
74
+ }
75
+
76
+ .show {
77
+ display: flex;
78
+ flex-direction: column;
79
+ justify-content: flex-start;
80
+ align-items: stretch;
81
+ gap: var(--spacing-l);
82
+ }
83
+ </style>
@@ -0,0 +1,28 @@
1
+ <script>
2
+ import "@spectrum-css/divider/dist/index-vars.css"
3
+ export let size = "M"
4
+
5
+ export let vertical = false
6
+ export let noMargin = false
7
+ export let noGrid = false
8
+ </script>
9
+
10
+ <hr
11
+ class:noMargin
12
+ class:noGrid
13
+ class="spectrum-Divider spectrum-Divider--{vertical
14
+ ? 'vertical'
15
+ : 'horizontal'} spectrum-Dialog-divider spectrum-Divider--size{size}"
16
+ />
17
+
18
+ <style>
19
+ hr {
20
+ background: var(--spectrum-global-color-gray-200);
21
+ }
22
+ hr.noMargin {
23
+ margin: 0;
24
+ }
25
+ hr.noGrid {
26
+ grid-area: auto;
27
+ }
28
+ </style>
@@ -0,0 +1,113 @@
1
+ <script>
2
+ import Portal from "svelte-portal"
3
+ import Button from "../Button/Button.svelte"
4
+ import Body from "../Typography/Body.svelte"
5
+ import Heading from "../Typography/Heading.svelte"
6
+
7
+ export let title
8
+ export let fillWidth
9
+ export let left = "314px"
10
+ export let width = "calc(100% - 576px)"
11
+
12
+ let visible = false
13
+
14
+ export function show() {
15
+ if (visible) {
16
+ return
17
+ }
18
+ visible = true
19
+ }
20
+
21
+ export function hide() {
22
+ if (!visible) {
23
+ return
24
+ }
25
+ visible = false
26
+ }
27
+
28
+ const easeInOutQuad = x => {
29
+ return x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2
30
+ }
31
+
32
+ // Use a custom svelte transition here because the built-in slide
33
+ // transition has a horrible overshoot
34
+ const slide = () => {
35
+ return {
36
+ duration: 360,
37
+ css: t => {
38
+ const translation = 100 - Math.round(easeInOutQuad(t) * 100)
39
+ return `transform: translateY(${translation}%);`
40
+ },
41
+ }
42
+ }
43
+ </script>
44
+
45
+ {#if visible}
46
+ <Portal>
47
+ <section
48
+ class:fillWidth
49
+ class="drawer"
50
+ transition:slide|local
51
+ style={`width: ${width}; left: ${left};`}
52
+ >
53
+ <header>
54
+ <div class="text">
55
+ <Heading size="XS">{title}</Heading>
56
+ <Body size="S">
57
+ <slot name="description" />
58
+ </Body>
59
+ </div>
60
+ <div class="buttons">
61
+ <Button secondary quiet on:click={hide}>Cancel</Button>
62
+ <slot name="buttons" />
63
+ </div>
64
+ </header>
65
+ <slot name="body" />
66
+ </section>
67
+ </Portal>
68
+ {/if}
69
+
70
+ <style>
71
+ .buttons {
72
+ display: flex;
73
+ gap: var(--spacing-m);
74
+ }
75
+
76
+ .drawer {
77
+ position: absolute;
78
+ bottom: 0;
79
+ background: var(--background);
80
+ border-top: var(--border-light);
81
+ z-index: 3;
82
+ }
83
+
84
+ .fillWidth {
85
+ left: 260px !important;
86
+ width: calc(100% - 260px) !important;
87
+ }
88
+
89
+ header {
90
+ display: flex;
91
+ justify-content: space-between;
92
+ align-items: center;
93
+ border-bottom: var(--border-light);
94
+ padding: var(--spacing-l) var(--spacing-xl);
95
+ gap: var(--spacing-xl);
96
+ }
97
+
98
+ .text {
99
+ display: flex;
100
+ flex-direction: column;
101
+ justify-content: center;
102
+ align-items: flex-start;
103
+ gap: var(--spacing-xs);
104
+ }
105
+
106
+ .buttons {
107
+ display: flex;
108
+ flex-direction: row;
109
+ justify-content: flex-start;
110
+ align-items: center;
111
+ gap: var(--spacing-m);
112
+ }
113
+ </style>
@@ -0,0 +1,42 @@
1
+ <script>
2
+ import { View } from "svench";
3
+ import Button from "../Button/Button.svelte";
4
+ import Drawer from "./Drawer.svelte";
5
+
6
+ let drawer1;
7
+ let drawer2;
8
+ </script>
9
+
10
+ <style>
11
+ .drawer {
12
+ height: 40vh;
13
+ }
14
+ </style>
15
+
16
+ <View name="Basic Bottom Drawer">
17
+ <Button primary on:click={drawer1.show}>Open Drawer</Button>
18
+ <Drawer
19
+ bind:this={drawer1}
20
+ title="A basic Drawer with some text"
21
+ on:close={() => alert('You closed the drawer!')}>
22
+ <p slot="body">
23
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Placeat,
24
+ architecto assumenda! Quia harum hic numquam, soluta maiores facere
25
+ explicabo vero obcaecati voluptas, qui placeat ad, dolorem recusandae
26
+ labore quos? Nisi!
27
+ </p>
28
+ </Drawer>
29
+ </View>
30
+ <View name="Basic Bottom Drawer">
31
+ <Button blue on:click={drawer2.show}>Open Drawer</Button>
32
+ <Drawer
33
+ bind:this={drawer2}
34
+ title={'Actions'}
35
+ on:close={() => alert('You closed the drawer!')}>
36
+ <heading slot="buttons">
37
+ <Button thin blue on:click={drawer2.hide}>Save</Button>
38
+ </heading>
39
+ <div slot="description">This describes the drawer!</div>
40
+ <div class="drawer" slot="body">Some content here</div>
41
+ </Drawer>
42
+ </View>
@@ -0,0 +1,46 @@
1
+ <div class="drawer-contents">
2
+ <div class:no-sidebar={!$$slots.sidebar} class="container">
3
+ {#if $$slots.sidebar}
4
+ <div class="sidebar">
5
+ <slot name="sidebar" />
6
+ </div>
7
+ {/if}
8
+ <div class="main">
9
+ <slot />
10
+ </div>
11
+ </div>
12
+ </div>
13
+
14
+ <style>
15
+ .drawer-contents {
16
+ height: 40vh;
17
+ overflow-y: auto;
18
+ }
19
+ .container {
20
+ height: 100%;
21
+ display: grid;
22
+ grid-template-columns: 320px 1fr;
23
+ }
24
+ .no-sidebar {
25
+ grid-template-columns: 1fr;
26
+ }
27
+ .sidebar {
28
+ border-right: var(--border-light);
29
+ overflow: auto;
30
+ padding: var(--spacing-xl);
31
+ scrollbar-width: none;
32
+ }
33
+ .sidebar::-webkit-scrollbar {
34
+ display: none;
35
+ }
36
+ .main {
37
+ font-family: var(--font-sans);
38
+ padding: var(--spacing-xl);
39
+ }
40
+ .main :global(textarea) {
41
+ min-height: 200px;
42
+ }
43
+ .main :global(p) {
44
+ margin: 0;
45
+ }
46
+ </style>
@@ -0,0 +1,23 @@
1
+ <script>
2
+ import Field from "./Field.svelte"
3
+ import Checkbox from "./Core/Checkbox.svelte"
4
+ import { createEventDispatcher } from "svelte"
5
+
6
+ export let value = null
7
+ export let label = null
8
+ export let labelPosition = "above"
9
+ export let text = null
10
+ export let disabled = false
11
+ export let error = null
12
+ export let size = "M"
13
+
14
+ const dispatch = createEventDispatcher()
15
+ const onChange = e => {
16
+ value = e.detail
17
+ dispatch("change", e.detail)
18
+ }
19
+ </script>
20
+
21
+ <Field {label} {labelPosition} {error}>
22
+ <Checkbox {error} {disabled} {text} {value} {size} on:change={onChange} />
23
+ </Field>
@@ -0,0 +1,45 @@
1
+ <script>
2
+ import Field from "./Field.svelte"
3
+ import Combobox from "./Core/Combobox.svelte"
4
+ import { createEventDispatcher } from "svelte"
5
+
6
+ export let value = null
7
+ export let label = undefined
8
+ export let disabled = false
9
+ export let readonly = false
10
+ export let labelPosition = "above"
11
+ export let error = null
12
+ export let placeholder = "Choose an option or type"
13
+ export let options = []
14
+ export let getOptionLabel = option => extractProperty(option, "label")
15
+ export let getOptionValue = option => extractProperty(option, "value")
16
+
17
+ const dispatch = createEventDispatcher()
18
+ const onChange = e => {
19
+ value = e.detail
20
+ dispatch("change", e.detail)
21
+ }
22
+ const extractProperty = (value, property) => {
23
+ if (value && typeof value === "object") {
24
+ return value[property]
25
+ }
26
+ return value
27
+ }
28
+ </script>
29
+
30
+ <Field {label} {labelPosition} {error}>
31
+ <Combobox
32
+ {error}
33
+ {disabled}
34
+ {value}
35
+ {options}
36
+ {placeholder}
37
+ {readonly}
38
+ {getOptionLabel}
39
+ {getOptionValue}
40
+ on:change={onChange}
41
+ on:pick
42
+ on:type
43
+ on:blur
44
+ />
45
+ </Field>
@@ -0,0 +1,69 @@
1
+ <script>
2
+ import "@spectrum-css/checkbox/dist/index-vars.css"
3
+ import "@spectrum-css/fieldgroup/dist/index-vars.css"
4
+ import { createEventDispatcher } from "svelte"
5
+
6
+ export let value = false
7
+ export let error = null
8
+ export let id = null
9
+ export let text = null
10
+ export let disabled = false
11
+ export let size
12
+
13
+ const dispatch = createEventDispatcher()
14
+ const onChange = event => {
15
+ dispatch("change", event.target.checked)
16
+ }
17
+
18
+ $: sizeClass = `spectrum-Checkbox--size${size || "M"}`
19
+ </script>
20
+
21
+ <label
22
+ class="spectrum-Checkbox spectrum-Checkbox--emphasized {sizeClass}"
23
+ class:is-invalid={!!error}
24
+ class:checked={value}
25
+ >
26
+ <input
27
+ checked={value}
28
+ {disabled}
29
+ on:change={onChange}
30
+ type="checkbox"
31
+ class="spectrum-Checkbox-input"
32
+ {id}
33
+ />
34
+ <span class="spectrum-Checkbox-box">
35
+ <svg
36
+ class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark"
37
+ focusable="false"
38
+ aria-hidden="true"
39
+ >
40
+ <use xlink:href="#spectrum-css-icon-Checkmark100" />
41
+ </svg>
42
+ <svg
43
+ class="spectrum-Icon spectrum-UIIcon-Dash100 spectrum-Checkbox-partialCheckmark"
44
+ focusable="false"
45
+ aria-hidden="true"
46
+ >
47
+ <use xlink:href="#spectrum-css-icon-Dash100" />
48
+ </svg>
49
+ </span>
50
+ {#if text}
51
+ <span class="spectrum-Checkbox-label">{text}</span>
52
+ {/if}
53
+ </label>
54
+
55
+ <style>
56
+ .spectrum-Checkbox--sizeL .spectrum-Checkbox-checkmark {
57
+ transform: scale(1.1);
58
+ left: 55%;
59
+ top: 55%;
60
+ }
61
+ .spectrum-Checkbox--sizeXL .spectrum-Checkbox-checkmark {
62
+ transform: scale(1.2);
63
+ left: 60%;
64
+ top: 60%;
65
+ }
66
+ .spectrum-Checkbox-input {
67
+ opacity: 0;
68
+ }
69
+ </style>
@@ -0,0 +1,68 @@
1
+ <script>
2
+ import "@spectrum-css/fieldgroup/dist/index-vars.css"
3
+ import "@spectrum-css/radio/dist/index-vars.css"
4
+ import { createEventDispatcher } from "svelte"
5
+
6
+ export let direction = "vertical"
7
+ export let value = []
8
+ export let options = []
9
+ export let error = null
10
+ export let disabled = false
11
+ export let getOptionLabel = option => option
12
+ export let getOptionValue = option => option
13
+
14
+ const dispatch = createEventDispatcher()
15
+ const onChange = e => {
16
+ let tempValue = value
17
+ let isChecked = e.target.checked
18
+ if (!tempValue.includes(e.target.value) && isChecked) {
19
+ tempValue.push(e.target.value)
20
+ }
21
+ value = tempValue
22
+ dispatch(
23
+ "change",
24
+ tempValue.filter(val => val !== e.target.value || isChecked)
25
+ )
26
+ }
27
+ </script>
28
+
29
+ <div class={`spectrum-FieldGroup spectrum-FieldGroup--${direction}`}>
30
+ {#if options && Array.isArray(options)}
31
+ {#each options as option}
32
+ <div
33
+ title={getOptionLabel(option)}
34
+ class="spectrum-Checkbox spectrum-FieldGroup-item"
35
+ class:is-invalid={!!error}
36
+ >
37
+ <label
38
+ class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-FieldGroup-item"
39
+ >
40
+ <input
41
+ on:change={onChange}
42
+ value={getOptionValue(option)}
43
+ type="checkbox"
44
+ class="spectrum-Checkbox-input"
45
+ {disabled}
46
+ checked={value.includes(getOptionValue(option))}
47
+ />
48
+ <span class="spectrum-Checkbox-box">
49
+ <svg
50
+ class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark"
51
+ focusable="false"
52
+ aria-hidden="true"
53
+ >
54
+ <use xlink:href="#spectrum-css-icon-Checkmark100" />
55
+ </svg>
56
+ </span>
57
+ <span class="spectrum-Checkbox-label">{getOptionLabel(option)}</span>
58
+ </label>
59
+ </div>
60
+ {/each}
61
+ {/if}
62
+ </div>
63
+
64
+ <style>
65
+ .spectrum-Checkbox-input {
66
+ opacity: 0;
67
+ }
68
+ </style>
@@ -0,0 +1,142 @@
1
+ <script>
2
+ import "@spectrum-css/inputgroup/dist/index-vars.css"
3
+ import "@spectrum-css/popover/dist/index-vars.css"
4
+ import "@spectrum-css/menu/dist/index-vars.css"
5
+ import { fly } from "svelte/transition"
6
+ import { createEventDispatcher } from "svelte"
7
+
8
+ export let value = null
9
+ export let id = null
10
+ export let placeholder = "Choose an option or type"
11
+ export let disabled = false
12
+ export let readonly = false
13
+ export let error = null
14
+ export let options = []
15
+ export let getOptionLabel = option => option
16
+ export let getOptionValue = option => option
17
+
18
+ const dispatch = createEventDispatcher()
19
+ let open = false
20
+ let focus = false
21
+
22
+ const selectOption = value => {
23
+ dispatch("change", value)
24
+ open = false
25
+ }
26
+
27
+ const onType = e => {
28
+ const value = e.target.value
29
+ dispatch("type", value)
30
+ selectOption(value)
31
+ }
32
+
33
+ const onPick = value => {
34
+ dispatch("pick", value)
35
+ selectOption(value)
36
+ }
37
+ </script>
38
+
39
+ <div
40
+ class="spectrum-InputGroup"
41
+ class:is-focused={open || focus}
42
+ class:is-invalid={!!error}
43
+ class:is-disabled={disabled}
44
+ >
45
+ <div
46
+ class="spectrum-Textfield spectrum-InputGroup-textfield"
47
+ class:is-invalid={!!error}
48
+ class:is-disabled={disabled}
49
+ class:is-focused={open || focus}
50
+ >
51
+ <input
52
+ {id}
53
+ type="text"
54
+ on:focus={() => (focus = true)}
55
+ on:blur={() => {
56
+ focus = false
57
+ dispatch("blur")
58
+ }}
59
+ on:change={onType}
60
+ value={value || ""}
61
+ placeholder={placeholder || ""}
62
+ {disabled}
63
+ {readonly}
64
+ class="spectrum-Textfield-input spectrum-InputGroup-input"
65
+ />
66
+ </div>
67
+ <button
68
+ class="spectrum-Picker spectrum-Picker--sizeM spectrum-InputGroup-button"
69
+ tabindex="-1"
70
+ aria-haspopup="true"
71
+ {disabled}
72
+ on:click={() => (open = true)}
73
+ >
74
+ <svg
75
+ class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon spectrum-InputGroup-icon"
76
+ focusable="false"
77
+ aria-hidden="true"
78
+ >
79
+ <use xlink:href="#spectrum-css-icon-Chevron100" />
80
+ </svg>
81
+ </button>
82
+ {#if open}
83
+ <div class="overlay" on:mousedown|self={() => (open = false)} />
84
+ <div
85
+ transition:fly={{ y: -20, duration: 200 }}
86
+ class="spectrum-Popover spectrum-Popover--bottom is-open"
87
+ >
88
+ <ul class="spectrum-Menu" role="listbox">
89
+ {#if options && Array.isArray(options)}
90
+ {#each options as option}
91
+ <li
92
+ class="spectrum-Menu-item"
93
+ class:is-selected={getOptionValue(option) === value}
94
+ role="option"
95
+ aria-selected="true"
96
+ tabindex="0"
97
+ on:click={() => onPick(getOptionValue(option))}
98
+ >
99
+ <span class="spectrum-Menu-itemLabel"
100
+ >{getOptionLabel(option)}</span
101
+ >
102
+ <svg
103
+ class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
104
+ focusable="false"
105
+ aria-hidden="true"
106
+ >
107
+ <use xlink:href="#spectrum-css-icon-Checkmark100" />
108
+ </svg>
109
+ </li>
110
+ {/each}
111
+ {/if}
112
+ </ul>
113
+ </div>
114
+ {/if}
115
+ </div>
116
+
117
+ <style>
118
+ .spectrum-InputGroup {
119
+ min-width: 0;
120
+ width: 100%;
121
+ }
122
+ .spectrum-Textfield {
123
+ width: 100%;
124
+ }
125
+ .spectrum-Textfield-input {
126
+ width: 0;
127
+ }
128
+ .overlay {
129
+ position: fixed;
130
+ top: 0;
131
+ left: 0;
132
+ width: 100vw;
133
+ height: 100vh;
134
+ z-index: 999;
135
+ }
136
+ .spectrum-Popover {
137
+ max-height: 240px;
138
+ width: 100%;
139
+ z-index: 999;
140
+ top: 100%;
141
+ }
142
+ </style>