ngx-xtroedge-cms 1.0.1 → 1.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.
- package/dist/index.d.mts +14 -4
- package/dist/index.d.ts +14 -4
- package/dist/index.global.js +112 -50
- package/dist/index.js +273 -61
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +273 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -32,32 +32,32 @@ var CMS_STYLES = `
|
|
|
32
32
|
.lcms-loader-overlay {
|
|
33
33
|
position: fixed; inset: 0; z-index: 10003;
|
|
34
34
|
display: flex; align-items: center; justify-content: center;
|
|
35
|
-
background: rgba(
|
|
35
|
+
background: rgba(8, 8, 15, 0.45);
|
|
36
36
|
backdrop-filter: blur(12px) saturate(1.4);
|
|
37
37
|
-webkit-backdrop-filter: blur(12px) saturate(1.4);
|
|
38
38
|
}
|
|
39
39
|
.lcms-loader-content { display: flex; flex-direction: column; align-items: center; gap: 28px; }
|
|
40
40
|
.lcms-orbit-loader { position: relative; width: 90px; height: 90px; }
|
|
41
41
|
.lcms-orbit { position: absolute; inset: 0; border-radius: 50%; border: 1px solid transparent; }
|
|
42
|
-
.lcms-orbit-1 { border-top-color: rgba(
|
|
43
|
-
.lcms-orbit-2 { inset: 10px; border-right-color: rgba(
|
|
44
|
-
.lcms-orbit-3 { inset: 20px; border-bottom-color: rgba(
|
|
42
|
+
.lcms-orbit-1 { border-top-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.5); animation: lcmsSpin 2.4s linear infinite; }
|
|
43
|
+
.lcms-orbit-2 { inset: 10px; border-right-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.4); animation: lcmsSpin 3.2s linear infinite reverse; }
|
|
44
|
+
.lcms-orbit-3 { inset: 20px; border-bottom-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.35); animation: lcmsSpin 4.2s linear infinite; }
|
|
45
45
|
.lcms-particle {
|
|
46
46
|
position: absolute; width: 8px; height: 8px; border-radius: 50%; top: -4px; left: 50%; margin-left: -4px;
|
|
47
47
|
box-shadow: 0 0 12px 3px currentColor;
|
|
48
48
|
}
|
|
49
|
-
.lcms-orbit-1 .lcms-particle { background: #
|
|
50
|
-
.lcms-orbit-2 .lcms-particle { background:
|
|
51
|
-
.lcms-orbit-3 .lcms-particle { background:
|
|
49
|
+
.lcms-orbit-1 .lcms-particle { background: var(--lcms-primary, #00C853); color: var(--lcms-primary, #00C853); }
|
|
50
|
+
.lcms-orbit-2 .lcms-particle { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.8); color: rgba(var(--lcms-primary-rgb, 0,200,83),0.8); top: 50%; left: auto; right: -4px; margin-left: 0; margin-top: -4px; }
|
|
51
|
+
.lcms-orbit-3 .lcms-particle { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.6); color: rgba(var(--lcms-primary-rgb, 0,200,83),0.6); top: auto; bottom: -4px; }
|
|
52
52
|
.lcms-core-glow {
|
|
53
53
|
position: absolute; width: 30px; height: 30px; top: 50%; left: 50%; transform: translate(-50%,-50%);
|
|
54
|
-
border-radius: 50%; background: radial-gradient(circle, rgba(
|
|
54
|
+
border-radius: 50%; background: radial-gradient(circle, rgba(var(--lcms-primary-rgb, 0,200,83),0.4), transparent 70%);
|
|
55
55
|
animation: lcmsPulse 2s ease-in-out infinite;
|
|
56
56
|
}
|
|
57
57
|
.lcms-core {
|
|
58
58
|
position: absolute; width: 12px; height: 12px; top: 50%; left: 50%; transform: translate(-50%,-50%);
|
|
59
|
-
border-radius: 50%; background: linear-gradient(135deg,
|
|
60
|
-
box-shadow: 0 0 20px rgba(
|
|
59
|
+
border-radius: 50%; background: linear-gradient(135deg, var(--lcms-primary, #00C853), rgba(var(--lcms-primary-rgb, 0,200,83),0.6));
|
|
60
|
+
box-shadow: 0 0 20px rgba(var(--lcms-primary-rgb, 0,200,83),0.6);
|
|
61
61
|
}
|
|
62
62
|
.lcms-loader-text {
|
|
63
63
|
font-family: system-ui, -apple-system, sans-serif; font-size: 12px; font-weight: 600;
|
|
@@ -74,10 +74,10 @@ var CMS_STYLES = `
|
|
|
74
74
|
padding: 10px 20px; border-radius: 10px; font-size: 13px; font-weight: 600;
|
|
75
75
|
font-family: system-ui, -apple-system, sans-serif; color: white;
|
|
76
76
|
display: flex; align-items: center; gap: 8px;
|
|
77
|
-
box-shadow: 0 8px 32px rgba(
|
|
77
|
+
box-shadow: 0 8px 32px rgba(var(--lcms-primary-rgb, 0,200,83),0.25);
|
|
78
78
|
animation: lcmsToastIn 0.3s ease, lcmsToastOut 0.3s ease 2.7s forwards; white-space: nowrap;
|
|
79
79
|
}
|
|
80
|
-
.lcms-toast-success { background: linear-gradient(135deg, #
|
|
80
|
+
.lcms-toast-success { background: linear-gradient(135deg, var(--lcms-primary, #00C853), var(--lcms-primary-dark, #2E7D32)); }
|
|
81
81
|
.lcms-toast-error { background: linear-gradient(135deg, #dc2626, #ef4444); }
|
|
82
82
|
@keyframes lcmsToastIn { from { opacity: 0; transform: translateX(-50%) translateY(-12px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }
|
|
83
83
|
@keyframes lcmsToastOut { from { opacity: 1; transform: translateX(-50%) translateY(0); } to { opacity: 0; transform: translateX(-50%) translateY(-12px); } }
|
|
@@ -86,15 +86,15 @@ var CMS_STYLES = `
|
|
|
86
86
|
.lcms-fab { position: fixed; z-index: 10001; user-select: none; touch-action: none; }
|
|
87
87
|
.lcms-fab-btn {
|
|
88
88
|
width: 52px; height: 52px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.2);
|
|
89
|
-
background: rgba(
|
|
89
|
+
background: rgba(var(--lcms-primary-rgb, 0,200,83),0.35); color: white;
|
|
90
90
|
backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
|
|
91
91
|
cursor: grab; display: flex; align-items: center; justify-content: center;
|
|
92
|
-
box-shadow: 0 4px 20px rgba(
|
|
92
|
+
box-shadow: 0 4px 20px rgba(var(--lcms-primary-rgb, 0,200,83),0.3), inset 0 1px 0 rgba(255,255,255,0.15);
|
|
93
93
|
transition: transform 0.2s, box-shadow 0.2s, background 0.2s; position: relative;
|
|
94
94
|
}
|
|
95
|
-
.lcms-fab-btn:not(.lcms-fab-active) { background: rgba(
|
|
96
|
-
.lcms-fab-btn.lcms-fab-active { background: rgba(
|
|
97
|
-
.lcms-fab-btn:hover { transform: scale(1.08); background: rgba(
|
|
95
|
+
.lcms-fab-btn:not(.lcms-fab-active) { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.25); box-shadow: 0 4px 16px rgba(0,0,0,0.2), inset 0 1px 0 rgba(255,255,255,0.1); }
|
|
96
|
+
.lcms-fab-btn.lcms-fab-active { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.4); box-shadow: 0 4px 24px rgba(var(--lcms-primary-rgb, 0,200,83),0.4), 0 0 16px rgba(var(--lcms-primary-rgb, 0,200,83),0.2), inset 0 1px 0 rgba(255,255,255,0.2); }
|
|
97
|
+
.lcms-fab-btn:hover { transform: scale(1.08); background: rgba(var(--lcms-primary-rgb, 0,200,83),0.5); box-shadow: 0 6px 28px rgba(var(--lcms-primary-rgb, 0,200,83),0.4), inset 0 1px 0 rgba(255,255,255,0.2); }
|
|
98
98
|
.lcms-badge {
|
|
99
99
|
position: absolute; top: -4px; right: -4px; background: #ef4444; color: white;
|
|
100
100
|
font-size: 11px; font-weight: 700; width: 20px; height: 20px; border-radius: 50%;
|
|
@@ -103,14 +103,45 @@ var CMS_STYLES = `
|
|
|
103
103
|
|
|
104
104
|
/* PANEL */
|
|
105
105
|
.lcms-panel {
|
|
106
|
-
background: rgba(
|
|
107
|
-
border: 1px solid rgba(
|
|
106
|
+
background: rgba(12,12,18,0.55); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
|
|
107
|
+
border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.25); border-radius: 16px; padding: 16px; min-width: 230px;
|
|
108
108
|
box-shadow: 0 8px 32px rgba(0,0,0,0.25), inset 0 1px 0 rgba(255,255,255,0.06);
|
|
109
109
|
color: white; font-family: system-ui, -apple-system, sans-serif;
|
|
110
110
|
animation: lcmsPanelIn 0.25s ease; position: absolute;
|
|
111
111
|
}
|
|
112
112
|
@keyframes lcmsPanelIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } }
|
|
113
113
|
|
|
114
|
+
/* SITE IDENTIFIER */
|
|
115
|
+
.lcms-site-id {
|
|
116
|
+
display: flex; align-items: center; gap: 5px;
|
|
117
|
+
font-size: 10px; color: rgba(255,255,255,0.4);
|
|
118
|
+
padding: 0 0 8px; margin-bottom: 8px;
|
|
119
|
+
border-bottom: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.12);
|
|
120
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
121
|
+
letter-spacing: 0.3px;
|
|
122
|
+
}
|
|
123
|
+
.lcms-site-id-icon { font-size: 12px; opacity: 0.7; }
|
|
124
|
+
.lcms-site-id-text {
|
|
125
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 180px;
|
|
126
|
+
font-weight: 500;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* BRANDING */
|
|
130
|
+
.lcms-branding {
|
|
131
|
+
display: flex; align-items: center; gap: 6px; padding: 8px 0 4px;
|
|
132
|
+
border-top: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.15); margin-top: 10px;
|
|
133
|
+
cursor: pointer; transition: opacity 0.2s; user-select: none;
|
|
134
|
+
}
|
|
135
|
+
.lcms-branding:hover { opacity: 0.8; }
|
|
136
|
+
.lcms-branding-logo {
|
|
137
|
+
width: 18px; height: 18px; border-radius: 4px; background: linear-gradient(135deg, var(--lcms-primary, #00C853), var(--lcms-primary-dark, #2E7D32));
|
|
138
|
+
display: flex; align-items: center; justify-content: center;
|
|
139
|
+
}
|
|
140
|
+
.lcms-branding-text {
|
|
141
|
+
font-size: 10px; font-weight: 600; color: rgba(255,255,255,0.35); letter-spacing: 0.5px;
|
|
142
|
+
}
|
|
143
|
+
.lcms-branding-text span { color: var(--lcms-primary, #00C853); font-weight: 700; }
|
|
144
|
+
|
|
114
145
|
.lcms-panel-header { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
|
|
115
146
|
.lcms-toggle { display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; }
|
|
116
147
|
.lcms-toggle input { display: none; }
|
|
@@ -122,53 +153,84 @@ var CMS_STYLES = `
|
|
|
122
153
|
content: ''; position: absolute; width: 16px; height: 16px; border-radius: 50%;
|
|
123
154
|
top: 2px; left: 2px; background: rgba(255,255,255,0.6); transition: transform 0.25s, background 0.25s;
|
|
124
155
|
}
|
|
125
|
-
.lcms-toggle input:checked + .lcms-toggle-slider { background: #
|
|
156
|
+
.lcms-toggle input:checked + .lcms-toggle-slider { background: var(--lcms-primary, #00C853); }
|
|
126
157
|
.lcms-toggle input:checked + .lcms-toggle-slider::after { transform: translateX(16px); background: white; }
|
|
127
158
|
.lcms-toggle-label { font-size: 12px; font-weight: 700; color: rgba(255,255,255,0.5); letter-spacing: 0.5px; transition: color 0.25s; }
|
|
128
|
-
.lcms-toggle input:checked ~ .lcms-toggle-label { color:
|
|
129
|
-
.lcms-lang-switch { display: flex; border: 1px solid rgba(
|
|
159
|
+
.lcms-toggle input:checked ~ .lcms-toggle-label { color: rgba(var(--lcms-primary-rgb, 0,200,83),0.75); }
|
|
160
|
+
.lcms-lang-switch { display: flex; border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.4); border-radius: 6px; overflow: hidden; margin-left: auto; }
|
|
130
161
|
.lcms-lang-btn { background: transparent; border: none; color: rgba(255,255,255,0.45); padding: 3px 12px; font-size: 11px; font-weight: 600; cursor: pointer; transition: all 0.2s; }
|
|
131
|
-
.lcms-lang-btn.active { background: #
|
|
132
|
-
.lcms-lang-btn:hover:not(.active) { color: white; background: rgba(
|
|
162
|
+
.lcms-lang-btn.active { background: var(--lcms-primary, #00C853); color: white; }
|
|
163
|
+
.lcms-lang-btn:hover:not(.active) { color: white; background: rgba(var(--lcms-primary-rgb, 0,200,83),0.2); }
|
|
133
164
|
.lcms-close-btn { background: transparent; border: none; color: rgba(255,255,255,0.4); cursor: pointer; padding: 2px; display: flex; transition: color 0.2s; }
|
|
134
165
|
.lcms-close-btn:hover { color: white; }
|
|
135
|
-
.lcms-changes-info { font-size: 12px; color:
|
|
166
|
+
.lcms-changes-info { font-size: 12px; color: rgba(var(--lcms-primary-rgb, 0,200,83),0.75); margin-bottom: 10px; padding-left: 2px; }
|
|
136
167
|
|
|
137
168
|
.lcms-undo-row { display: flex; gap: 6px; margin-bottom: 12px; }
|
|
138
169
|
.lcms-icon-btn {
|
|
139
|
-
width: 36px; height: 32px; border-radius: 8px; border: 1px solid rgba(
|
|
140
|
-
background: rgba(
|
|
170
|
+
width: 36px; height: 32px; border-radius: 8px; border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.3);
|
|
171
|
+
background: rgba(var(--lcms-primary-rgb, 0,200,83),0.1); color: rgba(255,255,255,0.8); cursor: pointer;
|
|
141
172
|
display: flex; align-items: center; justify-content: center; transition: all 0.2s;
|
|
142
173
|
}
|
|
143
|
-
.lcms-icon-btn:hover:not(:disabled) { background: rgba(
|
|
174
|
+
.lcms-icon-btn:hover:not(:disabled) { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.25); border-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.5); color: white; }
|
|
144
175
|
.lcms-icon-btn:disabled { opacity: 0.25; cursor: not-allowed; }
|
|
145
176
|
|
|
177
|
+
/* COLOR THEME PICKER */
|
|
178
|
+
.lcms-theme-row {
|
|
179
|
+
display: flex; align-items: center; gap: 8px; margin-bottom: 12px;
|
|
180
|
+
padding: 6px 0;
|
|
181
|
+
}
|
|
182
|
+
.lcms-theme-label {
|
|
183
|
+
font-size: 10px; font-weight: 700; color: rgba(255,255,255,0.45);
|
|
184
|
+
text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap;
|
|
185
|
+
}
|
|
186
|
+
.lcms-theme-colors {
|
|
187
|
+
display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
|
|
188
|
+
}
|
|
189
|
+
.lcms-theme-swatch {
|
|
190
|
+
width: 20px; height: 20px; border-radius: 50%; border: 2px solid transparent;
|
|
191
|
+
cursor: pointer; transition: all 0.2s; position: relative;
|
|
192
|
+
}
|
|
193
|
+
.lcms-theme-swatch:hover { transform: scale(1.15); }
|
|
194
|
+
.lcms-theme-swatch.active { border-color: white; box-shadow: 0 0 8px rgba(255,255,255,0.3); }
|
|
195
|
+
.lcms-theme-custom {
|
|
196
|
+
width: 20px; height: 20px; border-radius: 50%; border: 1px dashed rgba(255,255,255,0.3);
|
|
197
|
+
cursor: pointer; overflow: hidden; position: relative;
|
|
198
|
+
}
|
|
199
|
+
.lcms-theme-custom input {
|
|
200
|
+
position: absolute; inset: -4px; width: 28px; height: 28px; border: none;
|
|
201
|
+
background: transparent; cursor: pointer; opacity: 0;
|
|
202
|
+
}
|
|
203
|
+
.lcms-theme-custom-preview {
|
|
204
|
+
width: 100%; height: 100%; border-radius: 50%;
|
|
205
|
+
background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
|
|
206
|
+
}
|
|
207
|
+
|
|
146
208
|
.lcms-history-btn {
|
|
147
209
|
width: 100%; padding: 7px 12px; border-radius: 8px;
|
|
148
|
-
border: 1px dashed rgba(
|
|
210
|
+
border: 1px dashed rgba(var(--lcms-primary-rgb, 0,200,83),0.35); background: rgba(var(--lcms-primary-rgb, 0,200,83),0.08);
|
|
149
211
|
color: rgba(255,255,255,0.6); font-size: 12px; font-weight: 500; cursor: pointer;
|
|
150
212
|
display: flex; align-items: center; justify-content: center; gap: 6px;
|
|
151
213
|
transition: all 0.2s; margin-bottom: 12px; font-family: system-ui, -apple-system, sans-serif;
|
|
152
214
|
}
|
|
153
|
-
.lcms-history-btn:hover { background: rgba(
|
|
154
|
-
.lcms-history-btn.active { background: rgba(
|
|
215
|
+
.lcms-history-btn:hover { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.18); border-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.5); color: white; }
|
|
216
|
+
.lcms-history-btn.active { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.25); border-color: var(--lcms-primary, #00C853); border-style: solid; color: white; }
|
|
155
217
|
|
|
156
|
-
.lcms-history-panel { margin-top: 8px; border-top: 1px solid rgba(
|
|
218
|
+
.lcms-history-panel { margin-top: 8px; border-top: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.15); padding-top: 10px; }
|
|
157
219
|
.lcms-history-title { font-size: 11px; font-weight: 700; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }
|
|
158
220
|
.lcms-history-empty { font-size: 12px; color: rgba(255,255,255,0.3); text-align: center; padding: 12px 0; }
|
|
159
221
|
.lcms-history-list { max-height: 200px; overflow-y: auto; display: flex; flex-direction: column; gap: 4px; }
|
|
160
222
|
.lcms-history-list::-webkit-scrollbar { width: 4px; }
|
|
161
223
|
.lcms-history-list::-webkit-scrollbar-track { background: transparent; }
|
|
162
|
-
.lcms-history-list::-webkit-scrollbar-thumb { background: rgba(
|
|
224
|
+
.lcms-history-list::-webkit-scrollbar-thumb { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.3); border-radius: 4px; }
|
|
163
225
|
.lcms-history-item {
|
|
164
|
-
width: 100%; text-align: left; background: rgba(
|
|
165
|
-
border: 1px solid rgba(
|
|
226
|
+
width: 100%; text-align: left; background: rgba(var(--lcms-primary-rgb, 0,200,83),0.06);
|
|
227
|
+
border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.12); border-radius: 8px; padding: 8px 10px;
|
|
166
228
|
cursor: pointer; transition: all 0.2s; color: white; font-family: system-ui, -apple-system, sans-serif;
|
|
167
229
|
}
|
|
168
|
-
.lcms-history-item:hover { background: rgba(
|
|
230
|
+
.lcms-history-item:hover { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.15); border-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.3); }
|
|
169
231
|
.lcms-history-label { font-size: 12px; font-weight: 500; margin-bottom: 2px; }
|
|
170
232
|
.lcms-history-meta { font-size: 10px; color: rgba(255,255,255,0.4); display: flex; align-items: center; gap: 6px; }
|
|
171
|
-
.lcms-history-lang { background: rgba(
|
|
233
|
+
.lcms-history-lang { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.2); padding: 1px 5px; border-radius: 3px; font-size: 9px; font-weight: 600; color: rgba(var(--lcms-primary-rgb, 0,200,83),0.75); }
|
|
172
234
|
|
|
173
235
|
.lcms-actions { display: flex; flex-direction: column; gap: 6px; }
|
|
174
236
|
.lcms-actions button {
|
|
@@ -176,14 +238,14 @@ var CMS_STYLES = `
|
|
|
176
238
|
cursor: pointer; transition: all 0.2s; display: flex; align-items: center; justify-content: center; gap: 6px; border: none;
|
|
177
239
|
font-family: system-ui, -apple-system, sans-serif;
|
|
178
240
|
}
|
|
179
|
-
.lcms-btn-save { background: #
|
|
180
|
-
.lcms-btn-save:hover { background: #
|
|
181
|
-
.lcms-btn-save:disabled { background: rgba(
|
|
182
|
-
.lcms-btn-publish { background: linear-gradient(135deg, #
|
|
183
|
-
.lcms-btn-publish:hover { background: linear-gradient(135deg, #
|
|
184
|
-
.lcms-btn-publish:disabled { background: rgba(
|
|
185
|
-
.lcms-btn-cancel { background: transparent; color: rgba(255,255,255,0.5); border: 1px solid rgba(
|
|
186
|
-
.lcms-btn-cancel:hover { color: white; border-color: rgba(
|
|
241
|
+
.lcms-btn-save { background: var(--lcms-primary, #00C853); color: white; }
|
|
242
|
+
.lcms-btn-save:hover { background: var(--lcms-primary, #00C853); filter: brightness(1.15); }
|
|
243
|
+
.lcms-btn-save:disabled { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.2); color: rgba(255,255,255,0.35); cursor: not-allowed; filter: none; }
|
|
244
|
+
.lcms-btn-publish { background: linear-gradient(135deg, #2196F3, #1976D2); color: white; }
|
|
245
|
+
.lcms-btn-publish:hover { background: linear-gradient(135deg, #1976D2, #1565C0); }
|
|
246
|
+
.lcms-btn-publish:disabled { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.2); color: rgba(255,255,255,0.35); cursor: not-allowed; }
|
|
247
|
+
.lcms-btn-cancel { background: transparent; color: rgba(255,255,255,0.5); border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.25) !important; }
|
|
248
|
+
.lcms-btn-cancel:hover { color: white; border-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.5) !important; background: rgba(var(--lcms-primary-rgb, 0,200,83),0.08); }
|
|
187
249
|
.lcms-btn-cancel:disabled { opacity: 0.3; cursor: not-allowed; }
|
|
188
250
|
|
|
189
251
|
.lcms-spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.3); border-top-color: white; border-radius: 50%; animation: lcmsSpin 0.6s linear infinite; }
|
|
@@ -192,14 +254,14 @@ var CMS_STYLES = `
|
|
|
192
254
|
.lcms-img-upload-overlay {
|
|
193
255
|
position: fixed; inset: 0; z-index: 10005;
|
|
194
256
|
display: flex; align-items: center; justify-content: center;
|
|
195
|
-
background: rgba(
|
|
257
|
+
background: rgba(8, 8, 15, 0.5); backdrop-filter: blur(8px);
|
|
196
258
|
}
|
|
197
259
|
.lcms-img-upload-content {
|
|
198
260
|
display: flex; flex-direction: column; align-items: center; gap: 16px;
|
|
199
261
|
color: white; font-family: system-ui, -apple-system, sans-serif;
|
|
200
262
|
font-size: 13px; font-weight: 600;
|
|
201
263
|
}
|
|
202
|
-
.lcms-spinner-lg { width: 36px; height: 36px; border: 3px solid rgba(255,255,255,0.2); border-top-color: #
|
|
264
|
+
.lcms-spinner-lg { width: 36px; height: 36px; border: 3px solid rgba(255,255,255,0.2); border-top-color: var(--lcms-primary, #00C853); border-radius: 50%; animation: lcmsSpin 0.6s linear infinite; }
|
|
203
265
|
|
|
204
266
|
/* HIDDEN ELEMENTS */
|
|
205
267
|
.lcms-hidden { display: none !important; }
|
|
@@ -244,6 +306,9 @@ var DEFAULT_EDITABLE_TAGS = [
|
|
|
244
306
|
];
|
|
245
307
|
var XtroedgeCMS = class _XtroedgeCMS {
|
|
246
308
|
constructor(config) {
|
|
309
|
+
this.brandingEl = null;
|
|
310
|
+
this.siteIdentifier = "";
|
|
311
|
+
this.siteIdEl = null;
|
|
247
312
|
// ===== State =====
|
|
248
313
|
this.editMode = false;
|
|
249
314
|
this.currentLang = "en";
|
|
@@ -322,14 +387,17 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
322
387
|
this.db = null;
|
|
323
388
|
// ===== i18n cache =====
|
|
324
389
|
this.translationCache = /* @__PURE__ */ new Map();
|
|
325
|
-
this.config = config;
|
|
326
|
-
this.containerSelector = config.containerSelector || "
|
|
327
|
-
this.editableTags = (config.editableTags || DEFAULT_EDITABLE_TAGS).map((t) => t.toLowerCase());
|
|
328
|
-
this.languages = config.languages || ["en"];
|
|
329
|
-
this.defaultLanguage = config.defaultLanguage || this.languages[0] || "en";
|
|
330
|
-
this.highlightColor = config.highlightColor || "#
|
|
331
|
-
this.historyRetentionMs = (config.historyRetentionDays || 7) * 24 * 60 * 60 * 1e3;
|
|
390
|
+
this.config = config || {};
|
|
391
|
+
this.containerSelector = this.config.containerSelector || "";
|
|
392
|
+
this.editableTags = (this.config.editableTags || DEFAULT_EDITABLE_TAGS).map((t) => t.toLowerCase());
|
|
393
|
+
this.languages = this.config.languages || ["en"];
|
|
394
|
+
this.defaultLanguage = this.config.defaultLanguage || this.languages[0] || "en";
|
|
395
|
+
this.highlightColor = this.config.highlightColor || "#00C853";
|
|
396
|
+
this.historyRetentionMs = (this.config.historyRetentionDays || 7) * 24 * 60 * 60 * 1e3;
|
|
332
397
|
this.currentLang = this.defaultLanguage;
|
|
398
|
+
this.siteIdentifier = this.resolveSiteIdentifier();
|
|
399
|
+
const savedColor = localStorage.getItem("xtroedge_theme_color");
|
|
400
|
+
if (savedColor) this.highlightColor = savedColor;
|
|
333
401
|
this.boundMouseMove = (e) => this.onDragMove(e);
|
|
334
402
|
this.boundMouseUp = () => this.onDragEnd();
|
|
335
403
|
this.boundTouchMove = (e) => this.onTouchMove(e);
|
|
@@ -343,9 +411,16 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
343
411
|
init() {
|
|
344
412
|
this.posY = window.innerHeight - 72;
|
|
345
413
|
this.injectStyles();
|
|
414
|
+
this.applyThemeColor(this.highlightColor);
|
|
346
415
|
this.buildUI();
|
|
347
416
|
this.interceptNavigation();
|
|
348
417
|
this.observer = new MutationObserver(() => {
|
|
418
|
+
if (this.rootEl && !document.contains(this.rootEl)) {
|
|
419
|
+
document.body.appendChild(this.rootEl);
|
|
420
|
+
}
|
|
421
|
+
if (this.styleEl && !document.contains(this.styleEl)) {
|
|
422
|
+
document.head.appendChild(this.styleEl);
|
|
423
|
+
}
|
|
349
424
|
if (this.scanTimeout) clearTimeout(this.scanTimeout);
|
|
350
425
|
this.scanTimeout = setTimeout(() => this.autoDetectAndScan(), 150);
|
|
351
426
|
});
|
|
@@ -508,6 +583,10 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
508
583
|
});
|
|
509
584
|
header.appendChild(closeBtn);
|
|
510
585
|
this.panelEl.appendChild(header);
|
|
586
|
+
this.siteIdEl = this.createElement("div", "lcms-site-id");
|
|
587
|
+
const isDomain = this.siteIdentifier.includes(".");
|
|
588
|
+
this.siteIdEl.innerHTML = `<span class="lcms-site-id-icon">${isDomain ? "\u{1F310}" : "\u{1F511}"}</span><span class="lcms-site-id-text">${isDomain ? this.siteIdentifier : this.siteIdentifier.substring(0, 8)}</span>`;
|
|
589
|
+
this.panelEl.appendChild(this.siteIdEl);
|
|
511
590
|
this.editModeContent = this.createElement("div", "lcms-hidden");
|
|
512
591
|
this.changesInfoEl = this.createElement("div", "lcms-changes-info lcms-hidden");
|
|
513
592
|
this.editModeContent.appendChild(this.changesInfoEl);
|
|
@@ -531,6 +610,37 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
531
610
|
undoRow.appendChild(this.undoBtn);
|
|
532
611
|
undoRow.appendChild(this.redoBtn);
|
|
533
612
|
this.editModeContent.appendChild(undoRow);
|
|
613
|
+
const themeRow = this.createElement("div", "lcms-theme-row");
|
|
614
|
+
const themeLabel = this.createElement("span", "lcms-theme-label");
|
|
615
|
+
themeLabel.textContent = "Theme";
|
|
616
|
+
themeRow.appendChild(themeLabel);
|
|
617
|
+
const themeColors = this.createElement("div", "lcms-theme-colors");
|
|
618
|
+
const presetColors = ["#00C853", "#6722FB", "#2196F3", "#FF5722", "#E91E63", "#FFD600"];
|
|
619
|
+
for (const color of presetColors) {
|
|
620
|
+
const swatch = this.createElement("div", "lcms-theme-swatch");
|
|
621
|
+
swatch.style.background = color;
|
|
622
|
+
swatch.dataset.color = color;
|
|
623
|
+
if (color === this.highlightColor) swatch.classList.add("active");
|
|
624
|
+
swatch.addEventListener("click", (e) => {
|
|
625
|
+
e.stopPropagation();
|
|
626
|
+
this.applyThemeColor(color);
|
|
627
|
+
});
|
|
628
|
+
themeColors.appendChild(swatch);
|
|
629
|
+
}
|
|
630
|
+
const customSwatch = this.createElement("div", "lcms-theme-custom");
|
|
631
|
+
const customPreview = this.createElement("div", "lcms-theme-custom-preview");
|
|
632
|
+
const customInput = document.createElement("input");
|
|
633
|
+
customInput.type = "color";
|
|
634
|
+
customInput.value = this.highlightColor;
|
|
635
|
+
customInput.addEventListener("input", (e) => {
|
|
636
|
+
e.stopPropagation();
|
|
637
|
+
this.applyThemeColor(e.target.value);
|
|
638
|
+
});
|
|
639
|
+
customSwatch.appendChild(customPreview);
|
|
640
|
+
customSwatch.appendChild(customInput);
|
|
641
|
+
themeColors.appendChild(customSwatch);
|
|
642
|
+
themeRow.appendChild(themeColors);
|
|
643
|
+
this.editModeContent.appendChild(themeRow);
|
|
534
644
|
this.historyBtnEl = document.createElement("button");
|
|
535
645
|
this.historyBtnEl.className = "lcms-history-btn";
|
|
536
646
|
this.historyBtnEl.innerHTML = `${ICON.history} History (7 days)`;
|
|
@@ -573,6 +683,13 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
573
683
|
this.actionsEl.appendChild(this.cancelBtn);
|
|
574
684
|
this.editModeContent.appendChild(this.actionsEl);
|
|
575
685
|
this.panelEl.appendChild(this.editModeContent);
|
|
686
|
+
this.brandingEl = this.createElement("div", "lcms-branding");
|
|
687
|
+
this.brandingEl.innerHTML = `<div class="lcms-branding-logo"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg></div><div class="lcms-branding-text">Powered by <span>XtroEdge</span></div>`;
|
|
688
|
+
this.brandingEl.addEventListener("click", (e) => {
|
|
689
|
+
e.stopPropagation();
|
|
690
|
+
window.open("https://xtro.vercel.app/", "_blank");
|
|
691
|
+
});
|
|
692
|
+
this.panelEl.appendChild(this.brandingEl);
|
|
576
693
|
}
|
|
577
694
|
buildLangButtons() {
|
|
578
695
|
if (!this.langSwitchEl) return;
|
|
@@ -655,8 +772,14 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
655
772
|
this.scanDOM();
|
|
656
773
|
this.scanImages();
|
|
657
774
|
}
|
|
775
|
+
resolveContainer() {
|
|
776
|
+
if (this.containerSelector) {
|
|
777
|
+
return document.querySelector(this.containerSelector) || document.body;
|
|
778
|
+
}
|
|
779
|
+
return document.querySelector(".layout") || document.body;
|
|
780
|
+
}
|
|
658
781
|
autoDetectElements() {
|
|
659
|
-
const container =
|
|
782
|
+
const container = this.resolveContainer();
|
|
660
783
|
if (!container) return;
|
|
661
784
|
for (const el of this.autoDetectedElements) {
|
|
662
785
|
if (!document.contains(el)) this.autoDetectedElements.delete(el);
|
|
@@ -693,7 +816,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
693
816
|
}
|
|
694
817
|
}
|
|
695
818
|
scanImages() {
|
|
696
|
-
const container =
|
|
819
|
+
const container = this.resolveContainer();
|
|
697
820
|
if (!container) return;
|
|
698
821
|
const currentImages = { ...this.pageImages };
|
|
699
822
|
let hasNew = false;
|
|
@@ -939,7 +1062,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
939
1062
|
});
|
|
940
1063
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
941
1064
|
const data = await res.json();
|
|
942
|
-
const baseUrl = this.config.imageBaseUrl || new URL(this.config.apiBase).origin;
|
|
1065
|
+
const baseUrl = this.config.imageBaseUrl || (this.config.apiBase ? new URL(this.config.apiBase).origin : "");
|
|
943
1066
|
const fullUrl = baseUrl + data.path;
|
|
944
1067
|
if (this.activeImageEl) {
|
|
945
1068
|
const key = this.managedImages.get(this.activeImageEl)?.key || "";
|
|
@@ -1084,8 +1207,15 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1084
1207
|
}
|
|
1085
1208
|
this.autoDetectAndScan();
|
|
1086
1209
|
if (this.editMode) this.applyEditMode(true);
|
|
1087
|
-
if (
|
|
1088
|
-
|
|
1210
|
+
if (this.config.apiBase) {
|
|
1211
|
+
if (loadDraft) this.loadPageContent("draft");
|
|
1212
|
+
else this.loadPublishedContent();
|
|
1213
|
+
} else {
|
|
1214
|
+
this.buildDefaultTexts();
|
|
1215
|
+
this.originalTexts = JSON.parse(JSON.stringify(this.pageTexts));
|
|
1216
|
+
this.originalImages = JSON.parse(JSON.stringify(this.pageImages));
|
|
1217
|
+
this.setLoading(false);
|
|
1218
|
+
}
|
|
1089
1219
|
this.updateUI();
|
|
1090
1220
|
}
|
|
1091
1221
|
flattenTranslations(obj, prefix, pageSection) {
|
|
@@ -1111,7 +1241,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1111
1241
|
this.setLoading(true);
|
|
1112
1242
|
this.cleanOldHistory();
|
|
1113
1243
|
try {
|
|
1114
|
-
const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=${status}`);
|
|
1244
|
+
const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=${status}&site_identifier=${encodeURIComponent(this.siteIdentifier)}`);
|
|
1115
1245
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1116
1246
|
const page = await res.json();
|
|
1117
1247
|
const texts = page?.published_content?.texts || page?.content?.texts;
|
|
@@ -1141,7 +1271,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1141
1271
|
async loadPublishedContent() {
|
|
1142
1272
|
this.setLoading(true);
|
|
1143
1273
|
try {
|
|
1144
|
-
const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=published`);
|
|
1274
|
+
const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=published&site_identifier=${encodeURIComponent(this.siteIdentifier)}`);
|
|
1145
1275
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1146
1276
|
const page = await res.json();
|
|
1147
1277
|
const texts = page?.published_content?.texts;
|
|
@@ -1191,11 +1321,16 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1191
1321
|
}
|
|
1192
1322
|
}
|
|
1193
1323
|
async saveChanges() {
|
|
1324
|
+
if (!this.config.apiBase) {
|
|
1325
|
+
this.showToast("No API configured. Set apiBase to enable save.", "error");
|
|
1326
|
+
return;
|
|
1327
|
+
}
|
|
1194
1328
|
this.isSaving = true;
|
|
1195
1329
|
this.updateUI();
|
|
1196
1330
|
const payload = {
|
|
1197
1331
|
slug: this.currentSlug,
|
|
1198
1332
|
title: this.currentTitle,
|
|
1333
|
+
site_identifier: this.siteIdentifier,
|
|
1199
1334
|
content: { texts: this.pageTexts, images: this.pageImages }
|
|
1200
1335
|
};
|
|
1201
1336
|
try {
|
|
@@ -1218,11 +1353,16 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1218
1353
|
}
|
|
1219
1354
|
}
|
|
1220
1355
|
async publishChanges() {
|
|
1356
|
+
if (!this.config.apiBase) {
|
|
1357
|
+
this.showToast("No API configured. Set apiBase to enable publish.", "error");
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1221
1360
|
this.isPublishing = true;
|
|
1222
1361
|
this.updateUI();
|
|
1223
1362
|
const payload = {
|
|
1224
1363
|
slug: this.currentSlug,
|
|
1225
1364
|
title: this.currentTitle,
|
|
1365
|
+
site_identifier: this.siteIdentifier,
|
|
1226
1366
|
published_content: { texts: this.pageTexts, images: this.pageImages }
|
|
1227
1367
|
};
|
|
1228
1368
|
try {
|
|
@@ -1499,6 +1639,59 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1499
1639
|
return `${months[d.getMonth()]} ${d.getDate()}, ${h12}:${m} ${ampm}`;
|
|
1500
1640
|
}
|
|
1501
1641
|
// ===============================================
|
|
1642
|
+
// SITE IDENTIFIER
|
|
1643
|
+
// ===============================================
|
|
1644
|
+
resolveSiteIdentifier() {
|
|
1645
|
+
const hostname = window.location.hostname;
|
|
1646
|
+
if (hostname && hostname !== "localhost" && hostname !== "127.0.0.1" && !hostname.startsWith("192.168.")) {
|
|
1647
|
+
return hostname;
|
|
1648
|
+
}
|
|
1649
|
+
let id = localStorage.getItem("xtroedge_site_id");
|
|
1650
|
+
if (!id) {
|
|
1651
|
+
id = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
1652
|
+
const r = Math.random() * 16 | 0;
|
|
1653
|
+
return (c === "x" ? r : r & 3 | 8).toString(16);
|
|
1654
|
+
});
|
|
1655
|
+
localStorage.setItem("xtroedge_site_id", id);
|
|
1656
|
+
}
|
|
1657
|
+
return id;
|
|
1658
|
+
}
|
|
1659
|
+
// ===============================================
|
|
1660
|
+
// THEME COLOR
|
|
1661
|
+
// ===============================================
|
|
1662
|
+
hexToRgb(hex) {
|
|
1663
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
1664
|
+
if (!result) return "0,200,83";
|
|
1665
|
+
return `${parseInt(result[1], 16)},${parseInt(result[2], 16)},${parseInt(result[3], 16)}`;
|
|
1666
|
+
}
|
|
1667
|
+
getDarkerColor(hex) {
|
|
1668
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
1669
|
+
if (!result) return "#2E7D32";
|
|
1670
|
+
const r = Math.max(0, Math.floor(parseInt(result[1], 16) * 0.6));
|
|
1671
|
+
const g = Math.max(0, Math.floor(parseInt(result[2], 16) * 0.6));
|
|
1672
|
+
const b = Math.max(0, Math.floor(parseInt(result[3], 16) * 0.6));
|
|
1673
|
+
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
1674
|
+
}
|
|
1675
|
+
applyThemeColor(color) {
|
|
1676
|
+
this.highlightColor = color;
|
|
1677
|
+
document.documentElement.style.setProperty("--lcms-primary", color);
|
|
1678
|
+
document.documentElement.style.setProperty("--lcms-primary-rgb", this.hexToRgb(color));
|
|
1679
|
+
document.documentElement.style.setProperty("--lcms-primary-dark", this.getDarkerColor(color));
|
|
1680
|
+
if (this.editMode) {
|
|
1681
|
+
for (const [el] of this.managedElements) {
|
|
1682
|
+
el.style.borderBottom = `2px dashed ${color}`;
|
|
1683
|
+
}
|
|
1684
|
+
for (const [img] of this.managedImages) {
|
|
1685
|
+
img.style.outline = `2px dashed ${color}`;
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
const swatches = this.panelEl?.querySelectorAll(".lcms-theme-swatch");
|
|
1689
|
+
swatches?.forEach((s) => {
|
|
1690
|
+
s.classList.toggle("active", s.dataset.color === color);
|
|
1691
|
+
});
|
|
1692
|
+
localStorage.setItem("xtroedge_theme_color", color);
|
|
1693
|
+
}
|
|
1694
|
+
// ===============================================
|
|
1502
1695
|
// STATIC CONVENIENCE
|
|
1503
1696
|
// ===============================================
|
|
1504
1697
|
/** Quick init - create and start CMS in one call */
|
|
@@ -1507,7 +1700,26 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1507
1700
|
cms.init();
|
|
1508
1701
|
return cms;
|
|
1509
1702
|
}
|
|
1703
|
+
/** Auto-init: called automatically when package is loaded. No user code needed. */
|
|
1704
|
+
static autoInit() {
|
|
1705
|
+
if (window.__xtroedge_cms_instance__) return;
|
|
1706
|
+
const userConfig = window.__XTROEDGE_CMS_CONFIG__ || {};
|
|
1707
|
+
const cms = _XtroedgeCMS.create(userConfig);
|
|
1708
|
+
window.__xtroedge_cms_instance__ = cms;
|
|
1709
|
+
}
|
|
1510
1710
|
};
|
|
1711
|
+
|
|
1712
|
+
// src/index.ts
|
|
1713
|
+
function boot() {
|
|
1714
|
+
XtroedgeCMS.autoInit();
|
|
1715
|
+
}
|
|
1716
|
+
if (typeof window !== "undefined") {
|
|
1717
|
+
if (document.readyState === "loading") {
|
|
1718
|
+
document.addEventListener("DOMContentLoaded", boot);
|
|
1719
|
+
} else {
|
|
1720
|
+
boot();
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1511
1723
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1512
1724
|
0 && (module.exports = {
|
|
1513
1725
|
XtroedgeCMS
|