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.mjs
CHANGED
|
@@ -6,32 +6,32 @@ var CMS_STYLES = `
|
|
|
6
6
|
.lcms-loader-overlay {
|
|
7
7
|
position: fixed; inset: 0; z-index: 10003;
|
|
8
8
|
display: flex; align-items: center; justify-content: center;
|
|
9
|
-
background: rgba(
|
|
9
|
+
background: rgba(8, 8, 15, 0.45);
|
|
10
10
|
backdrop-filter: blur(12px) saturate(1.4);
|
|
11
11
|
-webkit-backdrop-filter: blur(12px) saturate(1.4);
|
|
12
12
|
}
|
|
13
13
|
.lcms-loader-content { display: flex; flex-direction: column; align-items: center; gap: 28px; }
|
|
14
14
|
.lcms-orbit-loader { position: relative; width: 90px; height: 90px; }
|
|
15
15
|
.lcms-orbit { position: absolute; inset: 0; border-radius: 50%; border: 1px solid transparent; }
|
|
16
|
-
.lcms-orbit-1 { border-top-color: rgba(
|
|
17
|
-
.lcms-orbit-2 { inset: 10px; border-right-color: rgba(
|
|
18
|
-
.lcms-orbit-3 { inset: 20px; border-bottom-color: rgba(
|
|
16
|
+
.lcms-orbit-1 { border-top-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.5); animation: lcmsSpin 2.4s linear infinite; }
|
|
17
|
+
.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; }
|
|
18
|
+
.lcms-orbit-3 { inset: 20px; border-bottom-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.35); animation: lcmsSpin 4.2s linear infinite; }
|
|
19
19
|
.lcms-particle {
|
|
20
20
|
position: absolute; width: 8px; height: 8px; border-radius: 50%; top: -4px; left: 50%; margin-left: -4px;
|
|
21
21
|
box-shadow: 0 0 12px 3px currentColor;
|
|
22
22
|
}
|
|
23
|
-
.lcms-orbit-1 .lcms-particle { background: #
|
|
24
|
-
.lcms-orbit-2 .lcms-particle { background:
|
|
25
|
-
.lcms-orbit-3 .lcms-particle { background:
|
|
23
|
+
.lcms-orbit-1 .lcms-particle { background: var(--lcms-primary, #00C853); color: var(--lcms-primary, #00C853); }
|
|
24
|
+
.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; }
|
|
25
|
+
.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; }
|
|
26
26
|
.lcms-core-glow {
|
|
27
27
|
position: absolute; width: 30px; height: 30px; top: 50%; left: 50%; transform: translate(-50%,-50%);
|
|
28
|
-
border-radius: 50%; background: radial-gradient(circle, rgba(
|
|
28
|
+
border-radius: 50%; background: radial-gradient(circle, rgba(var(--lcms-primary-rgb, 0,200,83),0.4), transparent 70%);
|
|
29
29
|
animation: lcmsPulse 2s ease-in-out infinite;
|
|
30
30
|
}
|
|
31
31
|
.lcms-core {
|
|
32
32
|
position: absolute; width: 12px; height: 12px; top: 50%; left: 50%; transform: translate(-50%,-50%);
|
|
33
|
-
border-radius: 50%; background: linear-gradient(135deg,
|
|
34
|
-
box-shadow: 0 0 20px rgba(
|
|
33
|
+
border-radius: 50%; background: linear-gradient(135deg, var(--lcms-primary, #00C853), rgba(var(--lcms-primary-rgb, 0,200,83),0.6));
|
|
34
|
+
box-shadow: 0 0 20px rgba(var(--lcms-primary-rgb, 0,200,83),0.6);
|
|
35
35
|
}
|
|
36
36
|
.lcms-loader-text {
|
|
37
37
|
font-family: system-ui, -apple-system, sans-serif; font-size: 12px; font-weight: 600;
|
|
@@ -48,10 +48,10 @@ var CMS_STYLES = `
|
|
|
48
48
|
padding: 10px 20px; border-radius: 10px; font-size: 13px; font-weight: 600;
|
|
49
49
|
font-family: system-ui, -apple-system, sans-serif; color: white;
|
|
50
50
|
display: flex; align-items: center; gap: 8px;
|
|
51
|
-
box-shadow: 0 8px 32px rgba(
|
|
51
|
+
box-shadow: 0 8px 32px rgba(var(--lcms-primary-rgb, 0,200,83),0.25);
|
|
52
52
|
animation: lcmsToastIn 0.3s ease, lcmsToastOut 0.3s ease 2.7s forwards; white-space: nowrap;
|
|
53
53
|
}
|
|
54
|
-
.lcms-toast-success { background: linear-gradient(135deg, #
|
|
54
|
+
.lcms-toast-success { background: linear-gradient(135deg, var(--lcms-primary, #00C853), var(--lcms-primary-dark, #2E7D32)); }
|
|
55
55
|
.lcms-toast-error { background: linear-gradient(135deg, #dc2626, #ef4444); }
|
|
56
56
|
@keyframes lcmsToastIn { from { opacity: 0; transform: translateX(-50%) translateY(-12px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }
|
|
57
57
|
@keyframes lcmsToastOut { from { opacity: 1; transform: translateX(-50%) translateY(0); } to { opacity: 0; transform: translateX(-50%) translateY(-12px); } }
|
|
@@ -60,15 +60,15 @@ var CMS_STYLES = `
|
|
|
60
60
|
.lcms-fab { position: fixed; z-index: 10001; user-select: none; touch-action: none; }
|
|
61
61
|
.lcms-fab-btn {
|
|
62
62
|
width: 52px; height: 52px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.2);
|
|
63
|
-
background: rgba(
|
|
63
|
+
background: rgba(var(--lcms-primary-rgb, 0,200,83),0.35); color: white;
|
|
64
64
|
backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
|
|
65
65
|
cursor: grab; display: flex; align-items: center; justify-content: center;
|
|
66
|
-
box-shadow: 0 4px 20px rgba(
|
|
66
|
+
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);
|
|
67
67
|
transition: transform 0.2s, box-shadow 0.2s, background 0.2s; position: relative;
|
|
68
68
|
}
|
|
69
|
-
.lcms-fab-btn:not(.lcms-fab-active) { background: rgba(
|
|
70
|
-
.lcms-fab-btn.lcms-fab-active { background: rgba(
|
|
71
|
-
.lcms-fab-btn:hover { transform: scale(1.08); background: rgba(
|
|
69
|
+
.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); }
|
|
70
|
+
.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); }
|
|
71
|
+
.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); }
|
|
72
72
|
.lcms-badge {
|
|
73
73
|
position: absolute; top: -4px; right: -4px; background: #ef4444; color: white;
|
|
74
74
|
font-size: 11px; font-weight: 700; width: 20px; height: 20px; border-radius: 50%;
|
|
@@ -77,14 +77,45 @@ var CMS_STYLES = `
|
|
|
77
77
|
|
|
78
78
|
/* PANEL */
|
|
79
79
|
.lcms-panel {
|
|
80
|
-
background: rgba(
|
|
81
|
-
border: 1px solid rgba(
|
|
80
|
+
background: rgba(12,12,18,0.55); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
|
|
81
|
+
border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.25); border-radius: 16px; padding: 16px; min-width: 230px;
|
|
82
82
|
box-shadow: 0 8px 32px rgba(0,0,0,0.25), inset 0 1px 0 rgba(255,255,255,0.06);
|
|
83
83
|
color: white; font-family: system-ui, -apple-system, sans-serif;
|
|
84
84
|
animation: lcmsPanelIn 0.25s ease; position: absolute;
|
|
85
85
|
}
|
|
86
86
|
@keyframes lcmsPanelIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } }
|
|
87
87
|
|
|
88
|
+
/* SITE IDENTIFIER */
|
|
89
|
+
.lcms-site-id {
|
|
90
|
+
display: flex; align-items: center; gap: 5px;
|
|
91
|
+
font-size: 10px; color: rgba(255,255,255,0.4);
|
|
92
|
+
padding: 0 0 8px; margin-bottom: 8px;
|
|
93
|
+
border-bottom: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.12);
|
|
94
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
95
|
+
letter-spacing: 0.3px;
|
|
96
|
+
}
|
|
97
|
+
.lcms-site-id-icon { font-size: 12px; opacity: 0.7; }
|
|
98
|
+
.lcms-site-id-text {
|
|
99
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 180px;
|
|
100
|
+
font-weight: 500;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* BRANDING */
|
|
104
|
+
.lcms-branding {
|
|
105
|
+
display: flex; align-items: center; gap: 6px; padding: 8px 0 4px;
|
|
106
|
+
border-top: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.15); margin-top: 10px;
|
|
107
|
+
cursor: pointer; transition: opacity 0.2s; user-select: none;
|
|
108
|
+
}
|
|
109
|
+
.lcms-branding:hover { opacity: 0.8; }
|
|
110
|
+
.lcms-branding-logo {
|
|
111
|
+
width: 18px; height: 18px; border-radius: 4px; background: linear-gradient(135deg, var(--lcms-primary, #00C853), var(--lcms-primary-dark, #2E7D32));
|
|
112
|
+
display: flex; align-items: center; justify-content: center;
|
|
113
|
+
}
|
|
114
|
+
.lcms-branding-text {
|
|
115
|
+
font-size: 10px; font-weight: 600; color: rgba(255,255,255,0.35); letter-spacing: 0.5px;
|
|
116
|
+
}
|
|
117
|
+
.lcms-branding-text span { color: var(--lcms-primary, #00C853); font-weight: 700; }
|
|
118
|
+
|
|
88
119
|
.lcms-panel-header { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
|
|
89
120
|
.lcms-toggle { display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; }
|
|
90
121
|
.lcms-toggle input { display: none; }
|
|
@@ -96,53 +127,84 @@ var CMS_STYLES = `
|
|
|
96
127
|
content: ''; position: absolute; width: 16px; height: 16px; border-radius: 50%;
|
|
97
128
|
top: 2px; left: 2px; background: rgba(255,255,255,0.6); transition: transform 0.25s, background 0.25s;
|
|
98
129
|
}
|
|
99
|
-
.lcms-toggle input:checked + .lcms-toggle-slider { background: #
|
|
130
|
+
.lcms-toggle input:checked + .lcms-toggle-slider { background: var(--lcms-primary, #00C853); }
|
|
100
131
|
.lcms-toggle input:checked + .lcms-toggle-slider::after { transform: translateX(16px); background: white; }
|
|
101
132
|
.lcms-toggle-label { font-size: 12px; font-weight: 700; color: rgba(255,255,255,0.5); letter-spacing: 0.5px; transition: color 0.25s; }
|
|
102
|
-
.lcms-toggle input:checked ~ .lcms-toggle-label { color:
|
|
103
|
-
.lcms-lang-switch { display: flex; border: 1px solid rgba(
|
|
133
|
+
.lcms-toggle input:checked ~ .lcms-toggle-label { color: rgba(var(--lcms-primary-rgb, 0,200,83),0.75); }
|
|
134
|
+
.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; }
|
|
104
135
|
.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; }
|
|
105
|
-
.lcms-lang-btn.active { background: #
|
|
106
|
-
.lcms-lang-btn:hover:not(.active) { color: white; background: rgba(
|
|
136
|
+
.lcms-lang-btn.active { background: var(--lcms-primary, #00C853); color: white; }
|
|
137
|
+
.lcms-lang-btn:hover:not(.active) { color: white; background: rgba(var(--lcms-primary-rgb, 0,200,83),0.2); }
|
|
107
138
|
.lcms-close-btn { background: transparent; border: none; color: rgba(255,255,255,0.4); cursor: pointer; padding: 2px; display: flex; transition: color 0.2s; }
|
|
108
139
|
.lcms-close-btn:hover { color: white; }
|
|
109
|
-
.lcms-changes-info { font-size: 12px; color:
|
|
140
|
+
.lcms-changes-info { font-size: 12px; color: rgba(var(--lcms-primary-rgb, 0,200,83),0.75); margin-bottom: 10px; padding-left: 2px; }
|
|
110
141
|
|
|
111
142
|
.lcms-undo-row { display: flex; gap: 6px; margin-bottom: 12px; }
|
|
112
143
|
.lcms-icon-btn {
|
|
113
|
-
width: 36px; height: 32px; border-radius: 8px; border: 1px solid rgba(
|
|
114
|
-
background: rgba(
|
|
144
|
+
width: 36px; height: 32px; border-radius: 8px; border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.3);
|
|
145
|
+
background: rgba(var(--lcms-primary-rgb, 0,200,83),0.1); color: rgba(255,255,255,0.8); cursor: pointer;
|
|
115
146
|
display: flex; align-items: center; justify-content: center; transition: all 0.2s;
|
|
116
147
|
}
|
|
117
|
-
.lcms-icon-btn:hover:not(:disabled) { background: rgba(
|
|
148
|
+
.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; }
|
|
118
149
|
.lcms-icon-btn:disabled { opacity: 0.25; cursor: not-allowed; }
|
|
119
150
|
|
|
151
|
+
/* COLOR THEME PICKER */
|
|
152
|
+
.lcms-theme-row {
|
|
153
|
+
display: flex; align-items: center; gap: 8px; margin-bottom: 12px;
|
|
154
|
+
padding: 6px 0;
|
|
155
|
+
}
|
|
156
|
+
.lcms-theme-label {
|
|
157
|
+
font-size: 10px; font-weight: 700; color: rgba(255,255,255,0.45);
|
|
158
|
+
text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap;
|
|
159
|
+
}
|
|
160
|
+
.lcms-theme-colors {
|
|
161
|
+
display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
|
|
162
|
+
}
|
|
163
|
+
.lcms-theme-swatch {
|
|
164
|
+
width: 20px; height: 20px; border-radius: 50%; border: 2px solid transparent;
|
|
165
|
+
cursor: pointer; transition: all 0.2s; position: relative;
|
|
166
|
+
}
|
|
167
|
+
.lcms-theme-swatch:hover { transform: scale(1.15); }
|
|
168
|
+
.lcms-theme-swatch.active { border-color: white; box-shadow: 0 0 8px rgba(255,255,255,0.3); }
|
|
169
|
+
.lcms-theme-custom {
|
|
170
|
+
width: 20px; height: 20px; border-radius: 50%; border: 1px dashed rgba(255,255,255,0.3);
|
|
171
|
+
cursor: pointer; overflow: hidden; position: relative;
|
|
172
|
+
}
|
|
173
|
+
.lcms-theme-custom input {
|
|
174
|
+
position: absolute; inset: -4px; width: 28px; height: 28px; border: none;
|
|
175
|
+
background: transparent; cursor: pointer; opacity: 0;
|
|
176
|
+
}
|
|
177
|
+
.lcms-theme-custom-preview {
|
|
178
|
+
width: 100%; height: 100%; border-radius: 50%;
|
|
179
|
+
background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
|
|
180
|
+
}
|
|
181
|
+
|
|
120
182
|
.lcms-history-btn {
|
|
121
183
|
width: 100%; padding: 7px 12px; border-radius: 8px;
|
|
122
|
-
border: 1px dashed rgba(
|
|
184
|
+
border: 1px dashed rgba(var(--lcms-primary-rgb, 0,200,83),0.35); background: rgba(var(--lcms-primary-rgb, 0,200,83),0.08);
|
|
123
185
|
color: rgba(255,255,255,0.6); font-size: 12px; font-weight: 500; cursor: pointer;
|
|
124
186
|
display: flex; align-items: center; justify-content: center; gap: 6px;
|
|
125
187
|
transition: all 0.2s; margin-bottom: 12px; font-family: system-ui, -apple-system, sans-serif;
|
|
126
188
|
}
|
|
127
|
-
.lcms-history-btn:hover { background: rgba(
|
|
128
|
-
.lcms-history-btn.active { background: rgba(
|
|
189
|
+
.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; }
|
|
190
|
+
.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; }
|
|
129
191
|
|
|
130
|
-
.lcms-history-panel { margin-top: 8px; border-top: 1px solid rgba(
|
|
192
|
+
.lcms-history-panel { margin-top: 8px; border-top: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.15); padding-top: 10px; }
|
|
131
193
|
.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; }
|
|
132
194
|
.lcms-history-empty { font-size: 12px; color: rgba(255,255,255,0.3); text-align: center; padding: 12px 0; }
|
|
133
195
|
.lcms-history-list { max-height: 200px; overflow-y: auto; display: flex; flex-direction: column; gap: 4px; }
|
|
134
196
|
.lcms-history-list::-webkit-scrollbar { width: 4px; }
|
|
135
197
|
.lcms-history-list::-webkit-scrollbar-track { background: transparent; }
|
|
136
|
-
.lcms-history-list::-webkit-scrollbar-thumb { background: rgba(
|
|
198
|
+
.lcms-history-list::-webkit-scrollbar-thumb { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.3); border-radius: 4px; }
|
|
137
199
|
.lcms-history-item {
|
|
138
|
-
width: 100%; text-align: left; background: rgba(
|
|
139
|
-
border: 1px solid rgba(
|
|
200
|
+
width: 100%; text-align: left; background: rgba(var(--lcms-primary-rgb, 0,200,83),0.06);
|
|
201
|
+
border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.12); border-radius: 8px; padding: 8px 10px;
|
|
140
202
|
cursor: pointer; transition: all 0.2s; color: white; font-family: system-ui, -apple-system, sans-serif;
|
|
141
203
|
}
|
|
142
|
-
.lcms-history-item:hover { background: rgba(
|
|
204
|
+
.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); }
|
|
143
205
|
.lcms-history-label { font-size: 12px; font-weight: 500; margin-bottom: 2px; }
|
|
144
206
|
.lcms-history-meta { font-size: 10px; color: rgba(255,255,255,0.4); display: flex; align-items: center; gap: 6px; }
|
|
145
|
-
.lcms-history-lang { background: rgba(
|
|
207
|
+
.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); }
|
|
146
208
|
|
|
147
209
|
.lcms-actions { display: flex; flex-direction: column; gap: 6px; }
|
|
148
210
|
.lcms-actions button {
|
|
@@ -150,14 +212,14 @@ var CMS_STYLES = `
|
|
|
150
212
|
cursor: pointer; transition: all 0.2s; display: flex; align-items: center; justify-content: center; gap: 6px; border: none;
|
|
151
213
|
font-family: system-ui, -apple-system, sans-serif;
|
|
152
214
|
}
|
|
153
|
-
.lcms-btn-save { background: #
|
|
154
|
-
.lcms-btn-save:hover { background: #
|
|
155
|
-
.lcms-btn-save:disabled { background: rgba(
|
|
156
|
-
.lcms-btn-publish { background: linear-gradient(135deg, #
|
|
157
|
-
.lcms-btn-publish:hover { background: linear-gradient(135deg, #
|
|
158
|
-
.lcms-btn-publish:disabled { background: rgba(
|
|
159
|
-
.lcms-btn-cancel { background: transparent; color: rgba(255,255,255,0.5); border: 1px solid rgba(
|
|
160
|
-
.lcms-btn-cancel:hover { color: white; border-color: rgba(
|
|
215
|
+
.lcms-btn-save { background: var(--lcms-primary, #00C853); color: white; }
|
|
216
|
+
.lcms-btn-save:hover { background: var(--lcms-primary, #00C853); filter: brightness(1.15); }
|
|
217
|
+
.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; }
|
|
218
|
+
.lcms-btn-publish { background: linear-gradient(135deg, #2196F3, #1976D2); color: white; }
|
|
219
|
+
.lcms-btn-publish:hover { background: linear-gradient(135deg, #1976D2, #1565C0); }
|
|
220
|
+
.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; }
|
|
221
|
+
.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; }
|
|
222
|
+
.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); }
|
|
161
223
|
.lcms-btn-cancel:disabled { opacity: 0.3; cursor: not-allowed; }
|
|
162
224
|
|
|
163
225
|
.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; }
|
|
@@ -166,14 +228,14 @@ var CMS_STYLES = `
|
|
|
166
228
|
.lcms-img-upload-overlay {
|
|
167
229
|
position: fixed; inset: 0; z-index: 10005;
|
|
168
230
|
display: flex; align-items: center; justify-content: center;
|
|
169
|
-
background: rgba(
|
|
231
|
+
background: rgba(8, 8, 15, 0.5); backdrop-filter: blur(8px);
|
|
170
232
|
}
|
|
171
233
|
.lcms-img-upload-content {
|
|
172
234
|
display: flex; flex-direction: column; align-items: center; gap: 16px;
|
|
173
235
|
color: white; font-family: system-ui, -apple-system, sans-serif;
|
|
174
236
|
font-size: 13px; font-weight: 600;
|
|
175
237
|
}
|
|
176
|
-
.lcms-spinner-lg { width: 36px; height: 36px; border: 3px solid rgba(255,255,255,0.2); border-top-color: #
|
|
238
|
+
.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; }
|
|
177
239
|
|
|
178
240
|
/* HIDDEN ELEMENTS */
|
|
179
241
|
.lcms-hidden { display: none !important; }
|
|
@@ -218,6 +280,9 @@ var DEFAULT_EDITABLE_TAGS = [
|
|
|
218
280
|
];
|
|
219
281
|
var XtroedgeCMS = class _XtroedgeCMS {
|
|
220
282
|
constructor(config) {
|
|
283
|
+
this.brandingEl = null;
|
|
284
|
+
this.siteIdentifier = "";
|
|
285
|
+
this.siteIdEl = null;
|
|
221
286
|
// ===== State =====
|
|
222
287
|
this.editMode = false;
|
|
223
288
|
this.currentLang = "en";
|
|
@@ -296,14 +361,17 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
296
361
|
this.db = null;
|
|
297
362
|
// ===== i18n cache =====
|
|
298
363
|
this.translationCache = /* @__PURE__ */ new Map();
|
|
299
|
-
this.config = config;
|
|
300
|
-
this.containerSelector = config.containerSelector || "
|
|
301
|
-
this.editableTags = (config.editableTags || DEFAULT_EDITABLE_TAGS).map((t) => t.toLowerCase());
|
|
302
|
-
this.languages = config.languages || ["en"];
|
|
303
|
-
this.defaultLanguage = config.defaultLanguage || this.languages[0] || "en";
|
|
304
|
-
this.highlightColor = config.highlightColor || "#
|
|
305
|
-
this.historyRetentionMs = (config.historyRetentionDays || 7) * 24 * 60 * 60 * 1e3;
|
|
364
|
+
this.config = config || {};
|
|
365
|
+
this.containerSelector = this.config.containerSelector || "";
|
|
366
|
+
this.editableTags = (this.config.editableTags || DEFAULT_EDITABLE_TAGS).map((t) => t.toLowerCase());
|
|
367
|
+
this.languages = this.config.languages || ["en"];
|
|
368
|
+
this.defaultLanguage = this.config.defaultLanguage || this.languages[0] || "en";
|
|
369
|
+
this.highlightColor = this.config.highlightColor || "#00C853";
|
|
370
|
+
this.historyRetentionMs = (this.config.historyRetentionDays || 7) * 24 * 60 * 60 * 1e3;
|
|
306
371
|
this.currentLang = this.defaultLanguage;
|
|
372
|
+
this.siteIdentifier = this.resolveSiteIdentifier();
|
|
373
|
+
const savedColor = localStorage.getItem("xtroedge_theme_color");
|
|
374
|
+
if (savedColor) this.highlightColor = savedColor;
|
|
307
375
|
this.boundMouseMove = (e) => this.onDragMove(e);
|
|
308
376
|
this.boundMouseUp = () => this.onDragEnd();
|
|
309
377
|
this.boundTouchMove = (e) => this.onTouchMove(e);
|
|
@@ -317,9 +385,16 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
317
385
|
init() {
|
|
318
386
|
this.posY = window.innerHeight - 72;
|
|
319
387
|
this.injectStyles();
|
|
388
|
+
this.applyThemeColor(this.highlightColor);
|
|
320
389
|
this.buildUI();
|
|
321
390
|
this.interceptNavigation();
|
|
322
391
|
this.observer = new MutationObserver(() => {
|
|
392
|
+
if (this.rootEl && !document.contains(this.rootEl)) {
|
|
393
|
+
document.body.appendChild(this.rootEl);
|
|
394
|
+
}
|
|
395
|
+
if (this.styleEl && !document.contains(this.styleEl)) {
|
|
396
|
+
document.head.appendChild(this.styleEl);
|
|
397
|
+
}
|
|
323
398
|
if (this.scanTimeout) clearTimeout(this.scanTimeout);
|
|
324
399
|
this.scanTimeout = setTimeout(() => this.autoDetectAndScan(), 150);
|
|
325
400
|
});
|
|
@@ -482,6 +557,10 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
482
557
|
});
|
|
483
558
|
header.appendChild(closeBtn);
|
|
484
559
|
this.panelEl.appendChild(header);
|
|
560
|
+
this.siteIdEl = this.createElement("div", "lcms-site-id");
|
|
561
|
+
const isDomain = this.siteIdentifier.includes(".");
|
|
562
|
+
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>`;
|
|
563
|
+
this.panelEl.appendChild(this.siteIdEl);
|
|
485
564
|
this.editModeContent = this.createElement("div", "lcms-hidden");
|
|
486
565
|
this.changesInfoEl = this.createElement("div", "lcms-changes-info lcms-hidden");
|
|
487
566
|
this.editModeContent.appendChild(this.changesInfoEl);
|
|
@@ -505,6 +584,37 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
505
584
|
undoRow.appendChild(this.undoBtn);
|
|
506
585
|
undoRow.appendChild(this.redoBtn);
|
|
507
586
|
this.editModeContent.appendChild(undoRow);
|
|
587
|
+
const themeRow = this.createElement("div", "lcms-theme-row");
|
|
588
|
+
const themeLabel = this.createElement("span", "lcms-theme-label");
|
|
589
|
+
themeLabel.textContent = "Theme";
|
|
590
|
+
themeRow.appendChild(themeLabel);
|
|
591
|
+
const themeColors = this.createElement("div", "lcms-theme-colors");
|
|
592
|
+
const presetColors = ["#00C853", "#6722FB", "#2196F3", "#FF5722", "#E91E63", "#FFD600"];
|
|
593
|
+
for (const color of presetColors) {
|
|
594
|
+
const swatch = this.createElement("div", "lcms-theme-swatch");
|
|
595
|
+
swatch.style.background = color;
|
|
596
|
+
swatch.dataset.color = color;
|
|
597
|
+
if (color === this.highlightColor) swatch.classList.add("active");
|
|
598
|
+
swatch.addEventListener("click", (e) => {
|
|
599
|
+
e.stopPropagation();
|
|
600
|
+
this.applyThemeColor(color);
|
|
601
|
+
});
|
|
602
|
+
themeColors.appendChild(swatch);
|
|
603
|
+
}
|
|
604
|
+
const customSwatch = this.createElement("div", "lcms-theme-custom");
|
|
605
|
+
const customPreview = this.createElement("div", "lcms-theme-custom-preview");
|
|
606
|
+
const customInput = document.createElement("input");
|
|
607
|
+
customInput.type = "color";
|
|
608
|
+
customInput.value = this.highlightColor;
|
|
609
|
+
customInput.addEventListener("input", (e) => {
|
|
610
|
+
e.stopPropagation();
|
|
611
|
+
this.applyThemeColor(e.target.value);
|
|
612
|
+
});
|
|
613
|
+
customSwatch.appendChild(customPreview);
|
|
614
|
+
customSwatch.appendChild(customInput);
|
|
615
|
+
themeColors.appendChild(customSwatch);
|
|
616
|
+
themeRow.appendChild(themeColors);
|
|
617
|
+
this.editModeContent.appendChild(themeRow);
|
|
508
618
|
this.historyBtnEl = document.createElement("button");
|
|
509
619
|
this.historyBtnEl.className = "lcms-history-btn";
|
|
510
620
|
this.historyBtnEl.innerHTML = `${ICON.history} History (7 days)`;
|
|
@@ -547,6 +657,13 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
547
657
|
this.actionsEl.appendChild(this.cancelBtn);
|
|
548
658
|
this.editModeContent.appendChild(this.actionsEl);
|
|
549
659
|
this.panelEl.appendChild(this.editModeContent);
|
|
660
|
+
this.brandingEl = this.createElement("div", "lcms-branding");
|
|
661
|
+
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>`;
|
|
662
|
+
this.brandingEl.addEventListener("click", (e) => {
|
|
663
|
+
e.stopPropagation();
|
|
664
|
+
window.open("https://xtro.vercel.app/", "_blank");
|
|
665
|
+
});
|
|
666
|
+
this.panelEl.appendChild(this.brandingEl);
|
|
550
667
|
}
|
|
551
668
|
buildLangButtons() {
|
|
552
669
|
if (!this.langSwitchEl) return;
|
|
@@ -629,8 +746,14 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
629
746
|
this.scanDOM();
|
|
630
747
|
this.scanImages();
|
|
631
748
|
}
|
|
749
|
+
resolveContainer() {
|
|
750
|
+
if (this.containerSelector) {
|
|
751
|
+
return document.querySelector(this.containerSelector) || document.body;
|
|
752
|
+
}
|
|
753
|
+
return document.querySelector(".layout") || document.body;
|
|
754
|
+
}
|
|
632
755
|
autoDetectElements() {
|
|
633
|
-
const container =
|
|
756
|
+
const container = this.resolveContainer();
|
|
634
757
|
if (!container) return;
|
|
635
758
|
for (const el of this.autoDetectedElements) {
|
|
636
759
|
if (!document.contains(el)) this.autoDetectedElements.delete(el);
|
|
@@ -667,7 +790,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
667
790
|
}
|
|
668
791
|
}
|
|
669
792
|
scanImages() {
|
|
670
|
-
const container =
|
|
793
|
+
const container = this.resolveContainer();
|
|
671
794
|
if (!container) return;
|
|
672
795
|
const currentImages = { ...this.pageImages };
|
|
673
796
|
let hasNew = false;
|
|
@@ -913,7 +1036,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
913
1036
|
});
|
|
914
1037
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
915
1038
|
const data = await res.json();
|
|
916
|
-
const baseUrl = this.config.imageBaseUrl || new URL(this.config.apiBase).origin;
|
|
1039
|
+
const baseUrl = this.config.imageBaseUrl || (this.config.apiBase ? new URL(this.config.apiBase).origin : "");
|
|
917
1040
|
const fullUrl = baseUrl + data.path;
|
|
918
1041
|
if (this.activeImageEl) {
|
|
919
1042
|
const key = this.managedImages.get(this.activeImageEl)?.key || "";
|
|
@@ -1058,8 +1181,15 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1058
1181
|
}
|
|
1059
1182
|
this.autoDetectAndScan();
|
|
1060
1183
|
if (this.editMode) this.applyEditMode(true);
|
|
1061
|
-
if (
|
|
1062
|
-
|
|
1184
|
+
if (this.config.apiBase) {
|
|
1185
|
+
if (loadDraft) this.loadPageContent("draft");
|
|
1186
|
+
else this.loadPublishedContent();
|
|
1187
|
+
} else {
|
|
1188
|
+
this.buildDefaultTexts();
|
|
1189
|
+
this.originalTexts = JSON.parse(JSON.stringify(this.pageTexts));
|
|
1190
|
+
this.originalImages = JSON.parse(JSON.stringify(this.pageImages));
|
|
1191
|
+
this.setLoading(false);
|
|
1192
|
+
}
|
|
1063
1193
|
this.updateUI();
|
|
1064
1194
|
}
|
|
1065
1195
|
flattenTranslations(obj, prefix, pageSection) {
|
|
@@ -1085,7 +1215,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1085
1215
|
this.setLoading(true);
|
|
1086
1216
|
this.cleanOldHistory();
|
|
1087
1217
|
try {
|
|
1088
|
-
const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=${status}`);
|
|
1218
|
+
const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=${status}&site_identifier=${encodeURIComponent(this.siteIdentifier)}`);
|
|
1089
1219
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1090
1220
|
const page = await res.json();
|
|
1091
1221
|
const texts = page?.published_content?.texts || page?.content?.texts;
|
|
@@ -1115,7 +1245,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1115
1245
|
async loadPublishedContent() {
|
|
1116
1246
|
this.setLoading(true);
|
|
1117
1247
|
try {
|
|
1118
|
-
const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=published`);
|
|
1248
|
+
const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=published&site_identifier=${encodeURIComponent(this.siteIdentifier)}`);
|
|
1119
1249
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1120
1250
|
const page = await res.json();
|
|
1121
1251
|
const texts = page?.published_content?.texts;
|
|
@@ -1165,11 +1295,16 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1165
1295
|
}
|
|
1166
1296
|
}
|
|
1167
1297
|
async saveChanges() {
|
|
1298
|
+
if (!this.config.apiBase) {
|
|
1299
|
+
this.showToast("No API configured. Set apiBase to enable save.", "error");
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1168
1302
|
this.isSaving = true;
|
|
1169
1303
|
this.updateUI();
|
|
1170
1304
|
const payload = {
|
|
1171
1305
|
slug: this.currentSlug,
|
|
1172
1306
|
title: this.currentTitle,
|
|
1307
|
+
site_identifier: this.siteIdentifier,
|
|
1173
1308
|
content: { texts: this.pageTexts, images: this.pageImages }
|
|
1174
1309
|
};
|
|
1175
1310
|
try {
|
|
@@ -1192,11 +1327,16 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1192
1327
|
}
|
|
1193
1328
|
}
|
|
1194
1329
|
async publishChanges() {
|
|
1330
|
+
if (!this.config.apiBase) {
|
|
1331
|
+
this.showToast("No API configured. Set apiBase to enable publish.", "error");
|
|
1332
|
+
return;
|
|
1333
|
+
}
|
|
1195
1334
|
this.isPublishing = true;
|
|
1196
1335
|
this.updateUI();
|
|
1197
1336
|
const payload = {
|
|
1198
1337
|
slug: this.currentSlug,
|
|
1199
1338
|
title: this.currentTitle,
|
|
1339
|
+
site_identifier: this.siteIdentifier,
|
|
1200
1340
|
published_content: { texts: this.pageTexts, images: this.pageImages }
|
|
1201
1341
|
};
|
|
1202
1342
|
try {
|
|
@@ -1473,6 +1613,59 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1473
1613
|
return `${months[d.getMonth()]} ${d.getDate()}, ${h12}:${m} ${ampm}`;
|
|
1474
1614
|
}
|
|
1475
1615
|
// ===============================================
|
|
1616
|
+
// SITE IDENTIFIER
|
|
1617
|
+
// ===============================================
|
|
1618
|
+
resolveSiteIdentifier() {
|
|
1619
|
+
const hostname = window.location.hostname;
|
|
1620
|
+
if (hostname && hostname !== "localhost" && hostname !== "127.0.0.1" && !hostname.startsWith("192.168.")) {
|
|
1621
|
+
return hostname;
|
|
1622
|
+
}
|
|
1623
|
+
let id = localStorage.getItem("xtroedge_site_id");
|
|
1624
|
+
if (!id) {
|
|
1625
|
+
id = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
1626
|
+
const r = Math.random() * 16 | 0;
|
|
1627
|
+
return (c === "x" ? r : r & 3 | 8).toString(16);
|
|
1628
|
+
});
|
|
1629
|
+
localStorage.setItem("xtroedge_site_id", id);
|
|
1630
|
+
}
|
|
1631
|
+
return id;
|
|
1632
|
+
}
|
|
1633
|
+
// ===============================================
|
|
1634
|
+
// THEME COLOR
|
|
1635
|
+
// ===============================================
|
|
1636
|
+
hexToRgb(hex) {
|
|
1637
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
1638
|
+
if (!result) return "0,200,83";
|
|
1639
|
+
return `${parseInt(result[1], 16)},${parseInt(result[2], 16)},${parseInt(result[3], 16)}`;
|
|
1640
|
+
}
|
|
1641
|
+
getDarkerColor(hex) {
|
|
1642
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
1643
|
+
if (!result) return "#2E7D32";
|
|
1644
|
+
const r = Math.max(0, Math.floor(parseInt(result[1], 16) * 0.6));
|
|
1645
|
+
const g = Math.max(0, Math.floor(parseInt(result[2], 16) * 0.6));
|
|
1646
|
+
const b = Math.max(0, Math.floor(parseInt(result[3], 16) * 0.6));
|
|
1647
|
+
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
1648
|
+
}
|
|
1649
|
+
applyThemeColor(color) {
|
|
1650
|
+
this.highlightColor = color;
|
|
1651
|
+
document.documentElement.style.setProperty("--lcms-primary", color);
|
|
1652
|
+
document.documentElement.style.setProperty("--lcms-primary-rgb", this.hexToRgb(color));
|
|
1653
|
+
document.documentElement.style.setProperty("--lcms-primary-dark", this.getDarkerColor(color));
|
|
1654
|
+
if (this.editMode) {
|
|
1655
|
+
for (const [el] of this.managedElements) {
|
|
1656
|
+
el.style.borderBottom = `2px dashed ${color}`;
|
|
1657
|
+
}
|
|
1658
|
+
for (const [img] of this.managedImages) {
|
|
1659
|
+
img.style.outline = `2px dashed ${color}`;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
const swatches = this.panelEl?.querySelectorAll(".lcms-theme-swatch");
|
|
1663
|
+
swatches?.forEach((s) => {
|
|
1664
|
+
s.classList.toggle("active", s.dataset.color === color);
|
|
1665
|
+
});
|
|
1666
|
+
localStorage.setItem("xtroedge_theme_color", color);
|
|
1667
|
+
}
|
|
1668
|
+
// ===============================================
|
|
1476
1669
|
// STATIC CONVENIENCE
|
|
1477
1670
|
// ===============================================
|
|
1478
1671
|
/** Quick init - create and start CMS in one call */
|
|
@@ -1481,7 +1674,26 @@ var XtroedgeCMS = class _XtroedgeCMS {
|
|
|
1481
1674
|
cms.init();
|
|
1482
1675
|
return cms;
|
|
1483
1676
|
}
|
|
1677
|
+
/** Auto-init: called automatically when package is loaded. No user code needed. */
|
|
1678
|
+
static autoInit() {
|
|
1679
|
+
if (window.__xtroedge_cms_instance__) return;
|
|
1680
|
+
const userConfig = window.__XTROEDGE_CMS_CONFIG__ || {};
|
|
1681
|
+
const cms = _XtroedgeCMS.create(userConfig);
|
|
1682
|
+
window.__xtroedge_cms_instance__ = cms;
|
|
1683
|
+
}
|
|
1484
1684
|
};
|
|
1685
|
+
|
|
1686
|
+
// src/index.ts
|
|
1687
|
+
function boot() {
|
|
1688
|
+
XtroedgeCMS.autoInit();
|
|
1689
|
+
}
|
|
1690
|
+
if (typeof window !== "undefined") {
|
|
1691
|
+
if (document.readyState === "loading") {
|
|
1692
|
+
document.addEventListener("DOMContentLoaded", boot);
|
|
1693
|
+
} else {
|
|
1694
|
+
boot();
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1485
1697
|
export {
|
|
1486
1698
|
XtroedgeCMS
|
|
1487
1699
|
};
|