@nopwdio/ui
Version:
Nopwd Design System
267 lines (242 loc) • 7.77 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators.js";
import { clipboardDocument, clipboardDocumentCheck } from "../icons/outline.js";
var State;
(function (State) {
State[State["IDLE"] = 0] = "IDLE";
State[State["BUSY"] = 1] = "BUSY";
State[State["DONE"] = 2] = "DONE";
})(State || (State = {}));
const ANIMATION_DELAY = 150;
const DONE_DELAY = 1500;
/**
* `ui-clipboard` is a custom element that provides a button to copy text to the clipboard.
*
* @element ui-clipboard
*
* @property {string} value - The text value to be copied to the clipboard.
*
* @csspart button - The button element used to trigger the copy action.
* @csspart icon - The icon inside the button.
*
* @cssprop --np-border-color - Border color of the host element.
* @cssprop --np-border-width - Border width of the host element.
* @cssprop --np-border-radius - Border radius of the host element.
* @cssprop --np-shadow-emphasis - Box shadow of the host element.
* @cssprop --np-fill-color-accent - Fill color when the host element is hovered.
* @cssprop --np-transition-duration - Transition duration for hover effects.
* @cssprop --np-padding-emphasis - Padding inside the anchor element.
* @cssprop --np-gap-emphasis - Gap inside the anchor element.
* @cssprop --np-text-color - Text color of the heading and button.
* @cssprop --np-text-size - Text size of the heading and button.
* @cssprop --np-text-weight-emphasis - Font weight of the heading.
* @cssprop --np-text-color-muted - Muted text color for the icon and paragraph.
* @cssprop --np-text-size-muted - Text size of the paragraph.
* @cssprop --np-text-weight - Font weight of the paragraph.
* @cssprop --np-padding-muted - Padding inside the button.
* @cssprop --np-bg-color-emphasis - Background color of the selected button.
* @cssprop --np-shadow-muted - Box shadow of the selected button.
*/
let UiClipboard = class UiClipboard extends LitElement {
constructor() {
super(...arguments);
this.value = "";
this.state = State.IDLE;
}
connectedCallback() {
super.connectedCallback();
this.style.setProperty("--delay", `${ANIMATION_DELAY}ms`);
}
/**
* Copies the `value` property to the clipboard.
*/
copyToClipboard() {
return __awaiter(this, void 0, void 0, function* () {
if (this.state !== State.IDLE) {
return;
}
if (this.value.length === 0) {
return;
}
this.state = State.BUSY;
const done = navigator.clipboard.writeText(this.value);
const wait = this.wait(ANIMATION_DELAY);
yield Promise.all([done, wait]);
this.state = State.DONE;
yield this.wait(DONE_DELAY);
this.state = State.IDLE;
});
}
wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
render() {
return html `
${this.state === State.IDLE
? html `<span class="idle" @click=${this.copyToClipboard}>${clipboardDocument}</span>`
: this.state === State.BUSY
? html `<span class="busy">${clipboardDocument}</span>`
: this.state === State.DONE
? html `<span class="done">${clipboardDocumentCheck}</span>`
: html ``}
`;
}
};
UiClipboard.styles = [
css `
:host {
display: flex;
}
span.idle {
cursor: pointer;
}
.icon {
width: var(--np-text-size);
height: var(--np-text-size);
}
span.busy .icon {
animation: hideIt var(--delay) linear forwards;
}
span.done .icon {
animation: showIt var(--delay) linear forwards;
}
@keyframes hideIt {
from {
transform: scale(1);
}
to {
transform: scale(0);
}
}
@keyframes showIt {
from {
transform: scale(0);
}
50% {
transform: scale(1.4);
}
to {
transform: scale(1);
}
}
.icon {
width: 1em;
height: 1em;
}
`,
];
__decorate([
property({ type: String })
], UiClipboard.prototype, "value", void 0);
__decorate([
property({ type: Number })
], UiClipboard.prototype, "state", void 0);
UiClipboard = __decorate([
customElement("ui-clipboard")
], UiClipboard);
export { UiClipboard };
/**
*
* enum State {
IDLE,
BUSY,
DONE,
}
const ANIMATION_DELAY = 150;
const DONE_DELAY = 1500;
@customElement("ui-clipboard")
export class UiClipboard extends LitElement {
@property() text: string = "";
@property({ type: Number }) state: State = State.IDLE;
connectedCallback(): void {
super.connectedCallback();
this.style.setProperty("--delay", `${ANIMATION_DELAY}ms`);
}
async copy() {
if (this.state !== State.IDLE) {
return;
}
if (this.text.length === 0) {
return;
}
this.state = State.BUSY;
const done = navigator.clipboard.writeText(this.text);
await this.wait(ANIMATION_DELAY);
await done;
this.state = State.DONE;
await this.wait(DONE_DELAY);
this.state = State.IDLE;
}
private wait(ms: number) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
render() {
return html`${this.state === State.IDLE
? html`<span class="idle" @click=${this.copy}>${clipboardDocument}</span>`
: this.state === State.BUSY
? html`<span class="busy">${clipboardDocument}</span>`
: this.state === State.DONE
? html`<span class="done">${clipboardDocumentCheck}</span>`
: html``}`;
}
static styles = css`
:host,
span {
display: flex;
align-items: center;
}
.icon {
width: 1em;
height: 1em;
}
span.idle {
cursor: pointer;
}
span.busy .icon {
animation: hideIt var(--delay) linear forwards;
}
span.done .icon {
animation: showIt var(--delay) linear forwards;
}
@keyframes hideIt {
from {
transform: scale(1);
}
to {
transform: scale(0);
}
}
@keyframes showIt {
from {
transform: scale(0);
}
50% {
transform: scale(1.4);
}
to {
transform: scale(1);
}
}
`;
}
*/
//# sourceMappingURL=ui-clipboard.js.map