@budibase/bbui 1.0.123-alpha.0 → 1.0.123

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/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": "1.0.123-alpha.0",
4
+ "version": "1.0.123",
5
5
  "license": "MPL-2.0",
6
6
  "svelte": "src/index.js",
7
7
  "module": "dist/bbui.es.js",
@@ -38,7 +38,7 @@
38
38
  ],
39
39
  "dependencies": {
40
40
  "@adobe/spectrum-css-workflow-icons": "^1.2.1",
41
- "@budibase/string-templates": "^1.0.123-alpha.0",
41
+ "@budibase/string-templates": "^1.0.123",
42
42
  "@spectrum-css/actionbutton": "^1.0.1",
43
43
  "@spectrum-css/actiongroup": "^1.0.1",
44
44
  "@spectrum-css/avatar": "^3.0.2",
@@ -84,5 +84,5 @@
84
84
  "svelte-flatpickr": "^3.2.3",
85
85
  "svelte-portal": "^1.0.0"
86
86
  },
87
- "gitHead": "94632aed5c844bb780b9a81238207b4965c40a54"
87
+ "gitHead": "db99c31b53d0dbbb788335126e45d1cc2f39fbf0"
88
88
  }
@@ -80,4 +80,8 @@
80
80
  .active svg {
81
81
  color: var(--spectrum-global-color-blue-600);
82
82
  }
83
+
84
+ .spectrum-ActionButton-label {
85
+ padding-bottom: 2px;
86
+ }
83
87
  </style>
@@ -6,7 +6,6 @@
6
6
  export let disabled = false
7
7
  export let align = "left"
8
8
  export let portalTarget
9
- export let dataCy
10
9
 
11
10
  let anchor
12
11
  let dropdown
@@ -37,7 +36,7 @@
37
36
  <div use:getAnchor on:click={openMenu}>
38
37
  <slot name="control" />
39
38
  </div>
40
- <Popover bind:this={dropdown} {anchor} {align} {portalTarget} {dataCy}>
39
+ <Popover bind:this={dropdown} {anchor} {align} {portalTarget}>
41
40
  <Menu>
42
41
  <slot />
43
42
  </Menu>
@@ -19,33 +19,18 @@
19
19
  const dispatch = createEventDispatcher()
20
20
  const flatpickrId = `${uuid()}-wrapper`
21
21
  let open = false
22
- let flatpickr, flatpickrOptions
23
-
24
- const resolveTimeStamp = timestamp => {
25
- let maskedDate = new Date(`0-${timestamp}`)
26
-
27
- if (maskedDate instanceof Date && !isNaN(maskedDate.getTime())) {
28
- return maskedDate
29
- } else {
30
- return null
31
- }
32
- }
22
+ let flatpickr, flatpickrOptions, isTimeOnly
33
23
 
24
+ $: isTimeOnly = !timeOnly && value ? !isNaN(new Date(`0-${value}`)) : timeOnly
34
25
  $: flatpickrOptions = {
35
26
  element: `#${flatpickrId}`,
36
- enableTime: timeOnly || enableTime || false,
37
- noCalendar: timeOnly || false,
27
+ enableTime: isTimeOnly || enableTime || false,
28
+ noCalendar: isTimeOnly || false,
38
29
  altInput: true,
39
- altFormat: timeOnly ? "H:i" : enableTime ? "F j Y, H:i" : "F j, Y",
30
+ altFormat: isTimeOnly ? "H:i" : enableTime ? "F j Y, H:i" : "F j, Y",
40
31
  wrap: true,
41
32
  appendTo,
42
33
  disableMobile: "true",
43
- onReady: () => {
44
- let timestamp = resolveTimeStamp(value)
45
- if (timeOnly && timestamp) {
46
- dispatch("change", timestamp.toISOString())
47
- }
48
- },
49
34
  }
50
35
 
51
36
  const handleChange = event => {
@@ -54,9 +39,10 @@
54
39
  if (newValue) {
55
40
  newValue = newValue.toISOString()
56
41
  }
57
- // if time only set date component to 2000-01-01
42
+ // if time only set date component to today
58
43
  if (timeOnly) {
59
- newValue = `2000-01-01T${newValue.split("T")[1]}`
44
+ const todayDate = new Date().toISOString().split("T")[0]
45
+ newValue = `${todayDate}T${newValue.split("T")[1]}`
60
46
  }
61
47
  dispatch("change", newValue)
62
48
  }
@@ -90,13 +76,10 @@
90
76
  return null
91
77
  }
92
78
  let date
93
- let time
94
-
79
+ let time = new Date(`0-${val}`)
95
80
  // it is a string like 00:00:00, just time
96
- let ts = resolveTimeStamp(val)
97
-
98
- if (timeOnly && ts) {
99
- date = ts
81
+ if (timeOnly || (typeof val === "string" && !isNaN(time))) {
82
+ date = time
100
83
  } else if (val instanceof Date) {
101
84
  // Use real date obj if already parsed
102
85
  date = val
@@ -118,7 +101,7 @@
118
101
  }
119
102
  </script>
120
103
 
121
- {#key timeOnly}
104
+ {#key isTimeOnly}
122
105
  <Flatpickr
123
106
  bind:flatpickr
124
107
  value={parseDate(value)}
@@ -3,9 +3,6 @@
3
3
  </script>
4
4
 
5
5
  <script>
6
- import Tooltip from "../Tooltip/Tooltip.svelte"
7
- import { fade } from "svelte/transition"
8
-
9
6
  export let direction = "n"
10
7
  export let name = "Add"
11
8
  export let hidden = false
@@ -13,52 +10,30 @@
13
10
  export let hoverable = false
14
11
  export let disabled = false
15
12
  export let color
16
- export let tooltip
17
13
 
18
14
  $: rotation = getRotation(direction)
19
15
 
20
- let showTooltip = false
21
-
22
16
  const getRotation = direction => {
23
17
  return directions.indexOf(direction) * 45
24
18
  }
25
19
  </script>
26
20
 
27
- <div
28
- class="icon"
29
- on:mouseover={() => (showTooltip = true)}
30
- on:focus={() => (showTooltip = true)}
31
- on:mouseleave={() => (showTooltip = false)}
32
- on:click={() => (showTooltip = false)}
21
+ <svg
22
+ on:click
23
+ class:hoverable
24
+ class:disabled
25
+ class="spectrum-Icon spectrum-Icon--size{size}"
26
+ focusable="false"
27
+ aria-hidden={hidden}
28
+ aria-label={name}
29
+ style={`transform: rotate(${rotation}deg); ${
30
+ color ? `color: ${color};` : ""
31
+ }`}
33
32
  >
34
- <svg
35
- on:click
36
- class:hoverable
37
- class:disabled
38
- class="spectrum-Icon spectrum-Icon--size{size}"
39
- focusable="false"
40
- aria-hidden={hidden}
41
- aria-label={name}
42
- style={`transform: rotate(${rotation}deg); ${
43
- color ? `color: ${color};` : ""
44
- }`}
45
- >
46
- <use style="pointer-events: none;" xlink:href="#spectrum-icon-18-{name}" />
47
- </svg>
48
- {#if tooltip && showTooltip}
49
- <div class="tooltip" in:fade={{ duration: 130, delay: 250 }}>
50
- <Tooltip textWrapping direction={"bottom"} text={tooltip} />
51
- </div>
52
- {/if}
53
- </div>
33
+ <use xlink:href="#spectrum-icon-18-{name}" />
34
+ </svg>
54
35
 
55
36
  <style>
56
- .icon {
57
- position: relative;
58
- display: grid;
59
- place-items: center;
60
- }
61
-
62
37
  svg.hoverable {
63
38
  pointer-events: all;
64
39
  transition: color var(--spectrum-global-animation-duration-100, 130ms);
@@ -72,15 +47,4 @@
72
47
  color: var(--spectrum-global-color-gray-500) !important;
73
48
  pointer-events: none !important;
74
49
  }
75
-
76
- .tooltip {
77
- position: absolute;
78
- pointer-events: none;
79
- left: 50%;
80
- top: calc(100% + 4px);
81
- width: 100vw;
82
- max-width: 150px;
83
- transform: translateX(-50%);
84
- text-align: center;
85
- }
86
50
  </style>
@@ -36,10 +36,6 @@
36
36
  padding-left: var(--spacing-l);
37
37
  padding-right: var(--spacing-l);
38
38
  }
39
- .paddingX-XL {
40
- padding-left: var(--spacing-xl);
41
- padding-right: var(--spacing-xl);
42
- }
43
39
  .paddingY-S {
44
40
  padding-top: var(--spacing-s);
45
41
  padding-bottom: var(--spacing-s);
@@ -52,10 +48,6 @@
52
48
  padding-top: var(--spacing-l);
53
49
  padding-bottom: var(--spacing-l);
54
50
  }
55
- .paddingY-XL {
56
- padding-top: var(--spacing-xl);
57
- padding-bottom: var(--spacing-xl);
58
- }
59
51
  .gap-XXS {
60
52
  grid-gap: var(--spacing-xs);
61
53
  }
@@ -1,9 +1,8 @@
1
1
  <script>
2
2
  export let wide = false
3
- export let maxWidth = "80ch"
4
3
  </script>
5
4
 
6
- <div style="--max-width: {maxWidth}" class:wide>
5
+ <div class:wide>
7
6
  <slot />
8
7
  </div>
9
8
 
@@ -13,7 +12,7 @@
13
12
  flex-direction: column;
14
13
  justify-content: flex-start;
15
14
  align-items: stretch;
16
- max-width: var(--max-width);
15
+ max-width: 80ch;
17
16
  margin: 0 auto;
18
17
  padding: calc(var(--spacing-xl) * 2);
19
18
  min-height: calc(100% - var(--spacing-xl) * 4);
@@ -23,7 +23,6 @@
23
23
  export let secondaryButtonText = undefined
24
24
  export let secondaryAction = undefined
25
25
  export let secondaryButtonWarning = false
26
- export let dataCy = null
27
26
 
28
27
  const { hide, cancel } = getContext(Context.Modal)
29
28
  let loading = false
@@ -64,26 +63,21 @@
64
63
  role="dialog"
65
64
  tabindex="-1"
66
65
  aria-modal="true"
67
- data-cy={dataCy}
68
66
  >
69
67
  <div class="spectrum-Dialog-grid">
70
- {#if title || $$slots.header}
68
+ {#if title}
71
69
  <h1
72
70
  class="spectrum-Dialog-heading spectrum-Dialog-heading--noHeader"
73
71
  class:noDivider={!showDivider}
74
72
  class:header-spacing={$$slots.header}
75
73
  >
76
- {#if title}
77
- {title}
78
- {:else if $$slots.header}
79
- <slot name="header" />
80
- {/if}
74
+ {title}
75
+ <slot name="header" />
81
76
  </h1>
82
77
  {#if showDivider}
83
78
  <Divider size="M" />
84
79
  {/if}
85
80
  {/if}
86
-
87
81
  <!-- TODO: Remove content-grid class once Layout components are in bbui -->
88
82
  <section class="spectrum-Dialog-content content-grid">
89
83
  <slot />
@@ -10,17 +10,6 @@
10
10
  export let anchor
11
11
  export let align = "right"
12
12
  export let portalTarget
13
- export let dataCy
14
-
15
- export let direction = "bottom"
16
- export let showTip = false
17
-
18
- let tipSvg =
19
- '<svg xmlns="http://www.w3.org/svg/2000" width="23" height="12" class="spectrum-Popover-tip" > <path class="spectrum-Popover-tip-triangle" d="M 0.7071067811865476 0 L 11.414213562373096 10.707106781186548 L 22.121320343559645 0" /> </svg>'
20
-
21
- $: tooltipClasses = showTip
22
- ? `spectrum-Popover--withTip spectrum-Popover--${direction}`
23
- : ""
24
13
 
25
14
  export const show = () => {
26
15
  dispatch("open")
@@ -48,14 +37,9 @@
48
37
  use:positionDropdown={{ anchor, align }}
49
38
  use:clickOutside={hide}
50
39
  on:keydown={handleEscape}
51
- class={"spectrum-Popover is-open " + (tooltipClasses || "")}
40
+ class="spectrum-Popover is-open"
52
41
  role="presentation"
53
- data-cy={dataCy}
54
42
  >
55
- {#if showTip}
56
- {@html tipSvg}
57
- {/if}
58
-
59
43
  <slot />
60
44
  </div>
61
45
  </Portal>
@@ -65,13 +49,4 @@
65
49
  .spectrum-Popover {
66
50
  min-width: var(--spectrum-global-dimension-size-2000) !important;
67
51
  }
68
- .spectrum-Popover.is-open.spectrum-Popover--withTip {
69
- margin-top: var(--spacing-xs);
70
- margin-left: var(--spacing-xl);
71
- }
72
- :global(.spectrum-Popover--bottom .spectrum-Popover-tip),
73
- :global(.spectrum-Popover--top .spectrum-Popover-tip) {
74
- left: 90%;
75
- margin-left: calc(var(--spectrum-global-dimension-size-150) * -1);
76
- }
77
52
  </style>
@@ -16,11 +16,11 @@
16
16
  easing: easing,
17
17
  })
18
18
 
19
- $: if (value || value === 0) $progress = value
19
+ $: if (value) $progress = value
20
20
  </script>
21
21
 
22
22
  <div
23
- class:spectrum-ProgressBar--indeterminate={!value && value !== 0}
23
+ class:spectrum-ProgressBar--indeterminate={!value}
24
24
  class:spectrum-ProgressBar--sideLabel={sideLabel}
25
25
  class="spectrum-ProgressBar spectrum-ProgressBar--size{size}"
26
26
  value={$progress}
@@ -28,7 +28,7 @@
28
28
  aria-valuenow={$progress}
29
29
  aria-valuemin="0"
30
30
  aria-valuemax="100"
31
- style={width ? `width: ${width};` : ""}
31
+ style={width ? `width: ${width}px;` : ""}
32
32
  >
33
33
  {#if $$slots}
34
34
  <div
@@ -37,7 +37,7 @@
37
37
  <slot />
38
38
  </div>
39
39
  {/if}
40
- {#if value || value === 0}
40
+ {#if value}
41
41
  <div
42
42
  class="spectrum-FieldLabel spectrum-ProgressBar-percentage spectrum-FieldLabel--size{size}"
43
43
  >
@@ -47,7 +47,7 @@
47
47
  <div class="spectrum-ProgressBar-track">
48
48
  <div
49
49
  class="spectrum-ProgressBar-fill"
50
- style={value || value === 0 ? `width: ${$progress}%` : ""}
50
+ style={value ? `width: ${$progress}%` : ""}
51
51
  />
52
52
  </div>
53
53
  <div class="spectrum-ProgressBar-label" hidden="" />
@@ -1,21 +1,42 @@
1
1
  <script>
2
2
  import Icon from "../Icon/Icon.svelte"
3
- import { copyToClipboard } from "../helpers"
4
3
  import { notifications } from "../Stores/notifications"
5
-
6
4
  export let value
7
5
 
8
- const onClick = async e => {
6
+ const onClick = e => {
9
7
  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
- }
8
+ copyToClipboard(value)
9
+ }
10
+
11
+ const copyToClipboard = value => {
12
+ return new Promise(res => {
13
+ if (navigator.clipboard && window.isSecureContext) {
14
+ // Try using the clipboard API first
15
+ navigator.clipboard.writeText(value).then(res)
16
+ } else {
17
+ // Fall back to the textarea hack
18
+ let textArea = document.createElement("textarea")
19
+ textArea.value = value
20
+ textArea.style.position = "fixed"
21
+ textArea.style.left = "-9999px"
22
+ textArea.style.top = "-9999px"
23
+ document.body.appendChild(textArea)
24
+ textArea.focus()
25
+ textArea.select()
26
+ document.execCommand("copy")
27
+ textArea.remove()
28
+ res()
29
+ }
30
+ })
31
+ .then(() => {
32
+ notifications.success("Copied to clipboard")
33
+ })
34
+ .catch(() => {
35
+ notifications.error(
36
+ "Failed to copy to clipboard. Check the dev console for the value."
37
+ )
38
+ console.warn("Failed to copy the value", value)
39
+ })
19
40
  }
20
41
  </script>
21
42
 
@@ -36,7 +36,6 @@
36
36
  export let disableSorting = false
37
37
  export let autoSortColumns = true
38
38
  export let compact = false
39
- export let customPlaceholder = false
40
39
 
41
40
  const dispatch = createEventDispatcher()
42
41
 
@@ -388,24 +387,13 @@
388
387
  </div>
389
388
  {/each}
390
389
  {:else}
391
- <div
392
- class="placeholder"
393
- class:placeholder--custom={customPlaceholder}
394
- class:placeholder--no-fields={!fields?.length}
395
- >
396
- {#if customPlaceholder}
397
- <slot name="placeholder" />
398
- {:else}
399
- <div class="placeholder-content">
400
- <svg
401
- class="spectrum-Icon spectrum-Icon--sizeXXL"
402
- focusable="false"
403
- >
404
- <use xlink:href="#spectrum-icon-18-Table" />
405
- </svg>
406
- <div>No rows found</div>
407
- </div>
408
- {/if}
390
+ <div class="placeholder" class:placeholder--no-fields={!fields?.length}>
391
+ <div class="placeholder-content">
392
+ <svg class="spectrum-Icon spectrum-Icon--sizeXXL" focusable="false">
393
+ <use xlink:href="#spectrum-icon-18-Table" />
394
+ </svg>
395
+ <div>No rows found</div>
396
+ </div>
409
397
  </div>
410
398
  {/if}
411
399
  </div>
@@ -470,13 +458,6 @@
470
458
  justify-content: flex-start;
471
459
  align-items: center;
472
460
  user-select: none;
473
- border-top: var(--table-border);
474
- }
475
- .spectrum-Table-headCell:first-of-type {
476
- border-left: var(--table-border);
477
- }
478
- .spectrum-Table-headCell:last-of-type {
479
- border-right: var(--table-border);
480
461
  }
481
462
  .spectrum-Table-headCell--alignCenter {
482
463
  justify-content: center;
@@ -595,19 +576,16 @@
595
576
  border-top: none;
596
577
  grid-column: 1 / -1;
597
578
  background-color: var(--table-bg);
598
- padding: 40px;
599
579
  }
600
580
  .placeholder--no-fields {
601
581
  border-top: var(--table-border);
602
582
  }
603
- .placeholder--custom {
604
- justify-content: flex-start;
605
- }
606
583
  .wrapper--quiet .placeholder {
607
584
  border-left: none;
608
585
  border-right: none;
609
586
  }
610
587
  .placeholder-content {
588
+ padding: 40px;
611
589
  display: flex;
612
590
  flex-direction: column;
613
591
  justify-content: center;
@@ -108,7 +108,7 @@
108
108
  padding-left: var(--spacing-xl);
109
109
  padding-right: var(--spacing-xl);
110
110
  position: relative;
111
- border-bottom: 1px solid var(--spectrum-global-color-gray-300);
111
+ border-bottom: var(--border-light);
112
112
  }
113
113
  .spectrum-Tabs-content {
114
114
  margin-top: var(--spectrum-global-dimension-static-size-150);
@@ -5,14 +5,12 @@
5
5
  export let serif = false
6
6
  export let weight = null
7
7
  export let textAlign = null
8
- export let color = null
9
8
  </script>
10
9
 
11
10
  <p
12
11
  style={`
13
12
  ${weight ? `font-weight:${weight};` : ""}
14
13
  ${textAlign ? `text-align:${textAlign};` : ""}
15
- ${color ? `color:${color};` : ""}
16
14
  `}
17
15
  class="spectrum-Body spectrum-Body--size{size}"
18
16
  class:spectrum-Body--serif={serif}
@@ -5,13 +5,12 @@
5
5
  export let size = "M"
6
6
  export let textAlign
7
7
  export let noPadding = false
8
- export let weight = "default" // light, heavy, default
9
8
  </script>
10
9
 
11
10
  <h1
12
11
  style={textAlign ? `text-align:${textAlign}` : ``}
13
12
  class:noPadding
14
- class="spectrum-Heading spectrum-Heading--size{size} spectrum-Heading--{weight}"
13
+ class="spectrum-Heading spectrum-Heading--size{size}"
15
14
  >
16
15
  <slot />
17
16
  </h1>
package/src/helpers.js CHANGED
@@ -106,29 +106,3 @@ export const deepSet = (obj, key, value) => {
106
106
  export const cloneDeep = obj => {
107
107
  return JSON.parse(JSON.stringify(obj))
108
108
  }
109
-
110
- /**
111
- * Copies a value to the clipboard
112
- * @param value the value to copy
113
- */
114
- export const copyToClipboard = value => {
115
- return new Promise(res => {
116
- if (navigator.clipboard && window.isSecureContext) {
117
- // Try using the clipboard API first
118
- navigator.clipboard.writeText(value).then(res)
119
- } else {
120
- // Fall back to the textarea hack
121
- let textArea = document.createElement("textarea")
122
- textArea.value = value
123
- textArea.style.position = "fixed"
124
- textArea.style.left = "-9999px"
125
- textArea.style.top = "-9999px"
126
- document.body.appendChild(textArea)
127
- textArea.focus()
128
- textArea.select()
129
- document.execCommand("copy")
130
- textArea.remove()
131
- res()
132
- }
133
- })
134
- }