From 883cb161ec4c684fcc4676763acfc6b8553656fd Mon Sep 17 00:00:00 2001 From: Konnor Rogers Date: Wed, 30 Aug 2023 09:42:34 -0400 Subject: [PATCH 01/19] show errors in dev server (#1547) * show errors in dev server * fix build * prettier --- scripts/build.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/build.js b/scripts/build.js index e46f4ef9..02491557 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -34,6 +34,9 @@ const shoelaceVersion = JSON.stringify(packageData.version.toString()); async function buildTheDocs(watch = false) { return new Promise(async (resolve, reject) => { const afterSignal = '[eleventy.after]'; + + // Totally non-scientific way to handle errors. Perhaps its just better to resolve on stderr? :shrug: + const errorSignal = 'Original error stack trace:'; const args = ['@11ty/eleventy', '--quiet']; const output = []; @@ -65,6 +68,13 @@ async function buildTheDocs(watch = false) { resolve({ child, output }); } }); + + child.stderr.on('data', data => { + if (data.includes(errorSignal)) { + // This closes the dev server, not sure if thats what we want? + reject(output); + } + }); } else { child.on('close', () => { resolve({ child, output }); From 242e8e92ae3d00d6125ec6f9c4e773b77f69780a Mon Sep 17 00:00:00 2001 From: Burton Smith Date: Thu, 7 Sep 2023 21:32:45 -0400 Subject: [PATCH 02/19] fix web-types reference --- docs/pages/getting-started/usage.md | 2 +- package.json | 2 +- scripts/build.js | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/pages/getting-started/usage.md b/docs/pages/getting-started/usage.md index 4032588e..9aabfc24 100644 --- a/docs/pages/getting-started/usage.md +++ b/docs/pages/getting-started/usage.md @@ -210,7 +210,7 @@ Shoelace ships with a file called `vscode.html-custom-data.json` that can be use If `settings.json` already exists, simply add the above line to the root of the object. Note that you may need to restart VS Code for the changes to take affect. -## JetBrains IDEs +### JetBrains IDEs If you are using a [JetBrains IDE](https://www.jetbrains.com/) and you are installing Shoelace from NPM, the editor will automatically detect the `web-types.json` file from the package and you should immediately see component information in your editor. diff --git a/package.json b/package.json index 5cca9356..31187aa6 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "./dist/react/*": "./dist/react/*", "./dist/translations/*": "./dist/translations/*" }, - "files": ["dist", "cdn"], + "files": ["dist", "cdn", "web-types.json"], "keywords": ["web components", "custom elements", "components"], "repository": { "type": "git", diff --git a/scripts/build.js b/scripts/build.js index 02491557..b95c770e 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -217,7 +217,6 @@ await nextTask('Running the TypeScript compiler', () => { // Copy the above steps to the CDN directory directly so we don't need to twice the work for nothing. await nextTask(`Copying Web Types, Themes, Icons, and TS Types to "${cdndir}"`, async () => { await deleteAsync(cdndir); - await copy('./web-types.json', `${outdir}/web-types.json`); await copy(outdir, cdndir); }); From 8d86f374f91d72e157ccc429e7754341bdd37f64 Mon Sep 17 00:00:00 2001 From: Burton Smith Date: Thu, 7 Sep 2023 21:38:16 -0400 Subject: [PATCH 03/19] clean up messaging --- scripts/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.js b/scripts/build.js index b95c770e..ef6c2846 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -215,7 +215,7 @@ await nextTask('Running the TypeScript compiler', () => { }); // Copy the above steps to the CDN directory directly so we don't need to twice the work for nothing. -await nextTask(`Copying Web Types, Themes, Icons, and TS Types to "${cdndir}"`, async () => { +await nextTask(`Themes, Icons, and TS Types to "${cdndir}"`, async () => { await deleteAsync(cdndir); await copy(outdir, cdndir); }); From 7d6f770cd9973da2da2bde9d900f07b6a658f7bf Mon Sep 17 00:00:00 2001 From: Burton Smith Date: Thu, 7 Sep 2023 23:04:31 -0400 Subject: [PATCH 04/19] simplify implementation --- custom-elements-manifest.config.js | 1 + docs/pages/getting-started/usage.md | 2 +- package.json | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/custom-elements-manifest.config.js b/custom-elements-manifest.config.js index e5912cd0..8d3e7fe5 100644 --- a/custom-elements-manifest.config.js +++ b/custom-elements-manifest.config.js @@ -203,6 +203,7 @@ export default { ] }), customElementJetBrainsPlugin({ + outdir: './dist', excludeCss: true, referencesTemplate: (_, tag) => { return { diff --git a/docs/pages/getting-started/usage.md b/docs/pages/getting-started/usage.md index 9aabfc24..33a2debe 100644 --- a/docs/pages/getting-started/usage.md +++ b/docs/pages/getting-started/usage.md @@ -214,7 +214,7 @@ If `settings.json` already exists, simply add the above line to the root of the If you are using a [JetBrains IDE](https://www.jetbrains.com/) and you are installing Shoelace from NPM, the editor will automatically detect the `web-types.json` file from the package and you should immediately see component information in your editor. -If you are installing from the CDN, you can [download a local copy](https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace/cdn/web-types.json) and add it to the root of your project. +If you are installing from the CDN, you can [download a local copy](https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace/dist/web-types.json) and add it to the root of your project. ### Other Editors diff --git a/package.json b/package.json index 31187aa6..681bdf2d 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "author": "Cory LaViska", "license": "MIT", "customElements": "dist/custom-elements.json", - "web-types": "./web-types.json", + "web-types": "./dist/web-types.json", "type": "module", "types": "dist/shoelace.d.ts", "jsdelivr": "./cdn/shoelace-autoloader.js", @@ -25,7 +25,7 @@ "./dist/react/*": "./dist/react/*", "./dist/translations/*": "./dist/translations/*" }, - "files": ["dist", "cdn", "web-types.json"], + "files": ["dist", "cdn"], "keywords": ["web components", "custom elements", "components"], "repository": { "type": "git", From 2b5e8286dff60c821f6cc520f3264b8374becafc Mon Sep 17 00:00:00 2001 From: Mario Hamann Date: Fri, 8 Sep 2023 14:31:57 +0200 Subject: [PATCH 05/19] fix: make German translation more consistent + neutral (#1558) In German you can say "Du" (=informal) or "Sie" (= formal). Before this commit both versions were used at the same time. It is preferred to make interfaces neutral, as some systems use "Du" (iOS, macOS) and some "Sie" (MS, Android). In addition all other translations were neutral, too, so this makes it more consistent. --- src/translations/de.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/translations/de.ts b/src/translations/de.ts index 1894e600..21b1e069 100644 --- a/src/translations/de.ts +++ b/src/translations/de.ts @@ -13,7 +13,7 @@ const translation: Translation = { copy: 'Kopieren', currentValue: 'Aktueller Wert', error: 'Fehler', - goToSlide: (slide, count) => `Gehen Sie zu Folie ${slide} von ${count}`, + goToSlide: (slide, count) => `Zu Folie ${slide} von ${count} gehen`, hidePassword: 'Passwort verbergen', loading: 'Wird geladen', nextSlide: 'Nächste Folie', @@ -28,7 +28,7 @@ const translation: Translation = { resize: 'Größe ändern', scrollToEnd: 'Zum Ende scrollen', scrollToStart: 'Zum Anfang scrollen', - selectAColorFromTheScreen: 'Wähle eine Farbe vom Bildschirm', + selectAColorFromTheScreen: 'Farbe vom Bildschirm auswählen', showPassword: 'Passwort anzeigen', slideNum: slide => `Folie ${slide}`, toggleColorFormat: 'Farbformat umschalten' From 42f881806b59d06dda7d988bbde6b14414cfc5fb Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Fri, 8 Sep 2023 08:32:48 -0400 Subject: [PATCH 06/19] remove webtypes --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0a2fc3d4..1cf47052 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,8 @@ _site .cache .DS_Store +cdn dist docs/assets/images/sprite.svg node_modules src/react -cdn -web-types.json \ No newline at end of file From e6db8c953afbb7adddaa71374b6de6ec0237cae4 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Tue, 12 Sep 2023 12:09:29 -0400 Subject: [PATCH 07/19] update bootstrap icons --- docs/pages/resources/changelog.md | 1 + package-lock.json | 14 +++++++------- package.json | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index c6f73cec..559e63f7 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -16,6 +16,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti - Fixed a bug in `` that resulted in improper spacing between the label and the required asterisk [#1540] - Updated `@ctrl/tinycolor` to 4.0.1 [#1542] +- Updated Bootstrap Icons to 1.11.0 ## 2.8.0 diff --git a/package-lock.json b/package-lock.json index 9379318a..44151bdb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "@web/test-runner": "^0.15.0", "@web/test-runner-commands": "^0.6.5", "@web/test-runner-playwright": "^0.9.0", - "bootstrap-icons": "^1.10.5", + "bootstrap-icons": "^1.11.0", "browser-sync": "^2.29.3", "chalk": "^5.2.0", "change-case": "^4.1.2", @@ -3988,9 +3988,9 @@ } }, "node_modules/bootstrap-icons": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.5.tgz", - "integrity": "sha512-oSX26F37V7QV7NCE53PPEL45d7EGXmBgHG3pDpZvcRaKVzWMqIRL9wcqJUyEha1esFtM3NJzvmxFXDxjJYD0jQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.0.tgz", + "integrity": "sha512-bLTbtACfUqwZf6f/xUYUb7bTRZC68QaQwwy9h1b96NPKfnwqzSatHqDypW6R2CBW7zUE7lP+O93GdZuPY3RIHA==", "dev": true, "funding": [ { @@ -20213,9 +20213,9 @@ } }, "bootstrap-icons": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.5.tgz", - "integrity": "sha512-oSX26F37V7QV7NCE53PPEL45d7EGXmBgHG3pDpZvcRaKVzWMqIRL9wcqJUyEha1esFtM3NJzvmxFXDxjJYD0jQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.0.tgz", + "integrity": "sha512-bLTbtACfUqwZf6f/xUYUb7bTRZC68QaQwwy9h1b96NPKfnwqzSatHqDypW6R2CBW7zUE7lP+O93GdZuPY3RIHA==", "dev": true }, "boxen": { diff --git a/package.json b/package.json index 681bdf2d..a1359114 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "@web/test-runner": "^0.15.0", "@web/test-runner-commands": "^0.6.5", "@web/test-runner-playwright": "^0.9.0", - "bootstrap-icons": "^1.10.5", + "bootstrap-icons": "^1.11.0", "browser-sync": "^2.29.3", "chalk": "^5.2.0", "change-case": "^4.1.2", From 317d567fe801aa078b4604bb7bde621b85347efa Mon Sep 17 00:00:00 2001 From: Wes Date: Wed, 13 Sep 2023 08:50:02 -0700 Subject: [PATCH 08/19] fix(autoloader): only attempt to register root element if it's shoelace element (#1563) --- src/shoelace-autoloader.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/shoelace-autoloader.ts b/src/shoelace-autoloader.ts index a0d66c00..2f49515d 100644 --- a/src/shoelace-autoloader.ts +++ b/src/shoelace-autoloader.ts @@ -15,13 +15,13 @@ const observer = new MutationObserver(mutations => { */ export async function discover(root: Element | ShadowRoot) { const rootTagName = root instanceof Element ? root.tagName.toLowerCase() : ''; - const rootIsCustomElement = rootTagName?.includes('-'); + const rootIsShoelaceElement = rootTagName?.startsWith('sl-'); const tags = [...root.querySelectorAll(':not(:defined)')] .map(el => el.tagName.toLowerCase()) .filter(tag => tag.startsWith('sl-')); - // If the root element is an undefined custom element, add it to the list - if (rootIsCustomElement && !customElements.get(rootTagName)) { + // If the root element is an undefined shoelace custom element, add it to the list + if (rootIsShoelaceElement && !customElements.get(rootTagName)) { tags.push(rootTagName); } @@ -35,14 +35,14 @@ export async function discover(root: Element | ShadowRoot) { * Registers an element by tag name. */ function register(tagName: string): Promise { - const tagWithoutPrefix = tagName.replace(/^sl-/i, ''); - const path = getBasePath(`components/${tagWithoutPrefix}/${tagWithoutPrefix}.js`); - // If the element is already defined, there's nothing more to do if (customElements.get(tagName)) { return Promise.resolve(); } + const tagWithoutPrefix = tagName.replace(/^sl-/i, ''); + const path = getBasePath(`components/${tagWithoutPrefix}/${tagWithoutPrefix}.js`); + // Register it return new Promise((resolve, reject) => { import(path).then(() => resolve()).catch(() => reject(new Error(`Unable to autoload <${tagName}> from ${path}`))); From c858bc3723f1b7aaeac2d4bc811417de5a2e7061 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Wed, 13 Sep 2023 11:51:50 -0400 Subject: [PATCH 09/19] update changelog --- docs/pages/resources/changelog.md | 1 + src/shoelace-autoloader.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index 559e63f7..0c6492d7 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -14,6 +14,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti ## Next +- Fixed a bug in the autoloader causing it to register non-Shoelace elements [#1563] - Fixed a bug in `` that resulted in improper spacing between the label and the required asterisk [#1540] - Updated `@ctrl/tinycolor` to 4.0.1 [#1542] - Updated Bootstrap Icons to 1.11.0 diff --git a/src/shoelace-autoloader.ts b/src/shoelace-autoloader.ts index 2f49515d..4b42c452 100644 --- a/src/shoelace-autoloader.ts +++ b/src/shoelace-autoloader.ts @@ -20,7 +20,7 @@ export async function discover(root: Element | ShadowRoot) { .map(el => el.tagName.toLowerCase()) .filter(tag => tag.startsWith('sl-')); - // If the root element is an undefined shoelace custom element, add it to the list + // If the root element is an undefined Shoelace component, add it to the list if (rootIsShoelaceElement && !customElements.get(rootTagName)) { tags.push(rootTagName); } From 3b77c3b99fa7ea995eb10f884aed04f4baa23c4b Mon Sep 17 00:00:00 2001 From: Alan Chambers Date: Thu, 14 Sep 2023 16:13:29 +0100 Subject: [PATCH 10/19] updated react wrapper (#1565) - updated @lit-labs/react to latest version with improved type compatibility - added small preact section to the react docs with link to preact/compat typescript config guide --- docs/pages/frameworks/react.md | 4 ++++ package-lock.json | 14 +++++++------- package.json | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/pages/frameworks/react.md b/docs/pages/frameworks/react.md index 86f208ef..b87cb9c7 100644 --- a/docs/pages/frameworks/react.md +++ b/docs/pages/frameworks/react.md @@ -32,6 +32,10 @@ If you'd rather not use the CDN for assets, you can create a [build task](https: Now you can start using components! +### Preact + +Preact users facing type errors using components may benefit from setting "paths" in their tsconfig.json so that react types will instead resolve to preact/compat as described in [Preact's typescript documentation](https://preactjs.com/guide/v10/typescript/#typescript-preactcompat-configuration). + ## Usage ### Importing Components diff --git a/package-lock.json b/package-lock.json index 44151bdb..f5355740 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@ctrl/tinycolor": "^4.0.1", "@floating-ui/dom": "^1.2.1", - "@lit-labs/react": "^2.0.1", + "@lit-labs/react": "^2.0.3", "@shoelace-style/animations": "^1.1.0", "@shoelace-style/localize": "^3.1.1", "composed-offset-position": "^0.0.4", @@ -1474,9 +1474,9 @@ } }, "node_modules/@lit-labs/react": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-2.0.1.tgz", - "integrity": "sha512-Nj+XB3HamqaWefN91lpFPJaqjJ78XzGkPWCedB4jyH22GBFEenpE9A/h8B/2dnIGXtNtd9D/RFpUdQ/dBtWFqA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-2.0.3.tgz", + "integrity": "sha512-lSvWbTrbxWqYv/iiOwbAEJfFZrKjO/QjJ4IEXhg43sdD5fNFz4wRXpVsntfVn4DnxpQd+NVRnrsF2USgK0XCTw==", "peerDependencies": { "@types/react": "17 || 18" } @@ -18290,9 +18290,9 @@ } }, "@lit-labs/react": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-2.0.1.tgz", - "integrity": "sha512-Nj+XB3HamqaWefN91lpFPJaqjJ78XzGkPWCedB4jyH22GBFEenpE9A/h8B/2dnIGXtNtd9D/RFpUdQ/dBtWFqA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-2.0.3.tgz", + "integrity": "sha512-lSvWbTrbxWqYv/iiOwbAEJfFZrKjO/QjJ4IEXhg43sdD5fNFz4wRXpVsntfVn4DnxpQd+NVRnrsF2USgK0XCTw==", "requires": {} }, "@lit-labs/ssr-dom-shim": { diff --git a/package.json b/package.json index a1359114..a0de7626 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "dependencies": { "@ctrl/tinycolor": "^4.0.1", "@floating-ui/dom": "^1.2.1", - "@lit-labs/react": "^2.0.1", + "@lit-labs/react": "^2.0.3", "@shoelace-style/animations": "^1.1.0", "@shoelace-style/localize": "^3.1.1", "composed-offset-position": "^0.0.4", From 1d28e1bbc53fcee43840b2db16a10904a53b0c1f Mon Sep 17 00:00:00 2001 From: Christian Schuller Date: Thu, 14 Sep 2023 17:17:12 +0200 Subject: [PATCH 11/19] fix: add missing super.disconnectCallback() calls (#1564) --- src/components/details/details.component.ts | 1 + src/components/mutation-observer/mutation-observer.component.ts | 1 + src/components/popup/popup.component.ts | 1 + src/components/tab-group/tab-group.component.ts | 1 + 4 files changed, 4 insertions(+) diff --git a/src/components/details/details.component.ts b/src/components/details/details.component.ts index b7eab446..d8b83a43 100644 --- a/src/components/details/details.component.ts +++ b/src/components/details/details.component.ts @@ -87,6 +87,7 @@ export default class SlDetails extends ShoelaceElement { } disconnectedCallback() { + super.disconnectedCallback(); this.detailsObserver.disconnect(); } diff --git a/src/components/mutation-observer/mutation-observer.component.ts b/src/components/mutation-observer/mutation-observer.component.ts index 61b05ce4..85ed39e7 100644 --- a/src/components/mutation-observer/mutation-observer.component.ts +++ b/src/components/mutation-observer/mutation-observer.component.ts @@ -52,6 +52,7 @@ export default class SlMutationObserver extends ShoelaceElement { } disconnectedCallback() { + super.disconnectedCallback(); this.stopObserver(); } diff --git a/src/components/popup/popup.component.ts b/src/components/popup/popup.component.ts index 3ab4c0d1..f04f0be4 100644 --- a/src/components/popup/popup.component.ts +++ b/src/components/popup/popup.component.ts @@ -198,6 +198,7 @@ export default class SlPopup extends ShoelaceElement { } disconnectedCallback() { + super.disconnectedCallback(); this.stop(); } diff --git a/src/components/tab-group/tab-group.component.ts b/src/components/tab-group/tab-group.component.ts index f1753807..27ecf18a 100644 --- a/src/components/tab-group/tab-group.component.ts +++ b/src/components/tab-group/tab-group.component.ts @@ -117,6 +117,7 @@ export default class SlTabGroup extends ShoelaceElement { } disconnectedCallback() { + super.disconnectedCallback(); this.mutationObserver.disconnect(); this.resizeObserver.unobserve(this.nav); } From 4d3297937afe1cdfe648de2964f1e6f6eb155ab1 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Thu, 14 Sep 2023 12:08:05 -0400 Subject: [PATCH 12/19] fixes #1548 --- docs/pages/resources/changelog.md | 1 + src/components/popup/popup.component.ts | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index 0c6492d7..267f5f30 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -16,6 +16,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti - Fixed a bug in the autoloader causing it to register non-Shoelace elements [#1563] - Fixed a bug in `` that resulted in improper spacing between the label and the required asterisk [#1540] +- Removed error when a missing popup anchor is provided [#1548] - Updated `@ctrl/tinycolor` to 4.0.1 [#1542] - Updated Bootstrap Icons to 1.11.0 diff --git a/src/components/popup/popup.component.ts b/src/components/popup/popup.component.ts index 3ab4c0d1..49c660ac 100644 --- a/src/components/popup/popup.component.ts +++ b/src/components/popup/popup.component.ts @@ -246,13 +246,10 @@ export default class SlPopup extends ShoelaceElement { this.anchorEl = this.anchorEl.assignedElements({ flatten: true })[0] as HTMLElement; } - if (!this.anchorEl) { - throw new Error( - 'Invalid anchor element: no anchor could be found using the anchor slot or the anchor attribute.' - ); + // If the anchor is valid, start it up + if (this.anchorEl) { + this.start(); } - - this.start(); } private start() { From 25dd15b92c58b050c43e1b04396f91df9dc6d6b3 Mon Sep 17 00:00:00 2001 From: Yehuda Ringler Date: Wed, 20 Sep 2023 16:43:26 -0400 Subject: [PATCH 13/19] ONLY-USE: Fix bug: svg url treated as sprite --- docs/pages/resources/changelog.md | 1 + src/components/icon/icon.component.ts | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index 267f5f30..2a03b339 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -19,6 +19,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti - Removed error when a missing popup anchor is provided [#1548] - Updated `@ctrl/tinycolor` to 4.0.1 [#1542] - Updated Bootstrap Icons to 1.11.0 +- Fixed a bug in `` where we load svg URL via `` if the default icon library was changed to be a sprite. ## 2.8.0 diff --git a/src/components/icon/icon.component.ts b/src/components/icon/icon.component.ts index 4f379de9..92415935 100644 --- a/src/components/icon/icon.component.ts +++ b/src/components/icon/icon.component.ts @@ -15,6 +15,11 @@ type SVGResult = HTMLTemplateResult | SVGSVGElement | typeof RETRYABLE_ERROR | t let parser: DOMParser; const iconCache = new Map>(); +interface IconSource { + url?: string; + fromLibrary: boolean; +} + /** * @summary Icons are symbols that can be used to represent various options within an application. * @documentation https://shoelace.style/components/icon @@ -104,12 +109,19 @@ export default class SlIcon extends ShoelaceElement { unwatchIcon(this); } - private getUrl() { + private getUrl(): IconSource { const library = getIconLibrary(this.library); if (this.name && library) { - return library.resolver(this.name); + return { + url: library.resolver(this.name), + fromLibrary: true + }; } - return this.src; + + return { + url: this.src, + fromLibrary: false + }; } @watch('label') @@ -129,8 +141,8 @@ export default class SlIcon extends ShoelaceElement { @watch(['name', 'src', 'library']) async setIcon() { - const library = getIconLibrary(this.library); - const url = this.getUrl(); + const { url, fromLibrary } = this.getUrl(); + const library = fromLibrary ? getIconLibrary(this.library) : undefined; if (!url) { this.svg = null; @@ -154,7 +166,7 @@ export default class SlIcon extends ShoelaceElement { iconCache.delete(url); } - if (url !== this.getUrl()) { + if (url !== this.getUrl().url) { // If the url has changed while fetching the icon, ignore this request return; } From a41e4e89284ae60a4d8661cdd5921a8f0cd15e91 Mon Sep 17 00:00:00 2001 From: mfocqueteau <48293117+mfocqueteau@users.noreply.github.com> Date: Mon, 25 Sep 2023 09:59:51 -0300 Subject: [PATCH 14/19] Fixed typo (Alert doc): "take affect" -> "take effect" (#1578) One of the examples given in the documentation for Alerts says "Settings will take **affect** on next login". Which is a typo since affect is a verb, not a noun. --- docs/pages/components/alert.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pages/components/alert.md b/docs/pages/components/alert.md index a2451e20..9e6b576e 100644 --- a/docs/pages/components/alert.md +++ b/docs/pages/components/alert.md @@ -54,7 +54,7 @@ Set the `variant` attribute to change the alert's variant. Your settings have been updated
- Settings will take affect on next login. + Settings will take effect on next login.

@@ -102,7 +102,7 @@ const App = () => ( Your settings have been updated
- Settings will take affect on next login. + Settings will take effect on next login.
From 24f7b190f748b73642696948b2de4ea39965744a Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Mon, 25 Sep 2023 09:01:24 -0400 Subject: [PATCH 15/19] fix words; #1578 --- docs/pages/components/alert.md | 4 ++-- docs/pages/getting-started/usage.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/pages/components/alert.md b/docs/pages/components/alert.md index 9e6b576e..5ea30cbb 100644 --- a/docs/pages/components/alert.md +++ b/docs/pages/components/alert.md @@ -276,7 +276,7 @@ You should always use the `closable` attribute so users can dismiss the notifica Your settings have been updated
- Settings will take affect on next login. + Settings will take effect on next login.
@@ -361,7 +361,7 @@ const App = () => { Your settings have been updated
- Settings will take affect on next login. + Settings will take effect on next login. diff --git a/docs/pages/getting-started/usage.md b/docs/pages/getting-started/usage.md index 33a2debe..6cf1075d 100644 --- a/docs/pages/getting-started/usage.md +++ b/docs/pages/getting-started/usage.md @@ -208,7 +208,7 @@ Shoelace ships with a file called `vscode.html-custom-data.json` that can be use } ``` -If `settings.json` already exists, simply add the above line to the root of the object. Note that you may need to restart VS Code for the changes to take affect. +If `settings.json` already exists, simply add the above line to the root of the object. Note that you may need to restart VS Code for the changes to take effect. ### JetBrains IDEs From 9b969339a1dda4b40d604a9cc73d253fc6f737d7 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Mon, 25 Sep 2023 09:08:04 -0400 Subject: [PATCH 16/19] fixes #1576 --- docs/pages/components/radio-button.md | 96 +++++++++++++-------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/docs/pages/components/radio-button.md b/docs/pages/components/radio-button.md index c7bea66e..fe161c69 100644 --- a/docs/pages/components/radio-button.md +++ b/docs/pages/components/radio-button.md @@ -87,26 +87,26 @@ const App = () => ( Use the `size` attribute to change a radio button's size. ```html:preview - - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3
- - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3
- - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3 ``` @@ -115,26 +115,26 @@ import SlRadioButton from '@shoelace-style/shoelace/dist/react/radio-button'; import SlRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group'; const App = () => ( - - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3
- - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3
- - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3 ); ``` @@ -144,26 +144,26 @@ const App = () => ( Use the `pill` attribute to give radio buttons rounded edges. ```html:preview - - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3
- - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3
- - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3 ``` @@ -172,26 +172,26 @@ import SlRadioButton from '@shoelace-style/shoelace/dist/react/radio-button'; import SlRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group'; const App = () => ( - - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3
- - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3
- - Option 1 - Option 2 - Option 3 + + Option 1 + Option 2 + Option 3 ); ``` From cbd43367739290082ace0259e5e224ed063d1b06 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Tue, 26 Sep 2023 08:50:11 -0400 Subject: [PATCH 17/19] add support for external modals; fixes #1571 (#1575) --- docs/pages/resources/changelog.md | 1 + src/components/dialog/dialog.component.ts | 6 ++++- src/components/drawer/drawer.component.ts | 6 ++++- src/internal/modal.ts | 30 ++++++++++++++++------- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index 267f5f30..e5bf9479 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -14,6 +14,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti ## Next +- Added the `modal` property to `` and `` to support third-party modals [#1571] - Fixed a bug in the autoloader causing it to register non-Shoelace elements [#1563] - Fixed a bug in `` that resulted in improper spacing between the label and the required asterisk [#1540] - Removed error when a missing popup anchor is provided [#1548] diff --git a/src/components/dialog/dialog.component.ts b/src/components/dialog/dialog.component.ts index 7e708db1..30afa3d5 100644 --- a/src/components/dialog/dialog.component.ts +++ b/src/components/dialog/dialog.component.ts @@ -60,6 +60,10 @@ import type { CSSResultGroup } from 'lit'; * @animation dialog.denyClose - The animation to use when a request to close the dialog is denied. * @animation dialog.overlay.show - The animation to use when showing the dialog's overlay. * @animation dialog.overlay.hide - The animation to use when hiding the dialog's overlay. + * + * @property modal - Exposes the internal modal utility that controls focus trapping. To temporarily disable focus + * trapping and allow third-party modals spawned from an active Shoelace modal, call `modal.activateExternal()` when + * the third-party modal opens. Upon closing, call `modal.deactivateExternal()` to restore Shoelace's focus trapping. */ export default class SlDialog extends ShoelaceElement { static styles: CSSResultGroup = styles; @@ -69,8 +73,8 @@ export default class SlDialog extends ShoelaceElement { private readonly hasSlotController = new HasSlotController(this, 'footer'); private readonly localize = new LocalizeController(this); - private modal = new Modal(this); private originalTrigger: HTMLElement | null; + public modal = new Modal(this); @query('.dialog') dialog: HTMLElement; @query('.dialog__panel') panel: HTMLElement; diff --git a/src/components/drawer/drawer.component.ts b/src/components/drawer/drawer.component.ts index 6ce9e885..d3a84171 100644 --- a/src/components/drawer/drawer.component.ts +++ b/src/components/drawer/drawer.component.ts @@ -68,6 +68,10 @@ import type { CSSResultGroup } from 'lit'; * @animation drawer.denyClose - The animation to use when a request to close the drawer is denied. * @animation drawer.overlay.show - The animation to use when showing the drawer's overlay. * @animation drawer.overlay.hide - The animation to use when hiding the drawer's overlay. + * + * @property modal - Exposes the internal modal utility that controls focus trapping. To temporarily disable focus + * trapping and allow third-party modals spawned from an active Shoelace modal, call `modal.activateExternal()` when + * the third-party modal opens. Upon closing, call `modal.deactivateExternal()` to restore Shoelace's focus trapping. */ export default class SlDrawer extends ShoelaceElement { static styles: CSSResultGroup = styles; @@ -75,8 +79,8 @@ export default class SlDrawer extends ShoelaceElement { private readonly hasSlotController = new HasSlotController(this, 'footer'); private readonly localize = new LocalizeController(this); - private modal = new Modal(this); private originalTrigger: HTMLElement | null; + public modal = new Modal(this); @query('.drawer') drawer: HTMLElement; @query('.drawer__panel') panel: HTMLElement; diff --git a/src/internal/modal.ts b/src/internal/modal.ts index 680a0e97..40128393 100644 --- a/src/internal/modal.ts +++ b/src/internal/modal.ts @@ -5,6 +5,7 @@ let activeModals: HTMLElement[] = []; export default class Modal { element: HTMLElement; + isExternalActivated: boolean; tabDirection: 'forward' | 'backward' = 'forward'; currentFocus: HTMLElement | null; @@ -12,6 +13,7 @@ export default class Modal { this.element = element; } + /** Activates focus trapping. */ activate() { activeModals.push(this.element); document.addEventListener('focusin', this.handleFocusIn); @@ -19,6 +21,7 @@ export default class Modal { document.addEventListener('keyup', this.handleKeyUp); } + /** Deactivates focus trapping. */ deactivate() { activeModals = activeModals.filter(modal => modal !== this.element); this.currentFocus = null; @@ -27,13 +30,24 @@ export default class Modal { document.removeEventListener('keyup', this.handleKeyUp); } + /** Determines if this modal element is currently active or not. */ isActive() { // The "active" modal is always the most recent one shown return activeModals[activeModals.length - 1] === this.element; } - checkFocus() { - if (this.isActive()) { + /** Activates external modal behavior and temporarily disables focus trapping. */ + activateExternal() { + this.isExternalActivated = true; + } + + /** Deactivates external modal behavior and re-enables focus trapping. */ + deactivateExternal() { + this.isExternalActivated = false; + } + + private checkFocus() { + if (this.isActive() && !this.isExternalActivated) { const tabbableElements = getTabbableElements(this.element); if (!this.element.matches(':focus-within')) { const start = tabbableElements[0]; @@ -56,11 +70,9 @@ export default class Modal { return getTabbableElements(this.element).findIndex(el => el === this.currentFocus); } - /** - * Checks if the `startElement` is already focused. This is important if the modal already - * has an existing focus prior to the first tab key. - */ - startElementAlreadyFocused(startElement: HTMLElement) { + // Checks if the `startElement` is already focused. This is important if the modal already has an existing focus prior + // to the first tab key. + private startElementAlreadyFocused(startElement: HTMLElement) { for (const activeElement of activeElements()) { if (startElement === activeElement) { return true; @@ -70,8 +82,8 @@ export default class Modal { return false; } - handleKeyDown = (event: KeyboardEvent) => { - if (event.key !== 'Tab') return; + private handleKeyDown = (event: KeyboardEvent) => { + if (event.key !== 'Tab' || this.isExternalActivated) return; if (event.shiftKey) { this.tabDirection = 'backward'; From c9f810ac3efd4c308783874086ab5535a413b08a Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Tue, 26 Sep 2023 09:05:17 -0400 Subject: [PATCH 18/19] rename private var; #1572 --- src/components/icon/icon.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/icon/icon.component.ts b/src/components/icon/icon.component.ts index 92415935..542ede6e 100644 --- a/src/components/icon/icon.component.ts +++ b/src/components/icon/icon.component.ts @@ -109,7 +109,7 @@ export default class SlIcon extends ShoelaceElement { unwatchIcon(this); } - private getUrl(): IconSource { + private getIconSource(): IconSource { const library = getIconLibrary(this.library); if (this.name && library) { return { @@ -141,7 +141,7 @@ export default class SlIcon extends ShoelaceElement { @watch(['name', 'src', 'library']) async setIcon() { - const { url, fromLibrary } = this.getUrl(); + const { url, fromLibrary } = this.getIconSource(); const library = fromLibrary ? getIconLibrary(this.library) : undefined; if (!url) { @@ -166,7 +166,7 @@ export default class SlIcon extends ShoelaceElement { iconCache.delete(url); } - if (url !== this.getUrl().url) { + if (url !== this.getIconSource().url) { // If the url has changed while fetching the icon, ignore this request return; } From ed7949261e566552d87d72229134c5e2af65564a Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Tue, 26 Sep 2023 09:06:48 -0400 Subject: [PATCH 19/19] update changelog --- docs/pages/resources/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index 25d3ce9b..b9f57b57 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -17,10 +17,10 @@ New versions of Shoelace are released as-needed and generally occur when a criti - Added the `modal` property to `` and `` to support third-party modals [#1571] - Fixed a bug in the autoloader causing it to register non-Shoelace elements [#1563] - Fixed a bug in `` that resulted in improper spacing between the label and the required asterisk [#1540] +- Fixed a bug in `` that caused icons to not load when the default library used a sprite [#1572] - Removed error when a missing popup anchor is provided [#1548] - Updated `@ctrl/tinycolor` to 4.0.1 [#1542] - Updated Bootstrap Icons to 1.11.0 -- Fixed a bug in `` where we load svg URL via `` if the default icon library was changed to be a sprite. ## 2.8.0