117 lines
2.3 KiB
TypeScript
117 lines
2.3 KiB
TypeScript
import { FolkShape } from "./folk-shape";
|
|
import { css, html } from "./tags";
|
|
|
|
const styles = css`
|
|
:host {
|
|
background: transparent;
|
|
min-width: 200px;
|
|
min-height: 150px;
|
|
}
|
|
|
|
.slide-container {
|
|
width: 100%;
|
|
height: 100%;
|
|
position: relative;
|
|
border: 2px dashed #94a3b8;
|
|
border-radius: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.slide-label {
|
|
position: absolute;
|
|
top: 8px;
|
|
left: 12px;
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: #64748b;
|
|
background: white;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.slide-content {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #94a3b8;
|
|
font-size: 48px;
|
|
}
|
|
`;
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
"folk-slide": FolkSlide;
|
|
}
|
|
}
|
|
|
|
export class FolkSlide extends FolkShape {
|
|
static override tagName = "folk-slide";
|
|
|
|
static {
|
|
const sheet = new CSSStyleSheet();
|
|
const parentRules = Array.from(FolkShape.styles.cssRules)
|
|
.map((r) => r.cssText)
|
|
.join("\n");
|
|
const childRules = Array.from(styles.cssRules)
|
|
.map((r) => r.cssText)
|
|
.join("\n");
|
|
sheet.replaceSync(`${parentRules}\n${childRules}`);
|
|
this.styles = sheet;
|
|
}
|
|
|
|
#label = "Slide 1";
|
|
|
|
get label() {
|
|
return this.#label;
|
|
}
|
|
|
|
set label(value: string) {
|
|
this.#label = value;
|
|
this.requestUpdate("label");
|
|
}
|
|
|
|
override createRenderRoot() {
|
|
const root = super.createRenderRoot();
|
|
|
|
const wrapper = document.createElement("div");
|
|
wrapper.innerHTML = html`
|
|
<div class="slide-container" data-drag>
|
|
<div class="slide-label">Slide 1</div>
|
|
<div class="slide-content">
|
|
<slot></slot>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
const slot = root.querySelector("slot");
|
|
if (slot?.parentElement) {
|
|
slot.parentElement.replaceChild(
|
|
wrapper.querySelector(".slide-container")!,
|
|
slot.parentElement.querySelector("div")!
|
|
);
|
|
}
|
|
|
|
// Update label from attribute
|
|
this.#label = this.getAttribute("label") || "Slide 1";
|
|
const labelEl = root.querySelector(".slide-label") as HTMLElement;
|
|
if (labelEl) {
|
|
labelEl.textContent = this.#label;
|
|
}
|
|
|
|
return root;
|
|
}
|
|
|
|
override toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
type: "folk-slide",
|
|
label: this.label,
|
|
};
|
|
}
|
|
}
|