@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.
- package/LICENSE +375 -0
- package/README.md +42 -0
- package/dist/bbui.es.js +8 -0
- package/dist/bbui.es.js.map +1 -0
- package/package.json +94 -0
- package/src/Accordion/Accordion.svelte +58 -0
- package/src/ActionButton/ActionButton.svelte +132 -0
- package/src/ActionGroup/ActionGroup.svelte +26 -0
- package/src/ActionMenu/ActionMenu.svelte +43 -0
- package/src/Actions/ClickOutside.svench.svx +30 -0
- package/src/Actions/PositionDropdown.svench.svx +81 -0
- package/src/Actions/autoresize_textarea.js +14 -0
- package/src/Actions/click_outside.js +76 -0
- package/src/Actions/position_dropdown.js +116 -0
- package/src/Avatar/Avatar.svelte +63 -0
- package/src/Badge/Badge.svelte +42 -0
- package/src/Banner/Banner.svelte +72 -0
- package/src/Banner/BannerDisplay.svelte +41 -0
- package/src/Button/Button.svelte +118 -0
- package/src/Button/Button.svench +138 -0
- package/src/ButtonGroup/ButtonGroup.svelte +30 -0
- package/src/ClearButton/ClearButton.svelte +19 -0
- package/src/ColorPicker/ColorPicker.svelte +304 -0
- package/src/DetailSummary/DetailSummary.svelte +92 -0
- package/src/Divider/Divider.svelte +28 -0
- package/src/Drawer/Drawer.svelte +113 -0
- package/src/Drawer/Drawer.svench +42 -0
- package/src/Drawer/DrawerContent.svelte +45 -0
- package/src/FancyForm/FancyButton.svelte +30 -0
- package/src/FancyForm/FancyButtonRadio.svelte +70 -0
- package/src/FancyForm/FancyCheckbox.svelte +53 -0
- package/src/FancyForm/FancyField.svelte +126 -0
- package/src/FancyForm/FancyFieldLabel.svelte +25 -0
- package/src/FancyForm/FancyForm.svelte +40 -0
- package/src/FancyForm/FancyInput.svelte +109 -0
- package/src/FancyForm/FancySelect.svelte +147 -0
- package/src/FancyForm/index.js +6 -0
- package/src/Form/Checkbox.svelte +23 -0
- package/src/Form/Combobox.svelte +45 -0
- package/src/Form/Core/Checkbox.svelte +69 -0
- package/src/Form/Core/CheckboxGroup.svelte +68 -0
- package/src/Form/Core/Combobox.svelte +142 -0
- package/src/Form/Core/DatePicker.svelte +265 -0
- package/src/Form/Core/Dropzone.svelte +482 -0
- package/src/Form/Core/EnvDropdown.svelte +276 -0
- package/src/Form/Core/File.svelte +115 -0
- package/src/Form/Core/InputDropdown.svelte +235 -0
- package/src/Form/Core/Multiselect.svelte +99 -0
- package/src/Form/Core/Picker.svelte +314 -0
- package/src/Form/Core/PickerDropdown.svelte +431 -0
- package/src/Form/Core/RadioGroup.svelte +65 -0
- package/src/Form/Core/RichTextField.svelte +42 -0
- package/src/Form/Core/Search.svelte +105 -0
- package/src/Form/Core/Select.svelte +90 -0
- package/src/Form/Core/Slider.svelte +86 -0
- package/src/Form/Core/Stepper.svelte +172 -0
- package/src/Form/Core/Switch.svelte +35 -0
- package/src/Form/Core/TextArea.svelte +78 -0
- package/src/Form/Core/TextField.svelte +115 -0
- package/src/Form/Core/index.js +16 -0
- package/src/Form/DatePicker.svelte +46 -0
- package/src/Form/Dropzone.svelte +44 -0
- package/src/Form/EnvDropdown.svelte +50 -0
- package/src/Form/Field.svelte +42 -0
- package/src/Form/FieldLabel.svelte +32 -0
- package/src/Form/File.svelte +37 -0
- package/src/Form/Input.svelte +45 -0
- package/src/Form/InputDropdown.svelte +53 -0
- package/src/Form/Multiselect.svelte +49 -0
- package/src/Form/PickerDropdown.svelte +131 -0
- package/src/Form/RadioGroup.svelte +42 -0
- package/src/Form/RichTextField.svelte +36 -0
- package/src/Form/Search.svelte +36 -0
- package/src/Form/Select.svelte +67 -0
- package/src/Form/Slider.svelte +24 -0
- package/src/Form/Stepper.svelte +45 -0
- package/src/Form/TextArea.svelte +34 -0
- package/src/Form/Toggle.svelte +22 -0
- package/src/Icon/Icon.svelte +94 -0
- package/src/Icon/IconAvatar.svelte +61 -0
- package/src/IconPicker/IconPicker.svelte +184 -0
- package/src/IconSideNav/IconSideNav.svelte +14 -0
- package/src/IconSideNav/IconSideNavItem.svelte +56 -0
- package/src/InlineAlert/InlineAlert.svelte +63 -0
- package/src/Input/CopyInput.svelte +59 -0
- package/src/Label/Label.svelte +31 -0
- package/src/Layout/Layout.svelte +94 -0
- package/src/Layout/Page.svelte +101 -0
- package/src/Link/Link.svelte +27 -0
- package/src/List/List.svelte +28 -0
- package/src/List/ListItem.svelte +93 -0
- package/src/Markdown/MarkdownEditor.svelte +60 -0
- package/src/Markdown/MarkdownViewer.svelte +70 -0
- package/src/Markdown/SpectrumMDE.svelte +184 -0
- package/src/Menu/Item.svelte +94 -0
- package/src/Menu/Menu.svelte +7 -0
- package/src/Menu/Menu.svench +19 -0
- package/src/Menu/Section.svelte +10 -0
- package/src/Menu/Separator.svelte +1 -0
- package/src/Modal/Content.svelte +6 -0
- package/src/Modal/CustomContent.svelte +37 -0
- package/src/Modal/Modal.svelte +178 -0
- package/src/Modal/Modal.svench +116 -0
- package/src/Modal/ModalContent.svelte +190 -0
- package/src/Modal/QuizModal.svelte +53 -0
- package/src/Notification/Notification.svelte +74 -0
- package/src/Notification/NotificationDisplay.svelte +43 -0
- package/src/Pagination/Pagination.svelte +57 -0
- package/src/Popover/Popover.svelte +95 -0
- package/src/Popover/Popover.svench +120 -0
- package/src/ProgressBar/ProgressBar.svelte +67 -0
- package/src/ProgressCircle/ProgressCircle.svelte +62 -0
- package/src/SideNavigation/Item.svelte +59 -0
- package/src/SideNavigation/Navigation.svelte +12 -0
- package/src/StatusLight/StatusLight.svelte +80 -0
- package/src/Stores/Notifications.svench.svx +78 -0
- package/src/Stores/banner.js +65 -0
- package/src/Stores/notifications.js +84 -0
- package/src/Table/ArrayRenderer.svelte +18 -0
- package/src/Table/AttachmentRenderer.svelte +73 -0
- package/src/Table/BoldRenderer.svelte +15 -0
- package/src/Table/BooleanRenderer.svelte +42 -0
- package/src/Table/CellRenderer.svelte +70 -0
- package/src/Table/CodeRenderer.svelte +14 -0
- package/src/Table/DateTimeRenderer.svelte +29 -0
- package/src/Table/InternalRenderer.svelte +24 -0
- package/src/Table/RelationshipRenderer.svelte +35 -0
- package/src/Table/SelectEditRenderer.svelte +28 -0
- package/src/Table/StringRenderer.svelte +22 -0
- package/src/Table/Table.svelte +657 -0
- package/src/Table/index.js +1 -0
- package/src/Tabs/Tab.svelte +88 -0
- package/src/Tabs/Tabs.svelte +130 -0
- package/src/Tags/Tag.svelte +43 -0
- package/src/Tags/Tags.svelte +17 -0
- package/src/Tooltip/Tooltip.svelte +34 -0
- package/src/Tooltip/TooltipWrapper.svelte +60 -0
- package/src/TreeView/Item.svelte +41 -0
- package/src/TreeView/Tree.svelte +16 -0
- package/src/Typography/Body.svelte +22 -0
- package/src/Typography/Code.svelte +10 -0
- package/src/Typography/Detail.svelte +19 -0
- package/src/Typography/Heading.svelte +24 -0
- package/src/bbui.css +118 -0
- package/src/context.js +4 -0
- package/src/helpers.js +116 -0
- package/src/index.js +109 -0
- package/src/spectrum-icons-rollup.js +31 -0
- 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>
|