Skip to content

Commit

Permalink
using slots
Browse files Browse the repository at this point in the history
  • Loading branch information
daKmoR committed Jul 31, 2023
1 parent 64541fa commit 8e52111
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 40 deletions.
67 changes: 47 additions & 20 deletions docs/pages/components/clipboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,53 @@ meta:
layout: component
---

```html:preview
<p>Clicking the clipboard button will put "shoelace rocks" into your clipboard</p>
<sl-clipboard value="shoelace rocks"></sl-clipboard>
```

```jsx:react
import { SlClipboard } from '@shoelace-style/shoelace/dist/react';
const App = () => (
<>
<p>Clicking the clipboard button will put "shoelace rocks" into your clipboard</p>
<SlClipboard value="shoelace rocks"></SlClipboard>
</>
);
```

## Examples

### Use your own button

```html:preview
<sl-clipboard value="shoelace rocks">
<button type="button">Copy to clipboard</button>
<button slot="copied">copied</button>
</sl-clipboard>
<br>
<sl-clipboard value="shoelace rocks">
<sl-button>Copy</sl-button>
<sl-button slot="copied">Copied</sl-button>
</sl-clipboard>
```

```jsx:react
import { SlClipboard } from '@shoelace-style/shoelace/dist/react';
const App = () => (
<>
<SlClipboard value="shoelace rocks">
<button type="button">Copy to clipboard</button>
<div slot="copied">copied</div>
</SlClipboard>
</>
);
```

### Get the textValue from a different element

```html:preview
<div class="row">
<dl>
Expand Down Expand Up @@ -47,26 +94,6 @@ const App = () => (
);
```

## Examples

### Providing directly a text value

```html:preview
<p>Clicking the clipboard button will put "shoelace rocks" into your clipboard</p>
<sl-clipboard value="shoelace rocks"></sl-clipboard>
```

```jsx:react
import { SlClipboard } from '@shoelace-style/shoelace/dist/react';
const App = () => (
<>
<p>Clicking the clipboard button will put "shoelace rocks" into your clipboard</p>
<SlClipboard value="shoelace rocks"></SlClipboard>
</>
);
```

## Disclaimer

The public API is partially inspired by https://github.com/github/clipboard-copy-element
50 changes: 36 additions & 14 deletions src/components/clipboard/clipboard.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,24 @@ import type { CSSResultGroup, PropertyValueMap } from 'lit';
*
* @dependency sl-icon-button
* @dependency sl-tooltip
*
* @slot - The content that gets clicked to copy.
* @slot copied - The content shown after a successful copy.
*/
export default class SlClipboard extends ShoelaceElement {
static styles: CSSResultGroup = styles;
static dependencies = { 'sl-tooltip': SlTooltip, 'sl-icon-button': SlIconButton };

/**
* Indicates whether or not copy info is shown.
* Indicates whether or not copied info is shown.
*/
@property({ type: Boolean, reflect: true }) copy = false;

/**
* Indicates whether or not copy error is shown.
*/
@property({ type: Boolean }) copyError = false;

/**
* The value to copy.
*/
Expand All @@ -36,21 +44,26 @@ export default class SlClipboard extends ShoelaceElement {
@property({ type: String }) for = '';

private handleClick() {
if (this.copy) return;
if (this.copy || this.copyError) return;
this.__executeCopy();
}

private __executeCopy() {
private async __executeCopy() {
if (this.for) {
const target = document.getElementById(this.for)!;
if (target) {
this.value = target.textContent || '';
}
}
if (this.value) {
navigator.clipboard.writeText(this.value);
this.copy = true;
setTimeout(() => (this.copy = false), 2000);
try {
await navigator.clipboard.writeText(this.value);
this.copy = true;
setTimeout(() => (this.copy = false), 2000);
} catch (error) {
this.copyError = true;
setTimeout(() => (this.copyError = false), 2000);
}
}
}

Expand All @@ -67,16 +80,25 @@ export default class SlClipboard extends ShoelaceElement {
part="base"
class=${classMap({
clipboard: true,
'clipboard--copy': this.copy
'clipboard--copy': this.copy,
'clipboard--copy-error': this.copyError
})}
>
<sl-tooltip content=${this.copy ? 'Copied' : 'Copy'}>
<sl-icon-button
@click=${this.handleClick}
name=${this.copy ? 'file-earmark-check' : 'files'}
label=${this.copy ? 'Copied' : 'Copy'}
></sl-icon-button>
</sl-tooltip>
<slot id="default" @click=${this.handleClick}>
<sl-tooltip content="Copy">
<sl-icon-button name="files" label="Copy"></sl-icon-button>
</sl-tooltip>
</slot>
<slot name="copied" @click=${this.handleClick}>
<sl-tooltip content="Copied">
<sl-icon-button class="green" name="file-earmark-check" label="Copied"></sl-icon-button>
</sl-tooltip>
</slot>
<slot name="copy-error" @click=${this.handleClick}>
<sl-tooltip content="Failed to copy">
<sl-icon-button class="red" name="file-earmark-x" label="Failed to copy"></sl-icon-button>
</sl-tooltip>
</slot>
</div>
`;
}
Expand Down
43 changes: 37 additions & 6 deletions src/components/clipboard/clipboard.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,47 @@ export default css`
display: inline-block;
}
.clipboard--copy sl-icon-button::part(base) {
color: var(--sl-color-success-600);
/* successful copy */
slot[name='copied'] {
display: none;
}
.clipboard--copy #default {
display: none;
}
.clipboard--copy slot[name='copied'] {
display: block;
}
.clipboard--copy sl-icon-button::part(base):hover,
.clipboard--copy sl-icon-button::part(base):focus {
.green::part(base) {
color: var(--sl-color-success-600);
}
.clipboard--copy sl-icon-button::part(base):active {
.green::part(base):hover,
.green::part(base):focus {
color: var(--sl-color-success-600);
}
.green::part(base):active {
color: var(--sl-color-success-600);
}
/* failed to copy */
slot[name='copy-error'] {
display: none;
}
.clipboard--copy-error #default {
display: none;
}
.clipboard--copy-error slot[name='copy-error'] {
display: block;
}
.red::part(base) {
color: var(--sl-color-danger-600);
}
.red::part(base):hover,
.red::part(base):focus {
color: var(--sl-color-danger-600);
}
.red::part(base):active {
color: var(--sl-color-danger-600);
}
`;

0 comments on commit 8e52111

Please sign in to comment.