import { FolkShape } from "./folk-shape"; import { css, html } from "./tags"; const styles = css` :host { background: white; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); min-width: 260px; min-height: 180px; } .header { display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; background: #059669; color: white; border-radius: 8px 8px 0 0; font-size: 12px; font-weight: 600; cursor: move; } .header-title { display: flex; align-items: center; gap: 6px; } .header-actions button { background: transparent; border: none; color: white; cursor: pointer; padding: 2px 6px; border-radius: 4px; font-size: 14px; } .header-actions button:hover { background: rgba(255, 255, 255, 0.2); } .dest-body { padding: 12px; } .dest-name { font-size: 16px; font-weight: 700; color: #1e293b; margin-bottom: 2px; } .dest-country { font-size: 12px; color: #64748b; margin-bottom: 8px; } .dest-dates { display: flex; gap: 12px; font-size: 11px; color: #475569; margin-bottom: 10px; padding: 6px 8px; background: #f1f5f9; border-radius: 4px; } .dest-dates span { display: flex; align-items: center; gap: 4px; } .dest-dates .label { color: #94a3b8; font-weight: 500; } .dest-notes { font-size: 12px; color: #475569; line-height: 1.5; padding: 8px; background: #fafaf9; border-radius: 4px; border: 1px solid #e2e8f0; min-height: 40px; white-space: pre-wrap; } .dest-notes[contenteditable]:focus { outline: none; border-color: #059669; } .coords { font-size: 10px; color: #94a3b8; margin-top: 6px; } .empty-name { color: #94a3b8; font-style: italic; } `; declare global { interface HTMLElementTagNameMap { "folk-destination": FolkDestination; } } export class FolkDestination extends FolkShape { static override tagName = "folk-destination"; 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; } #destName = ""; #country = ""; #lat: number | null = null; #lng: number | null = null; #arrivalDate = ""; #departureDate = ""; #notes = ""; #nameEl: HTMLElement | null = null; #countryEl: HTMLElement | null = null; #notesEl: HTMLElement | null = null; #datesEl: HTMLElement | null = null; get destName() { return this.#destName; } set destName(v: string) { this.#destName = v; if (this.#nameEl) this.#nameEl.textContent = v || "Unnamed destination"; this.dispatchEvent(new CustomEvent("content-change")); } get country() { return this.#country; } set country(v: string) { this.#country = v; if (this.#countryEl) this.#countryEl.textContent = v; this.dispatchEvent(new CustomEvent("content-change")); } get lat() { return this.#lat; } set lat(v: number | null) { this.#lat = v; } get lng() { return this.#lng; } set lng(v: number | null) { this.#lng = v; } get arrivalDate() { return this.#arrivalDate; } set arrivalDate(v: string) { this.#arrivalDate = v; this.#renderDates(); this.dispatchEvent(new CustomEvent("content-change")); } get departureDate() { return this.#departureDate; } set departureDate(v: string) { this.#departureDate = v; this.#renderDates(); this.dispatchEvent(new CustomEvent("content-change")); } get notes() { return this.#notes; } set notes(v: string) { this.#notes = v; if (this.#notesEl && this.#notesEl.textContent !== v) { this.#notesEl.textContent = v; } this.dispatchEvent(new CustomEvent("content-change")); } override createRenderRoot() { const root = super.createRenderRoot(); const wrapper = document.createElement("div"); wrapper.innerHTML = html`