Skip to content

Commit

Permalink
fix(icon)!: remove getIconUrl for webpack's sake (#2766)
Browse files Browse the repository at this point in the history
* fix(icon)!: remove getIconUrl for webpack's sake

* test(icon): refactor tests

* chore: update icons

* docs(icon): fix custom sets demo

* chore: update rhds dep
  • Loading branch information
bennypowers authored Jun 25, 2024
1 parent 6d5743f commit 7901999
Show file tree
Hide file tree
Showing 10 changed files with 335 additions and 262 deletions.
34 changes: 34 additions & 0 deletions .changeset/dirty-bears-win.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
"@patternfly/elements": major
---
`<pf-icon>`: removed the `getIconUrl` static method, and replaced it with the
`resolve` static method

The steps for overriding icon loading behaviour have changed. Before, you had to
return a string from the `getIconUrl` method, or the second argument to
`addIconSet`. Now, both of those functions must return a Node, or any lit-html
renderable value, or a Promise thereof.

BEFORE:

```js
PfIcon.addIconSet('local', (set, icon) =>
new URL(`/assets/icons/${set}-${icon}.js`));

// or
PfIcon.getIconUrl = (set, icon) =>
new URL(`/assets/icons/${set}-${icon}.js`))
```

AFTER
```js
PfIcon.addIconSet('local', (set, icon) =>
import(`/assets/icons/${set}-${icon}.js`))
.then(mod => mod.default);

// or
PfIcon.resolve = (set, icon) =>
import(`/assets/icons/${set}-${icon}.js`))
.then(mod => mod.default);
```

4 changes: 4 additions & 0 deletions .changeset/fresh-shrimps-work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
"@patternfly/elements": major
---
`<pf-icon>`: removed the `defaultIconSet` static field.
2 changes: 1 addition & 1 deletion elements/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
],
"dependencies": {
"@lit/context": "^1.1.0",
"@patternfly/icons": "^1.0.2",
"@patternfly/icons": "^1.0.3",
"@patternfly/pfe-core": "^3.0.0",
"lit": "^3.1.2",
"tslib": "^2.6.2"
Expand Down
33 changes: 24 additions & 9 deletions elements/pf-icon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Icon comes with three built-in icon sets:

1. `fas`: Font Awesome Free Solid icons (the default set)
1. `far`: Font Awesome Free Regular icons
1. `fab`: Font Awesome Free Bold icons
1. `patternfly`: PatternFly icons

Use the `set` attribute to pick an alternative icon set.
Expand All @@ -61,19 +62,31 @@ Use the `set` attribute to pick an alternative icon set.
It is possible to add custom icon sets or override the default sets.
Icon sets are defined in detail in [the docs][icon-sets].

### Bundling
### Bundling and custom loading behaviour

When bundling PfIcon with other modules, the default icon imports will be
relative to the bundle, not the source file, so be sure to either register all
the icon sets you'll need, or override the default getter.
When bundling `<pf-icon>` with other modules (e.g. using webpack, rollup,
esbuild, vite, or similar tools), icon imports will be code-split into chunks,
as they are imported from the `@patternfly/icons` package. Ensure that your
bundler is configured to permit dynamic imports, or mark the `@patternfly/icons`
package as "external" and apply an [import map][importmap] to your page instead.
If you would like to
customize the loading behaviour, override the `PfIcon.resolve()` static method.
This methods takes two arguments: the icon set (a string) and the icon name
(a string), and returns a promise of the icon contents, which is a DOM node, or
[anything else that lit-html can render][renderable].

```js
// Workaround for bundled pf-icon: make icon imports absolute, instead of
relative to the bundle
import { PfIcon } from '/pfe.min.js';
PfIcon.getIconUrl = (set, icon) =>
new URL(`/assets/icons/${set}/${icon}.js`, import.meta.url);
// default: new URL(`./icons/${set}/${icon}.js`, import.meta.url);
PfIcon.resolve = async function(set, icon) {
try {
const { default: content } = await import(`/assets/icons/${set}/${icon}.js`);
if (content instanceof Node) {
return content.cloneNode(true);
}
} catch (e) {
return '';
}
}
```

## Loading
Expand All @@ -84,3 +97,5 @@ see the [docs][docs] for more info.

[docs]: https://patternflyelements.org/components/icon/
[icon-sets]: https://patternflyelements.org/components/icon/#icon-sets
[renderable]: https://lit.dev/docs/components/rendering/#renderable-values
[importmap]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap
10 changes: 6 additions & 4 deletions elements/pf-icon/demo/custom-icon-sets.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ <h3>Custom Icon Sets</h3>
```
```js
import { PfIcon } from '@patternfly/elements/pf-icon/pf-icon.js';
PfIcon.addIconSet('rh', (set, icon) =>
new URL(`./icons/${set}/${icon}.js`, import.meta.url));
PfIcon.addIconSet('rh', async (set, icon) =>
import(`./icons/${set}/${icon}.js`)
.then(mod => mod.default));
```
</script>
</zero-md>
Expand All @@ -25,8 +26,9 @@ <h3>Custom Icon Sets</h3>
<script type="module">
import 'zero-md';
import { PfIcon } from '@patternfly/elements/pf-icon/pf-icon.js';
PfIcon.addIconSet('rh', (set, icon) =>
new URL(`../icons/${set}/${icon}.js`, import.meta.url));
PfIcon.addIconSet('rh', async (set, icon) =>
import(`../icons/${set}/${icon}.js`)
.then(mod => mod.default));
</script>

<style>
Expand Down
23 changes: 10 additions & 13 deletions elements/pf-icon/docs/pf-icon.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ Icons are JavaScript module which export a [lit renderable][renderable],
typically an inline SVG element [template literal][template-literals] tagged
with the Lit [`svg`][svg-tag] template tag. To register a new icon set, call
the static `addIconSet` method with the set name and a getter function. The
getter function takes the icon set and icon name and returns a URL object or a
string that points to the icon's JavaScript module.
getter function takes the icon set and icon name and returns a promise containing
the icon node, or any other [renderable][renderable] value.

```ts
type getter = (set: string, icon: string) => URL | string
type IconResolveFunction = (set: string, icon: string) => Promise<Node> | Node;
```

```javascript
Expand All @@ -74,7 +74,8 @@ import { PfIcon } from '@patternfly/pf-icon';
// const PfIcon = await customElements.whenDefined('pf-icon');

PfIcon.addIconSet('local', (set, icon) =>
new URL(`/assets/icons/${set}-${icon}.js`));
import(`/assets/icons/${set}-${icon}.js`))
.then(mod => mod.default);
```

### Updating an Existing Icon Set
Expand All @@ -89,7 +90,8 @@ PfIcon.addIconSet('patternfly', (set, icon) => {
// add your custom icons
case 'my-custom-icon':
case 'other-custom-icon':
return new URL(`/icons/patternfly-custom/${icon}.js`, window.location.href);
return import(`/icon-overrides/patternfly-custom/${icon}.js`)
.then(mod => mod.default);
// fall back to built-in icons
default:
return PfIcon.getIconUrl(set, icon);
Expand All @@ -107,14 +109,9 @@ like to override the default icon sets across the entire page, you can use
```js
import { PfIcon } from '@patternfly/pf-icon';

PfIcon.getIconUrl = (set, icon) =>
new URL(`/icons/js/${set}/${icon}.js`, 'https://static.redhat.com');
```

To change the default set name, you can also override `PfIcon.defaultIconSet`

```js
PfIcon.defaultIconSet = 'patternfly';
PfIcon.resolve = (set, icon) =>
import(`/icons/${set}-${icon}.js`))
.then(mod => mod.default);
```

Now when `<pf-icon>` is loaded from the [RedHat DX
Expand Down
Loading

0 comments on commit 7901999

Please sign in to comment.