@budibase/bbui 1.0.121 → 1.0.123-alpha.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/dist/bbui.es.js +35 -35
- package/dist/bbui.es.js.map +1 -1
- package/package.json +3 -3
- package/src/ActionButton/ActionButton.svelte +0 -4
- package/src/ActionMenu/ActionMenu.svelte +2 -1
- package/src/Form/Core/DatePicker.svelte +29 -12
- package/src/Icon/Icon.svelte +49 -13
- package/src/Layout/Layout.svelte +8 -0
- package/src/Layout/Page.svelte +3 -2
- package/src/Modal/ModalContent.svelte +9 -3
- package/src/Popover/Popover.svelte +26 -1
- package/src/ProgressBar/ProgressBar.svelte +5 -5
- package/src/Table/InternalRenderer.svelte +12 -33
- package/src/Table/Table.svelte +30 -8
- package/src/Tabs/Tabs.svelte +1 -1
- package/src/Typography/Body.svelte +2 -0
- package/src/Typography/Heading.svelte +2 -1
- package/src/helpers.js +26 -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": "1.0.
|
|
4
|
+
"version": "1.0.123-alpha.1",
|
|
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.
|
|
41
|
+
"@budibase/string-templates": "^1.0.123-alpha.1",
|
|
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": "
|
|
87
|
+
"gitHead": "de25ffe0adae448be6c6244977e7d4e91d81ef52"
|
|
88
88
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
export let disabled = false
|
|
7
7
|
export let align = "left"
|
|
8
8
|
export let portalTarget
|
|
9
|
+
export let dataCy
|
|
9
10
|
|
|
10
11
|
let anchor
|
|
11
12
|
let dropdown
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
<div use:getAnchor on:click={openMenu}>
|
|
37
38
|
<slot name="control" />
|
|
38
39
|
</div>
|
|
39
|
-
<Popover bind:this={dropdown} {anchor} {align} {portalTarget}>
|
|
40
|
+
<Popover bind:this={dropdown} {anchor} {align} {portalTarget} {dataCy}>
|
|
40
41
|
<Menu>
|
|
41
42
|
<slot />
|
|
42
43
|
</Menu>
|
|
@@ -19,18 +19,33 @@
|
|
|
19
19
|
const dispatch = createEventDispatcher()
|
|
20
20
|
const flatpickrId = `${uuid()}-wrapper`
|
|
21
21
|
let open = false
|
|
22
|
-
let flatpickr, flatpickrOptions
|
|
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
|
+
}
|
|
23
33
|
|
|
24
|
-
$: isTimeOnly = !timeOnly && value ? !isNaN(new Date(`0-${value}`)) : timeOnly
|
|
25
34
|
$: flatpickrOptions = {
|
|
26
35
|
element: `#${flatpickrId}`,
|
|
27
|
-
enableTime:
|
|
28
|
-
noCalendar:
|
|
36
|
+
enableTime: timeOnly || enableTime || false,
|
|
37
|
+
noCalendar: timeOnly || false,
|
|
29
38
|
altInput: true,
|
|
30
|
-
altFormat:
|
|
39
|
+
altFormat: timeOnly ? "H:i" : enableTime ? "F j Y, H:i" : "F j, Y",
|
|
31
40
|
wrap: true,
|
|
32
41
|
appendTo,
|
|
33
42
|
disableMobile: "true",
|
|
43
|
+
onReady: () => {
|
|
44
|
+
let timestamp = resolveTimeStamp(value)
|
|
45
|
+
if (timeOnly && timestamp) {
|
|
46
|
+
dispatch("change", timestamp.toISOString())
|
|
47
|
+
}
|
|
48
|
+
},
|
|
34
49
|
}
|
|
35
50
|
|
|
36
51
|
const handleChange = event => {
|
|
@@ -39,10 +54,9 @@
|
|
|
39
54
|
if (newValue) {
|
|
40
55
|
newValue = newValue.toISOString()
|
|
41
56
|
}
|
|
42
|
-
// if time only set date component to
|
|
57
|
+
// if time only set date component to 2000-01-01
|
|
43
58
|
if (timeOnly) {
|
|
44
|
-
|
|
45
|
-
newValue = `${todayDate}T${newValue.split("T")[1]}`
|
|
59
|
+
newValue = `2000-01-01T${newValue.split("T")[1]}`
|
|
46
60
|
}
|
|
47
61
|
dispatch("change", newValue)
|
|
48
62
|
}
|
|
@@ -76,10 +90,13 @@
|
|
|
76
90
|
return null
|
|
77
91
|
}
|
|
78
92
|
let date
|
|
79
|
-
let time
|
|
93
|
+
let time
|
|
94
|
+
|
|
80
95
|
// it is a string like 00:00:00, just time
|
|
81
|
-
|
|
82
|
-
|
|
96
|
+
let ts = resolveTimeStamp(val)
|
|
97
|
+
|
|
98
|
+
if (timeOnly && ts) {
|
|
99
|
+
date = ts
|
|
83
100
|
} else if (val instanceof Date) {
|
|
84
101
|
// Use real date obj if already parsed
|
|
85
102
|
date = val
|
|
@@ -101,7 +118,7 @@
|
|
|
101
118
|
}
|
|
102
119
|
</script>
|
|
103
120
|
|
|
104
|
-
{#key
|
|
121
|
+
{#key timeOnly}
|
|
105
122
|
<Flatpickr
|
|
106
123
|
bind:flatpickr
|
|
107
124
|
value={parseDate(value)}
|
package/src/Icon/Icon.svelte
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
<script>
|
|
6
|
+
import Tooltip from "../Tooltip/Tooltip.svelte"
|
|
7
|
+
import { fade } from "svelte/transition"
|
|
8
|
+
|
|
6
9
|
export let direction = "n"
|
|
7
10
|
export let name = "Add"
|
|
8
11
|
export let hidden = false
|
|
@@ -10,30 +13,52 @@
|
|
|
10
13
|
export let hoverable = false
|
|
11
14
|
export let disabled = false
|
|
12
15
|
export let color
|
|
16
|
+
export let tooltip
|
|
13
17
|
|
|
14
18
|
$: rotation = getRotation(direction)
|
|
15
19
|
|
|
20
|
+
let showTooltip = false
|
|
21
|
+
|
|
16
22
|
const getRotation = direction => {
|
|
17
23
|
return directions.indexOf(direction) * 45
|
|
18
24
|
}
|
|
19
25
|
</script>
|
|
20
26
|
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
aria-hidden={hidden}
|
|
28
|
-
aria-label={name}
|
|
29
|
-
style={`transform: rotate(${rotation}deg); ${
|
|
30
|
-
color ? `color: ${color};` : ""
|
|
31
|
-
}`}
|
|
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)}
|
|
32
33
|
>
|
|
33
|
-
<
|
|
34
|
-
|
|
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>
|
|
35
54
|
|
|
36
55
|
<style>
|
|
56
|
+
.icon {
|
|
57
|
+
position: relative;
|
|
58
|
+
display: grid;
|
|
59
|
+
place-items: center;
|
|
60
|
+
}
|
|
61
|
+
|
|
37
62
|
svg.hoverable {
|
|
38
63
|
pointer-events: all;
|
|
39
64
|
transition: color var(--spectrum-global-animation-duration-100, 130ms);
|
|
@@ -47,4 +72,15 @@
|
|
|
47
72
|
color: var(--spectrum-global-color-gray-500) !important;
|
|
48
73
|
pointer-events: none !important;
|
|
49
74
|
}
|
|
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
|
+
}
|
|
50
86
|
</style>
|
package/src/Layout/Layout.svelte
CHANGED
|
@@ -36,6 +36,10 @@
|
|
|
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
|
+
}
|
|
39
43
|
.paddingY-S {
|
|
40
44
|
padding-top: var(--spacing-s);
|
|
41
45
|
padding-bottom: var(--spacing-s);
|
|
@@ -48,6 +52,10 @@
|
|
|
48
52
|
padding-top: var(--spacing-l);
|
|
49
53
|
padding-bottom: var(--spacing-l);
|
|
50
54
|
}
|
|
55
|
+
.paddingY-XL {
|
|
56
|
+
padding-top: var(--spacing-xl);
|
|
57
|
+
padding-bottom: var(--spacing-xl);
|
|
58
|
+
}
|
|
51
59
|
.gap-XXS {
|
|
52
60
|
grid-gap: var(--spacing-xs);
|
|
53
61
|
}
|
package/src/Layout/Page.svelte
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
export let wide = false
|
|
3
|
+
export let maxWidth = "80ch"
|
|
3
4
|
</script>
|
|
4
5
|
|
|
5
|
-
<div class:wide>
|
|
6
|
+
<div style="--max-width: {maxWidth}" class:wide>
|
|
6
7
|
<slot />
|
|
7
8
|
</div>
|
|
8
9
|
|
|
@@ -12,7 +13,7 @@
|
|
|
12
13
|
flex-direction: column;
|
|
13
14
|
justify-content: flex-start;
|
|
14
15
|
align-items: stretch;
|
|
15
|
-
max-width:
|
|
16
|
+
max-width: var(--max-width);
|
|
16
17
|
margin: 0 auto;
|
|
17
18
|
padding: calc(var(--spacing-xl) * 2);
|
|
18
19
|
min-height: calc(100% - var(--spacing-xl) * 4);
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
export let secondaryButtonText = undefined
|
|
24
24
|
export let secondaryAction = undefined
|
|
25
25
|
export let secondaryButtonWarning = false
|
|
26
|
+
export let dataCy = null
|
|
26
27
|
|
|
27
28
|
const { hide, cancel } = getContext(Context.Modal)
|
|
28
29
|
let loading = false
|
|
@@ -63,21 +64,26 @@
|
|
|
63
64
|
role="dialog"
|
|
64
65
|
tabindex="-1"
|
|
65
66
|
aria-modal="true"
|
|
67
|
+
data-cy={dataCy}
|
|
66
68
|
>
|
|
67
69
|
<div class="spectrum-Dialog-grid">
|
|
68
|
-
{#if title}
|
|
70
|
+
{#if title || $$slots.header}
|
|
69
71
|
<h1
|
|
70
72
|
class="spectrum-Dialog-heading spectrum-Dialog-heading--noHeader"
|
|
71
73
|
class:noDivider={!showDivider}
|
|
72
74
|
class:header-spacing={$$slots.header}
|
|
73
75
|
>
|
|
74
|
-
{title}
|
|
75
|
-
|
|
76
|
+
{#if title}
|
|
77
|
+
{title}
|
|
78
|
+
{:else if $$slots.header}
|
|
79
|
+
<slot name="header" />
|
|
80
|
+
{/if}
|
|
76
81
|
</h1>
|
|
77
82
|
{#if showDivider}
|
|
78
83
|
<Divider size="M" />
|
|
79
84
|
{/if}
|
|
80
85
|
{/if}
|
|
86
|
+
|
|
81
87
|
<!-- TODO: Remove content-grid class once Layout components are in bbui -->
|
|
82
88
|
<section class="spectrum-Dialog-content content-grid">
|
|
83
89
|
<slot />
|
|
@@ -10,6 +10,17 @@
|
|
|
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
|
+
: ""
|
|
13
24
|
|
|
14
25
|
export const show = () => {
|
|
15
26
|
dispatch("open")
|
|
@@ -37,9 +48,14 @@
|
|
|
37
48
|
use:positionDropdown={{ anchor, align }}
|
|
38
49
|
use:clickOutside={hide}
|
|
39
50
|
on:keydown={handleEscape}
|
|
40
|
-
class="spectrum-Popover is-open"
|
|
51
|
+
class={"spectrum-Popover is-open " + (tooltipClasses || "")}
|
|
41
52
|
role="presentation"
|
|
53
|
+
data-cy={dataCy}
|
|
42
54
|
>
|
|
55
|
+
{#if showTip}
|
|
56
|
+
{@html tipSvg}
|
|
57
|
+
{/if}
|
|
58
|
+
|
|
43
59
|
<slot />
|
|
44
60
|
</div>
|
|
45
61
|
</Portal>
|
|
@@ -49,4 +65,13 @@
|
|
|
49
65
|
.spectrum-Popover {
|
|
50
66
|
min-width: var(--spectrum-global-dimension-size-2000) !important;
|
|
51
67
|
}
|
|
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
|
+
}
|
|
52
77
|
</style>
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
easing: easing,
|
|
17
17
|
})
|
|
18
18
|
|
|
19
|
-
$: if (value) $progress = value
|
|
19
|
+
$: if (value || value === 0) $progress = value
|
|
20
20
|
</script>
|
|
21
21
|
|
|
22
22
|
<div
|
|
23
|
-
class:spectrum-ProgressBar--indeterminate={!value}
|
|
23
|
+
class:spectrum-ProgressBar--indeterminate={!value && value !== 0}
|
|
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};` : ""}
|
|
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}
|
|
40
|
+
{#if value || value === 0}
|
|
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 ? `width: ${$progress}%` : ""}
|
|
50
|
+
style={value || value === 0 ? `width: ${$progress}%` : ""}
|
|
51
51
|
/>
|
|
52
52
|
</div>
|
|
53
53
|
<div class="spectrum-ProgressBar-label" hidden="" />
|
|
@@ -1,42 +1,21 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import Icon from "../Icon/Icon.svelte"
|
|
3
|
+
import { copyToClipboard } from "../helpers"
|
|
3
4
|
import { notifications } from "../Stores/notifications"
|
|
5
|
+
|
|
4
6
|
export let value
|
|
5
7
|
|
|
6
|
-
const onClick = e => {
|
|
8
|
+
const onClick = async e => {
|
|
7
9
|
e.stopPropagation()
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
})
|
|
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
|
+
}
|
|
40
19
|
}
|
|
41
20
|
</script>
|
|
42
21
|
|
package/src/Table/Table.svelte
CHANGED
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
export let disableSorting = false
|
|
37
37
|
export let autoSortColumns = true
|
|
38
38
|
export let compact = false
|
|
39
|
+
export let customPlaceholder = false
|
|
39
40
|
|
|
40
41
|
const dispatch = createEventDispatcher()
|
|
41
42
|
|
|
@@ -387,13 +388,24 @@
|
|
|
387
388
|
</div>
|
|
388
389
|
{/each}
|
|
389
390
|
{:else}
|
|
390
|
-
<div
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
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}
|
|
397
409
|
</div>
|
|
398
410
|
{/if}
|
|
399
411
|
</div>
|
|
@@ -458,6 +470,13 @@
|
|
|
458
470
|
justify-content: flex-start;
|
|
459
471
|
align-items: center;
|
|
460
472
|
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);
|
|
461
480
|
}
|
|
462
481
|
.spectrum-Table-headCell--alignCenter {
|
|
463
482
|
justify-content: center;
|
|
@@ -576,16 +595,19 @@
|
|
|
576
595
|
border-top: none;
|
|
577
596
|
grid-column: 1 / -1;
|
|
578
597
|
background-color: var(--table-bg);
|
|
598
|
+
padding: 40px;
|
|
579
599
|
}
|
|
580
600
|
.placeholder--no-fields {
|
|
581
601
|
border-top: var(--table-border);
|
|
582
602
|
}
|
|
603
|
+
.placeholder--custom {
|
|
604
|
+
justify-content: flex-start;
|
|
605
|
+
}
|
|
583
606
|
.wrapper--quiet .placeholder {
|
|
584
607
|
border-left: none;
|
|
585
608
|
border-right: none;
|
|
586
609
|
}
|
|
587
610
|
.placeholder-content {
|
|
588
|
-
padding: 40px;
|
|
589
611
|
display: flex;
|
|
590
612
|
flex-direction: column;
|
|
591
613
|
justify-content: center;
|
package/src/Tabs/Tabs.svelte
CHANGED
|
@@ -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: var(--
|
|
111
|
+
border-bottom: 1px solid var(--spectrum-global-color-gray-300);
|
|
112
112
|
}
|
|
113
113
|
.spectrum-Tabs-content {
|
|
114
114
|
margin-top: var(--spectrum-global-dimension-static-size-150);
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
export let serif = false
|
|
6
6
|
export let weight = null
|
|
7
7
|
export let textAlign = null
|
|
8
|
+
export let color = null
|
|
8
9
|
</script>
|
|
9
10
|
|
|
10
11
|
<p
|
|
11
12
|
style={`
|
|
12
13
|
${weight ? `font-weight:${weight};` : ""}
|
|
13
14
|
${textAlign ? `text-align:${textAlign};` : ""}
|
|
15
|
+
${color ? `color:${color};` : ""}
|
|
14
16
|
`}
|
|
15
17
|
class="spectrum-Body spectrum-Body--size{size}"
|
|
16
18
|
class:spectrum-Body--serif={serif}
|
|
@@ -5,12 +5,13 @@
|
|
|
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
|
|
8
9
|
</script>
|
|
9
10
|
|
|
10
11
|
<h1
|
|
11
12
|
style={textAlign ? `text-align:${textAlign}` : ``}
|
|
12
13
|
class:noPadding
|
|
13
|
-
class="spectrum-Heading spectrum-Heading--size{size}"
|
|
14
|
+
class="spectrum-Heading spectrum-Heading--size{size} spectrum-Heading--{weight}"
|
|
14
15
|
>
|
|
15
16
|
<slot />
|
|
16
17
|
</h1>
|
package/src/helpers.js
CHANGED
|
@@ -106,3 +106,29 @@ 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
|
+
}
|