@customviews-js/customviews 1.1.2 → 1.1.3
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/custom-views.core.cjs.js +113 -53
- package/dist/custom-views.core.cjs.js.map +1 -1
- package/dist/custom-views.core.esm.js +113 -53
- package/dist/custom-views.core.esm.js.map +1 -1
- package/dist/custom-views.esm.js +113 -53
- package/dist/custom-views.esm.js.map +1 -1
- package/dist/custom-views.js +113 -53
- package/dist/custom-views.js.map +1 -1
- package/dist/custom-views.min.js +2 -2
- package/dist/custom-views.min.js.map +1 -1
- package/dist/types/core/core.d.ts.map +1 -1
- package/dist/types/core/url-state-manager.d.ts +2 -2
- package/dist/types/core/url-state-manager.d.ts.map +1 -1
- package/dist/types/core/widget.d.ts.map +1 -1
- package/dist/types/entry/browser-entry.d.ts.map +1 -1
- package/dist/types/lib/custom-views.d.ts.map +1 -1
- package/dist/types/styles/widget-styles.d.ts +1 -1
- package/dist/types/styles/widget-styles.d.ts.map +1 -1
- package/dist/types/types/types.d.ts +1 -1
- package/dist/types/types/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/custom-views.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @customviews-js/customviews v1.1.
|
|
2
|
+
* @customviews-js/customviews v1.1.3
|
|
3
3
|
* (c) 2025 Chan Ger Teck
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -130,14 +130,16 @@
|
|
|
130
130
|
return url.toString();
|
|
131
131
|
}
|
|
132
132
|
/**
|
|
133
|
-
* Encode state into URL-safe string
|
|
133
|
+
* Encode state into URL-safe string (Toggles and Tabs only currently)
|
|
134
134
|
*/
|
|
135
135
|
static encodeState(state) {
|
|
136
136
|
try {
|
|
137
137
|
// Create a compact representation
|
|
138
|
-
const compact = {
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
const compact = {};
|
|
139
|
+
// Add toggles if present and non-empty
|
|
140
|
+
if (state.toggles && state.toggles.length > 0) {
|
|
141
|
+
compact.t = state.toggles;
|
|
142
|
+
}
|
|
141
143
|
// Add tab groups if present
|
|
142
144
|
if (state.tabs && Object.keys(state.tabs).length > 0) {
|
|
143
145
|
compact.g = Object.entries(state.tabs);
|
|
@@ -163,7 +165,7 @@
|
|
|
163
165
|
}
|
|
164
166
|
}
|
|
165
167
|
/**
|
|
166
|
-
* Decode custom state from URL parameter
|
|
168
|
+
* Decode custom state from URL parameter (Toggles and Tabs only currently)
|
|
167
169
|
*/
|
|
168
170
|
static decodeState(encoded) {
|
|
169
171
|
try {
|
|
@@ -188,10 +190,12 @@
|
|
|
188
190
|
if (!compact || typeof compact !== 'object') {
|
|
189
191
|
throw new Error('Invalid compact state structure');
|
|
190
192
|
}
|
|
193
|
+
// Reconstruct State from compact format
|
|
194
|
+
// Reconstruct Toggles
|
|
191
195
|
const state = {
|
|
192
196
|
toggles: Array.isArray(compact.t) ? compact.t : []
|
|
193
197
|
};
|
|
194
|
-
// Reconstruct
|
|
198
|
+
// Reconstruct Tabs
|
|
195
199
|
if (Array.isArray(compact.g)) {
|
|
196
200
|
state.tabs = {};
|
|
197
201
|
for (const [groupId, tabId] of compact.g) {
|
|
@@ -874,7 +878,7 @@ ${TAB_STYLES}
|
|
|
874
878
|
this.rootEl = opt.rootEl || document.body;
|
|
875
879
|
this.persistenceManager = new PersistenceManager();
|
|
876
880
|
this.visibilityManager = new VisibilityManager();
|
|
877
|
-
this.showUrlEnabled = opt.showUrl ??
|
|
881
|
+
this.showUrlEnabled = opt.showUrl ?? false;
|
|
878
882
|
this.lastAppliedState = this.cloneState(this.config?.defaultState);
|
|
879
883
|
}
|
|
880
884
|
getConfig() {
|
|
@@ -1074,9 +1078,9 @@ ${TAB_STYLES}
|
|
|
1074
1078
|
});
|
|
1075
1079
|
}
|
|
1076
1080
|
cloneState(state) {
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
return
|
|
1081
|
+
if (!state)
|
|
1082
|
+
return {};
|
|
1083
|
+
return JSON.parse(JSON.stringify(state));
|
|
1080
1084
|
}
|
|
1081
1085
|
getTrackedStateSnapshot() {
|
|
1082
1086
|
if (this.lastAppliedState) {
|
|
@@ -1085,7 +1089,7 @@ ${TAB_STYLES}
|
|
|
1085
1089
|
if (this.config) {
|
|
1086
1090
|
return this.cloneState(this.config.defaultState);
|
|
1087
1091
|
}
|
|
1088
|
-
return {
|
|
1092
|
+
return {};
|
|
1089
1093
|
}
|
|
1090
1094
|
}
|
|
1091
1095
|
|
|
@@ -1176,8 +1180,14 @@ ${TAB_STYLES}
|
|
|
1176
1180
|
const baseURL = opts.baseURL || '';
|
|
1177
1181
|
if (opts.assetsJsonPath) {
|
|
1178
1182
|
const assetsPath = prependBaseUrl(opts.assetsJsonPath, baseURL);
|
|
1179
|
-
|
|
1180
|
-
|
|
1183
|
+
try {
|
|
1184
|
+
const assetsJson = await (await fetch(assetsPath)).json();
|
|
1185
|
+
assetsManager = new AssetsManager(assetsJson, baseURL);
|
|
1186
|
+
}
|
|
1187
|
+
catch (error) {
|
|
1188
|
+
console.error(`[CustomViews] Failed to load assets JSON from ${assetsPath}:`, error);
|
|
1189
|
+
assetsManager = new AssetsManager({}, baseURL);
|
|
1190
|
+
}
|
|
1181
1191
|
}
|
|
1182
1192
|
else {
|
|
1183
1193
|
assetsManager = new AssetsManager({}, baseURL);
|
|
@@ -1190,7 +1200,7 @@ ${TAB_STYLES}
|
|
|
1190
1200
|
else {
|
|
1191
1201
|
console.error("No config provided, using minimal default config");
|
|
1192
1202
|
// Create a minimal default config
|
|
1193
|
-
config = { allToggles: [], defaultState: {
|
|
1203
|
+
config = { allToggles: [], defaultState: {} };
|
|
1194
1204
|
}
|
|
1195
1205
|
const coreOptions = {
|
|
1196
1206
|
assetsManager,
|
|
@@ -1651,9 +1661,61 @@ ${TAB_STYLES}
|
|
|
1651
1661
|
margin: 0;
|
|
1652
1662
|
}
|
|
1653
1663
|
|
|
1654
|
-
.cv-
|
|
1655
|
-
|
|
1656
|
-
width:
|
|
1664
|
+
.cv-toggle-switch {
|
|
1665
|
+
position: relative;
|
|
1666
|
+
width: 44px;
|
|
1667
|
+
height: 24px;
|
|
1668
|
+
background: #ccc;
|
|
1669
|
+
border-radius: 12px;
|
|
1670
|
+
margin-right: 12px;
|
|
1671
|
+
cursor: pointer;
|
|
1672
|
+
transition: background-color 0.3s ease;
|
|
1673
|
+
flex-shrink: 0;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
.cv-toggle-switch:hover {
|
|
1677
|
+
background: #bbb;
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
.cv-toggle-switch.cv-toggle-active {
|
|
1681
|
+
background: #007bff;
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
.cv-toggle-switch.cv-toggle-active:hover {
|
|
1685
|
+
background: #0056b3;
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
.cv-toggle-handle {
|
|
1689
|
+
position: absolute;
|
|
1690
|
+
top: 2px;
|
|
1691
|
+
left: 2px;
|
|
1692
|
+
width: 20px;
|
|
1693
|
+
height: 20px;
|
|
1694
|
+
background: white;
|
|
1695
|
+
border-radius: 50%;
|
|
1696
|
+
transition: transform 0.3s ease;
|
|
1697
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
.cv-toggle-switch.cv-toggle-active .cv-toggle-handle {
|
|
1701
|
+
transform: translateX(20px);
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
/* Dark theme toggle switch styles */
|
|
1705
|
+
.cv-widget-theme-dark .cv-toggle-switch {
|
|
1706
|
+
background: #4a5568;
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
.cv-widget-theme-dark .cv-toggle-switch:hover {
|
|
1710
|
+
background: #5a6578;
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
.cv-widget-theme-dark .cv-toggle-switch.cv-toggle-active {
|
|
1714
|
+
background: #63b3ed;
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
.cv-widget-theme-dark .cv-toggle-switch.cv-toggle-active:hover {
|
|
1718
|
+
background: #4299e1;
|
|
1657
1719
|
}
|
|
1658
1720
|
|
|
1659
1721
|
.cv-tab-groups {
|
|
@@ -1882,11 +1944,11 @@ ${TAB_STYLES}
|
|
|
1882
1944
|
position: options.position || 'middle-left',
|
|
1883
1945
|
theme: options.theme || 'light',
|
|
1884
1946
|
showReset: options.showReset ?? true,
|
|
1885
|
-
title: options.title || '
|
|
1947
|
+
title: options.title || 'Customize View',
|
|
1886
1948
|
description: options.description || 'Toggle different content sections to customize your view. Changes are applied instantly and the URL will be updated for sharing.',
|
|
1887
1949
|
showWelcome: options.showWelcome ?? false,
|
|
1888
|
-
welcomeTitle: options.welcomeTitle || '
|
|
1889
|
-
welcomeMessage: options.welcomeMessage || 'This site
|
|
1950
|
+
welcomeTitle: options.welcomeTitle || 'Site Customization',
|
|
1951
|
+
welcomeMessage: options.welcomeMessage || 'This site is powered by Custom Views. Use the widget on the side (⚙) to customize your experience. Your preferences will be saved and can be shared via URL.<br><br>Learn more at <a href="https://github.com/customviews-js/customviews" target="_blank">customviews GitHub</a>.',
|
|
1890
1952
|
showTabGroups: options.showTabGroups ?? true
|
|
1891
1953
|
};
|
|
1892
1954
|
// No external state manager to initialize
|
|
@@ -1969,7 +2031,9 @@ ${TAB_STYLES}
|
|
|
1969
2031
|
? toggles.map(toggle => `
|
|
1970
2032
|
<div class="cv-custom-state-toggle">
|
|
1971
2033
|
<label>
|
|
1972
|
-
<
|
|
2034
|
+
<div class="cv-toggle-switch" data-toggle="${toggle}">
|
|
2035
|
+
<div class="cv-toggle-handle"></div>
|
|
2036
|
+
</div>
|
|
1973
2037
|
${this.formatToggleName(toggle)}
|
|
1974
2038
|
</label>
|
|
1975
2039
|
</div>
|
|
@@ -2000,7 +2064,7 @@ ${TAB_STYLES}
|
|
|
2000
2064
|
this.modal.innerHTML = `
|
|
2001
2065
|
<div class="cv-widget-modal cv-custom-state-modal">
|
|
2002
2066
|
<div class="cv-widget-modal-header">
|
|
2003
|
-
<h3
|
|
2067
|
+
<h3>${this.options.title}</h3>
|
|
2004
2068
|
<button class="cv-widget-modal-close" aria-label="Close modal">×</button>
|
|
2005
2069
|
</div>
|
|
2006
2070
|
<div class="cv-widget-modal-content">
|
|
@@ -2055,10 +2119,11 @@ ${TAB_STYLES}
|
|
|
2055
2119
|
this.loadCurrentStateIntoForm();
|
|
2056
2120
|
});
|
|
2057
2121
|
}
|
|
2058
|
-
// Listen to toggle
|
|
2059
|
-
const
|
|
2060
|
-
|
|
2061
|
-
|
|
2122
|
+
// Listen to toggle switches
|
|
2123
|
+
const toggleSwitches = this.modal.querySelectorAll('.cv-toggle-switch');
|
|
2124
|
+
toggleSwitches.forEach(toggleSwitch => {
|
|
2125
|
+
toggleSwitch.addEventListener('click', () => {
|
|
2126
|
+
toggleSwitch.classList.toggle('cv-toggle-active');
|
|
2062
2127
|
const state = this.getCurrentCustomStateFromModal();
|
|
2063
2128
|
this.core.applyState(state);
|
|
2064
2129
|
});
|
|
@@ -2107,14 +2172,14 @@ ${TAB_STYLES}
|
|
|
2107
2172
|
*/
|
|
2108
2173
|
getCurrentCustomStateFromModal() {
|
|
2109
2174
|
if (!this.modal) {
|
|
2110
|
-
return {
|
|
2175
|
+
return {};
|
|
2111
2176
|
}
|
|
2112
2177
|
// Collect toggle values
|
|
2113
2178
|
const toggles = [];
|
|
2114
|
-
const
|
|
2115
|
-
|
|
2116
|
-
const toggle =
|
|
2117
|
-
if (toggle &&
|
|
2179
|
+
const toggleSwitches = this.modal.querySelectorAll('.cv-toggle-switch');
|
|
2180
|
+
toggleSwitches.forEach(toggleSwitch => {
|
|
2181
|
+
const toggle = toggleSwitch.dataset.toggle;
|
|
2182
|
+
if (toggle && toggleSwitch.classList.contains('cv-toggle-active')) {
|
|
2118
2183
|
toggles.push(toggle);
|
|
2119
2184
|
}
|
|
2120
2185
|
});
|
|
@@ -2127,7 +2192,11 @@ ${TAB_STYLES}
|
|
|
2127
2192
|
tabs[groupId] = select.value;
|
|
2128
2193
|
}
|
|
2129
2194
|
});
|
|
2130
|
-
|
|
2195
|
+
const result = { toggles };
|
|
2196
|
+
if (Object.keys(tabs).length > 0) {
|
|
2197
|
+
result.tabs = tabs;
|
|
2198
|
+
}
|
|
2199
|
+
return result;
|
|
2131
2200
|
}
|
|
2132
2201
|
/**
|
|
2133
2202
|
* Copy shareable URL to clipboard
|
|
@@ -2147,20 +2216,16 @@ ${TAB_STYLES}
|
|
|
2147
2216
|
return;
|
|
2148
2217
|
// Get currently active toggles (from custom state or default configuration)
|
|
2149
2218
|
const activeToggles = this.core.getCurrentActiveToggles();
|
|
2150
|
-
// First,
|
|
2151
|
-
const
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
checkbox.disabled = false;
|
|
2155
|
-
checkbox.parentElement?.removeAttribute('aria-hidden');
|
|
2219
|
+
// First, deactivate all toggle switches
|
|
2220
|
+
const allToggleSwitches = this.modal.querySelectorAll('.cv-toggle-switch');
|
|
2221
|
+
allToggleSwitches.forEach(toggleSwitch => {
|
|
2222
|
+
toggleSwitch.classList.remove('cv-toggle-active');
|
|
2156
2223
|
});
|
|
2157
|
-
// Then
|
|
2224
|
+
// Then activate the ones that should be active
|
|
2158
2225
|
activeToggles.forEach(toggle => {
|
|
2159
|
-
const
|
|
2160
|
-
if (
|
|
2161
|
-
|
|
2162
|
-
checkbox.checked = true;
|
|
2163
|
-
}
|
|
2226
|
+
const toggleSwitch = this.modal?.querySelector(`[data-toggle="${toggle}"]`);
|
|
2227
|
+
if (toggleSwitch) {
|
|
2228
|
+
toggleSwitch.classList.add('cv-toggle-active');
|
|
2164
2229
|
}
|
|
2165
2230
|
});
|
|
2166
2231
|
// Load tab group selections
|
|
@@ -2213,7 +2278,7 @@ ${TAB_STYLES}
|
|
|
2213
2278
|
</div>
|
|
2214
2279
|
<div class="cv-widget-modal-content">
|
|
2215
2280
|
<div class="cv-welcome-content">
|
|
2216
|
-
<p>${this.options.welcomeMessage}</p>
|
|
2281
|
+
<p style="text-align: justify;">${this.options.welcomeMessage}</p>
|
|
2217
2282
|
|
|
2218
2283
|
<div class="cv-welcome-widget-preview">
|
|
2219
2284
|
<div class="cv-welcome-widget-icon">⚙</div>
|
|
@@ -2334,13 +2399,8 @@ ${TAB_STYLES}
|
|
|
2334
2399
|
console.warn(`[CustomViews] Config file not found at ${fullConfigPath}. Using defaults.`);
|
|
2335
2400
|
// Provide minimal default config structure
|
|
2336
2401
|
configFile = {
|
|
2337
|
-
config: {
|
|
2338
|
-
|
|
2339
|
-
defaultState: { toggles: [] }
|
|
2340
|
-
},
|
|
2341
|
-
widget: {
|
|
2342
|
-
enabled: true
|
|
2343
|
-
}
|
|
2402
|
+
config: { allToggles: [], defaultState: {} },
|
|
2403
|
+
widget: { enabled: true }
|
|
2344
2404
|
};
|
|
2345
2405
|
}
|
|
2346
2406
|
else {
|