@budibase/bbui 2.3.19 → 2.3.21-alpha.0

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": "2.3.19",
4
+ "version": "2.3.21-alpha.0",
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": "^2.3.19",
41
+ "@budibase/string-templates": "2.3.21-alpha.0",
42
42
  "@spectrum-css/accordion": "3.0.24",
43
43
  "@spectrum-css/actionbutton": "1.0.1",
44
44
  "@spectrum-css/actiongroup": "1.0.1",
@@ -89,5 +89,5 @@
89
89
  "resolutions": {
90
90
  "loader-utils": "1.4.1"
91
91
  },
92
- "gitHead": "dfb412df1e5ae11e6d0772a83d4add7c4ee7d1d2"
92
+ "gitHead": "e07c36dd8ca5d1fcfcf18961457dc539016535ca"
93
93
  }
@@ -1,6 +1,9 @@
1
1
  <script>
2
2
  import "@spectrum-css/actionbutton/dist/index-vars.css"
3
3
  import { createEventDispatcher } from "svelte"
4
+ import Tooltip from "../Tooltip/Tooltip.svelte"
5
+ import { fade } from "svelte/transition"
6
+
4
7
  const dispatch = createEventDispatcher()
5
8
 
6
9
  export let quiet = false
@@ -13,6 +16,9 @@
13
16
  export let active = false
14
17
  export let fullWidth = false
15
18
  export let noPadding = false
19
+ export let tooltip = ""
20
+
21
+ let showTooltip = false
16
22
 
17
23
  function longPress(element) {
18
24
  if (!longPressable) return
@@ -35,42 +41,54 @@
35
41
  }
36
42
  </script>
37
43
 
38
- <button
39
- use:longPress
40
- class:spectrum-ActionButton--quiet={quiet}
41
- class:spectrum-ActionButton--emphasized={emphasized}
42
- class:is-selected={selected}
43
- class:noPadding
44
- class:fullWidth
45
- class="spectrum-ActionButton spectrum-ActionButton--size{size}"
46
- class:active
47
- {disabled}
48
- on:longPress
49
- on:click|preventDefault
44
+ <span
45
+ class="btn-wrap"
46
+ on:mouseover={() => (showTooltip = true)}
47
+ on:mouseleave={() => (showTooltip = false)}
48
+ on:focus={() => (showTooltip = true)}
50
49
  >
51
- {#if longPressable}
52
- <svg
53
- class="spectrum-Icon spectrum-UIIcon-CornerTriangle100 spectrum-ActionButton-hold"
54
- focusable="false"
55
- aria-hidden="true"
56
- >
57
- <use xlink:href="#spectrum-css-icon-CornerTriangle100" />
58
- </svg>
59
- {/if}
60
- {#if icon}
61
- <svg
62
- class="spectrum-Icon spectrum-Icon--size{size}"
63
- focusable="false"
64
- aria-hidden="true"
65
- aria-label={icon}
66
- >
67
- <use xlink:href="#spectrum-icon-18-{icon}" />
68
- </svg>
69
- {/if}
70
- {#if $$slots}
71
- <span class="spectrum-ActionButton-label"><slot /></span>
72
- {/if}
73
- </button>
50
+ <button
51
+ use:longPress
52
+ class:spectrum-ActionButton--quiet={quiet}
53
+ class:spectrum-ActionButton--emphasized={emphasized}
54
+ class:is-selected={selected}
55
+ class:noPadding
56
+ class:fullWidth
57
+ class="spectrum-ActionButton spectrum-ActionButton--size{size}"
58
+ class:active
59
+ {disabled}
60
+ on:longPress
61
+ on:click|preventDefault
62
+ >
63
+ {#if longPressable}
64
+ <svg
65
+ class="spectrum-Icon spectrum-UIIcon-CornerTriangle100 spectrum-ActionButton-hold"
66
+ focusable="false"
67
+ aria-hidden="true"
68
+ >
69
+ <use xlink:href="#spectrum-css-icon-CornerTriangle100" />
70
+ </svg>
71
+ {/if}
72
+ {#if icon}
73
+ <svg
74
+ class="spectrum-Icon spectrum-Icon--size{size}"
75
+ focusable="false"
76
+ aria-hidden="true"
77
+ aria-label={icon}
78
+ >
79
+ <use xlink:href="#spectrum-icon-18-{icon}" />
80
+ </svg>
81
+ {/if}
82
+ {#if $$slots}
83
+ <span class="spectrum-ActionButton-label"><slot /></span>
84
+ {/if}
85
+ {#if tooltip && showTooltip}
86
+ <div class="tooltip" in:fade={{ duration: 130, delay: 250 }}>
87
+ <Tooltip textWrapping direction="bottom" text={tooltip} />
88
+ </div>
89
+ {/if}
90
+ </button>
91
+ </span>
74
92
 
75
93
  <style>
76
94
  .fullWidth {
@@ -98,4 +116,14 @@
98
116
  .is-selected:not(.emphasized) .spectrum-Icon {
99
117
  color: var(--spectrum-global-color-gray-900);
100
118
  }
119
+ .tooltip {
120
+ position: absolute;
121
+ pointer-events: none;
122
+ left: 50%;
123
+ top: calc(100% + 4px);
124
+ width: 100vw;
125
+ max-width: 150px;
126
+ transform: translateX(-50%);
127
+ text-align: center;
128
+ }
101
129
  </style>
@@ -14,6 +14,9 @@
14
14
  export let autocomplete = false
15
15
  export let sort = false
16
16
  export let autoWidth = false
17
+ export let fetchTerm = null
18
+ export let useFetch = false
19
+ export let customPopoverHeight
17
20
 
18
21
  const dispatch = createEventDispatcher()
19
22
 
@@ -83,10 +86,13 @@
83
86
  {options}
84
87
  isPlaceholder={!value?.length}
85
88
  {autocomplete}
89
+ bind:fetchTerm
90
+ {useFetch}
86
91
  {isOptionSelected}
87
92
  {getOptionLabel}
88
93
  {getOptionValue}
89
94
  onSelectOption={toggleOption}
90
95
  {sort}
91
96
  {autoWidth}
97
+ {customPopoverHeight}
92
98
  />
@@ -24,6 +24,7 @@
24
24
  export let getOptionLabel = option => option
25
25
  export let getOptionValue = option => option
26
26
  export let getOptionIcon = () => null
27
+ export let useOptionIconImage = false
27
28
  export let getOptionColour = () => null
28
29
  export let open = false
29
30
  export let readonly = false
@@ -31,6 +32,11 @@
31
32
  export let autoWidth = false
32
33
  export let autocomplete = false
33
34
  export let sort = false
35
+ export let fetchTerm = null
36
+ export let useFetch = false
37
+ export let customPopoverHeight
38
+ export let align = "left"
39
+ export let footer = null
34
40
 
35
41
  const dispatch = createEventDispatcher()
36
42
 
@@ -71,7 +77,7 @@
71
77
  }
72
78
 
73
79
  const getFilteredOptions = (options, term, getLabel) => {
74
- if (autocomplete && term) {
80
+ if (autocomplete && term && !fetchTerm) {
75
81
  const lowerCaseTerm = term.toLowerCase()
76
82
  return options.filter(option => {
77
83
  return `${getLabel(option)}`.toLowerCase().includes(lowerCaseTerm)
@@ -130,12 +136,13 @@
130
136
 
131
137
  <Popover
132
138
  anchor={button}
133
- align="left"
139
+ align={align || "left"}
134
140
  bind:this={popover}
135
141
  {open}
136
142
  on:close={() => (open = false)}
137
143
  useAnchorWidth={!autoWidth}
138
144
  maxWidth={autoWidth ? 400 : null}
145
+ customHeight={customPopoverHeight}
139
146
  >
140
147
  <div
141
148
  class="popover-content"
@@ -144,8 +151,9 @@
144
151
  >
145
152
  {#if autocomplete}
146
153
  <Search
147
- value={searchTerm}
148
- on:change={event => (searchTerm = event.detail)}
154
+ value={useFetch ? fetchTerm : searchTerm}
155
+ on:change={event =>
156
+ useFetch ? (fetchTerm = event.detail) : (searchTerm = event.detail)}
149
157
  {disabled}
150
158
  placeholder="Search"
151
159
  />
@@ -183,7 +191,16 @@
183
191
  >
184
192
  {#if getOptionIcon(option, idx)}
185
193
  <span class="option-extra icon">
186
- <Icon size="S" name={getOptionIcon(option, idx)} />
194
+ {#if useOptionIconImage}
195
+ <img
196
+ src={getOptionIcon(option, idx)}
197
+ alt="icon"
198
+ width="15"
199
+ height="15"
200
+ />
201
+ {:else}
202
+ <Icon size="S" name={getOptionIcon(option, idx)} />
203
+ {/if}
187
204
  </span>
188
205
  {/if}
189
206
  {#if getOptionColour(option, idx)}
@@ -205,6 +222,12 @@
205
222
  {/each}
206
223
  {/if}
207
224
  </ul>
225
+
226
+ {#if footer}
227
+ <div class="footer">
228
+ {footer}
229
+ </div>
230
+ {/if}
208
231
  </div>
209
232
  </Popover>
210
233
 
@@ -247,7 +270,7 @@
247
270
  }
248
271
  .popover-content.auto-width .spectrum-Menu-itemLabel {
249
272
  white-space: nowrap;
250
- overflow: hidden;
273
+ overflow: none;
251
274
  text-overflow: ellipsis;
252
275
  }
253
276
  .popover-content:not(.auto-width) .spectrum-Menu-itemLabel {
@@ -281,4 +304,11 @@
281
304
  .popover-content :global(.spectrum-Search .spectrum-Textfield-icon) {
282
305
  top: 9px;
283
306
  }
307
+
308
+ .footer {
309
+ padding: 4px 12px 12px 12px;
310
+ font-style: italic;
311
+ max-width: 170px;
312
+ font-size: 12px;
313
+ }
284
314
  </style>
@@ -11,6 +11,7 @@
11
11
  export let getOptionLabel = option => option
12
12
  export let getOptionValue = option => option
13
13
  export let getOptionIcon = () => null
14
+ export let useOptionIconImage = false
14
15
  export let getOptionColour = () => null
15
16
  export let isOptionEnabled
16
17
  export let readonly = false
@@ -18,6 +19,8 @@
18
19
  export let autoWidth = false
19
20
  export let autocomplete = false
20
21
  export let sort = false
22
+ export let align
23
+ export let footer = null
21
24
 
22
25
  const dispatch = createEventDispatcher()
23
26
 
@@ -41,7 +44,7 @@
41
44
  const getFieldText = (value, options, placeholder) => {
42
45
  // Always use placeholder if no value
43
46
  if (value == null || value === "") {
44
- return placeholder || "Choose an option"
47
+ return placeholder !== false ? "Choose an option" : ""
45
48
  }
46
49
 
47
50
  return getFieldAttribute(getOptionLabel, value, options)
@@ -66,15 +69,18 @@
66
69
  {fieldColour}
67
70
  {options}
68
71
  {autoWidth}
72
+ {align}
73
+ {footer}
69
74
  {getOptionLabel}
70
75
  {getOptionValue}
71
76
  {getOptionIcon}
77
+ {useOptionIconImage}
72
78
  {getOptionColour}
73
79
  {isOptionEnabled}
74
80
  {autocomplete}
75
81
  {sort}
76
82
  isPlaceholder={value == null || value === ""}
77
- placeholderOption={placeholder}
83
+ placeholderOption={placeholder === false ? null : placeholder}
78
84
  isOptionSelected={option => option === value}
79
85
  onSelectOption={selectOption}
80
86
  />
@@ -15,6 +15,11 @@
15
15
  export let getOptionValue = option => option
16
16
  export let sort = false
17
17
  export let autoWidth = false
18
+ export let autocomplete = false
19
+ export let fetchTerm = null
20
+ export let useFetch = false
21
+ export let customPopoverHeight
22
+
18
23
  const dispatch = createEventDispatcher()
19
24
  const onChange = e => {
20
25
  value = e.detail
@@ -34,6 +39,10 @@
34
39
  {getOptionLabel}
35
40
  {getOptionValue}
36
41
  {autoWidth}
42
+ {autocomplete}
43
+ {customPopoverHeight}
44
+ bind:fetchTerm
45
+ {useFetch}
37
46
  on:change={onChange}
38
47
  on:click
39
48
  />
@@ -14,12 +14,17 @@
14
14
  export let getOptionLabel = option => extractProperty(option, "label")
15
15
  export let getOptionValue = option => extractProperty(option, "value")
16
16
  export let getOptionIcon = option => option?.icon
17
+ export let useOptionIconImage = false
17
18
  export let getOptionColour = option => option?.colour
18
19
  export let isOptionEnabled
19
20
  export let quiet = false
20
21
  export let autoWidth = false
21
22
  export let sort = false
22
23
  export let tooltip = ""
24
+ export let autocomplete = false
25
+ export let customPopoverHeight
26
+ export let align
27
+ export let footer = null
23
28
 
24
29
  const dispatch = createEventDispatcher()
25
30
  const onChange = e => {
@@ -46,11 +51,16 @@
46
51
  {placeholder}
47
52
  {autoWidth}
48
53
  {sort}
54
+ {align}
55
+ {footer}
49
56
  {getOptionLabel}
50
57
  {getOptionValue}
51
58
  {getOptionIcon}
52
59
  {getOptionColour}
60
+ {useOptionIconImage}
53
61
  {isOptionEnabled}
62
+ {autocomplete}
63
+ {customPopoverHeight}
54
64
  on:change={onChange}
55
65
  on:click
56
66
  />
@@ -67,6 +67,9 @@
67
67
  color: var(--spectrum-alias-icon-color-selected-hover) !important;
68
68
  cursor: pointer;
69
69
  }
70
+ svg.hoverable:active {
71
+ color: var(--spectrum-global-color-blue-400) !important;
72
+ }
70
73
 
71
74
  svg.disabled {
72
75
  color: var(--spectrum-global-color-gray-500) !important;
@@ -57,5 +57,7 @@
57
57
  --spectrum-semantic-negative-icon-color: #e34850;
58
58
  min-width: 100px;
59
59
  margin: 0;
60
+ border-color: var(--spectrum-global-color-gray-400);
61
+ border-width: 1px;
60
62
  }
61
63
  </style>
@@ -21,7 +21,7 @@
21
21
  label {
22
22
  padding: 0;
23
23
  white-space: nowrap;
24
- color: var(--spectrum-global-color-gray-600);
24
+ color: var(--spectrum-global-color-gray-700);
25
25
  }
26
26
 
27
27
  .muted {
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
  import "@spectrum-css/modal/dist/index-vars.css"
3
3
  import "@spectrum-css/underlay/dist/index-vars.css"
4
- import { createEventDispatcher, setContext, tick } from "svelte"
4
+ import { createEventDispatcher, setContext, tick, onMount } from "svelte"
5
5
  import { fade, fly } from "svelte/transition"
6
6
  import Portal from "svelte-portal"
7
7
  import Context from "../context"
@@ -62,9 +62,14 @@
62
62
  }
63
63
 
64
64
  setContext(Context.Modal, { show, hide, cancel })
65
- </script>
66
65
 
67
- <svelte:window on:keydown={handleKey} />
66
+ onMount(() => {
67
+ document.addEventListener("keydown", handleKey)
68
+ return () => {
69
+ document.removeEventListener("keydown", handleKey)
70
+ }
71
+ })
72
+ </script>
68
73
 
69
74
  {#if inline}
70
75
  {#if visible}
@@ -18,6 +18,7 @@
18
18
  export let useAnchorWidth = false
19
19
  export let dismissible = true
20
20
  export let offset = 5
21
+ export let customHeight
21
22
 
22
23
  $: target = portalTarget || getContext(Context.PopoverRoot) || ".spectrum"
23
24
 
@@ -74,6 +75,7 @@
74
75
  on:keydown={handleEscape}
75
76
  class="spectrum-Popover is-open"
76
77
  role="presentation"
78
+ style="height: {customHeight}"
77
79
  transition:fly|local={{ y: -20, duration: 200 }}
78
80
  >
79
81
  <slot />
package/src/helpers.js CHANGED
@@ -104,6 +104,9 @@ export const deepSet = (obj, key, value) => {
104
104
  * @param obj the object to clone
105
105
  */
106
106
  export const cloneDeep = obj => {
107
+ if (!obj) {
108
+ return obj
109
+ }
107
110
  return JSON.parse(JSON.stringify(obj))
108
111
  }
109
112