@cbpds/web-components
Version:
Web components for the CBP Design System.
204 lines (197 loc) • 6.25 kB
JavaScript
/*!
* CPB Design System web components - built with Stencil
*/
import { d as getRenderingRef, f as forceUpdate } from './index-6c11fa0c.js';
const appendToMap = (map, propName, value) => {
const items = map.get(propName);
if (!items) {
map.set(propName, [value]);
}
else if (!items.includes(value)) {
items.push(value);
}
};
const debounce = (fn, ms) => {
let timeoutId;
return (...args) => {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(() => {
timeoutId = 0;
fn(...args);
}, ms);
};
};
/**
* Check if a possible element isConnected.
* The property might not be there, so we check for it.
*
* We want it to return true if isConnected is not a property,
* otherwise we would remove these elements and would not update.
*
* Better leak in Edge than to be useless.
*/
const isConnected = (maybeElement) => !('isConnected' in maybeElement) || maybeElement.isConnected;
const cleanupElements = debounce((map) => {
for (let key of map.keys()) {
map.set(key, map.get(key).filter(isConnected));
}
}, 2_000);
const stencilSubscription = () => {
if (typeof getRenderingRef !== 'function') {
// If we are not in a stencil project, we do nothing.
// This function is not really exported by @stencil/core.
return {};
}
const elmsToUpdate = new Map();
return {
dispose: () => elmsToUpdate.clear(),
get: (propName) => {
const elm = getRenderingRef();
if (elm) {
appendToMap(elmsToUpdate, propName, elm);
}
},
set: (propName) => {
const elements = elmsToUpdate.get(propName);
if (elements) {
elmsToUpdate.set(propName, elements.filter(forceUpdate));
}
cleanupElements(elmsToUpdate);
},
reset: () => {
elmsToUpdate.forEach((elms) => elms.forEach(forceUpdate));
cleanupElements(elmsToUpdate);
},
};
};
const unwrap = (val) => (typeof val === 'function' ? val() : val);
const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) => {
const unwrappedState = unwrap(defaultState);
let states = new Map(Object.entries(unwrappedState ?? {}));
const handlers = {
dispose: [],
get: [],
set: [],
reset: [],
};
const reset = () => {
// When resetting the state, the default state may be a function - unwrap it to invoke it.
// otherwise, the state won't be properly reset
states = new Map(Object.entries(unwrap(defaultState) ?? {}));
handlers.reset.forEach((cb) => cb());
};
const dispose = () => {
// Call first dispose as resetting the state would
// cause less updates ;)
handlers.dispose.forEach((cb) => cb());
reset();
};
const get = (propName) => {
handlers.get.forEach((cb) => cb(propName));
return states.get(propName);
};
const set = (propName, value) => {
const oldValue = states.get(propName);
if (shouldUpdate(value, oldValue, propName)) {
states.set(propName, value);
handlers.set.forEach((cb) => cb(propName, value, oldValue));
}
};
const state = (typeof Proxy === 'undefined'
? {}
: new Proxy(unwrappedState, {
get(_, propName) {
return get(propName);
},
ownKeys(_) {
return Array.from(states.keys());
},
getOwnPropertyDescriptor() {
return {
enumerable: true,
configurable: true,
};
},
has(_, propName) {
return states.has(propName);
},
set(_, propName, value) {
set(propName, value);
return true;
},
}));
const on = (eventName, callback) => {
handlers[eventName].push(callback);
return () => {
removeFromArray(handlers[eventName], callback);
};
};
const onChange = (propName, cb) => {
const unSet = on('set', (key, newValue) => {
if (key === propName) {
cb(newValue);
}
});
// We need to unwrap the defaultState because it might be a function.
// Otherwise we might not be sending the right reset value.
const unReset = on('reset', () => cb(unwrap(defaultState)[propName]));
return () => {
unSet();
unReset();
};
};
const use = (...subscriptions) => {
const unsubs = subscriptions.reduce((unsubs, subscription) => {
if (subscription.set) {
unsubs.push(on('set', subscription.set));
}
if (subscription.get) {
unsubs.push(on('get', subscription.get));
}
if (subscription.reset) {
unsubs.push(on('reset', subscription.reset));
}
if (subscription.dispose) {
unsubs.push(on('dispose', subscription.dispose));
}
return unsubs;
}, []);
return () => unsubs.forEach((unsub) => unsub());
};
const forceUpdate = (key) => {
const oldValue = states.get(key);
handlers.set.forEach((cb) => cb(key, oldValue, oldValue));
};
return {
state,
get,
set,
on,
onChange,
use,
dispose,
reset,
forceUpdate,
};
};
const removeFromArray = (array, item) => {
const index = array.indexOf(item);
if (index >= 0) {
array[index] = array[array.length - 1];
array.length--;
}
};
const createStore = (defaultState, shouldUpdate) => {
const map = createObservableMap(defaultState, shouldUpdate);
map.use(stencilSubscription());
return map;
};
const { state } = createStore({
currentPage: undefined,
currentParent: undefined,
activeItemName: undefined,
});
export { state as s };
//# sourceMappingURL=store-6cad20b5.js.map