@budibase/bbui 1.1.28 → 1.1.29-alpha.2

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.1.28",
4
+ "version": "1.1.29-alpha.2",
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.1.28",
41
+ "@budibase/string-templates": "^1.1.29-alpha.2",
42
42
  "@spectrum-css/actionbutton": "^1.0.1",
43
43
  "@spectrum-css/actiongroup": "^1.0.1",
44
44
  "@spectrum-css/avatar": "^3.0.2",
@@ -85,5 +85,5 @@
85
85
  "svelte-flatpickr": "^3.2.3",
86
86
  "svelte-portal": "^1.0.0"
87
87
  },
88
- "gitHead": "a05e429f1713e13b4d321ad3709c3cb1913e0159"
88
+ "gitHead": "b6680b2f69b7a019cb1ddd6bfd924edeac02d9d8"
89
89
  }
@@ -84,6 +84,7 @@
84
84
  }
85
85
  :global([dir="ltr"] .spectrum-ActionButton .spectrum-Icon) {
86
86
  margin-left: 0;
87
+ transition: color ease-out 130ms;
87
88
  }
88
89
  .is-selected:not(.spectrum-ActionButton--emphasized) {
89
90
  background: var(--spectrum-global-color-gray-300);
@@ -92,4 +93,10 @@
92
93
  padding: 0;
93
94
  min-width: 0;
94
95
  }
96
+ .spectrum-ActionButton--quiet {
97
+ padding: 0 8px;
98
+ }
99
+ .is-selected:not(.emphasized) .spectrum-Icon {
100
+ color: var(--spectrum-global-color-gray-900);
101
+ }
95
102
  </style>
@@ -4,7 +4,7 @@
4
4
  ["XXS", "--spectrum-alias-avatar-size-50"],
5
5
  ["XS", "--spectrum-alias-avatar-size-75"],
6
6
  ["S", "--spectrum-alias-avatar-size-200"],
7
- ["M", "--spectrum-alias-avatar-size-300"],
7
+ ["M", "--spectrum-alias-avatar-size-400"],
8
8
  ["L", "--spectrum-alias-avatar-size-500"],
9
9
  ["XL", "--spectrum-alias-avatar-size-600"],
10
10
  ["XXL", "--spectrum-alias-avatar-size-700"],
@@ -13,6 +13,19 @@
13
13
  export let url = ""
14
14
  export let disabled = false
15
15
  export let initials = "JD"
16
+
17
+ const DefaultColor = "#3aab87"
18
+
19
+ $: color = getColor(initials)
20
+
21
+ const getColor = initials => {
22
+ if (!initials?.length) {
23
+ return DefaultColor
24
+ }
25
+ const code = initials[0].toLowerCase().charCodeAt(0)
26
+ const hue = ((code % 26) / 26) * 360
27
+ return `hsl(${hue}, 50%, 50%)`
28
+ }
16
29
  </script>
17
30
 
18
31
  {#if url}
@@ -25,10 +38,11 @@
25
38
  />
26
39
  {:else}
27
40
  <div
41
+ class="spectrum-Avatar"
28
42
  class:is-disabled={disabled}
29
43
  style="width: var({sizes.get(size)}); height: var({sizes.get(
30
44
  size
31
- )}); font-size: calc(var({sizes.get(size)}) / 2)"
45
+ )}); font-size: calc(var({sizes.get(size)}) / 2); background: {color};"
32
46
  >
33
47
  {initials || ""}
34
48
  </div>
@@ -40,7 +54,6 @@
40
54
  display: grid;
41
55
  place-items: center;
42
56
  font-weight: 600;
43
- background: #3aab87;
44
57
  border-radius: 50%;
45
58
  overflow: hidden;
46
59
  user-select: none;
@@ -0,0 +1,218 @@
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
+ import clickOutside from "../../Actions/click_outside"
8
+
9
+ export let inputValue
10
+ export let dropdownValue
11
+ export let id = null
12
+ export let inputType = "text"
13
+ export let placeholder = "Choose an option or type"
14
+ export let disabled = false
15
+ export let readonly = false
16
+ export let updateOnChange = true
17
+ export let error = null
18
+ export let options = []
19
+ export let getOptionLabel = option => extractProperty(option, "label")
20
+ export let getOptionValue = option => extractProperty(option, "value")
21
+
22
+ export let isOptionSelected = () => false
23
+
24
+ const dispatch = createEventDispatcher()
25
+ let open = false
26
+ let focus = false
27
+
28
+ $: fieldText = getFieldText(dropdownValue, options, placeholder)
29
+
30
+ const getFieldText = (dropdownValue, options, placeholder) => {
31
+ // Always use placeholder if no value
32
+ if (dropdownValue == null || dropdownValue === "") {
33
+ return placeholder || "Choose an option or type"
34
+ }
35
+
36
+ // Wait for options to load if there is a value but no options
37
+ if (!options?.length) {
38
+ return ""
39
+ }
40
+
41
+ // Render the label if the selected option is found, otherwise raw value
42
+ const selected = options.find(
43
+ option => getOptionValue(option) === dropdownValue
44
+ )
45
+ return selected ? getOptionLabel(selected) : dropdownValue
46
+ }
47
+
48
+ const updateValue = newValue => {
49
+ if (readonly) {
50
+ return
51
+ }
52
+ dispatch("change", newValue)
53
+ }
54
+
55
+ const onFocus = () => {
56
+ if (readonly) {
57
+ return
58
+ }
59
+ focus = true
60
+ }
61
+
62
+ const onBlur = event => {
63
+ if (readonly) {
64
+ return
65
+ }
66
+ focus = false
67
+ updateValue(event.target.value)
68
+ }
69
+
70
+ const onInput = event => {
71
+ if (readonly || !updateOnChange) {
72
+ return
73
+ }
74
+ updateValue(event.target.value)
75
+ }
76
+
77
+ const updateValueOnEnter = event => {
78
+ if (readonly) {
79
+ return
80
+ }
81
+ if (event.key === "Enter") {
82
+ updateValue(event.target.value)
83
+ }
84
+ }
85
+
86
+ const onClick = () => {
87
+ dispatch("click")
88
+ if (readonly) {
89
+ return
90
+ }
91
+ open = true
92
+ }
93
+
94
+ const onPick = newValue => {
95
+ dispatch("pick", newValue)
96
+ open = false
97
+ }
98
+
99
+ const extractProperty = (value, property) => {
100
+ if (value && typeof value === "object") {
101
+ return value[property]
102
+ }
103
+ return value
104
+ }
105
+ </script>
106
+
107
+ <div
108
+ class="spectrum-InputGroup"
109
+ class:is-invalid={!!error}
110
+ class:is-disabled={disabled}
111
+ >
112
+ <div
113
+ class="spectrum-Textfield spectrum-InputGroup-textfield"
114
+ class:is-invalid={!!error}
115
+ class:is-disabled={disabled}
116
+ class:is-focused={focus}
117
+ >
118
+ <input
119
+ {id}
120
+ on:click
121
+ on:blur
122
+ on:focus
123
+ on:input
124
+ on:keyup
125
+ on:blur={onBlur}
126
+ on:focus={onFocus}
127
+ on:input={onInput}
128
+ on:keyup={updateValueOnEnter}
129
+ value={inputValue || ""}
130
+ placeholder={placeholder || ""}
131
+ {disabled}
132
+ {readonly}
133
+ {inputType}
134
+ class="spectrum-Textfield-input spectrum-InputGroup-input"
135
+ />
136
+ </div>
137
+ <div style="width: 30%">
138
+ <button
139
+ {id}
140
+ class="spectrum-Picker spectrum-Picker--sizeM override-borders"
141
+ {disabled}
142
+ class:is-open={open}
143
+ aria-haspopup="listbox"
144
+ on:mousedown={onClick}
145
+ >
146
+ <span class="spectrum-Picker-label">
147
+ <div>
148
+ {fieldText}
149
+ </div></span
150
+ >
151
+ <svg
152
+ class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon"
153
+ focusable="false"
154
+ aria-hidden="true"
155
+ >
156
+ <use xlink:href="#spectrum-css-icon-Chevron100" />
157
+ </svg>
158
+ </button>
159
+ {#if open}
160
+ <div
161
+ use:clickOutside={() => (open = false)}
162
+ transition:fly|local={{ y: -20, duration: 200 }}
163
+ class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
164
+ >
165
+ <ul class="spectrum-Menu" role="listbox">
166
+ {#each options as option, idx}
167
+ <li
168
+ class="spectrum-Menu-item"
169
+ class:is-selected={isOptionSelected(getOptionValue(option, idx))}
170
+ role="option"
171
+ aria-selected="true"
172
+ tabindex="0"
173
+ on:click={() => onPick(getOptionValue(option, idx))}
174
+ >
175
+ <span class="spectrum-Menu-itemLabel">
176
+ {getOptionLabel(option, idx)}
177
+ </span>
178
+ <svg
179
+ class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
180
+ focusable="false"
181
+ aria-hidden="true"
182
+ >
183
+ <use xlink:href="#spectrum-css-icon-Checkmark100" />
184
+ </svg>
185
+ </li>
186
+ {/each}
187
+ </ul>
188
+ </div>
189
+ {/if}
190
+ </div>
191
+ </div>
192
+
193
+ <style>
194
+ .spectrum-InputGroup {
195
+ min-width: 0;
196
+ width: 100%;
197
+ }
198
+
199
+ .spectrum-InputGroup-input {
200
+ border-right-width: 1px;
201
+ }
202
+ .spectrum-Textfield {
203
+ width: 100%;
204
+ }
205
+ .spectrum-Textfield-input {
206
+ width: 0;
207
+ }
208
+
209
+ .override-borders {
210
+ border-top-left-radius: 0px;
211
+ border-bottom-left-radius: 0px;
212
+ }
213
+ .spectrum-Popover {
214
+ max-height: 240px;
215
+ z-index: 999;
216
+ top: 100%;
217
+ }
218
+ </style>
@@ -13,6 +13,7 @@
13
13
  export let readonly = false
14
14
  export let autocomplete = false
15
15
  export let sort = false
16
+ export let autoWidth = false
16
17
 
17
18
  const dispatch = createEventDispatcher()
18
19
  $: selectedLookupMap = getSelectedLookupMap(value)
@@ -85,4 +86,5 @@
85
86
  {getOptionValue}
86
87
  onSelectOption={toggleOption}
87
88
  {sort}
89
+ {autoWidth}
88
90
  />
@@ -87,10 +87,15 @@
87
87
  on:mousedown={onClick}
88
88
  >
89
89
  {#if fieldIcon}
90
- <span class="option-icon">
90
+ <span class="option-extra">
91
91
  <Icon name={fieldIcon} />
92
92
  </span>
93
93
  {/if}
94
+ {#if fieldColour}
95
+ <span class="option-extra">
96
+ <StatusLight square color={fieldColour} />
97
+ </span>
98
+ {/if}
94
99
  <span
95
100
  class="spectrum-Picker-label"
96
101
  class:is-placeholder={isPlaceholder}
@@ -108,11 +113,6 @@
108
113
  <use xlink:href="#spectrum-icon-18-Alert" />
109
114
  </svg>
110
115
  {/if}
111
- {#if fieldColour}
112
- <span class="option-colour">
113
- <StatusLight size="L" color={fieldColour} />
114
- </span>
115
- {/if}
116
116
  <svg
117
117
  class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon"
118
118
  focusable="false"
@@ -166,10 +166,15 @@
166
166
  on:click={() => onSelectOption(getOptionValue(option, idx))}
167
167
  >
168
168
  {#if getOptionIcon(option, idx)}
169
- <span class="option-icon">
169
+ <span class="option-extra">
170
170
  <Icon name={getOptionIcon(option, idx)} />
171
171
  </span>
172
172
  {/if}
173
+ {#if getOptionColour(option, idx)}
174
+ <span class="option-extra">
175
+ <StatusLight square color={getOptionColour(option, idx)} />
176
+ </span>
177
+ {/if}
173
178
  <span class="spectrum-Menu-itemLabel">
174
179
  {getOptionLabel(option, idx)}
175
180
  </span>
@@ -180,11 +185,6 @@
180
185
  >
181
186
  <use xlink:href="#spectrum-css-icon-Checkmark100" />
182
187
  </svg>
183
- {#if getOptionColour(option, idx)}
184
- <span class="option-colour">
185
- <StatusLight size="L" color={getOptionColour(option, idx)} />
186
- </span>
187
- {/if}
188
188
  </li>
189
189
  {/each}
190
190
  {/if}
@@ -209,6 +209,9 @@
209
209
  width: 100%;
210
210
  box-shadow: none;
211
211
  }
212
+ .spectrum-Picker-label.auto-width {
213
+ margin-right: var(--spacing-xs);
214
+ }
212
215
  .spectrum-Picker-label:not(.auto-width) {
213
216
  overflow: hidden;
214
217
  text-overflow: ellipsis;
@@ -221,16 +224,16 @@
221
224
  .spectrum-Picker-label.auto-width.is-placeholder {
222
225
  padding-right: 2px;
223
226
  }
227
+ .auto-width .spectrum-Menu-item {
228
+ padding-right: var(--spacing-xl);
229
+ }
224
230
 
225
231
  /* Icon and colour alignment */
226
232
  .spectrum-Menu-checkmark {
227
233
  align-self: center;
228
234
  margin-top: 0;
229
235
  }
230
- .option-colour {
231
- padding-left: 8px;
232
- }
233
- .option-icon {
236
+ .option-extra {
234
237
  padding-right: 8px;
235
238
  }
236
239