('.plugins-list')?.prepend(plugin);
- }
-
- loadPluginList() {
- const plugins = this.getPlugins();
-
- for (const plugin of plugins) {
- this.createPlugin(plugin.name, plugin.url);
- }
- }
-
- getPlugins() {
- const pluginsStorage = localStorage.getItem('plugins');
-
- if (!pluginsStorage) {
- return [];
- }
-
- return JSON.parse(pluginsStorage) as {
- name: string;
- url: string;
- }[];
- }
-
- savePlugins(plugins: { name: string; url: string }[]) {
- localStorage.setItem('plugins', JSON.stringify(plugins));
- }
-
- submitNewPlugin(event: Event) {
- event.preventDefault();
-
- const form = event.target as HTMLFormElement;
- const input = form.querySelector('input') as HTMLInputElement;
-
- if (!input) {
- return;
- }
-
- const url = input.value;
-
- input.value = '';
-
- void loadManifest(url)
- .then((manifest) => {
- this.createPlugin(manifest.name, url);
-
- const pluginsStorage = localStorage.getItem('plugins');
-
- if (!pluginsStorage) {
- localStorage.setItem(
- 'plugins',
- JSON.stringify([{ name: manifest.name, url }])
- );
- } else {
- const plugins = this.getPlugins();
- plugins.push({ name: manifest.name, url });
-
- this.savePlugins(plugins);
- }
-
- this.error(false);
- })
- .catch((error) => {
- console.error(error);
- this.error(true);
- });
- }
-
- error(show: boolean) {
- this.dialog?.querySelector('.error')?.classList.toggle('show', show);
- }
-
- connectedCallback() {
- if (!this.shadowRoot) {
- throw new Error('Error creating shadow root');
- }
-
- this.dialog = document.createElement('dialog');
-
- this.dialog.innerHTML = `
-
-
-
- Error instaling plugin
-
-
-
- `;
-
- this.dialog.querySelector('.close')?.addEventListener('click', () => {
- this.closeModal();
- });
-
- this.shadowRoot.appendChild(this.dialog);
-
- this.dialog.addEventListener('submit', (event: Event) => {
- this.submitNewPlugin(event);
- });
-
- this.loadPluginList();
-
- const style = document.createElement('style');
- style.textContent = `
- * {
- font-family worksans, sans-serif
- }
-
- ::backdrop {
- background-color: rgba(0, 0, 0, 0.8);
- }
-
- dialog {
- border: 0;
- width: 700px;
- height: 500px;
- padding: 20px;
- background-color: white;
- border-radius: 10px;
- flex-direction: column;
- display: none;
- }
-
- dialog[open] {
- display: flex;
- }
-
- .header {
- display: flex;
- justify-content: space-between;
- }
-
- h1 {
- margin: 0;
- margin-block-end: 10px;
- }
-
- ul {
- padding: 0;
- }
-
- li {
- list-style: none;
- }
-
- .input {
- display: flex;
- border: 1px solid;
- border-radius: calc( 0.25rem * 2);
- font-size: 12px;
- font-weight: 400;
- line-height: 1.4;
- outline: none;
- padding-block: calc( 0.25rem * 2);
- padding-inline: calc( 0.25rem * 2);
- background-color: #f3f4f6;
- border-color: #f3f4f6;
- color: #000;
-
- &:hover {
- background-color: #eef0f2;
- border-color: #eef0f2;
- }
-
- &:focus {
- background-color: #ffffff
- border-color: ##6911d4;
- }
- }
-
- button {
- background: transparent;
- border: 0;
- cursor: pointer;
- }
-
- .button {
- border: 1px solid transparent;
- font-weight: 500;
- font-size: 12px;
- border-radius: 8px;
- line-height: 1.2;
- padding: 8px 24px 8px 24px;
- text-transform: uppercase;
- background-color: #7EFFF5;
- border: 1px solid 7EFFF5;
- outline: 2px solid transparent;
-
- &:hover:not(:disabled) {
- cursor: pointer;
- }
-
- &:focus-visible {
- outline: none;
- }
- }
-
- .remove {
- background-color: #ff3277;
- border: 1px solid #ff3277;
- outline: 2px solid transparent;
- }
-
- form {
- display: flex;
- gap: 10px;
- margin-block-end: 20px;
- }
-
- .url-input {
- inline-size: 400px;
- }
-
- .plugins-list {
- display: flex;
- flex-direction: column;
- gap: 10px;
- }
-
- .plugin {
- display: flex;
- justify-content: space-between;
- }
-
- .actions {
- display: flex;
- gap: 10px;
- }
-
- .error {
- display: none;
- color: red;
-
- &.show {
- display: block;
- }
- }
- `;
-
- this.shadowRoot.appendChild(style);
- }
-
- closeModal() {
- this.shadowRoot?.querySelector('dialog')?.close();
-
- window.removeEventListener('paste', pasteEventHandler, true);
- }
-
- openModal() {
- this.shadowRoot?.querySelector('dialog')?.showModal();
-
- // prevent paste event in penpot workspace
- window.addEventListener('paste', pasteEventHandler, true);
- }
-}
-
-export function initInstaller() {
- customElements.define('installer-modal', InstallerElement);
-
- const modal = document.createElement('installer-modal');
-
- document.body.appendChild(modal);
-
- document.addEventListener('keydown', (event: KeyboardEvent) => {
- if (event.key.toUpperCase() === 'I' && event.ctrlKey) {
- document.querySelector('installer-modal')?.openModal();
- }
- });
-}