@budibase/bbui 0.0.1

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 (149) hide show
  1. package/LICENSE +375 -0
  2. package/README.md +42 -0
  3. package/dist/bbui.es.js +8 -0
  4. package/dist/bbui.es.js.map +1 -0
  5. package/package.json +94 -0
  6. package/src/Accordion/Accordion.svelte +58 -0
  7. package/src/ActionButton/ActionButton.svelte +132 -0
  8. package/src/ActionGroup/ActionGroup.svelte +26 -0
  9. package/src/ActionMenu/ActionMenu.svelte +43 -0
  10. package/src/Actions/ClickOutside.svench.svx +30 -0
  11. package/src/Actions/PositionDropdown.svench.svx +81 -0
  12. package/src/Actions/autoresize_textarea.js +14 -0
  13. package/src/Actions/click_outside.js +76 -0
  14. package/src/Actions/position_dropdown.js +116 -0
  15. package/src/Avatar/Avatar.svelte +63 -0
  16. package/src/Badge/Badge.svelte +42 -0
  17. package/src/Banner/Banner.svelte +72 -0
  18. package/src/Banner/BannerDisplay.svelte +41 -0
  19. package/src/Button/Button.svelte +118 -0
  20. package/src/Button/Button.svench +138 -0
  21. package/src/ButtonGroup/ButtonGroup.svelte +30 -0
  22. package/src/ClearButton/ClearButton.svelte +19 -0
  23. package/src/ColorPicker/ColorPicker.svelte +304 -0
  24. package/src/DetailSummary/DetailSummary.svelte +92 -0
  25. package/src/Divider/Divider.svelte +28 -0
  26. package/src/Drawer/Drawer.svelte +113 -0
  27. package/src/Drawer/Drawer.svench +42 -0
  28. package/src/Drawer/DrawerContent.svelte +45 -0
  29. package/src/FancyForm/FancyButton.svelte +30 -0
  30. package/src/FancyForm/FancyButtonRadio.svelte +70 -0
  31. package/src/FancyForm/FancyCheckbox.svelte +53 -0
  32. package/src/FancyForm/FancyField.svelte +126 -0
  33. package/src/FancyForm/FancyFieldLabel.svelte +25 -0
  34. package/src/FancyForm/FancyForm.svelte +40 -0
  35. package/src/FancyForm/FancyInput.svelte +109 -0
  36. package/src/FancyForm/FancySelect.svelte +147 -0
  37. package/src/FancyForm/index.js +6 -0
  38. package/src/Form/Checkbox.svelte +23 -0
  39. package/src/Form/Combobox.svelte +45 -0
  40. package/src/Form/Core/Checkbox.svelte +69 -0
  41. package/src/Form/Core/CheckboxGroup.svelte +68 -0
  42. package/src/Form/Core/Combobox.svelte +142 -0
  43. package/src/Form/Core/DatePicker.svelte +265 -0
  44. package/src/Form/Core/Dropzone.svelte +482 -0
  45. package/src/Form/Core/EnvDropdown.svelte +276 -0
  46. package/src/Form/Core/File.svelte +115 -0
  47. package/src/Form/Core/InputDropdown.svelte +235 -0
  48. package/src/Form/Core/Multiselect.svelte +99 -0
  49. package/src/Form/Core/Picker.svelte +314 -0
  50. package/src/Form/Core/PickerDropdown.svelte +431 -0
  51. package/src/Form/Core/RadioGroup.svelte +65 -0
  52. package/src/Form/Core/RichTextField.svelte +42 -0
  53. package/src/Form/Core/Search.svelte +105 -0
  54. package/src/Form/Core/Select.svelte +90 -0
  55. package/src/Form/Core/Slider.svelte +86 -0
  56. package/src/Form/Core/Stepper.svelte +172 -0
  57. package/src/Form/Core/Switch.svelte +35 -0
  58. package/src/Form/Core/TextArea.svelte +78 -0
  59. package/src/Form/Core/TextField.svelte +115 -0
  60. package/src/Form/Core/index.js +16 -0
  61. package/src/Form/DatePicker.svelte +46 -0
  62. package/src/Form/Dropzone.svelte +44 -0
  63. package/src/Form/EnvDropdown.svelte +50 -0
  64. package/src/Form/Field.svelte +42 -0
  65. package/src/Form/FieldLabel.svelte +32 -0
  66. package/src/Form/File.svelte +37 -0
  67. package/src/Form/Input.svelte +45 -0
  68. package/src/Form/InputDropdown.svelte +53 -0
  69. package/src/Form/Multiselect.svelte +49 -0
  70. package/src/Form/PickerDropdown.svelte +131 -0
  71. package/src/Form/RadioGroup.svelte +42 -0
  72. package/src/Form/RichTextField.svelte +36 -0
  73. package/src/Form/Search.svelte +36 -0
  74. package/src/Form/Select.svelte +67 -0
  75. package/src/Form/Slider.svelte +24 -0
  76. package/src/Form/Stepper.svelte +45 -0
  77. package/src/Form/TextArea.svelte +34 -0
  78. package/src/Form/Toggle.svelte +22 -0
  79. package/src/Icon/Icon.svelte +94 -0
  80. package/src/Icon/IconAvatar.svelte +61 -0
  81. package/src/IconPicker/IconPicker.svelte +184 -0
  82. package/src/IconSideNav/IconSideNav.svelte +14 -0
  83. package/src/IconSideNav/IconSideNavItem.svelte +56 -0
  84. package/src/InlineAlert/InlineAlert.svelte +63 -0
  85. package/src/Input/CopyInput.svelte +59 -0
  86. package/src/Label/Label.svelte +31 -0
  87. package/src/Layout/Layout.svelte +94 -0
  88. package/src/Layout/Page.svelte +101 -0
  89. package/src/Link/Link.svelte +27 -0
  90. package/src/List/List.svelte +28 -0
  91. package/src/List/ListItem.svelte +93 -0
  92. package/src/Markdown/MarkdownEditor.svelte +60 -0
  93. package/src/Markdown/MarkdownViewer.svelte +70 -0
  94. package/src/Markdown/SpectrumMDE.svelte +184 -0
  95. package/src/Menu/Item.svelte +94 -0
  96. package/src/Menu/Menu.svelte +7 -0
  97. package/src/Menu/Menu.svench +19 -0
  98. package/src/Menu/Section.svelte +10 -0
  99. package/src/Menu/Separator.svelte +1 -0
  100. package/src/Modal/Content.svelte +6 -0
  101. package/src/Modal/CustomContent.svelte +37 -0
  102. package/src/Modal/Modal.svelte +178 -0
  103. package/src/Modal/Modal.svench +116 -0
  104. package/src/Modal/ModalContent.svelte +190 -0
  105. package/src/Modal/QuizModal.svelte +53 -0
  106. package/src/Notification/Notification.svelte +74 -0
  107. package/src/Notification/NotificationDisplay.svelte +43 -0
  108. package/src/Pagination/Pagination.svelte +57 -0
  109. package/src/Popover/Popover.svelte +95 -0
  110. package/src/Popover/Popover.svench +120 -0
  111. package/src/ProgressBar/ProgressBar.svelte +67 -0
  112. package/src/ProgressCircle/ProgressCircle.svelte +62 -0
  113. package/src/SideNavigation/Item.svelte +59 -0
  114. package/src/SideNavigation/Navigation.svelte +12 -0
  115. package/src/StatusLight/StatusLight.svelte +80 -0
  116. package/src/Stores/Notifications.svench.svx +78 -0
  117. package/src/Stores/banner.js +65 -0
  118. package/src/Stores/notifications.js +84 -0
  119. package/src/Table/ArrayRenderer.svelte +18 -0
  120. package/src/Table/AttachmentRenderer.svelte +73 -0
  121. package/src/Table/BoldRenderer.svelte +15 -0
  122. package/src/Table/BooleanRenderer.svelte +42 -0
  123. package/src/Table/CellRenderer.svelte +70 -0
  124. package/src/Table/CodeRenderer.svelte +14 -0
  125. package/src/Table/DateTimeRenderer.svelte +29 -0
  126. package/src/Table/InternalRenderer.svelte +24 -0
  127. package/src/Table/RelationshipRenderer.svelte +35 -0
  128. package/src/Table/SelectEditRenderer.svelte +28 -0
  129. package/src/Table/StringRenderer.svelte +22 -0
  130. package/src/Table/Table.svelte +657 -0
  131. package/src/Table/index.js +1 -0
  132. package/src/Tabs/Tab.svelte +88 -0
  133. package/src/Tabs/Tabs.svelte +130 -0
  134. package/src/Tags/Tag.svelte +43 -0
  135. package/src/Tags/Tags.svelte +17 -0
  136. package/src/Tooltip/Tooltip.svelte +34 -0
  137. package/src/Tooltip/TooltipWrapper.svelte +60 -0
  138. package/src/TreeView/Item.svelte +41 -0
  139. package/src/TreeView/Tree.svelte +16 -0
  140. package/src/Typography/Body.svelte +22 -0
  141. package/src/Typography/Code.svelte +10 -0
  142. package/src/Typography/Detail.svelte +19 -0
  143. package/src/Typography/Heading.svelte +24 -0
  144. package/src/bbui.css +118 -0
  145. package/src/context.js +4 -0
  146. package/src/helpers.js +116 -0
  147. package/src/index.js +109 -0
  148. package/src/spectrum-icons-rollup.js +31 -0
  149. package/src/spectrum-icons-vite.js +31 -0
@@ -0,0 +1,70 @@
1
+ <script>
2
+ import { createEventDispatcher } from "svelte"
3
+ import FancyField from "./FancyField.svelte"
4
+ import FancyFieldLabel from "./FancyFieldLabel.svelte"
5
+ import ActionButton from "../ActionButton/ActionButton.svelte"
6
+
7
+ export let label
8
+ export let value
9
+ export let disabled = false
10
+ export let error = null
11
+ export let validate = null
12
+ export let options = []
13
+ export let getOptionLabel = option => extractProperty(option, "label")
14
+ export let getOptionValue = option => extractProperty(option, "value")
15
+
16
+ const dispatch = createEventDispatcher()
17
+
18
+ $: placeholder = !value
19
+
20
+ const extractProperty = (value, property) => {
21
+ if (value && typeof value === "object") {
22
+ return value[property]
23
+ }
24
+ return value
25
+ }
26
+
27
+ const onChange = newValue => {
28
+ dispatch("change", newValue)
29
+ value = newValue
30
+ if (validate) {
31
+ error = validate(newValue)
32
+ }
33
+ }
34
+ </script>
35
+
36
+ <FancyField {error} {value} {validate} {disabled} autoHeight>
37
+ {#if label}
38
+ <FancyFieldLabel placeholder={false}>{label}</FancyFieldLabel>
39
+ {/if}
40
+
41
+ <div class="options">
42
+ {#each options as option}
43
+ <ActionButton
44
+ selected={getOptionValue(option) === value}
45
+ on:click={() => onChange(getOptionValue(option))}
46
+ >
47
+ {getOptionLabel(option)}
48
+ </ActionButton>
49
+ {/each}
50
+ </div>
51
+ </FancyField>
52
+
53
+ <style>
54
+ .options {
55
+ margin-top: 34px;
56
+ margin-bottom: 14px;
57
+ display: flex;
58
+ flex-direction: row;
59
+ justify-content: flex-start;
60
+ align-items: center;
61
+ gap: 6px;
62
+ flex-wrap: wrap;
63
+ }
64
+ .options :global(.spectrum-ActionButton) {
65
+ font-size: 15px;
66
+ line-height: 17px;
67
+ height: auto;
68
+ padding: 6px 10px;
69
+ }
70
+ </style>
@@ -0,0 +1,53 @@
1
+ <script>
2
+ import { createEventDispatcher } from "svelte"
3
+ import FancyField from "./FancyField.svelte"
4
+ import Checkbox from "../Form/Core/Checkbox.svelte"
5
+
6
+ export let value
7
+ export let text
8
+ export let disabled = false
9
+ export let error = null
10
+ export let validate = null
11
+
12
+ const dispatch = createEventDispatcher()
13
+
14
+ const onChange = () => {
15
+ const newValue = !value
16
+ dispatch("change", newValue)
17
+ value = newValue
18
+ if (validate) {
19
+ error = validate(newValue)
20
+ }
21
+ }
22
+ </script>
23
+
24
+ <FancyField {error} {value} {validate} {disabled} clickable on:click={onChange}>
25
+ <span>
26
+ <Checkbox {disabled} {value} />
27
+ </span>
28
+ <div class="text">
29
+ {#if text}
30
+ {text}
31
+ {/if}
32
+ <slot />
33
+ </div>
34
+ </FancyField>
35
+
36
+ <style>
37
+ span {
38
+ pointer-events: none;
39
+ }
40
+ .text {
41
+ font-size: 15px;
42
+ line-height: 17px;
43
+ overflow: hidden;
44
+ text-overflow: ellipsis;
45
+ display: -webkit-box;
46
+ -webkit-line-clamp: 2;
47
+ line-clamp: 2;
48
+ -webkit-box-orient: vertical;
49
+ }
50
+ .text > :global(*) {
51
+ font-size: inherit !important;
52
+ }
53
+ </style>
@@ -0,0 +1,126 @@
1
+ <script>
2
+ import Icon from "../Icon/Icon.svelte"
3
+ import { getContext, onMount } from "svelte"
4
+ import { slide } from "svelte/transition"
5
+
6
+ export let disabled = false
7
+ export let error = null
8
+ export let focused = false
9
+ export let clickable = false
10
+ export let validate
11
+ export let value
12
+ export let ref
13
+ export let autoHeight
14
+
15
+ const formContext = getContext("fancy-form")
16
+ const id = Math.random()
17
+ const API = {
18
+ validate: () => {
19
+ if (validate) {
20
+ error = validate(value)
21
+ }
22
+ return !error
23
+ },
24
+ }
25
+
26
+ onMount(() => {
27
+ if (formContext) {
28
+ formContext.registerField(id, API)
29
+ }
30
+ return () => {
31
+ if (formContext) {
32
+ formContext.unregisterField(id)
33
+ }
34
+ }
35
+ })
36
+ </script>
37
+
38
+ <div
39
+ bind:this={ref}
40
+ class="fancy-field"
41
+ class:error
42
+ class:disabled
43
+ class:focused
44
+ class:clickable
45
+ class:auto-height={autoHeight}
46
+ >
47
+ <div class="content" on:click>
48
+ <div class="field">
49
+ <slot />
50
+ </div>
51
+ {#if error}
52
+ <div class="error-icon">
53
+ <Icon name="Alert" />
54
+ </div>
55
+ {/if}
56
+ </div>
57
+ {#if error}
58
+ <div transition:slide|local={{ duration: 130 }} class="error-message">
59
+ {error}
60
+ </div>
61
+ {/if}
62
+ </div>
63
+
64
+ <style>
65
+ .fancy-field {
66
+ max-width: 400px;
67
+ background: var(--spectrum-global-color-gray-75);
68
+ border: 1px solid var(--spectrum-global-color-gray-300);
69
+ border-radius: 4px;
70
+ box-sizing: border-box;
71
+ transition: border-color 130ms ease-out, background 130ms ease-out,
72
+ background 130ms ease-out;
73
+ color: var(--spectrum-global-color-gray-800);
74
+ }
75
+ .fancy-field:hover {
76
+ border-color: var(--spectrum-global-color-gray-400);
77
+ }
78
+ .fancy-field.clickable:hover {
79
+ background: var(--spectrum-global-color-gray-200);
80
+ cursor: pointer;
81
+ }
82
+ .fancy-field.focused {
83
+ border-color: var(--spectrum-global-color-blue-400);
84
+ }
85
+ .fancy-field.error {
86
+ border-color: var(--spectrum-global-color-red-400);
87
+ }
88
+ .fancy-field.disabled {
89
+ background: var(--spectrum-global-color-gray-200);
90
+ color: var(--spectrum-global-color-gray-400);
91
+ border: 1px solid var(--spectrum-global-color-gray-300);
92
+ pointer-events: none;
93
+ }
94
+ .content {
95
+ position: relative;
96
+ height: 64px;
97
+ padding: 0 16px;
98
+ }
99
+ .fancy-field.auto-height .content {
100
+ height: auto;
101
+ }
102
+ .content,
103
+ .field {
104
+ display: flex;
105
+ flex-direction: row;
106
+ justify-content: flex-start;
107
+ align-items: center;
108
+ gap: 16px;
109
+ }
110
+ .field {
111
+ flex: 1 1 auto;
112
+ }
113
+ .error-message {
114
+ background: var(--spectrum-global-color-red-400);
115
+ color: white;
116
+ font-size: 14px;
117
+ padding: 6px 16px;
118
+ font-weight: 500;
119
+ }
120
+ .error-icon {
121
+ flex: 0 0 auto;
122
+ }
123
+ .error-icon :global(.spectrum-Icon) {
124
+ fill: var(--spectrum-global-color-red-400);
125
+ }
126
+ </style>
@@ -0,0 +1,25 @@
1
+ <script>
2
+ export let placeholder = true
3
+ </script>
4
+
5
+ <div class:placeholder>
6
+ <slot />
7
+ </div>
8
+
9
+ <style>
10
+ div {
11
+ font-size: 14px;
12
+ line-height: 15px;
13
+ font-weight: 500;
14
+ position: absolute;
15
+ top: 10px;
16
+ color: var(--spectrum-global-color-gray-600);
17
+ transition: font-size 130ms ease-out, top 130ms ease-out,
18
+ transform 130ms ease-out;
19
+ }
20
+ div.placeholder {
21
+ top: 50%;
22
+ font-size: 15px;
23
+ transform: translateY(-50%);
24
+ }
25
+ </style>
@@ -0,0 +1,40 @@
1
+ <script>
2
+ import { setContext } from "svelte"
3
+
4
+ let fields = {}
5
+
6
+ setContext("fancy-form", {
7
+ registerField: (id, api) => {
8
+ fields = { ...fields, [id]: api }
9
+ },
10
+ unregisterField: id => {
11
+ delete fields[id]
12
+ fields = fields
13
+ },
14
+ })
15
+
16
+ export const validate = () => {
17
+ let valid = true
18
+ Object.values(fields).forEach(api => {
19
+ if (!api.validate()) {
20
+ valid = false
21
+ }
22
+ })
23
+ return valid
24
+ }
25
+ </script>
26
+
27
+ <div class="fancy-form">
28
+ <slot />
29
+ </div>
30
+
31
+ <style>
32
+ .fancy-form :global(.fancy-field:not(:first-of-type)) {
33
+ border-top-left-radius: 0;
34
+ border-top-right-radius: 0;
35
+ }
36
+ .fancy-form :global(.fancy-field:not(:last-of-type)) {
37
+ border-bottom-left-radius: 0;
38
+ border-bottom-right-radius: 0;
39
+ }
40
+ </style>
@@ -0,0 +1,109 @@
1
+ <script>
2
+ import { createEventDispatcher, onMount } from "svelte"
3
+ import FancyField from "./FancyField.svelte"
4
+ import FancyFieldLabel from "./FancyFieldLabel.svelte"
5
+ import { fade } from "svelte/transition"
6
+
7
+ export let label
8
+ export let value
9
+ export let type = "text"
10
+ export let disabled = false
11
+ export let error = null
12
+ export let validate = null
13
+ export let suffix = null
14
+
15
+ const dispatch = createEventDispatcher()
16
+
17
+ let ref
18
+ let focused = false
19
+ let autofilled = false
20
+
21
+ $: placeholder = !autofilled && !focused && !value
22
+
23
+ const onChange = e => {
24
+ const newValue = e.target.value
25
+ dispatch("change", newValue)
26
+ value = newValue
27
+ if (validate) {
28
+ error = validate(newValue)
29
+ }
30
+ }
31
+
32
+ onMount(() => {
33
+ // Start watching for autofill every 100ms
34
+ const interval = setInterval(() => {
35
+ autofilled = ref?.matches(":-webkit-autofill")
36
+ if (autofilled) {
37
+ clearInterval(interval)
38
+ }
39
+ }, 100)
40
+
41
+ // Give up after 2 seconds and assume autofill has not been used
42
+ const timeout = setTimeout(() => {
43
+ clearInterval(interval)
44
+ }, 2000)
45
+
46
+ // Cleanup
47
+ return () => {
48
+ clearInterval(interval)
49
+ clearTimeout(timeout)
50
+ }
51
+ })
52
+ </script>
53
+
54
+ <FancyField {error} {value} {validate} {disabled} {focused}>
55
+ {#if label}
56
+ <FancyFieldLabel {placeholder}>{label}</FancyFieldLabel>
57
+ {/if}
58
+ <input
59
+ {disabled}
60
+ value={value || ""}
61
+ type={type || "text"}
62
+ on:input={onChange}
63
+ on:focus={() => (focused = true)}
64
+ on:blur={() => (focused = false)}
65
+ class:placeholder
66
+ bind:this={ref}
67
+ />
68
+ {#if suffix && !placeholder}
69
+ <div in:fade|local={{ duration: 130 }} class="suffix">{suffix}</div>
70
+ {/if}
71
+ </FancyField>
72
+
73
+ <style>
74
+ input {
75
+ width: 100%;
76
+ transition: transform 130ms ease-out;
77
+ transform: translateY(9px);
78
+ background: transparent;
79
+ font-size: 15px;
80
+ line-height: 17px;
81
+ font-family: var(--font-sans);
82
+ color: var(--spectrum-global-color-gray-900);
83
+ outline: none;
84
+ border: none;
85
+ padding: 0;
86
+ margin: 0;
87
+ }
88
+ input.placeholder {
89
+ transform: translateY(0);
90
+ position: absolute;
91
+ top: 0;
92
+ left: 0;
93
+ height: 100%;
94
+ }
95
+ .suffix {
96
+ color: var(--spectrum-global-color-gray-600);
97
+ transform: translateY(9px);
98
+ font-size: 15px;
99
+ line-height: 17px;
100
+ font-family: var(--font-sans);
101
+ }
102
+ input:-webkit-autofill {
103
+ border-radius: 2px;
104
+ -webkit-box-shadow: 0 0 0 100px var(--spectrum-global-color-gray-300) inset;
105
+ -webkit-text-fill-color: var(--spectrum-global-color-gray-900);
106
+ transition: -webkit-box-shadow 130ms 200ms, background-color 0s 86400s;
107
+ padding: 3px 8px 4px 8px;
108
+ }
109
+ </style>
@@ -0,0 +1,147 @@
1
+ <script>
2
+ import { createEventDispatcher } from "svelte"
3
+ import FancyField from "./FancyField.svelte"
4
+ import Icon from "../Icon/Icon.svelte"
5
+ import Popover from "../Popover/Popover.svelte"
6
+ import FancyFieldLabel from "./FancyFieldLabel.svelte"
7
+
8
+ export let label
9
+ export let value
10
+ export let disabled = false
11
+ export let error = null
12
+ export let validate = null
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
+
19
+ let open = false
20
+ let popover
21
+ let wrapper
22
+
23
+ $: placeholder = !value
24
+ $: selectedLabel = getSelectedLabel(value)
25
+
26
+ const extractProperty = (value, property) => {
27
+ if (value && typeof value === "object") {
28
+ return value[property]
29
+ }
30
+ return value
31
+ }
32
+
33
+ const onChange = newValue => {
34
+ dispatch("change", newValue)
35
+ value = newValue
36
+ if (validate) {
37
+ error = validate(newValue)
38
+ }
39
+ open = false
40
+ }
41
+
42
+ const getSelectedLabel = value => {
43
+ if (!value || !options?.length) {
44
+ return ""
45
+ }
46
+ const selectedOption = options.find(x => getOptionValue(x) === value)
47
+ if (!selectedOption) {
48
+ return value
49
+ }
50
+ return getOptionLabel(selectedOption)
51
+ }
52
+ </script>
53
+
54
+ <FancyField
55
+ bind:ref={wrapper}
56
+ {error}
57
+ {value}
58
+ {validate}
59
+ {disabled}
60
+ clickable
61
+ on:click={() => (open = true)}
62
+ >
63
+ {#if label}
64
+ <FancyFieldLabel {placeholder}>{label}</FancyFieldLabel>
65
+ {/if}
66
+
67
+ <div class="value" class:placeholder>
68
+ {selectedLabel || ""}
69
+ </div>
70
+
71
+ <div class="arrow">
72
+ <Icon name="ChevronDown" />
73
+ </div>
74
+ </FancyField>
75
+
76
+ <Popover
77
+ anchor={wrapper}
78
+ align="left"
79
+ portalTarget={document.documentElement}
80
+ bind:this={popover}
81
+ {open}
82
+ on:close={() => (open = false)}
83
+ useAnchorWidth={true}
84
+ maxWidth={null}
85
+ >
86
+ <div class="popover-content">
87
+ {#if options.length}
88
+ {#each options as option, idx}
89
+ <div
90
+ class="popover-option"
91
+ tabindex="0"
92
+ on:click={() => onChange(getOptionValue(option, idx))}
93
+ >
94
+ <span class="option-text">
95
+ {getOptionLabel(option, idx)}
96
+ </span>
97
+ {#if value === getOptionValue(option, idx)}
98
+ <Icon name="Checkmark" />
99
+ {/if}
100
+ </div>
101
+ {/each}
102
+ {/if}
103
+ </div>
104
+ </Popover>
105
+
106
+ <style>
107
+ .value {
108
+ display: block;
109
+ flex: 1 1 auto;
110
+ font-size: 15px;
111
+ line-height: 17px;
112
+ color: var(--spectrum-global-color-gray-900);
113
+ transition: transform 130ms ease-out, opacity 130ms ease-out;
114
+ opacity: 1;
115
+ white-space: nowrap;
116
+ text-overflow: ellipsis;
117
+ overflow: hidden;
118
+ width: 0;
119
+ transform: translateY(9px);
120
+ }
121
+ .value.placeholder {
122
+ transform: translateY(0);
123
+ opacity: 0;
124
+ pointer-events: none;
125
+ margin-top: 0;
126
+ }
127
+ .popover-content {
128
+ display: flex;
129
+ flex-direction: column;
130
+ justify-content: flex-start;
131
+ align-items: stretch;
132
+ padding: 7px 0;
133
+ }
134
+ .popover-option {
135
+ display: flex;
136
+ flex-direction: row;
137
+ justify-content: space-between;
138
+ align-items: center;
139
+ padding: 7px 16px;
140
+ transition: background 130ms ease-out;
141
+ font-size: 15px;
142
+ }
143
+ .popover-option:hover {
144
+ background: var(--spectrum-global-color-gray-200);
145
+ cursor: pointer;
146
+ }
147
+ </style>
@@ -0,0 +1,6 @@
1
+ export { default as FancyInput } from "./FancyInput.svelte"
2
+ export { default as FancyCheckbox } from "./FancyCheckbox.svelte"
3
+ export { default as FancySelect } from "./FancySelect.svelte"
4
+ export { default as FancyButton } from "./FancyButton.svelte"
5
+ export { default as FancyForm } from "./FancyForm.svelte"
6
+ export { default as FancyButtonRadio } from "./FancyButtonRadio.svelte"
@@ -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>