@budibase/bbui 3.4.21 → 3.4.23

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 (38) hide show
  1. package/dist/bbui.mjs +2616 -2971
  2. package/package.json +2 -2
  3. package/src/Actions/position_dropdown.ts +1 -1
  4. package/src/Badge/Badge.svelte +2 -0
  5. package/src/ClearButton/ClearButton.svelte +3 -3
  6. package/src/Drawer/Drawer.svelte +1 -1
  7. package/src/Form/Checkbox.svelte +11 -11
  8. package/src/Form/Core/Multiselect.svelte +42 -32
  9. package/src/Icon/Icon.svelte +3 -0
  10. package/src/Layout/Page.svelte +1 -1
  11. package/src/Link/Link.svelte +1 -1
  12. package/src/Popover/Popover.svelte +3 -2
  13. package/src/Stores/{banner.js → banner.ts} +26 -11
  14. package/src/Stores/{notifications.js → notifications.ts} +31 -10
  15. package/src/Table/ArrayRenderer.svelte +2 -2
  16. package/src/Table/AttachmentRenderer.svelte +5 -5
  17. package/src/Table/BoldRenderer.svelte +2 -2
  18. package/src/Table/BooleanRenderer.svelte +2 -2
  19. package/src/Table/CellRenderer.svelte +10 -10
  20. package/src/Table/CodeRenderer.svelte +2 -2
  21. package/src/Table/DateTimeRenderer.svelte +4 -4
  22. package/src/Table/InternalRenderer.svelte +3 -3
  23. package/src/Table/RelationshipRenderer.svelte +5 -5
  24. package/src/Table/SelectEditRenderer.svelte +6 -6
  25. package/src/Table/StringRenderer.svelte +3 -3
  26. package/src/Table/Table.svelte +71 -50
  27. package/src/Tabs/Tabs.svelte +48 -23
  28. package/src/Tags/Tag.svelte +6 -6
  29. package/src/Tags/Tags.svelte +1 -1
  30. package/src/Tooltip/TooltipWrapper.svelte +4 -4
  31. package/src/TreeView/Item.svelte +6 -6
  32. package/src/TreeView/Tree.svelte +4 -4
  33. package/src/Typography/Code.svelte +2 -2
  34. package/src/Typography/Detail.svelte +4 -4
  35. package/src/index.ts +0 -2
  36. package/src/SideNavigation/Item.svelte +0 -63
  37. package/src/SideNavigation/Navigation.svelte +0 -13
  38. /package/src/Table/{index.js → index.ts} +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/bbui",
3
3
  "description": "A UI solution used in the different Budibase projects.",
4
- "version": "3.4.21",
4
+ "version": "3.4.23",
5
5
  "license": "MPL-2.0",
6
6
  "svelte": "src/index.ts",
7
7
  "module": "dist/bbui.mjs",
@@ -99,5 +99,5 @@
99
99
  }
100
100
  }
101
101
  },
102
- "gitHead": "eeb6e4ece3f2a32b32db2bedea6eb36430e0b010"
102
+ "gitHead": "fb5453d9f7c6b72b1ba00564564ce966536a19de"
103
103
  }
@@ -27,7 +27,7 @@ export type UpdateHandler = (
27
27
 
28
28
  interface Opts {
29
29
  anchor?: HTMLElement
30
- align: PopoverAlignment
30
+ align: PopoverAlignment | `${PopoverAlignment}`
31
31
  maxHeight?: number
32
32
  maxWidth?: number
33
33
  minWidth?: number
@@ -11,6 +11,7 @@
11
11
  export let active = false
12
12
  export let inactive = false
13
13
  export let hoverable = false
14
+ export let outlineColor = null
14
15
  </script>
15
16
 
16
17
  <!-- svelte-ignore a11y-no-static-element-interactions -->
@@ -29,6 +30,7 @@
29
30
  class:spectrum-Label--seafoam={seafoam}
30
31
  class:spectrum-Label--active={active}
31
32
  class:spectrum-Label--inactive={inactive}
33
+ style={outlineColor ? `border: 2px solid ${outlineColor}` : ""}
32
34
  >
33
35
  <slot />
34
36
  </span>
@@ -1,6 +1,6 @@
1
- <script>
2
- export let small = false
3
- export let disabled
1
+ <script lang="ts">
2
+ export let small: boolean = false
3
+ export let disabled: boolean = false
4
4
  </script>
5
5
 
6
6
  <button
@@ -64,7 +64,7 @@
64
64
  import { setContext, createEventDispatcher, onDestroy } from "svelte"
65
65
  import { generate } from "shortid"
66
66
 
67
- export let title
67
+ export let title = ""
68
68
  export let forceModal = false
69
69
 
70
70
  const dispatch = createEventDispatcher()
@@ -1,24 +1,24 @@
1
- <script>
1
+ <script lang="ts">
2
2
  import Field from "./Field.svelte"
3
3
  import Checkbox from "./Core/Checkbox.svelte"
4
4
  import { createEventDispatcher } from "svelte"
5
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
- export let helpText = null
6
+ export let value: boolean | undefined = undefined
7
+ export let label: string | undefined = undefined
8
+ export let labelPosition: "above" | "below" = "above"
9
+ export let text: string | undefined = undefined
10
+ export let disabled: boolean = false
11
+ export let error: string | undefined = undefined
12
+ export let size: "S" | "M" | "L" | "XL" = "M"
13
+ export let helpText: string | undefined = undefined
14
14
 
15
15
  const dispatch = createEventDispatcher()
16
- const onChange = e => {
16
+ const onChange = (e: CustomEvent<boolean>) => {
17
17
  value = e.detail
18
18
  dispatch("change", e.detail)
19
19
  }
20
20
  </script>
21
21
 
22
22
  <Field {helpText} {label} {labelPosition} {error}>
23
- <Checkbox {error} {disabled} {text} {value} {size} on:change={onChange} />
23
+ <Checkbox {disabled} {text} {value} {size} on:change={onChange} />
24
24
  </Field>
@@ -1,22 +1,26 @@
1
- <script>
1
+ <script lang="ts" context="module">
2
+ type Option = any
3
+ </script>
4
+
5
+ <script lang="ts">
2
6
  import Picker from "./Picker.svelte"
3
7
  import { createEventDispatcher } from "svelte"
4
8
 
5
- export let value = []
6
- export let id = null
7
- export let placeholder = null
8
- export let disabled = false
9
- export let options = []
10
- export let getOptionLabel = option => option
11
- export let getOptionValue = option => option
12
- export let readonly = false
13
- export let autocomplete = false
14
- export let sort = false
15
- export let autoWidth = false
16
- export let searchTerm = null
17
- export let customPopoverHeight = undefined
18
- export let open = false
19
- export let loading
9
+ export let value: string[] = []
10
+ export let id: string | undefined = undefined
11
+ export let placeholder: string | null = null
12
+ export let disabled: boolean = false
13
+ export let options: Option[] = []
14
+ export let getOptionLabel = (option: Option, _index?: number) => option
15
+ export let getOptionValue = (option: Option, _index?: number) => option
16
+ export let readonly: boolean = false
17
+ export let autocomplete: boolean = false
18
+ export let sort: boolean = false
19
+ export let autoWidth: boolean = false
20
+ export let searchTerm: string | null = null
21
+ export let customPopoverHeight: string | undefined = undefined
22
+ export let open: boolean = false
23
+ export let loading: boolean
20
24
  export let onOptionMouseenter = () => {}
21
25
  export let onOptionMouseleave = () => {}
22
26
 
@@ -27,10 +31,15 @@
27
31
  $: optionLookupMap = getOptionLookupMap(options)
28
32
 
29
33
  $: fieldText = getFieldText(arrayValue, optionLookupMap, placeholder)
30
- $: isOptionSelected = optionValue => selectedLookupMap[optionValue] === true
34
+ $: isOptionSelected = (optionValue: string) =>
35
+ selectedLookupMap[optionValue] === true
31
36
  $: toggleOption = makeToggleOption(selectedLookupMap, arrayValue)
32
37
 
33
- const getFieldText = (value, map, placeholder) => {
38
+ const getFieldText = (
39
+ value: string[],
40
+ map: Record<string, any> | null,
41
+ placeholder: string | null
42
+ ) => {
34
43
  if (Array.isArray(value) && value.length > 0) {
35
44
  if (!map) {
36
45
  return ""
@@ -42,8 +51,8 @@
42
51
  }
43
52
  }
44
53
 
45
- const getSelectedLookupMap = value => {
46
- let map = {}
54
+ const getSelectedLookupMap = (value: string[]) => {
55
+ const map: Record<string, boolean> = {}
47
56
  if (Array.isArray(value) && value.length > 0) {
48
57
  value.forEach(option => {
49
58
  if (option) {
@@ -54,22 +63,23 @@
54
63
  return map
55
64
  }
56
65
 
57
- const getOptionLookupMap = options => {
58
- let map = null
59
- if (options?.length) {
60
- map = {}
61
- options.forEach((option, idx) => {
62
- const optionValue = getOptionValue(option, idx)
63
- if (optionValue != null) {
64
- map[optionValue] = getOptionLabel(option, idx) || ""
65
- }
66
- })
66
+ const getOptionLookupMap = (options: Option[]) => {
67
+ if (!options?.length) {
68
+ return null
67
69
  }
70
+
71
+ const map: Record<string, any> = {}
72
+ options.forEach((option, idx) => {
73
+ const optionValue = getOptionValue(option, idx)
74
+ if (optionValue != null) {
75
+ map[optionValue] = getOptionLabel(option, idx) || ""
76
+ }
77
+ })
68
78
  return map
69
79
  }
70
80
 
71
- const makeToggleOption = (map, value) => {
72
- return optionValue => {
81
+ const makeToggleOption = (map: Record<string, boolean>, value: string[]) => {
82
+ return (optionValue: string) => {
73
83
  if (map[optionValue]) {
74
84
  const filtered = value.filter(option => option !== optionValue)
75
85
  dispatch("change", filtered)
@@ -28,6 +28,9 @@
28
28
  <svg
29
29
  on:contextmenu
30
30
  on:click
31
+ on:mouseover
32
+ on:mouseleave
33
+ on:focus
31
34
  class:hoverable
32
35
  class:disabled
33
36
  class="spectrum-Icon spectrum-Icon--size{size}"
@@ -47,7 +47,7 @@
47
47
  overflow-x: hidden;
48
48
  }
49
49
  .main {
50
- overflow-y: scroll;
50
+ overflow-y: auto;
51
51
  }
52
52
  .content {
53
53
  display: flex;
@@ -10,7 +10,7 @@
10
10
  export let secondary: boolean = false
11
11
  export let overBackground: boolean = false
12
12
  export let target: string | undefined = undefined
13
- export let download: boolean | undefined = undefined
13
+ export let download: string | undefined = undefined
14
14
  export let disabled: boolean = false
15
15
  export let tooltip: string | null = null
16
16
 
@@ -18,8 +18,9 @@
18
18
  import type { KeyboardEventHandler } from "svelte/elements"
19
19
  import { PopoverAlignment } from "../constants"
20
20
 
21
- export let anchor: HTMLElement
22
- export let align: PopoverAlignment = PopoverAlignment.Right
21
+ export let anchor: HTMLElement | undefined
22
+ export let align: PopoverAlignment | `${PopoverAlignment}` =
23
+ PopoverAlignment.Right
23
24
  export let portalTarget: string | undefined = undefined
24
25
  export let minWidth: number | undefined = undefined
25
26
  export let maxWidth: number | undefined = undefined
@@ -7,17 +7,26 @@ export const BANNER_TYPES = {
7
7
  WARNING: "warning",
8
8
  }
9
9
 
10
+ interface BannerConfig {
11
+ message?: string
12
+ type?: string
13
+ extraButtonText?: string
14
+ extraButtonAction?: () => void
15
+ onChange?: () => void
16
+ }
17
+
18
+ interface DefaultConfig {
19
+ messages: BannerConfig[]
20
+ }
21
+
10
22
  export function createBannerStore() {
11
- const DEFAULT_CONFIG = {
23
+ const DEFAULT_CONFIG: DefaultConfig = {
12
24
  messages: [],
13
25
  }
14
26
 
15
- const banner = writable(DEFAULT_CONFIG)
27
+ const banner = writable<DefaultConfig>(DEFAULT_CONFIG)
16
28
 
17
- const show = async (
18
- // eslint-disable-next-line
19
- config = { message, type, extraButtonText, extraButtonAction, onChange }
20
- ) => {
29
+ const show = async (config: BannerConfig = {}) => {
21
30
  banner.update(store => {
22
31
  return {
23
32
  ...store,
@@ -27,7 +36,7 @@ export function createBannerStore() {
27
36
  }
28
37
 
29
38
  const showStatus = async () => {
30
- const config = {
39
+ const config: BannerConfig = {
31
40
  message: "Some systems are experiencing issues",
32
41
  type: BANNER_TYPES.NEGATIVE,
33
42
  extraButtonText: "View Status",
@@ -37,18 +46,24 @@ export function createBannerStore() {
37
46
  await queue([config])
38
47
  }
39
48
 
40
- const queue = async entries => {
41
- const priority = {
49
+ const queue = async (entries: Array<BannerConfig>) => {
50
+ const priority: Record<string, number> = {
42
51
  [BANNER_TYPES.NEGATIVE]: 0,
43
52
  [BANNER_TYPES.WARNING]: 1,
44
53
  [BANNER_TYPES.INFO]: 2,
45
54
  }
46
55
  banner.update(store => {
47
56
  const sorted = [...store.messages, ...entries].sort((a, b) => {
48
- if (priority[a.type] == priority[b.type]) {
57
+ if (
58
+ priority[a.type as keyof typeof priority] ===
59
+ priority[b.type as keyof typeof priority]
60
+ ) {
49
61
  return 0
50
62
  }
51
- return priority[a.type] < priority[b.type] ? -1 : 1
63
+ return priority[a.type as keyof typeof priority] <
64
+ priority[b.type as keyof typeof priority]
65
+ ? -1
66
+ : 1
52
67
  })
53
68
  return {
54
69
  ...store,
@@ -2,9 +2,21 @@ import { writable } from "svelte/store"
2
2
 
3
3
  const NOTIFICATION_TIMEOUT = 3000
4
4
 
5
+ interface Notification {
6
+ id: string
7
+ type: string
8
+ message: string
9
+ icon: string
10
+ dismissable: boolean
11
+ action: (() => void) | null
12
+ actionMessage: string | null
13
+ wide: boolean
14
+ dismissTimeout: number
15
+ }
16
+
5
17
  export const createNotificationStore = () => {
6
- const timeoutIds = new Set()
7
- const _notifications = writable([], () => {
18
+ const timeoutIds = new Set<ReturnType<typeof setTimeout>>()
19
+ const _notifications = writable<Notification[]>([], () => {
8
20
  return () => {
9
21
  // clear all the timers
10
22
  timeoutIds.forEach(timeoutId => {
@@ -21,7 +33,7 @@ export const createNotificationStore = () => {
21
33
  }
22
34
 
23
35
  const send = (
24
- message,
36
+ message: string,
25
37
  {
26
38
  type = "default",
27
39
  icon = "",
@@ -30,7 +42,15 @@ export const createNotificationStore = () => {
30
42
  actionMessage = null,
31
43
  wide = false,
32
44
  dismissTimeout = NOTIFICATION_TIMEOUT,
33
- }
45
+ }: {
46
+ type?: string
47
+ icon?: string
48
+ autoDismiss?: boolean
49
+ action?: (() => void) | null
50
+ actionMessage?: string | null
51
+ wide?: boolean
52
+ dismissTimeout?: number
53
+ } = {}
34
54
  ) => {
35
55
  if (block) {
36
56
  return
@@ -60,7 +80,7 @@ export const createNotificationStore = () => {
60
80
  }
61
81
  }
62
82
 
63
- const dismissNotification = id => {
83
+ const dismissNotification = (id: string) => {
64
84
  _notifications.update(state => {
65
85
  return state.filter(n => n.id !== id)
66
86
  })
@@ -71,17 +91,18 @@ export const createNotificationStore = () => {
71
91
  return {
72
92
  subscribe,
73
93
  send,
74
- info: msg => send(msg, { type: "info", icon: "Info" }),
75
- error: msg =>
94
+ info: (msg: string) => send(msg, { type: "info", icon: "Info" }),
95
+ error: (msg: string) =>
76
96
  send(msg, { type: "error", icon: "Alert", autoDismiss: false }),
77
- warning: msg => send(msg, { type: "warning", icon: "Alert" }),
78
- success: msg => send(msg, { type: "success", icon: "CheckmarkCircle" }),
97
+ warning: (msg: string) => send(msg, { type: "warning", icon: "Alert" }),
98
+ success: (msg: string) =>
99
+ send(msg, { type: "success", icon: "CheckmarkCircle" }),
79
100
  blockNotifications,
80
101
  dismiss: dismissNotification,
81
102
  }
82
103
  }
83
104
 
84
- function id() {
105
+ function id(): string {
85
106
  return "_" + Math.random().toString(36).slice(2, 9)
86
107
  }
87
108
 
@@ -1,8 +1,8 @@
1
- <script>
1
+ <script lang="ts">
2
2
  import "@spectrum-css/label/dist/index-vars.css"
3
3
  import Badge from "../Badge/Badge.svelte"
4
4
 
5
- export let value
5
+ export let value: string | string[]
6
6
 
7
7
  const displayLimit = 5
8
8
 
@@ -1,15 +1,15 @@
1
- <script>
1
+ <script lang="ts">
2
2
  import Link from "../Link/Link.svelte"
3
3
 
4
- export let value
4
+ export let value: { name: string; url: string; extension: string }[]
5
5
 
6
6
  const displayLimit = 5
7
7
  $: attachments = value?.slice(0, displayLimit) ?? []
8
8
  $: leftover = (value?.length ?? 0) - attachments.length
9
9
 
10
- const imageExtensions = ["png", "tiff", "gif", "raw", "jpg", "jpeg"]
11
- const isImage = extension => {
12
- return imageExtensions.includes(extension?.toLowerCase())
10
+ const imageExtensions: string[] = ["png", "tiff", "gif", "raw", "jpg", "jpeg"]
11
+ const isImage = (extension: string | undefined): boolean => {
12
+ return imageExtensions.includes(extension?.toLowerCase() ?? "")
13
13
  }
14
14
  </script>
15
15
 
@@ -1,5 +1,5 @@
1
- <script>
2
- export let value
1
+ <script lang="ts">
2
+ export let value: string
3
3
  </script>
4
4
 
5
5
  <div class="bold">{value}</div>
@@ -1,7 +1,7 @@
1
- <script>
1
+ <script lang="ts">
2
2
  import "@spectrum-css/checkbox/dist/index-vars.css"
3
3
 
4
- export let value
4
+ export let value: boolean
5
5
  </script>
6
6
 
7
7
  <label
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script lang="ts">
2
2
  import StringRenderer from "./StringRenderer.svelte"
3
3
  import BooleanRenderer from "./BooleanRenderer.svelte"
4
4
  import DateTimeRenderer from "./DateTimeRenderer.svelte"
@@ -8,14 +8,14 @@
8
8
  import InternalRenderer from "./InternalRenderer.svelte"
9
9
  import { processStringSync } from "@budibase/string-templates"
10
10
 
11
- export let row
12
- export let schema
13
- export let value
14
- export let customRenderers = []
15
- export let snippets
11
+ export let row: Record<string, any>
12
+ export let schema: Record<string, any>
13
+ export let value: Record<string, any>
14
+ export let customRenderers: { column: string; component: any }[] = []
15
+ export let snippets: any
16
16
 
17
- let renderer
18
- const typeMap = {
17
+ let renderer: any
18
+ const typeMap: Record<string, any> = {
19
19
  boolean: BooleanRenderer,
20
20
  datetime: DateTimeRenderer,
21
21
  link: RelationshipRenderer,
@@ -33,7 +33,7 @@
33
33
  $: renderer = customRenderer?.component ?? typeMap[type] ?? StringRenderer
34
34
  $: cellValue = getCellValue(value, schema.template)
35
35
 
36
- const getType = schema => {
36
+ const getType = (schema: any): string => {
37
37
  // Use a string renderer for dates if we use a custom template
38
38
  if (schema?.type === "datetime" && schema?.template) {
39
39
  return "string"
@@ -41,7 +41,7 @@
41
41
  return schema?.type || "string"
42
42
  }
43
43
 
44
- const getCellValue = (value, template) => {
44
+ const getCellValue = (value: any, template: string | undefined): any => {
45
45
  if (!template) {
46
46
  return value
47
47
  }
@@ -1,5 +1,5 @@
1
- <script>
2
- export let value
1
+ <script lang="ts">
2
+ export let value: string
3
3
  </script>
4
4
 
5
5
  <code>{value}</code>
@@ -1,13 +1,13 @@
1
- <script>
1
+ <script lang="ts">
2
2
  import dayjs from "dayjs"
3
3
 
4
- export let value
5
- export let schema
4
+ export let value: string | Date
5
+ export let schema: { timeOnly?: boolean; dateOnly?: boolean }
6
6
 
7
7
  // adding the 0- will turn a string like 00:00:00 into a valid ISO
8
8
  // date, but will make actual ISO dates invalid
9
9
  $: time = new Date(`0-${value}`)
10
- $: isTimeOnly = !isNaN(time) || schema?.timeOnly
10
+ $: isTimeOnly = !isNaN(time as any) || schema?.timeOnly
11
11
  $: isDateOnly = schema?.dateOnly
12
12
  $: format = isTimeOnly
13
13
  ? "HH:mm:ss"
@@ -1,11 +1,11 @@
1
- <script>
1
+ <script lang="ts">
2
2
  import Icon from "../Icon/Icon.svelte"
3
3
  import { copyToClipboard } from "../helpers"
4
4
  import { notifications } from "../Stores/notifications"
5
5
 
6
- export let value
6
+ export let value: string
7
7
 
8
- const onClick = async e => {
8
+ const onClick = async (e: MouseEvent): Promise<void> => {
9
9
  e.stopPropagation()
10
10
  try {
11
11
  await copyToClipboard(value)
@@ -1,11 +1,11 @@
1
- <script>
1
+ <script lang="ts">
2
2
  import "@spectrum-css/label/dist/index-vars.css"
3
3
  import { createEventDispatcher } from "svelte"
4
4
  import Badge from "../Badge/Badge.svelte"
5
5
 
6
- export let row
7
- export let value
8
- export let schema
6
+ export let row: { tableId: string; _id: string }
7
+ export let value: { primaryDisplay?: string }[] | undefined
8
+ export let schema: { name?: string }
9
9
 
10
10
  const dispatch = createEventDispatcher()
11
11
  const displayLimit = 5
@@ -13,7 +13,7 @@
13
13
  $: relationships = value?.slice(0, displayLimit) ?? []
14
14
  $: leftover = (value?.length ?? 0) - relationships.length
15
15
 
16
- const onClick = e => {
16
+ const onClick = (e: MouseEvent) => {
17
17
  e.stopPropagation()
18
18
  dispatch("clickrelationship", {
19
19
  tableId: row.tableId,
@@ -1,12 +1,12 @@
1
- <script>
1
+ <script lang="ts">
2
2
  import Checkbox from "../Form/Checkbox.svelte"
3
3
  import ActionButton from "../ActionButton/ActionButton.svelte"
4
4
 
5
- export let selected
6
- export let onEdit
7
- export let allowSelectRows = false
8
- export let allowEditRows = false
9
- export let data
5
+ export let selected: boolean | undefined
6
+ export let onEdit: (_e: Event) => void
7
+ export let allowSelectRows: boolean = false
8
+ export let allowEditRows: boolean = false
9
+ export let data: Record<string, any>
10
10
  </script>
11
11
 
12
12
  <div>
@@ -1,6 +1,6 @@
1
- <script>
2
- export let value
3
- export let schema
1
+ <script lang="ts">
2
+ export let value: string | object
3
+ export let schema: { capitalise?: boolean }
4
4
  </script>
5
5
 
6
6
  <div class:capitalise={schema?.capitalise}>