front: add CopyableText component

This commit is contained in:
Alice Gaudon 2021-11-21 16:10:38 +01:00
parent e9db1f4ded
commit b24e9ab580
3 changed files with 121 additions and 13 deletions

View File

@ -27,6 +27,22 @@
}
// Buttons
button, .button {
&:not(.bold) {
--background-color: var(--surface);
&:hover::after {
--background-color: var(--on-surface);
:global(&) {
--background-color: var(--on-surface);
}
}
}
}
// States modifiers
.primary:not(.bold) {
--color: var(--primary-on-surface);
@ -49,19 +65,6 @@
--background-color: var(--surface);
}
// Buttons
button {
--background-color: var(--surface);
}
button:hover::after {
background-color: var(--on-surface);
}
:global(button:hover::after) {
background-color: var(--on-surface);
}
@if ($shadowStrength > 0) {
box-shadow: 0 #{$shadowStrength}px #{$shadowStrength}px #00000045;
}

View File

@ -0,0 +1,95 @@
<script lang="ts">
import Icon from "../utils/Icon.svelte";
import { fade } from "svelte/transition";
export let title: string;
export let content: string;
let contentNode: HTMLElement;
let copiedOverlay: HTMLElement;
function selectAll() {
const selection = window.getSelection();
if (contentNode && selection) {
selection.selectAllChildren(contentNode);
}
}
function copy() {
const selection = window.getSelection();
if (contentNode && selection) {
selectAll();
navigator.clipboard.writeText(contentNode.innerText);
showOverlay();
}
}
let showCopiedOverlay = false;
function showOverlay() {
showCopiedOverlay = true;
}
function releaseOverlay() {
showCopiedOverlay = false;
}
</script>
<style lang="scss">
@import "../../scss/helpers";
.copyable-text {
position: relative;
display: flex;
flex-direction: row;
margin: 8px;
padding: 0;
border-radius: 5px;
overflow: hidden;
.title {
padding: 8px;
}
.content {
width: 0;
flex-grow: 1;
overflow: hidden;
white-space: nowrap;
padding: 8px;
}
.copy-button {
margin: 0;
padding: 0;
border-radius: 0;
:global(.icon) {
--icon-size: 20px;
margin: 8px;
}
}
.copied-overlay {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
padding: 8px;
text-align: center;
background-color: var(--success);
}
}
</style>
<div class="copyable-text panel">
<div class="title">{title}</div>
<div class="content" bind:this={contentNode} on:click={selectAll}>{content}</div>
<button class="bold copy-button" on:click={copy}><Icon name="copy"/></button>
{#if showCopiedOverlay}
<div class="copied-overlay" bind:this={copiedOverlay} out:fade on:mouseleave={releaseOverlay}>Copied!</div>
{/if}
</div>

View File

@ -9,6 +9,7 @@
import Breadcrumb from "./components/Breadcrumb.svelte";
import Icon from "./utils/Icon.svelte";
import DesignButtons from "./DesignButtons.svelte";
import CopyableText from "./components/CopyableText.svelte";
const paginationData = new PaginationData(20, 20, 1000).serialize();
</script>
@ -114,6 +115,15 @@
{link: route('design'), title: 'self'},
]}/>
</div>
<div class="panel">
<h2>
<Icon name="copy"/>
Copyable text
</h2>
<CopyableText title="URL" content="https://swaf.dev"/>
</div>
</BaseTemplate>