budibase/packages/client/src/components/app/Link.svelte

145 lines
3.1 KiB
Svelte
Raw Normal View History

2020-02-20 18:06:50 +01:00
<script>
import { getContext } from "svelte"
const { linkable, styleable, builderStore } = getContext("sdk")
const component = getContext("component")
export let url
export let text
export let openInNewTab
export let color
export let align
export let bold
export let italic
export let underline
export let size
2020-02-25 16:21:23 +01:00
$: externalLink = url && typeof url === "string" && !url.startsWith("/")
2020-02-25 16:21:23 +01:00
$: target = openInNewTab ? "_blank" : "_self"
$: placeholder = $builderStore.inBuilder && !text
$: componentText = getComponentText(text, $builderStore, $component)
// Add color styles to main styles object, otherwise the styleable helper
// overrides the color when it's passed as inline style.
$: styles = enrichStyles($component.styles, color)
const getComponentText = (text, builderState, componentState) => {
if (!builderState.inBuilder || componentState.editing) {
return text || ""
}
return text || componentState.name || "Placeholder text"
}
const enrichStyles = (styles, color) => {
if (!color) {
return styles
}
return {
...styles,
normal: {
...styles?.normal,
color,
},
}
}
// Convert contenteditable HTML to text and save
const updateText = e => {
const html = e.target.innerHTML
const sanitized = html
.replace(/<\/div><div>/gi, "\n")
.replace(/<div>/gi, "")
.replace(/<\/div>/gi, "")
.replace(/<br>/gi, "")
builderStore.actions.updateProp("text", sanitized)
}
2020-02-20 18:06:50 +01:00
</script>
{#if $component.editing}
<div
contenteditable
use:styleable={styles}
class:bold
class:italic
class:underline
class="align--{align || 'left'} size--{size || 'M'}"
on:blur={$component.editing ? updateText : null}
>
{componentText}
</div>
{:else if $builderStore.inBuilder || componentText}
{#if externalLink}
<a
{target}
href={url || "/"}
use:styleable={styles}
class:placeholder
class:bold
class:italic
class:underline
class="align--{align || 'left'} size--{size || 'M'}"
>
{componentText}
</a>
{:else}
<a
use:linkable
href={url || "/"}
use:styleable={styles}
class:placeholder
class:bold
class:italic
class:underline
class="align--{align || 'left'} size--{size || 'M'}"
>
{componentText}
</a>
{/if}
2021-02-26 10:58:24 +01:00
{/if}
<style>
a,
div {
color: var(--spectrum-alias-text-color);
2021-06-30 17:33:35 +02:00
transition: color 130ms ease-in-out;
white-space: pre-wrap;
2021-06-30 17:33:35 +02:00
}
a:not(.placeholder):hover {
color: var(--spectrum-link-primary-m-text-color-hover) !important;
}
.placeholder {
font-style: italic;
color: var(--spectrum-global-color-gray-600);
}
.bold {
font-weight: 600;
}
.italic {
font-style: italic;
}
.underline {
text-decoration: underline;
}
.size--S {
font-size: 14px;
}
.size--M {
font-size: 16px;
}
.size--L {
font-size: 18px;
}
.align--left {
text-align: left;
}
.align--center {
text-align: center;
}
.align--right {
text-align: right;
}
.align-justify {
text-align: justify;
}
</style>