@empoleon/spotlight
Version:
Command center components for react and Empoleon
159 lines (156 loc) • 4.85 kB
JavaScript
import { clamp } from '@empoleon/hooks';
import { createStore, useStore } from '@empoleon/store';
const createSpotlightStore = () => createStore({
opened: false,
empty: false,
selected: -1,
listId: "",
query: "",
registeredActions: /* @__PURE__ */new Set()
});
const useSpotlight = store => useStore(store);
function updateSpotlightStateAction(update, store) {
const state = store.getState();
store.setState({
...state,
...update(store.getState())
});
}
function openSpotlightAction(store) {
updateSpotlightStateAction(() => ({
opened: true,
selected: -1
}), store);
}
function closeSpotlightAction(store) {
updateSpotlightStateAction(() => ({
opened: false
}), store);
}
function toggleSpotlightAction(store) {
updateSpotlightStateAction(state => ({
opened: !state.opened,
selected: state.opened ? state.selected : -1
}), store);
}
function setSelectedAction(index, store) {
store.updateState(state => ({
...state,
selected: index
}));
}
function setListId(id, store) {
store.updateState(state => ({
...state,
listId: id
}));
}
function findElementByQuerySelector(selector) {
let root = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
const element = root.querySelector(selector);
if (element) {
return element;
}
const children = root instanceof ShadowRoot ? root.host.children : root.children;
for (let i = 0; i < children.length; i += 1) {
const child = children[i];
if (child.shadowRoot) {
const shadowElement = findElementByQuerySelector(selector, child.shadowRoot);
if (shadowElement) {
return shadowElement;
}
}
const nestedElement = findElementByQuerySelector(selector, child);
if (nestedElement) {
return nestedElement;
}
}
return null;
}
function selectAction(index, store) {
const state = store.getState();
const actionsList = state.listId ? findElementByQuerySelector(`#${state.listId}`) : null;
const selected = actionsList?.querySelector("[data-selected]");
const actions = actionsList?.querySelectorAll("[data-action]") ?? [];
const nextIndex = index === -1 ? actions.length - 1 : index === actions.length ? 0 : index;
const selectedIndex = clamp(nextIndex, 0, actions.length - 1);
selected?.removeAttribute("data-selected");
actions[selectedIndex]?.scrollIntoView({
block: "nearest"
});
actions[selectedIndex]?.setAttribute("data-selected", "true");
setSelectedAction(selectedIndex, store);
return selectedIndex;
}
function selectNextAction(store) {
return selectAction(store.getState().selected + 1, store);
}
function selectPreviousAction(store) {
return selectAction(store.getState().selected - 1, store);
}
function triggerSelectedAction(store) {
const state = store.getState();
const selected = findElementByQuerySelector(`#${state.listId} [data-selected]`);
selected?.click();
}
function registerAction(id, store) {
const state = store.getState();
state.registeredActions.add(id);
return () => {
state.registeredActions.delete(id);
};
}
function setQuery(query, store) {
updateSpotlightStateAction(() => ({
query
}), store);
Promise.resolve().then(() => {
selectAction(0, store);
updateSpotlightStateAction(state => ({
empty: state.query.trim().length > 0 && state.registeredActions.size === 0 || false
}), store);
});
}
function clearSpotlightState(_ref, store) {
let {
clearQuery
} = _ref;
store.updateState(state => ({
...state,
selected: -1,
query: clearQuery ? "" : state.query,
empty: clearQuery ? false : state.empty
}));
}
const spotlightActions = {
open: openSpotlightAction,
close: closeSpotlightAction,
toggle: toggleSpotlightAction,
updateState: updateSpotlightStateAction,
setSelectedAction,
setListId,
selectAction,
selectNextAction,
selectPreviousAction,
triggerSelectedAction,
registerAction,
setQuery,
clearSpotlightState
};
function createSpotlight() {
const store = createSpotlightStore();
const actions = {
open: () => openSpotlightAction(store),
close: () => closeSpotlightAction(store),
toggle: () => toggleSpotlightAction(store)
};
return [store, actions];
}
const [spotlightStore, spotlight] = createSpotlight();
const {
open: openSpotlight,
close: closeSpotlight,
toggle: toggleSpotlight
} = spotlight;
export { clearSpotlightState, closeSpotlight, closeSpotlightAction, createSpotlight, createSpotlightStore, openSpotlight, openSpotlightAction, registerAction, selectAction, selectNextAction, selectPreviousAction, setListId, setQuery, setSelectedAction, spotlight, spotlightActions, spotlightStore, toggleSpotlight, toggleSpotlightAction, triggerSelectedAction, updateSpotlightStateAction, useSpotlight };
//# sourceMappingURL=spotlight.store.mjs.map