Skip to content

Commit 56d76f4

Browse files
authored
[icons] fix: restore transform-origin in static component markup (#6639)
1 parent 46a34ca commit 56d76f4

File tree

10 files changed

+39
-27
lines changed

10 files changed

+39
-27
lines changed

packages/core/src/components/icon/_icon.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
/* stylelint-enable */
2525
}
2626

27+
// TOOD: move to SVGIconContainer styles in @blueprintjs/icons in v6.0
2728
> svg {
2829
// prevent extra vertical whitespace
2930
display: block;
@@ -59,6 +60,8 @@
5960
//
6061
// Icon font styles
6162
//
63+
// TOOD: move to @blueprintjs/icons in v6.0
64+
//
6265

6366
span.#{$ns}-icon-standard {
6467
@include pt-icon($pt-icon-size-standard);

packages/core/src/components/icon/icon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ export const Icon: IconComponent = React.forwardRef(function <T extends Element>
193193
return (
194194
<SVGIconContainer<any>
195195
children={pathElements}
196-
// don't forward Classes.iconClass(icon) here, since the container will render that class
196+
// don't forward `Classes.ICON` or `Classes.iconClass(icon)` here, since the container will render those classes
197197
className={classNames(Classes.intentClass(intent), className)}
198198
color={color}
199199
htmlTitle={htmlTitle}

packages/docs-app/src/blueprint.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ The following example shows an `index.html` file; the same stylesheets should be
5252

5353
```html
5454
<link href="path/to/node_modules/normalize.css/normalize.css" rel="stylesheet" />
55-
<!-- blueprint-icons.css file must be included alongside blueprint.css! -->
56-
<link href="path/to/node_modules/@blueprintjs/icons/lib/css/blueprint-icons.css" rel="stylesheet" />
5755
<link href="path/to/node_modules/@blueprintjs/core/lib/css/blueprint.css" rel="stylesheet" />
56+
<!-- blueprint-icons.css file must be included alongside blueprint.css for icon font support -->
57+
<link href="path/to/node_modules/@blueprintjs/icons/lib/css/blueprint-icons.css" rel="stylesheet" />
5858
<!-- add other blueprint-*.css files here -->
5959
```
6060

packages/docs-app/src/getting-started.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,28 @@ The JavaScript components are stable and their APIs adhere to [semantic versioni
3232
contains supporting media such as fonts and images.
3333
3434
```scss
35-
// using node-style package resolution in a CSS file:
35+
// using Node.js-style package resolution in a CSS file:
3636
@import "normalize.css";
3737
@import "@blueprintjs/core/lib/css/blueprint.css";
38+
// include blueprint-icons.css for icon font support
3839
@import "@blueprintjs/icons/lib/css/blueprint-icons.css";
3940
```
4041
42+
```ts
43+
// or using a ESM bundler which resolves CSS files as modules:
44+
import "normalize.css";
45+
import "@blueprintjs/core/lib/css/blueprint.css";
46+
// include blueprint-icons.css for icon font support
47+
import "@blueprintjs/icons/lib/css/blueprint-icons.css";
48+
```
49+
4150
```html
4251
<!-- or using plain old HTML -->
4352
<head>
44-
<!-- include dependencies manually -->
4553
<link href="path/to/node_modules/normalize.css/normalize.css" rel="stylesheet" />
4654
<link href="path/to/node_modules/@blueprintjs/core/lib/css/blueprint.css" rel="stylesheet" />
55+
<!-- include blueprint-icons.css for icon font support -->
4756
<link href="path/to/node_modules/@blueprintjs/icons/lib/css/blueprint-icons.css" rel="stylesheet" />
48-
<!-- NOTE: blueprint-icons.css file must be included alongside blueprint.css! -->
4957
</head>
5058
```
5159

packages/icons/scripts/generate-icon-components.mjs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,19 @@ import { parse } from "svg-parser";
3030
import { generatedSrcDir, ICON_RASTER_SCALING_FACTOR, ICON_SIZES, scriptsDir } from "./common.mjs";
3131

3232
Handlebars.registerHelper("pascalCase", iconName => pascalCase(iconName));
33+
34+
/**
35+
* Notes on icon component template implementation:
36+
*
37+
* The components rendered by this template (`<AddClip>`, `<Calendar>`, etc.) rely on a centered scale `transform` to
38+
* display their SVG paths correctly.
39+
*
40+
* In this template, the `<path>` element applies `transform-origin` using the `style` attribute rather than
41+
* `transformOrigin`. Although `trasformOrigin` was added as a supported SVG attribute to React in 2023,
42+
* it is still difficult to use without compile-time and/or runtime errors, see:
43+
* - https://github.com/facebook/react/pull/26130
44+
* - https://github.com/palantir/blueprint/issues/6591
45+
*/
3346
const iconComponentTemplate = Handlebars.compile(readFileSync(resolve(scriptsDir, "iconComponent.tsx.hbs"), "utf8"));
3447
const componentsIndexTemplate = Handlebars.compile(readFileSync(resolve(scriptsDir, "componentsIndex.ts.hbs"), "utf8"));
3548
const indexTemplate = Handlebars.compile(readFileSync(resolve(scriptsDir, "index.ts.hbs"), "utf8"));

packages/icons/scripts/iconComponent.tsx.hbs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2021 Palantir Technologies, Inc. All rights reserved.
2+
* Copyright 2024 Palantir Technologies, Inc. All rights reserved.
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
55
* You may obtain a copy of the License at
@@ -22,15 +22,17 @@ export const {{pascalCase iconName}}: React.FC<SVGIconProps> = React.forwardRef<
2222
const isLarge = props.size! >= IconSize.LARGE;
2323
const pixelGridSize = isLarge ? IconSize.LARGE : IconSize.STANDARD;
2424
const translation = `${-1 * pixelGridSize / {{pathScaleFactor}} / 2}`;
25+
const style = { transformOrigin: "center" };
2526
return (
2627
<SVGIconContainer iconName="{{iconName}}" ref={ref} {...props}>
2728
<path
2829
d={isLarge ? "{{icon20pxPath}}" : "{{icon16pxPath}}"}
2930
fillRule="evenodd"
3031
transform={`scale({{pathScaleFactor}}, -{{pathScaleFactor}}) translate(${translation}, ${translation})`}
32+
style={style}
3133
/>
3234
</SVGIconContainer>
33-
)
35+
);
3436
});
3537
{{pascalCase iconName}}.defaultProps = {
3638
size: IconSize.STANDARD,

packages/icons/src/blueprint-icons.scss

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,3 @@ Licensed under the Apache License, Version 2.0.
55

66
@import "generated/16px/blueprint-icons-16";
77
@import "generated/20px/blueprint-icons-20";
8-
9-
/* stylelint-disable-next-line @blueprintjs/no-prefix-literal -- we don't have access to core variables in this file */
10-
.bp5-icon-svg {
11-
// Despite being added to added as a supported SVG attribute to React in 2023, the `transformOrigin` JSX attribute
12-
// is still difficult to use in our statically-generated icon components (`<AddClip>`, `<Calendar>`, etc.)
13-
// which rely on a centered scale `transform="..."` to display their `<path>` elements correctly. To work around
14-
// this, we apply the necessary style in CSS instead. Note that this needs to apply directly to the `<path>` element
15-
// and not the container `<svg>`. See:
16-
// - https://github.com/facebook/react/pull/26130
17-
// - https://github.com/palantir/blueprint/issues/6591
18-
path {
19-
transform-origin: center;
20-
}
21-
}

packages/icons/src/classes.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,3 @@
1515

1616
const NS = "bp5";
1717
export const ICON = `${NS}-icon`;
18-
export const ICON_SVG = `${ICON}-svg`;

packages/icons/src/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ reference: icons
55
@# Icons
66

77
The [**@blueprintjs/icons** NPM package](https://www.npmjs.com/package/@blueprintjs/icons)
8-
provides provides over 500 vector UI icons in two sizes (16px and 20px) and two formats (SVG and fonts).
8+
provides over 500 vector UI icons in two sizes (16px and 20px) and two formats (SVG and fonts).
99

1010
<div class="@ns-callout @ns-intent-primary @ns-icon-info-sign">
1111

@@ -17,7 +17,7 @@ See the [**`Icon` component documentation**](#core/components/icon) (in the `@bl
1717
npm install --save @blueprintjs/icons
1818
```
1919

20-
Import CSS with a bundler like webpack:
20+
For icon font support, import CSS with a bundler like webpack:
2121

2222
```js
2323
@import "@blueprintjs/icons/lib/css/blueprint-icons.css";

packages/icons/src/svgIconContainer.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,14 @@ export const SVGIconContainer: SVGIconContainerComponent = React.forwardRef(func
8484
ref={ref as React.Ref<SVGSVGElement>}
8585
{...sharedSvgProps}
8686
{...htmlProps}
87-
className={classNames(Classes.ICON_SVG, className, svgProps?.className)}
87+
className={classNames(className, svgProps?.className)}
8888
>
8989
{title && <title id={titleId}>{title}</title>}
9090
{children}
9191
</svg>
9292
);
9393
} else {
94+
// N.B. styles for `Classes.ICON` are defined in @blueprintjs/core in `_icon.scss`
9495
return React.createElement(
9596
tagName,
9697
{
@@ -100,7 +101,7 @@ export const SVGIconContainer: SVGIconContainerComponent = React.forwardRef(func
100101
ref,
101102
title: htmlTitle,
102103
},
103-
<svg data-icon={iconName} {...sharedSvgProps} className={classNames(Classes.ICON_SVG, svgProps?.className)}>
104+
<svg data-icon={iconName} {...sharedSvgProps} className={svgProps?.className}>
104105
{title && <title>{title}</title>}
105106
{children}
106107
</svg>,

0 commit comments

Comments
 (0)