@ussebastian/kitdigital
Version:
Kit Digital de la Universidad San Sebastián
231 lines (203 loc) • 6.59 kB
JavaScript
import pkg from '../../package.json';
import { initializeThemeToggler } from './components/initializeThemeToggler';
import { attachRemoveOnClickListeners } from './components/attachRemoveOnClickListeners';
import { attachRemoveTargetOnClickListeners } from './components/attachRemoveTargetOnClickListeners';
import { Toast } from './components/Toast';
const COMPONENT_DEFINITIONS = {
Tooltip: {
docs: '',
selectors: ['[data-uss-tooltip-content]', '[data-uss-tooltip-content-element-id]'],
importComponent: async () => {
const module = await import('./components/Tooltip');
return module.Tooltip;
},
},
Collapsable: {
docs: '',
selectors: ['[data-uss-collapsable-trigger-for]'],
importComponent: async () => {
const module = await import('./components/Collapsable');
return module.Collapsable;
},
},
Carousel: {
selectors: '[data-uss-carousel]',
importComponent: async () => {
const module = await import('./components/Carousel');
return module.Carousel;
},
},
CarouselV2: {
selectors: '.uss-carousel-v2',
importComponent: async () => {
const module = await import('./components/CarouselV2');
return module.CarouselV2;
},
},
Modal: {
selectors: '[data-uss-modal-id]',
importComponent: async () => {
const module = await import('./components/Modal');
return module.Modal;
},
},
Tabs: {
selectors: '.uss-tabs',
importComponent: async () => {
const module = await import('./components/Tabs');
return module.Tabs;
},
},
Navbar: {
selectors: ['.uss-mainnav__menu'],
importComponent: async () => {
const module = await import('./components/Navbar');
return module.Navbar;
},
},
NavbarMobile: {
selectors: ['.uss-mainnav--mobile'],
importComponent: async () => {
const module = await import('./components/NavbarMobile');
return module.NavbarMobile;
},
},
};
const handleImportAndMountComponent = async (importComponent, componentName, element, index) => {
const timestamp = +new Date();
const id = element.getAttribute('id');
const key = id || `${componentName}-${index}__${timestamp}`;
const Component = await importComponent();
let instance = null;
if (!element.getAttribute('data-uss-mounted')) {
instance = new Component(element, key);
instance.mount(element, key);
element.setAttribute('data-uss-mounted', true);
} else {
// eslint-disable-next-line no-console
console.warn(
`Component ${componentName} with key ${key} is already mounted in the element:`,
element,
);
}
return { key, instance };
};
const handleMountSubComponents = async (component, element) => {
const isAgendaComponent = ['AgendaSlider', 'AgendaPagination', 'AgendaRow'].includes(
component.componentName,
);
const innerComponnets = Array.isArray(component.innerComponnets)
? component.innerComponnets
: [component.innerComponnets];
const attributeToCheck = isAgendaComponent ? 'data-uss-agenda-fetched' : 'data-uss-mounted';
const checkIfAgendaComponent = () => {
if (element.getAttribute(attributeToCheck) === 'true') {
innerComponnets.forEach((innerComponentName) => {
window.USSKitDigital.mountComponent(innerComponentName, element, false);
});
} else setTimeout(checkIfAgendaComponent, 100);
};
checkIfAgendaComponent();
};
const mountComponent = async (
componentName,
elementRoot = document,
canMountSubcomponents = true,
) => {
const component = COMPONENT_DEFINITIONS[componentName];
component.componentName = componentName;
const { importComponent, selectors } = component;
const elements = elementRoot.querySelectorAll(selectors);
if (!elements.length) return;
let instances = await Promise.all(
Array.from(elements).map(async (element, index) => {
const instance = handleImportAndMountComponent(
importComponent,
componentName,
element,
index,
);
if (component.innerComponnets && canMountSubcomponents)
handleMountSubComponents(component, element);
return instance;
}),
);
instances = instances.reduce((acc, { key, instance }) => {
acc[key] = instance;
return acc;
}, {});
if (!window?.USSKitDigital?.mountedComponents) {
window.USSKitDigital.mountedComponents = {
[componentName]: {},
};
}
// Asignar las instancias al objeto
window.USSKitDigital.mountedComponents[componentName] = {
...window.USSKitDigital.mountedComponents[componentName], // Si existe, conservar sus propiedades
...instances, // Agregar las nuevas instancias
};
};
const unMountComponent = (componentName) => {
const instances = window.USSKitDigital.mountedComponents[componentName];
if (!instances) return;
Object.values(instances).forEach((instance) => {
instance.unMount();
});
window.USSKitDigital.mountedComponents[componentName] = {};
};
const mountAllComponents = async () => {
window.USSKitDigital.componentNames.forEach((componentName) => {
if (!window.USSKitDigital.options.preventMount.includes(componentName))
window.USSKitDigital.mountComponent(componentName);
});
};
const unMountAllComponents = () => {
window.USSKitDigital.componentNames.forEach((componentName) => {
window.USSKitDigital.unMountComponent(componentName);
});
};
const DEFAULT_OPTIONS = {
preventMount: [
// "Accordion",
// "AgendaSlider",
// "AgendaPagination",
// "GlobalFooter",
// "GlobalTopbar",
],
};
async function USSKitDigital(options = DEFAULT_OPTIONS) {
const components = Object.keys(COMPONENT_DEFINITIONS).reduce((acc, componentName) => {
acc[componentName] = {
...COMPONENT_DEFINITIONS[componentName],
};
return acc;
}, {});
window.USSKitDigital = {
version: pkg.version,
author: pkg.author,
contributors: pkg.contributors,
documentation: pkg.documentation,
// -----------------------------------
componentNames: Object.keys(COMPONENT_DEFINITIONS),
componentsSharedState: {},
mountedComponents: {},
mountComponent,
unMountComponent,
mountAllComponents,
unMountAllComponents,
components,
options,
};
}
document.addEventListener('DOMContentLoaded', async () => {
await USSKitDigital();
window.USSKitDigital.mountAllComponents();
initializeThemeToggler();
attachRemoveOnClickListeners();
attachRemoveTargetOnClickListeners();
window.USSKitDigital = {
Static: {
Toast,
},
};
});