@lit-pigeon/editor 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,195 @@
1
+ import { LitElement as b, html as a, css as g } from "lit";
2
+ import { property as h, customElement as u } from "lit/decorators.js";
3
+ import { generateId as p } from "@lit-pigeon/core";
4
+ import { t as i } from "./templates.js";
5
+ var m = Object.defineProperty, f = Object.getOwnPropertyDescriptor, c = (e, t, o, n) => {
6
+ for (var r = n > 1 ? void 0 : n ? f(t, o) : t, s = e.length - 1, d; s >= 0; s--)
7
+ (d = e[s]) && (r = (n ? d(t, o, r) : d(r)) || r);
8
+ return n && r && m(t, o, r), r;
9
+ };
10
+ let l = class extends b {
11
+ constructor() {
12
+ super(...arguments), this.brandKit = null;
13
+ }
14
+ render() {
15
+ const e = this.brandKit;
16
+ return e ? a`
17
+ ${this._renderColors(e)}
18
+ ${this._renderFonts(e)}
19
+ ${this._renderLogos(e)}
20
+ ` : a``;
21
+ }
22
+ _renderColors(e) {
23
+ return a`
24
+ <div class="section">
25
+ <div class="section-head">
26
+ <h4>${i("palette.brand.colors")}</h4>
27
+ <button class="add add-color" type="button" @click=${this._addColor}>${i("palette.brand.add")}</button>
28
+ </div>
29
+ ${e.colors.length === 0 ? a`<div class="empty">${i("palette.brand.no-colors")}</div>` : ""}
30
+ ${e.colors.map(
31
+ (t) => a`<div class="row" data-color-id=${t.id}>
32
+ <button
33
+ class="swatch" type="button" title=${`Apply ${t.name}`} aria-label=${`Apply ${t.name}`}
34
+ style=${`background:${t.value}`} @click=${() => this._applyColor(t)}
35
+ ></button>
36
+ <input
37
+ class="name-input" aria-label=${i("palette.brand.color-name-label")} .value=${t.name}
38
+ @change=${(o) => this._renameColor(t, o.target.value)}
39
+ />
40
+ <input
41
+ type="color" aria-label=${i("palette.brand.color-value-label")} .value=${t.value}
42
+ @input=${(o) => this._recolor(t, o.target.value)}
43
+ />
44
+ <button class="delete" type="button" title=${i("palette.brand.delete-title")} aria-label=${`Delete ${t.name}`} @click=${() => this._deleteColor(t)}>×</button>
45
+ </div>`
46
+ )}
47
+ </div>
48
+ `;
49
+ }
50
+ _renderFonts(e) {
51
+ return a`
52
+ <div class="section">
53
+ <div class="section-head">
54
+ <h4>${i("palette.brand.fonts")}</h4>
55
+ <button class="add add-font" type="button" @click=${this._addFont}>${i("palette.brand.add")}</button>
56
+ </div>
57
+ ${e.fonts.length === 0 ? a`<div class="empty">${i("palette.brand.no-fonts")}</div>` : ""}
58
+ ${e.fonts.map(
59
+ (t) => a`<div class="row" data-font-id=${t.id}>
60
+ <button class="apply" type="button" title=${`Apply ${t.name}`} aria-label=${`Apply font ${t.name}`} @click=${() => this._applyFont(t)}>
61
+ ${t.name}
62
+ </button>
63
+ <button class="delete" type="button" title=${i("palette.brand.delete-title")} aria-label=${`Delete ${t.name}`} @click=${() => this._deleteFont(t)}>×</button>
64
+ </div>`
65
+ )}
66
+ </div>
67
+ `;
68
+ }
69
+ _renderLogos(e) {
70
+ return a`
71
+ <div class="section">
72
+ <div class="section-head">
73
+ <h4>${i("palette.brand.logos")}</h4>
74
+ <button class="add add-logo" type="button" @click=${this._addLogo}>${i("palette.brand.add")}</button>
75
+ </div>
76
+ ${e.logos.length === 0 ? a`<div class="empty">${i("palette.brand.no-logos")}</div>` : ""}
77
+ ${e.logos.map(
78
+ (t) => a`<div class="row" data-logo-id=${t.id}>
79
+ <img class="logo-thumb" src=${t.src} alt=${t.name} />
80
+ <button class="apply" type="button" title=${i("palette.brand.insert-logo-title")} aria-label=${`Insert logo ${t.name}`} @click=${() => this._insertLogo(t)}>
81
+ ${t.name}
82
+ </button>
83
+ <button class="delete" type="button" title=${i("palette.brand.delete-title")} aria-label=${`Delete ${t.name}`} @click=${() => this._deleteLogo(t)}>×</button>
84
+ </div>`
85
+ )}
86
+ </div>
87
+ `;
88
+ }
89
+ /* ---- apply / insert (no kit mutation) ---- */
90
+ _applyColor(e) {
91
+ this._fire("brand-color-apply", { value: e.value });
92
+ }
93
+ _applyFont(e) {
94
+ this._fire("brand-font-apply", { family: e.family });
95
+ }
96
+ _insertLogo(e) {
97
+ this._fire("brand-logo-insert", { logo: e });
98
+ }
99
+ /* ---- mutations: compute new kit, emit brand-kit-edit ---- */
100
+ _emitKit(e) {
101
+ this._fire("brand-kit-edit", { kit: e });
102
+ }
103
+ _clone() {
104
+ const e = this.brandKit;
105
+ return { ...e, colors: [...e.colors], fonts: [...e.fonts], logos: [...e.logos] };
106
+ }
107
+ _addColor() {
108
+ const e = this._clone();
109
+ e.colors = [...e.colors, { id: p(), name: "New color", value: "#000000" }], this._emitKit(e);
110
+ }
111
+ _renameColor(e, t) {
112
+ const o = this._clone();
113
+ o.colors = o.colors.map((n) => n.id === e.id ? { ...n, name: t } : n), this._emitKit(o);
114
+ }
115
+ _recolor(e, t) {
116
+ const o = this._clone();
117
+ o.colors = o.colors.map((n) => n.id === e.id ? { ...n, value: t } : n), this._emitKit(o);
118
+ }
119
+ _deleteColor(e) {
120
+ const t = this._clone();
121
+ t.colors = t.colors.filter((o) => o.id !== e.id), this._emitKit(t);
122
+ }
123
+ _addFont() {
124
+ const e = this._clone();
125
+ e.fonts = [...e.fonts, { id: p(), name: "New font", family: "Arial, Helvetica, sans-serif" }], this._emitKit(e);
126
+ }
127
+ _deleteFont(e) {
128
+ const t = this._clone();
129
+ t.fonts = t.fonts.filter((o) => o.id !== e.id), this._emitKit(t);
130
+ }
131
+ _addLogo() {
132
+ const e = prompt("Logo image URL");
133
+ if (!e) return;
134
+ const t = this._clone();
135
+ t.logos = [...t.logos, { id: p(), name: "Logo", src: e }], this._emitKit(t);
136
+ }
137
+ _deleteLogo(e) {
138
+ const t = this._clone();
139
+ t.logos = t.logos.filter((o) => o.id !== e.id), this._emitKit(t);
140
+ }
141
+ _fire(e, t) {
142
+ this.dispatchEvent(new CustomEvent(e, { detail: t, bubbles: !0, composed: !0 }));
143
+ }
144
+ };
145
+ l.styles = g`
146
+ :host { display: block; }
147
+ .section { padding: 12px; }
148
+ .section:not(:last-child) { border-bottom: 1px solid var(--pigeon-border, #e2e8f0); }
149
+ .section-head {
150
+ display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;
151
+ }
152
+ .section-head h4 {
153
+ margin: 0; font-size: 11px; font-weight: 600; text-transform: uppercase;
154
+ letter-spacing: 0.5px; color: var(--pigeon-text-secondary, #64748b); font-family: var(--pigeon-font);
155
+ }
156
+ .add {
157
+ border: 1px solid var(--pigeon-border, #e2e8f0); background: var(--pigeon-surface, #f8fafc);
158
+ border-radius: var(--pigeon-radius-sm, 6px); cursor: pointer; font-size: 12px;
159
+ line-height: 1; padding: 4px 8px; color: var(--pigeon-text-secondary, #64748b);
160
+ }
161
+ .row {
162
+ display: flex; align-items: center; gap: 8px; padding: 4px 0; font-family: var(--pigeon-font);
163
+ font-size: 13px; color: var(--pigeon-text, #1e293b);
164
+ }
165
+ .swatch {
166
+ width: 20px; height: 20px; border-radius: var(--pigeon-radius-sm, 4px);
167
+ border: 1px solid var(--pigeon-input, #cbd5e1); padding: 0; cursor: pointer; flex-shrink: 0;
168
+ }
169
+ .name { flex: 1; }
170
+ .name-input {
171
+ flex: 1; height: 24px; border: 1px solid var(--pigeon-input, #cbd5e1);
172
+ border-radius: var(--pigeon-radius-sm, 4px); padding: 0 6px; font: inherit; min-width: 0;
173
+ }
174
+ .apply {
175
+ flex: 1; text-align: left; background: none; border: none; cursor: pointer; font: inherit;
176
+ color: var(--pigeon-text, #1e293b); padding: 0; min-width: 0;
177
+ }
178
+ .apply:hover { color: var(--pigeon-primary, #4f46e5); }
179
+ .delete {
180
+ background: none; border: none; cursor: pointer; color: var(--pigeon-text-muted, #94a3b8);
181
+ font-size: 14px; line-height: 1; padding: 2px;
182
+ }
183
+ .delete:hover { color: var(--pigeon-danger, #dc2626); }
184
+ .logo-thumb { width: 28px; height: 28px; object-fit: contain; flex-shrink: 0; }
185
+ .empty { font-size: 12px; color: var(--pigeon-text-muted, #94a3b8); font-family: var(--pigeon-font); }
186
+ `;
187
+ c([
188
+ h({ attribute: !1 })
189
+ ], l.prototype, "brandKit", 2);
190
+ l = c([
191
+ u("pigeon-brand-tab")
192
+ ], l);
193
+ export {
194
+ l as PigeonBrandTab
195
+ };
@@ -0,0 +1,93 @@
1
+ import { LitElement as c, html as l, css as f } from "lit";
2
+ import { property as b, state as g, customElement as u } from "lit/decorators.js";
3
+ import { writeDragTransfer as m } from "./index.js";
4
+ import { t as d } from "./templates.js";
5
+ var v = Object.defineProperty, h = Object.getOwnPropertyDescriptor, p = (e, t, n, o) => {
6
+ for (var r = o > 1 ? void 0 : o ? h(t, n) : t, i = e.length - 1, s; i >= 0; i--)
7
+ (s = e[i]) && (r = (o ? s(t, n, r) : s(r)) || r);
8
+ return o && r && v(t, n, r), r;
9
+ };
10
+ let a = class extends c {
11
+ constructor() {
12
+ super(...arguments), this._entries = [];
13
+ }
14
+ async connectedCallback() {
15
+ super.connectedCallback(), await this.refresh();
16
+ }
17
+ /** Re-load entries from storage. */
18
+ async refresh() {
19
+ if (!this.storage) {
20
+ this._entries = [];
21
+ return;
22
+ }
23
+ try {
24
+ this._entries = await this.storage.list();
25
+ } catch {
26
+ this._entries = [];
27
+ }
28
+ }
29
+ render() {
30
+ return l`
31
+ <div class="section">
32
+ ${this._entries.length === 0 ? l`<div class="empty">${d("palette.saved.empty")}</div>` : this._entries.map(
33
+ (e) => l`<div
34
+ class="row" data-entry-id=${e.id} draggable="true"
35
+ role="button" tabindex="0" aria-label=${`Insert ${e.name}`}
36
+ @dragstart=${(t) => this._onDragStart(t, e)}
37
+ @keydown=${(t) => this._onKeyDown(t, e)}
38
+ >
39
+ <span class="name">${e.name}</span>
40
+ <button class="delete" type="button" title=${d("palette.saved.delete-title")} aria-label=${`Delete ${e.name}`}
41
+ @click=${() => this._onDelete(e)}>×</button>
42
+ </div>`
43
+ )}
44
+ </div>
45
+ `;
46
+ }
47
+ _onKeyDown(e, t) {
48
+ e.key !== "Enter" && e.key !== " " || (e.preventDefault(), this.dispatchEvent(new CustomEvent("library-insert", {
49
+ detail: { node: t.node },
50
+ bubbles: !0,
51
+ composed: !0
52
+ })));
53
+ }
54
+ _onDragStart(e, t) {
55
+ m(e, { type: "library-row", node: t.node }), e.dataTransfer && (e.dataTransfer.effectAllowed = "copy");
56
+ }
57
+ _onDelete(e) {
58
+ this.dispatchEvent(new CustomEvent("library-delete", {
59
+ detail: { id: e.id },
60
+ bubbles: !0,
61
+ composed: !0
62
+ }));
63
+ }
64
+ };
65
+ a.styles = f`
66
+ :host { display: block; }
67
+ .section { padding: 12px; }
68
+ .empty { font-size: 12px; color: var(--pigeon-text-muted, #94a3b8); font-family: var(--pigeon-font); }
69
+ .row {
70
+ display: flex; align-items: center; gap: 8px; padding: 8px 12px; margin-bottom: 6px;
71
+ border: 1px solid var(--pigeon-border, #e2e8f0); border-radius: var(--pigeon-radius, 6px);
72
+ background: var(--pigeon-bg, #ffffff); cursor: grab; font-family: var(--pigeon-font); font-size: 13px;
73
+ }
74
+ .row:hover { border-color: var(--pigeon-primary, #3b82f6); background: var(--pigeon-surface, #f8fafc); }
75
+ .name { flex: 1; color: var(--pigeon-text, #1e293b); }
76
+ .delete {
77
+ background: none; border: none; cursor: pointer; color: var(--pigeon-text-muted, #94a3b8);
78
+ font-size: 14px; line-height: 1; padding: 2px;
79
+ }
80
+ .delete:hover { color: var(--pigeon-danger, #dc2626); }
81
+ `;
82
+ p([
83
+ b({ attribute: !1 })
84
+ ], a.prototype, "storage", 2);
85
+ p([
86
+ g()
87
+ ], a.prototype, "_entries", 2);
88
+ a = p([
89
+ u("pigeon-saved-tab")
90
+ ], a);
91
+ export {
92
+ a as PigeonSavedTab
93
+ };