Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,6 @@
"outputs": ["{projectRoot}/lib"],
"cache": true
},
"copy:scss": {
"outputs": ["{projectRoot}/lib/scss"],
"cache": true
},
"copy:fonts": {
"outputs": ["{projectRoot}/lib/css"],
"cache": true
},
"generate-icon-src": {
"outputs": ["{projectRoot}/src/generated"],
"cache": true
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/components/breadcrumbs/_breadcrumbs.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2016 Palantir Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0.

@import "@blueprintjs/icons/lib/scss/variables";
@import "../../common/variables";

.#{$ns}-breadcrumbs {
Expand Down
16 changes: 0 additions & 16 deletions packages/core/src/components/callout/_callout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,6 @@ $callout-padding-compact: $pt-spacing * 2;
background-color: rgba($gray3, 0.15);
}

// CSS API support
&[class*="#{$ns}-icon-"] {
padding-left: $callout-padding + $pt-icon-size-standard + ($pt-spacing * 2);

&::before {
@include pt-icon($pt-icon-size-standard);
color: $pt-icon-color;
left: $callout-padding;
position: absolute;
top: $callout-padding + $callout-header-margin-top;
}
}

// High contrast mode hides backgrounds, so we need to use a border instead
@media (forced-colors: active) and (prefers-color-scheme: dark) {
border: 1px solid $pt-high-contrast-mode-border-color;
Expand Down Expand Up @@ -78,7 +65,6 @@ $callout-padding-compact: $pt-spacing * 2;
background-color: rgba($gray3, 0.2);
}

&[class*="#{$ns}-icon-"]::before,
&.#{$ns}-callout-icon > .#{$ns}-icon:first-child {
color: $pt-dark-icon-color;
}
Expand All @@ -96,7 +82,6 @@ $callout-padding-compact: $pt-spacing * 2;
border: 1px solid $pt-high-contrast-mode-border-color;
}

&[class*="#{$ns}-icon-"]::before,
> .#{$ns}-icon:first-child,
.#{$ns}-heading {
color: map.get($pt-intent-text-colors, $intent);
Expand All @@ -109,7 +94,6 @@ $callout-padding-compact: $pt-spacing * 2;
background-color: rgba($color, 0.2);
}

&[class*="#{$ns}-icon-"]::before,
> .#{$ns}-icon:first-child,
.#{$ns}-heading {
color: map.get($pt-dark-intent-text-colors, $intent);
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/components/dialog/_dialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.

@use "sass:math";
@import "@blueprintjs/icons/lib/scss/variables";
@import "../../common/mixins";
@import "../../common/react-transition";
@import "../../common/variables";
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/components/dialog/_multistep-dialog.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2020 Palantir Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0.

@import "@blueprintjs/icons/lib/scss/variables";
@import "../../common/mixins";
@import "../../common/react-transition";
@import "../../common/variables";
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/components/drawer/_drawer.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2018 Palantir Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0.

@import "@blueprintjs/icons/lib/scss/variables";
@import "../../common/mixins";
@import "../../common/react-transition";
@import "../../common/variables";
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/components/forms/_common.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2015 Palantir Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0.

@import "@blueprintjs/icons/lib/scss/variables";
@import "../../common/variables";
@import "../button/common";

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/forms/_input-group.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ $input-button-height-small: $pt-button-height-smaller !default;
color: $pt-icon-color;

&:empty {
@include pt-icon($pt-icon-size-standard);
@include pt-icon-sized($pt-icon-size-standard);
}
}

Expand Down
21 changes: 3 additions & 18 deletions packages/core/src/components/icon/_icon-mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,10 @@

@import "@blueprintjs/colors/lib/scss/colors";

@mixin pt-icon-font-smoothing() {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
}

@mixin pt-icon-sized(
$font-size: $pt-icon-size-standard,
$font-family-size: strip-unit($font-size)
) {
font-family: "blueprint-icons-#{$font-family-size}", sans-serif;
@mixin pt-icon-sized($font-size: $pt-icon-size-standard) {
font-size: $font-size;
font-style: normal;
font-variant: normal;
font-weight: 400;
height: $font-size;
line-height: 1;
// We explicitly add dimensions here so that icon elements have proper sizing before their icon paths are loaded;
// this is useful (for example) to ensure that OverflowList takes proper measurements when partitioning on mount.
width: $font-size;
}

Expand All @@ -40,7 +26,6 @@
}
}

@mixin pt-icon($font-size: $pt-icon-size-standard, $font-family-size: strip-unit($font-size)) {
@include pt-icon-sized($font-size, $font-family-size);
@include pt-icon-font-smoothing;
@mixin pt-icon($font-size: $pt-icon-size-standard) {
@include pt-icon-sized($font-size);
}
38 changes: 2 additions & 36 deletions packages/core/src/components/icon/_icon.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2015 Palantir Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0.

@import "@blueprintjs/icons/lib/scss/variables";
@import "../../common/variables";
@import "../../common/variables-extended";
@import "icon-mixins";
Expand Down Expand Up @@ -57,45 +56,12 @@

// intent colors for both SVG and font icons are set in _typography-colors.scss

//
// Icon font styles
//
// TOOD: move to @blueprintjs/icons in v6.0
//

span.#{$ns}-icon-standard {
@include pt-icon($pt-icon-size-standard);
@include pt-icon-sized($pt-icon-size-standard);
display: inline-block;
}

span.#{$ns}-icon-large {
@include pt-icon($pt-icon-size-large);
@include pt-icon-sized($pt-icon-size-large);
display: inline-block;
}

// only apply icon font styles when <svg> image is not present
span.#{$ns}-icon:empty {
font-family: $blueprint-icons-20-font;
font-size: inherit;
font-style: normal;
font-weight: 400;
line-height: 1;

&::before {
@include pt-icon-font-smoothing;
}

&.#{$ns}-icon-standard {
font-size: $pt-icon-size-standard;
}

&.#{$ns}-icon-large {
font-size: $pt-icon-size-large;
}
}

@each $name, $codepoint in $blueprint-icon-codepoints {
.#{$ns}-icon-#{$name}::before {
content: $codepoint;
}
}
34 changes: 2 additions & 32 deletions packages/core/src/components/icon/icon.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ See the [**Icons package**](#icons) for a searchable list of all available UI ic
import { Icon } from "@blueprintjs/core";
```

Blueprint provides icons in two formats (SVG and fonts). It's easy to change their color
Blueprint provides icons as SVGs. It's easy to change their color
or apply effects like text shadows via standard SVG or CSS properties.

This section describes two ways of using Blueprint's UI icons:
via the `Icon` component to render SVG images or via CSS classes to use the icon font.
This section describes using Blueprint's UI icons via the `Icon` component to render SVG images.

Many Blueprint components provide an `icon` prop which accepts an icon name
(such as `"history"`) or a JSX element to use as the icon. When you specify
Expand Down Expand Up @@ -139,32 +138,3 @@ Note that some `<Icon>` props are not yet supported for these components, such a

@interface DefaultSVGIconProps

## CSS API

The CSS-only icons API uses the **icon fonts** from the **@blueprintjs/icons** package.
Note that _none of Blueprint's React components use the icon font_; it is only provided
for convenience to Blueprint consumers for rare situations where an icon font may be
preferred over icon SVGs.

To use Blueprint UI icons via CSS, you must apply two classes to a `<span>` element:

- a **sizing class**, either `@ns-icon-standard` (16px) or `@ns-icon-large` (20px)
- an **icon name class**, such as `@ns-icon-projects`

Icon classes also support the four `.@ns-intent-*` modifiers to color the image.

```html
<span class="@ns-icon-{{size}} @ns-icon-{{name}}"></span>

<span class="@ns-icon-standard @ns-icon-projects"></span>
<span class="@ns-icon-large @ns-icon-geosearch @ns-intent-success"></span>
```

<div class="@ns-callout @ns-intent-primary @ns-icon-info-sign @ns-callout-has-body-content">
<h5 class="@ns-heading">Non-standard sizes</h5>

Generally, font icons should only be used at either 16px or 20px. However, if a non-standard size is
necessary, set a `font-size` that is whole multiple of 16 or 20 with the relevant size class.
You can instead use the class `@ns-icon` to make the icon inherit its size from surrounding text.

</div>
75 changes: 27 additions & 48 deletions packages/core/src/components/icon/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import classNames from "classnames";
import { createElement, forwardRef, useEffect, useState } from "react";
import { forwardRef, useEffect, useState } from "react";

import {
type DefaultSVGIconProps,
Expand All @@ -39,6 +39,8 @@ import {
// re-export for convenience, since some users won't be importing from or have a direct dependency on the icons package
export { type IconName, IconSize };

const EMPTY_ICON_PATHS: IconPaths = [];

export interface IconOwnProps {
/**
* Whether the component should automatically load icon contents using an async import.
Expand Down Expand Up @@ -117,8 +119,8 @@ export const Icon: IconComponent = forwardRef(<T extends Element>(props: IconPro

const size = props.size ?? IconSize.STANDARD;

const [iconPaths, setIconPaths] = useState<IconPaths | undefined>(() =>
typeof icon === "string" ? Icons.getPaths(icon, size) : undefined,
const [iconPaths, setIconPaths] = useState<IconPaths>(() =>
typeof icon === "string" ? (Icons.getPaths(icon, size) ?? EMPTY_ICON_PATHS) : EMPTY_ICON_PATHS,
);

useEffect(() => {
Expand All @@ -137,7 +139,7 @@ export const Icon: IconComponent = forwardRef(<T extends Element>(props: IconPro
.then(() => {
// if this effect expired by the time icon loaded, then don't set state
if (!shouldCancelIconLoading) {
setIconPaths(Icons.getPaths(icon, size));
setIconPaths(Icons.getPaths(icon, size) ?? EMPTY_ICON_PATHS);
}
})
.catch(reason => {
Expand All @@ -160,49 +162,26 @@ export const Icon: IconComponent = forwardRef(<T extends Element>(props: IconPro
return icon;
}

if (iconPaths == null) {
// fall back to icon font if unloaded or unable to load SVG implementation
const sizeClass =
size === IconSize.STANDARD
? Classes.ICON_STANDARD
: size === IconSize.LARGE
? Classes.ICON_LARGE
: undefined;
return createElement(tagName || "span", {
"aria-hidden": title ? undefined : true,
...removeNonHTMLProps(htmlProps),
className: classNames(
Classes.ICON,
sizeClass,
Classes.iconClass(icon),
Classes.intentClass(intent),
className,
),
"data-icon": icon,
ref,
title: htmlTitle,
});
} else {
const pathElements = iconPaths.map((d, i) => <path d={d} key={i} fillRule="evenodd" />);
// HACKHACK: there is no good way to narrow the type of SVGIconContainerProps here because of the use
// of a conditional type within the type union that defines that interface. So we cast to <any>.
// see https://github.com/microsoft/TypeScript/issues/24929, https://github.com/microsoft/TypeScript/issues/33014
return (
<SVGIconContainer<any>
children={pathElements}
// don't forward `Classes.ICON` or `Classes.iconClass(icon)` here, since the container will render those classes
className={classNames(Classes.intentClass(intent), className)}
color={color}
htmlTitle={htmlTitle}
iconName={icon}
ref={ref}
size={size}
svgProps={svgProps}
tagName={tagName}
title={title}
{...removeNonHTMLProps(htmlProps)}
/>
);
}
const pathElements = iconPaths.map((d, i) => <path d={d} key={i} fillRule="evenodd" />);

// HACKHACK: there is no good way to narrow the type of SVGIconContainerProps here because of the use
// of a conditional type within the type union that defines that interface. So we cast to <any>.
// see https://github.com/microsoft/TypeScript/issues/24929, https://github.com/microsoft/TypeScript/issues/33014
return (
<SVGIconContainer<any>
children={pathElements}
// don't forward `Classes.ICON` or `Classes.iconClass(icon)` here, since the container will render those classes
className={classNames(Classes.intentClass(intent), className)}
color={color}
htmlTitle={htmlTitle}
iconName={icon}
ref={ref}
size={size}
svgProps={svgProps}
tagName={tagName}
title={title}
{...removeNonHTMLProps(htmlProps)}
/>
);
});
Icon.displayName = `${DISPLAYNAME_PREFIX}.Icon`;
5 changes: 2 additions & 3 deletions packages/core/src/components/menu/_menu.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.

@import "../../common/variables";
@import "@blueprintjs/icons/lib/scss/variables";
@import "../../common/mixins";

@import "./common";
Expand Down Expand Up @@ -32,15 +31,15 @@

&::before {
// support pt-icon-* classes directly on this element
@include pt-icon;
@include pt-icon-sized;
margin-right: $menu-item-padding;
}

.#{$ns}-large & {
@include menu-item-large;

&::before {
@include pt-icon($pt-icon-size-large);
@include pt-icon-sized($pt-icon-size-large);
margin-right: $menu-item-padding-large;
}
}
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/components/menu/_submenu.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.

@import "../../common/variables";
@import "@blueprintjs/icons/lib/scss/variables";
@import "./common";

.#{$ns}-submenu {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe("<SegmentedControl>", () => {
const button = screen.getByRole("radio");
const icon = button.querySelector(`.${Classes.ICON}`);
expect(icon).not.toBeNull();
expect(icon!).toHaveAttribute("data-icon", IconNames.GRID);
expect(icon!.querySelector("svg")).toHaveAttribute("data-icon", IconNames.GRID);
});

it("button text defaults to value when no label is passed", () => {
Expand Down
Loading