@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,80 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import "@spectrum-css/statuslight"
|
|
3
|
+
|
|
4
|
+
export let size = "M"
|
|
5
|
+
export let celery = false
|
|
6
|
+
export let yellow = false
|
|
7
|
+
export let fuchsia = false
|
|
8
|
+
export let indigo = false
|
|
9
|
+
export let seafoam = false
|
|
10
|
+
export let chartreuse = false
|
|
11
|
+
export let magenta = false
|
|
12
|
+
export let purple = false
|
|
13
|
+
export let neutral = false
|
|
14
|
+
export let info = false
|
|
15
|
+
export let positive = false
|
|
16
|
+
export let notice = false
|
|
17
|
+
export let negative = false
|
|
18
|
+
export let disabled = false
|
|
19
|
+
export let active = false
|
|
20
|
+
export let color = null
|
|
21
|
+
export let square = false
|
|
22
|
+
export let hoverable = false
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<div
|
|
26
|
+
on:click
|
|
27
|
+
class="spectrum-StatusLight spectrum-StatusLight--size{size}"
|
|
28
|
+
class:custom={!!color}
|
|
29
|
+
class:square
|
|
30
|
+
class:hoverable
|
|
31
|
+
style={`--color: ${color};`}
|
|
32
|
+
class:spectrum-StatusLight--celery={celery}
|
|
33
|
+
class:spectrum-StatusLight--yellow={yellow}
|
|
34
|
+
class:spectrum-StatusLight--fuchsia={fuchsia}
|
|
35
|
+
class:spectrum-StatusLight--indigo={indigo}
|
|
36
|
+
class:spectrum-StatusLight--seafoam={seafoam}
|
|
37
|
+
class:spectrum-StatusLight--chartreuse={chartreuse}
|
|
38
|
+
class:spectrum-StatusLight--magenta={magenta}
|
|
39
|
+
class:spectrum-StatusLight--purple={purple}
|
|
40
|
+
class:spectrum-StatusLight--neutral={neutral}
|
|
41
|
+
class:spectrum-StatusLight--info={info}
|
|
42
|
+
class:spectrum-StatusLight--positive={positive}
|
|
43
|
+
class:spectrum-StatusLight--notice={notice}
|
|
44
|
+
class:spectrum-StatusLight--negative={negative}
|
|
45
|
+
class:spectrum-StatusLight--disabled={disabled}
|
|
46
|
+
class:spectrum-StatusLight--active={active}
|
|
47
|
+
class:withText={!!$$slots.default}
|
|
48
|
+
>
|
|
49
|
+
<slot />
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<style>
|
|
53
|
+
.spectrum-StatusLight {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: row;
|
|
56
|
+
justify-content: center;
|
|
57
|
+
align-items: center;
|
|
58
|
+
--spectrum-statuslight-info-text-gap: 4px;
|
|
59
|
+
min-height: 0;
|
|
60
|
+
padding-top: 0;
|
|
61
|
+
padding-bottom: 0;
|
|
62
|
+
transition: color ease-out 130ms;
|
|
63
|
+
}
|
|
64
|
+
.spectrum-StatusLight.withText::before {
|
|
65
|
+
margin-right: 10px;
|
|
66
|
+
}
|
|
67
|
+
.custom::before {
|
|
68
|
+
background: var(--color) !important;
|
|
69
|
+
}
|
|
70
|
+
.square::before {
|
|
71
|
+
width: 14px;
|
|
72
|
+
height: 14px;
|
|
73
|
+
border-radius: 4px;
|
|
74
|
+
margin: 0;
|
|
75
|
+
}
|
|
76
|
+
.hoverable:hover {
|
|
77
|
+
cursor: pointer;
|
|
78
|
+
color: var(--spectrum-global-color-gray-900);
|
|
79
|
+
}
|
|
80
|
+
</style>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { flip } from 'svelte/animate';
|
|
3
|
+
import { fly } from "svelte/transition"
|
|
4
|
+
import { View } from "svench";
|
|
5
|
+
import { notifications } from "./notifications";
|
|
6
|
+
|
|
7
|
+
export let themes = {
|
|
8
|
+
danger: "#E26D69",
|
|
9
|
+
success: "#84C991",
|
|
10
|
+
warning: "#f0ad4e",
|
|
11
|
+
info: "#5bc0de",
|
|
12
|
+
default: "#aaaaaa",
|
|
13
|
+
}
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
## Notification Store
|
|
17
|
+
|
|
18
|
+
This custom can be used to display toast messages. It has 5 different methods: `send`, `danger`, `warning`, `success`, `info`.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
<View name="danger">
|
|
22
|
+
<button on:click={() => notifications.error('This is a danger!')}>Danger</button>
|
|
23
|
+
</View>
|
|
24
|
+
<View name="warning">
|
|
25
|
+
<button on:click={() => notifications.warning('This is a warning!')}>Warning</button>
|
|
26
|
+
</View>
|
|
27
|
+
<View name="success">
|
|
28
|
+
<button on:click={() => notifications.success('This is a success!')}>Success</button>
|
|
29
|
+
</View>
|
|
30
|
+
<View name="info">
|
|
31
|
+
<button on:click={() => notifications.info('This is an info toast!')}>Info</button>
|
|
32
|
+
</View>
|
|
33
|
+
|
|
34
|
+
<div class="notifications">
|
|
35
|
+
{#each $notifications as notification (notification.id)}
|
|
36
|
+
<div
|
|
37
|
+
animate:flip
|
|
38
|
+
class="toast"
|
|
39
|
+
style="background: {themes[notification.type]};"
|
|
40
|
+
transition:fly={{ y: -30 }}>
|
|
41
|
+
<div class="content">{notification.message}</div>
|
|
42
|
+
{#if notification.icon}<i class={notification.icon} />{/if}
|
|
43
|
+
</div>
|
|
44
|
+
{/each}
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<style>
|
|
48
|
+
.notifications {
|
|
49
|
+
position: fixed;
|
|
50
|
+
top: 10px;
|
|
51
|
+
left: 0;
|
|
52
|
+
right: 0;
|
|
53
|
+
margin: 0 auto;
|
|
54
|
+
padding: 0;
|
|
55
|
+
z-index: 9999;
|
|
56
|
+
display: flex;
|
|
57
|
+
flex-direction: column;
|
|
58
|
+
justify-content: flex-start;
|
|
59
|
+
align-items: center;
|
|
60
|
+
pointer-events: none;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.toast {
|
|
64
|
+
flex: 0 0 auto;
|
|
65
|
+
margin-bottom: 10px;
|
|
66
|
+
border-radius: var(--border-radius-s);
|
|
67
|
+
/* The toasts now support being auto sized, so this static width could be removed */
|
|
68
|
+
width: 40vw;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.content {
|
|
72
|
+
padding: 10px;
|
|
73
|
+
display: block;
|
|
74
|
+
color: white;
|
|
75
|
+
font-weight: 500;
|
|
76
|
+
}
|
|
77
|
+
</style>
|
|
78
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { writable } from "svelte/store"
|
|
2
|
+
|
|
3
|
+
export const BANNER_TYPES = {
|
|
4
|
+
INFO: "info",
|
|
5
|
+
NEGATIVE: "negative",
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function createBannerStore() {
|
|
9
|
+
const DEFAULT_CONFIG = {
|
|
10
|
+
messages: [],
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const banner = writable(DEFAULT_CONFIG)
|
|
14
|
+
|
|
15
|
+
const show = async (
|
|
16
|
+
// eslint-disable-next-line
|
|
17
|
+
config = { message, type, extraButtonText, extraButtonAction, onChange }
|
|
18
|
+
) => {
|
|
19
|
+
banner.update(store => {
|
|
20
|
+
return {
|
|
21
|
+
...store,
|
|
22
|
+
...config,
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const showStatus = async () => {
|
|
28
|
+
const config = {
|
|
29
|
+
message: "Some systems are experiencing issues",
|
|
30
|
+
type: BANNER_TYPES.NEGATIVE,
|
|
31
|
+
extraButtonText: "View Status",
|
|
32
|
+
extraButtonAction: () => window.open("https://status.budibase.com/"),
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
await queue([config])
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const queue = async entries => {
|
|
39
|
+
const priority = {
|
|
40
|
+
[BANNER_TYPES.NEGATIVE]: 0,
|
|
41
|
+
[BANNER_TYPES.INFO]: 1,
|
|
42
|
+
}
|
|
43
|
+
banner.update(store => {
|
|
44
|
+
const sorted = [...store.messages, ...entries].sort((a, b) => {
|
|
45
|
+
if (priority[a.type] == priority[b.type]) {
|
|
46
|
+
return 0
|
|
47
|
+
}
|
|
48
|
+
return priority[a.type] < priority[b.type] ? -1 : 1
|
|
49
|
+
})
|
|
50
|
+
return {
|
|
51
|
+
...store,
|
|
52
|
+
messages: sorted,
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
subscribe: banner.subscribe,
|
|
59
|
+
showStatus,
|
|
60
|
+
show,
|
|
61
|
+
queue,
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const banner = createBannerStore()
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { writable } from "svelte/store"
|
|
2
|
+
|
|
3
|
+
const NOTIFICATION_TIMEOUT = 3000
|
|
4
|
+
|
|
5
|
+
export const createNotificationStore = () => {
|
|
6
|
+
const timeoutIds = new Set()
|
|
7
|
+
const _notifications = writable([], () => {
|
|
8
|
+
return () => {
|
|
9
|
+
// clear all the timers
|
|
10
|
+
timeoutIds.forEach(timeoutId => {
|
|
11
|
+
clearTimeout(timeoutId)
|
|
12
|
+
})
|
|
13
|
+
_notifications.set([])
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
let block = false
|
|
17
|
+
|
|
18
|
+
const blockNotifications = (timeout = 1000) => {
|
|
19
|
+
block = true
|
|
20
|
+
setTimeout(() => (block = false), timeout)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const send = (
|
|
24
|
+
message,
|
|
25
|
+
{
|
|
26
|
+
type = "default",
|
|
27
|
+
icon = "",
|
|
28
|
+
autoDismiss = true,
|
|
29
|
+
action = null,
|
|
30
|
+
wide = false,
|
|
31
|
+
}
|
|
32
|
+
) => {
|
|
33
|
+
if (block) {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
let _id = id()
|
|
37
|
+
_notifications.update(state => {
|
|
38
|
+
return [
|
|
39
|
+
...state,
|
|
40
|
+
{
|
|
41
|
+
id: _id,
|
|
42
|
+
type,
|
|
43
|
+
message,
|
|
44
|
+
icon,
|
|
45
|
+
dismissable: !autoDismiss,
|
|
46
|
+
action,
|
|
47
|
+
wide,
|
|
48
|
+
},
|
|
49
|
+
]
|
|
50
|
+
})
|
|
51
|
+
if (autoDismiss) {
|
|
52
|
+
const timeoutId = setTimeout(() => {
|
|
53
|
+
dismissNotification(_id)
|
|
54
|
+
}, NOTIFICATION_TIMEOUT)
|
|
55
|
+
timeoutIds.add(timeoutId)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const dismissNotification = id => {
|
|
60
|
+
_notifications.update(state => {
|
|
61
|
+
return state.filter(n => n.id !== id)
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const { subscribe } = _notifications
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
subscribe,
|
|
69
|
+
send,
|
|
70
|
+
info: msg => send(msg, { type: "info", icon: "Info" }),
|
|
71
|
+
error: msg =>
|
|
72
|
+
send(msg, { type: "error", icon: "Alert", autoDismiss: false }),
|
|
73
|
+
warning: msg => send(msg, { type: "warning", icon: "Alert" }),
|
|
74
|
+
success: msg => send(msg, { type: "success", icon: "CheckmarkCircle" }),
|
|
75
|
+
blockNotifications,
|
|
76
|
+
dismiss: dismissNotification,
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function id() {
|
|
81
|
+
return "_" + Math.random().toString(36).slice(2, 9)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const notifications = createNotificationStore()
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import "@spectrum-css/label/dist/index-vars.css"
|
|
3
|
+
import Badge from "../Badge/Badge.svelte"
|
|
4
|
+
export let value
|
|
5
|
+
|
|
6
|
+
const displayLimit = 5
|
|
7
|
+
|
|
8
|
+
$: arrayValue = Array.isArray(value) ? value : [value].filter(x => !!x)
|
|
9
|
+
$: badges = arrayValue.slice(0, displayLimit)
|
|
10
|
+
$: leftover = arrayValue.length - badges.length
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
{#each badges as badge}
|
|
14
|
+
<Badge size="S" grey>{badge}</Badge>
|
|
15
|
+
{/each}
|
|
16
|
+
{#if leftover}
|
|
17
|
+
<div>+{leftover} more</div>
|
|
18
|
+
{/if}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import Link from "../Link/Link.svelte"
|
|
3
|
+
|
|
4
|
+
export let value
|
|
5
|
+
|
|
6
|
+
const displayLimit = 5
|
|
7
|
+
$: attachments = value?.slice(0, displayLimit) ?? []
|
|
8
|
+
$: leftover = (value?.length ?? 0) - attachments.length
|
|
9
|
+
|
|
10
|
+
const imageExtensions = ["png", "tiff", "gif", "raw", "jpg", "jpeg"]
|
|
11
|
+
const isImage = extension => {
|
|
12
|
+
return imageExtensions.includes(extension?.toLowerCase())
|
|
13
|
+
}
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
{#each attachments as attachment}
|
|
17
|
+
{#if isImage(attachment.extension)}
|
|
18
|
+
<Link
|
|
19
|
+
quiet
|
|
20
|
+
target="_blank"
|
|
21
|
+
download={attachment.name}
|
|
22
|
+
href={attachment.url}
|
|
23
|
+
on:click={e => {
|
|
24
|
+
e.stopPropagation()
|
|
25
|
+
}}
|
|
26
|
+
>
|
|
27
|
+
<div class="center" title={attachment.name}>
|
|
28
|
+
<img src={attachment.url} alt={attachment.extension} />
|
|
29
|
+
</div>
|
|
30
|
+
</Link>
|
|
31
|
+
{:else}
|
|
32
|
+
<div class="file" title={attachment.name}>
|
|
33
|
+
<Link
|
|
34
|
+
quiet
|
|
35
|
+
target="_blank"
|
|
36
|
+
download={attachment.name}
|
|
37
|
+
href={attachment.url}
|
|
38
|
+
on:click={e => {
|
|
39
|
+
e.stopPropagation()
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
{attachment.extension}
|
|
43
|
+
</Link>
|
|
44
|
+
</div>
|
|
45
|
+
{/if}
|
|
46
|
+
{/each}
|
|
47
|
+
{#if leftover}
|
|
48
|
+
<div>+{leftover} more</div>
|
|
49
|
+
{/if}
|
|
50
|
+
|
|
51
|
+
<style>
|
|
52
|
+
img {
|
|
53
|
+
height: 32px;
|
|
54
|
+
max-width: 64px;
|
|
55
|
+
}
|
|
56
|
+
.center,
|
|
57
|
+
.file {
|
|
58
|
+
display: flex;
|
|
59
|
+
flex-direction: row;
|
|
60
|
+
justify-content: flex-start;
|
|
61
|
+
align-items: center;
|
|
62
|
+
}
|
|
63
|
+
.file {
|
|
64
|
+
height: 32px;
|
|
65
|
+
padding: 0 8px;
|
|
66
|
+
color: var(--spectrum-global-color-gray-800);
|
|
67
|
+
border: 1px solid var(--spectrum-global-color-gray-300);
|
|
68
|
+
border-radius: 4px;
|
|
69
|
+
text-transform: uppercase;
|
|
70
|
+
font-weight: 600;
|
|
71
|
+
font-size: 11px;
|
|
72
|
+
}
|
|
73
|
+
</style>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import "@spectrum-css/checkbox/dist/index-vars.css"
|
|
3
|
+
|
|
4
|
+
export let value
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<label
|
|
8
|
+
class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-Checkbox--emphasized"
|
|
9
|
+
>
|
|
10
|
+
<input
|
|
11
|
+
type="checkbox"
|
|
12
|
+
class="spectrum-Checkbox-input"
|
|
13
|
+
id="checkbox-1"
|
|
14
|
+
disabled
|
|
15
|
+
checked={!!value}
|
|
16
|
+
/>
|
|
17
|
+
<span class="spectrum-Checkbox-box">
|
|
18
|
+
<svg
|
|
19
|
+
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark"
|
|
20
|
+
focusable="false"
|
|
21
|
+
aria-hidden="true"
|
|
22
|
+
>
|
|
23
|
+
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
|
24
|
+
</svg>
|
|
25
|
+
<svg
|
|
26
|
+
class="spectrum-Icon spectrum-UIIcon-Dash100 spectrum-Checkbox-partialCheckmark"
|
|
27
|
+
focusable="false"
|
|
28
|
+
aria-hidden="true"
|
|
29
|
+
>
|
|
30
|
+
<use xlink:href="#spectrum-css-icon-Dash100" />
|
|
31
|
+
</svg>
|
|
32
|
+
</span>
|
|
33
|
+
</label>
|
|
34
|
+
|
|
35
|
+
<style>
|
|
36
|
+
.spectrum-Checkbox {
|
|
37
|
+
min-height: 0;
|
|
38
|
+
}
|
|
39
|
+
.spectrum-Checkbox-box {
|
|
40
|
+
margin: 0;
|
|
41
|
+
}
|
|
42
|
+
</style>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import StringRenderer from "./StringRenderer.svelte"
|
|
3
|
+
import BooleanRenderer from "./BooleanRenderer.svelte"
|
|
4
|
+
import DateTimeRenderer from "./DateTimeRenderer.svelte"
|
|
5
|
+
import RelationshipRenderer from "./RelationshipRenderer.svelte"
|
|
6
|
+
import AttachmentRenderer from "./AttachmentRenderer.svelte"
|
|
7
|
+
import ArrayRenderer from "./ArrayRenderer.svelte"
|
|
8
|
+
import InternalRenderer from "./InternalRenderer.svelte"
|
|
9
|
+
import { processStringSync } from "@budibase/string-templates"
|
|
10
|
+
|
|
11
|
+
export let row
|
|
12
|
+
export let schema
|
|
13
|
+
export let value
|
|
14
|
+
export let customRenderers = []
|
|
15
|
+
|
|
16
|
+
let renderer
|
|
17
|
+
const typeMap = {
|
|
18
|
+
boolean: BooleanRenderer,
|
|
19
|
+
datetime: DateTimeRenderer,
|
|
20
|
+
link: RelationshipRenderer,
|
|
21
|
+
attachment: AttachmentRenderer,
|
|
22
|
+
string: StringRenderer,
|
|
23
|
+
options: StringRenderer,
|
|
24
|
+
number: StringRenderer,
|
|
25
|
+
longform: StringRenderer,
|
|
26
|
+
array: ArrayRenderer,
|
|
27
|
+
internal: InternalRenderer,
|
|
28
|
+
}
|
|
29
|
+
$: type = getType(schema)
|
|
30
|
+
$: customRenderer = customRenderers?.find(x => x.column === schema?.name)
|
|
31
|
+
$: renderer = customRenderer?.component ?? typeMap[type] ?? StringRenderer
|
|
32
|
+
$: width = schema?.width || "150px"
|
|
33
|
+
$: cellValue = getCellValue(value, schema.template)
|
|
34
|
+
|
|
35
|
+
const getType = schema => {
|
|
36
|
+
// Use a string renderer for dates if we use a custom template
|
|
37
|
+
if (schema?.type === "datetime" && schema?.template) {
|
|
38
|
+
return "string"
|
|
39
|
+
}
|
|
40
|
+
return schema?.type || "string"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const getCellValue = (value, template) => {
|
|
44
|
+
if (!template) {
|
|
45
|
+
return value
|
|
46
|
+
}
|
|
47
|
+
return processStringSync(template, { value })
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
{#if renderer && (customRenderer || (cellValue != null && cellValue !== ""))}
|
|
52
|
+
<div style="--max-cell-width: {schema.width ? 'none' : '200px'};">
|
|
53
|
+
<svelte:component
|
|
54
|
+
this={renderer}
|
|
55
|
+
{row}
|
|
56
|
+
{schema}
|
|
57
|
+
value={cellValue}
|
|
58
|
+
on:clickrelationship
|
|
59
|
+
on:buttonclick
|
|
60
|
+
>
|
|
61
|
+
<slot />
|
|
62
|
+
</svelte:component>
|
|
63
|
+
</div>
|
|
64
|
+
{/if}
|
|
65
|
+
|
|
66
|
+
<style>
|
|
67
|
+
div {
|
|
68
|
+
display: contents;
|
|
69
|
+
}
|
|
70
|
+
</style>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import dayjs from "dayjs"
|
|
3
|
+
|
|
4
|
+
export let value
|
|
5
|
+
export let schema
|
|
6
|
+
|
|
7
|
+
// adding the 0- will turn a string like 00:00:00 into a valid ISO
|
|
8
|
+
// date, but will make actual ISO dates invalid
|
|
9
|
+
$: time = new Date(`0-${value}`)
|
|
10
|
+
$: isTimeOnly = !isNaN(time) || schema?.timeOnly
|
|
11
|
+
$: isDateOnly = schema?.dateOnly
|
|
12
|
+
$: format = isTimeOnly
|
|
13
|
+
? "HH:mm:ss"
|
|
14
|
+
: isDateOnly
|
|
15
|
+
? "MMMM D YYYY"
|
|
16
|
+
: "MMMM D YYYY, HH:mm"
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<div>
|
|
20
|
+
{dayjs(isTimeOnly ? time : value).format(format)}
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<style>
|
|
24
|
+
div {
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
text-overflow: ellipsis;
|
|
27
|
+
white-space: nowrap;
|
|
28
|
+
}
|
|
29
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import Icon from "../Icon/Icon.svelte"
|
|
3
|
+
import { copyToClipboard } from "../helpers"
|
|
4
|
+
import { notifications } from "../Stores/notifications"
|
|
5
|
+
|
|
6
|
+
export let value
|
|
7
|
+
|
|
8
|
+
const onClick = async e => {
|
|
9
|
+
e.stopPropagation()
|
|
10
|
+
try {
|
|
11
|
+
await copyToClipboard(value)
|
|
12
|
+
notifications.success("Copied to clipboard")
|
|
13
|
+
} catch (error) {
|
|
14
|
+
notifications.error(
|
|
15
|
+
"Failed to copy to clipboard. Check the dev console for the value."
|
|
16
|
+
)
|
|
17
|
+
console.warn("Failed to copy the value", value)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<div on:click|stopPropagation={onClick}>
|
|
23
|
+
<Icon size="S" name="Copy" />
|
|
24
|
+
</div>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import "@spectrum-css/label/dist/index-vars.css"
|
|
3
|
+
import { createEventDispatcher } from "svelte"
|
|
4
|
+
import Badge from "../Badge/Badge.svelte"
|
|
5
|
+
|
|
6
|
+
export let row
|
|
7
|
+
export let value
|
|
8
|
+
export let schema
|
|
9
|
+
|
|
10
|
+
const dispatch = createEventDispatcher()
|
|
11
|
+
const displayLimit = 5
|
|
12
|
+
|
|
13
|
+
$: relationships = value?.slice(0, displayLimit) ?? []
|
|
14
|
+
$: leftover = (value?.length ?? 0) - relationships.length
|
|
15
|
+
|
|
16
|
+
const onClick = e => {
|
|
17
|
+
e.stopPropagation()
|
|
18
|
+
dispatch("clickrelationship", {
|
|
19
|
+
tableId: row.tableId,
|
|
20
|
+
rowId: row._id,
|
|
21
|
+
fieldName: schema?.name,
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
{#each relationships as relationship}
|
|
27
|
+
{#if relationship?.primaryDisplay}
|
|
28
|
+
<Badge hoverable grey on:click={onClick}>
|
|
29
|
+
{relationship.primaryDisplay}
|
|
30
|
+
</Badge>
|
|
31
|
+
{/if}
|
|
32
|
+
{/each}
|
|
33
|
+
{#if leftover}
|
|
34
|
+
<div>+{leftover} more</div>
|
|
35
|
+
{/if}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import Checkbox from "../Form/Checkbox.svelte"
|
|
3
|
+
import ActionButton from "../ActionButton/ActionButton.svelte"
|
|
4
|
+
|
|
5
|
+
export let selected
|
|
6
|
+
export let onEdit
|
|
7
|
+
export let allowSelectRows = false
|
|
8
|
+
export let allowEditRows = false
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<div>
|
|
12
|
+
{#if allowSelectRows}
|
|
13
|
+
<Checkbox value={selected} />
|
|
14
|
+
{/if}
|
|
15
|
+
{#if allowEditRows}
|
|
16
|
+
<ActionButton size="S" on:click={onEdit}>Edit</ActionButton>
|
|
17
|
+
{/if}
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<style>
|
|
21
|
+
div {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: row;
|
|
24
|
+
justify-content: flex-start;
|
|
25
|
+
align-items: center;
|
|
26
|
+
gap: var(--spacing-m);
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let value
|
|
3
|
+
export let schema
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<div class:capitalise={schema?.capitalise}>
|
|
7
|
+
{typeof value === "object" ? JSON.stringify(value) : value}
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<style>
|
|
11
|
+
div {
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
text-overflow: ellipsis;
|
|
14
|
+
white-space: nowrap;
|
|
15
|
+
max-width: var(--max-cell-width);
|
|
16
|
+
width: 0;
|
|
17
|
+
flex: 1 1 auto;
|
|
18
|
+
}
|
|
19
|
+
div.capitalise {
|
|
20
|
+
text-transform: capitalize;
|
|
21
|
+
}
|
|
22
|
+
</style>
|