@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,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>
@@ -0,0 +1,265 @@
1
+ <script>
2
+ import Flatpickr from "svelte-flatpickr"
3
+ import "flatpickr/dist/flatpickr.css"
4
+ import "@spectrum-css/inputgroup/dist/index-vars.css"
5
+ import "@spectrum-css/textfield/dist/index-vars.css"
6
+ import "@spectrum-css/picker/dist/index-vars.css"
7
+ import { createEventDispatcher } from "svelte"
8
+ import { uuid } from "../../helpers"
9
+
10
+ export let id = null
11
+ export let disabled = false
12
+ export let error = null
13
+ export let enableTime = true
14
+ export let value = null
15
+ export let placeholder = null
16
+ export let appendTo = undefined
17
+ export let timeOnly = false
18
+ export let ignoreTimezones = false
19
+ export let time24hr = false
20
+ export let range = false
21
+ const dispatch = createEventDispatcher()
22
+ const flatpickrId = `${uuid()}-wrapper`
23
+ let open = false
24
+ let flatpickr, flatpickrOptions
25
+
26
+ // Another classic flatpickr issue. Errors were randomly being thrown due to
27
+ // flatpickr internal code. Making sure that "destroy" is a valid function
28
+ // fixes it. The sooner we remove flatpickr the better.
29
+ $: {
30
+ if (flatpickr && !flatpickr.destroy) {
31
+ flatpickr.destroy = () => {}
32
+ }
33
+ }
34
+
35
+ const resolveTimeStamp = timestamp => {
36
+ let maskedDate = new Date(`0-${timestamp}`)
37
+
38
+ if (maskedDate instanceof Date && !isNaN(maskedDate.getTime())) {
39
+ return maskedDate
40
+ } else {
41
+ return null
42
+ }
43
+ }
44
+
45
+ $: flatpickrOptions = {
46
+ element: `#${flatpickrId}`,
47
+ enableTime: timeOnly || enableTime || false,
48
+ noCalendar: timeOnly || false,
49
+ altInput: true,
50
+ time_24hr: time24hr || false,
51
+ altFormat: timeOnly ? "H:i" : enableTime ? "F j Y, H:i" : "F j, Y",
52
+ wrap: true,
53
+ mode: range ? "range" : "single",
54
+ appendTo,
55
+ disableMobile: "true",
56
+ onReady: () => {
57
+ let timestamp = resolveTimeStamp(value)
58
+ if (timeOnly && timestamp) {
59
+ dispatch("change", timestamp.toISOString())
60
+ }
61
+ },
62
+ }
63
+
64
+ $: redrawOptions = {
65
+ timeOnly,
66
+ enableTime,
67
+ time24hr,
68
+ }
69
+
70
+ const handleChange = event => {
71
+ const [dates] = event.detail
72
+ const noTimezone = enableTime && !timeOnly && ignoreTimezones
73
+ let newValue = dates[0]
74
+ if (newValue) {
75
+ newValue = newValue.toISOString()
76
+ }
77
+ // If time only set date component to 2000-01-01
78
+ if (timeOnly) {
79
+ newValue = `2000-01-01T${newValue.split("T")[1]}`
80
+ }
81
+
82
+ // For date-only fields, construct a manual timestamp string without a time
83
+ // or time zone
84
+ else if (!enableTime) {
85
+ const year = dates[0].getFullYear()
86
+ const month = `${dates[0].getMonth() + 1}`.padStart(2, "0")
87
+ const day = `${dates[0].getDate()}`.padStart(2, "0")
88
+ newValue = `${year}-${month}-${day}T00:00:00.000`
89
+ }
90
+
91
+ // For non-timezone-aware fields, create an ISO 8601 timestamp of the exact
92
+ // time picked, without timezone
93
+ else if (noTimezone) {
94
+ const offset = dates[0].getTimezoneOffset() * 60000
95
+ newValue = new Date(dates[0].getTime() - offset)
96
+ .toISOString()
97
+ .slice(0, -1)
98
+ }
99
+
100
+ if (range) {
101
+ dispatch("change", event.detail)
102
+ } else {
103
+ dispatch("change", newValue)
104
+ }
105
+ }
106
+
107
+ const clearDateOnBackspace = event => {
108
+ if (["Backspace", "Clear", "Delete"].includes(event.key)) {
109
+ dispatch("change", "")
110
+ flatpickr.close()
111
+ }
112
+ }
113
+
114
+ const onOpen = () => {
115
+ open = true
116
+ document.addEventListener("keyup", clearDateOnBackspace)
117
+ }
118
+
119
+ const onClose = () => {
120
+ open = false
121
+ document.removeEventListener("keyup", clearDateOnBackspace)
122
+
123
+ // Manually blur all input fields since flatpickr creates a second
124
+ // duplicate input field.
125
+ // We need to blur both because the focus styling does not get properly
126
+ // applied.
127
+ const els = document.querySelectorAll(`#${flatpickrId} input`)
128
+ els.forEach(el => el.blur())
129
+ }
130
+
131
+ const parseDate = val => {
132
+ if (!val) {
133
+ return null
134
+ }
135
+ let date
136
+ let time
137
+
138
+ // it is a string like 00:00:00, just time
139
+ let ts = resolveTimeStamp(val)
140
+
141
+ if (timeOnly && ts) {
142
+ date = ts
143
+ } else if (val instanceof Date) {
144
+ // Use real date obj if already parsed
145
+ date = val
146
+ } else if (isNaN(val)) {
147
+ // Treat as date string of some sort
148
+ date = new Date(val)
149
+ } else {
150
+ // Treat as numerical timestamp
151
+ date = new Date(parseInt(val))
152
+ }
153
+
154
+ time = date.getTime()
155
+ if (isNaN(time)) {
156
+ return null
157
+ }
158
+
159
+ // By rounding to the nearest second we avoid locking up in an endless
160
+ // loop in the builder, caused by potentially enriching {{ now }} to every
161
+ // millisecond.
162
+ return new Date(Math.floor(time / 1000) * 1000)
163
+ }
164
+ </script>
165
+
166
+ {#key redrawOptions}
167
+ <Flatpickr
168
+ bind:flatpickr
169
+ value={range ? value : parseDate(value)}
170
+ on:open={onOpen}
171
+ on:close={onClose}
172
+ options={flatpickrOptions}
173
+ on:change={handleChange}
174
+ element={`#${flatpickrId}`}
175
+ >
176
+ <div
177
+ id={flatpickrId}
178
+ class:is-disabled={disabled}
179
+ class:is-invalid={!!error}
180
+ class="flatpickr spectrum-InputGroup spectrum-Datepicker"
181
+ class:is-focused={open}
182
+ aria-readonly="false"
183
+ aria-required="false"
184
+ aria-haspopup="true"
185
+ >
186
+ <div
187
+ on:click={flatpickr?.open}
188
+ class="spectrum-Textfield spectrum-InputGroup-textfield"
189
+ class:is-disabled={disabled}
190
+ class:is-invalid={!!error}
191
+ >
192
+ {#if !!error}
193
+ <svg
194
+ class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
195
+ focusable="false"
196
+ aria-hidden="true"
197
+ >
198
+ <use xlink:href="#spectrum-icon-18-Alert" />
199
+ </svg>
200
+ {/if}
201
+ <input
202
+ {disabled}
203
+ data-input
204
+ type="text"
205
+ class="spectrum-Textfield-input spectrum-InputGroup-input"
206
+ class:is-disabled={disabled}
207
+ {placeholder}
208
+ {id}
209
+ {value}
210
+ />
211
+ </div>
212
+ <button
213
+ type="button"
214
+ class="spectrum-Picker spectrum-Picker--sizeM spectrum-InputGroup-button"
215
+ tabindex="-1"
216
+ class:is-disabled={disabled}
217
+ class:is-invalid={!!error}
218
+ on:click={flatpickr?.open}
219
+ >
220
+ <svg
221
+ class="spectrum-Icon spectrum-Icon--sizeM"
222
+ focusable="false"
223
+ aria-hidden="true"
224
+ aria-label="Calendar"
225
+ >
226
+ <use xlink:href="#spectrum-icon-18-Calendar" />
227
+ </svg>
228
+ </button>
229
+ </div>
230
+ </Flatpickr>
231
+ {/key}
232
+ {#if open}
233
+ <div class="overlay" on:mousedown|self={flatpickr?.close} />
234
+ {/if}
235
+
236
+ <style>
237
+ .spectrum-Textfield-input {
238
+ pointer-events: none;
239
+ }
240
+ .spectrum-Textfield:not(.is-disabled):hover {
241
+ cursor: pointer;
242
+ }
243
+ .flatpickr {
244
+ width: 100%;
245
+ overflow: hidden;
246
+ }
247
+ .flatpickr .spectrum-Textfield {
248
+ width: 100%;
249
+ }
250
+ .overlay {
251
+ position: fixed;
252
+ top: 0;
253
+ left: 0;
254
+ width: 100vw;
255
+ height: 100vh;
256
+ z-index: 999;
257
+ max-height: 100%;
258
+ }
259
+ :global(.flatpickr-calendar) {
260
+ font-family: var(--font-sans);
261
+ }
262
+ .is-disabled {
263
+ pointer-events: none !important;
264
+ }
265
+ </style>