UNPKG

5.54 kBJavaScriptView Raw
1/*
2 * Copyright 2017 Palantir Technologies, Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import { __assign, __rest } from "tslib";
17import classNames from "classnames";
18import * as React from "react";
19import { Icons, IconSize, SVGIconContainer, } from "@blueprintjs/icons";
20import { Classes, DISPLAYNAME_PREFIX, removeNonHTMLProps } from "../../common";
21// re-export for convenience, since some users won't be importing from or have a direct dependency on the icons package
22export { IconSize };
23/**
24 * Icon component.
25 *
26 * @see https://blueprintjs.com/docs/#core/components/icon
27 */
28// eslint-disable-next-line prefer-arrow-callback
29export var Icon = React.forwardRef(function (props, ref) {
30 var _a, _b;
31 var autoLoad = props.autoLoad, className = props.className, color = props.color, icon = props.icon, intent = props.intent, tagName = props.tagName, svgProps = props.svgProps, title = props.title, htmlTitle = props.htmlTitle, htmlProps = __rest(props, ["autoLoad", "className", "color", "icon", "intent", "tagName", "svgProps", "title", "htmlTitle"]);
32 // Preserve Blueprint v4.x behavior: iconSize prop takes predecence, then size prop, then fall back to default value
33 // eslint-disable-next-line deprecation/deprecation
34 var size = (_b = (_a = props.iconSize) !== null && _a !== void 0 ? _a : props.size) !== null && _b !== void 0 ? _b : IconSize.STANDARD;
35 var _c = React.useState(function () {
36 return typeof icon === "string" ? Icons.getPaths(icon, size) : undefined;
37 }), iconPaths = _c[0], setIconPaths = _c[1];
38 React.useEffect(function () {
39 var shouldCancelIconLoading = false;
40 if (typeof icon === "string") {
41 // The icon may have been loaded already, in which case we can simply grab it.
42 // N.B. when `autoLoad={true}`, we can't rely on simply calling Icons.load() here to re-load an icon module
43 // which has already been loaded & cached, since it may have been loaded with special loading options which
44 // this component knows nothing about.
45 var loadedIconPaths = Icons.getPaths(icon, size);
46 if (loadedIconPaths !== undefined) {
47 setIconPaths(loadedIconPaths);
48 }
49 else if (autoLoad) {
50 Icons.load(icon, size)
51 .then(function () {
52 // if this effect expired by the time icon loaded, then don't set state
53 if (!shouldCancelIconLoading) {
54 setIconPaths(Icons.getPaths(icon, size));
55 }
56 })
57 .catch(function (reason) {
58 console.error("[Blueprint] Icon '".concat(icon, "' (").concat(size, "px) could not be loaded."), reason);
59 });
60 }
61 else {
62 console.error("[Blueprint] Icon '".concat(icon, "' (").concat(size, "px) is not loaded yet and autoLoad={false}, did you call Icons.load('").concat(icon, "', ").concat(size, ")?"));
63 }
64 }
65 return function () {
66 shouldCancelIconLoading = true;
67 };
68 }, [autoLoad, icon, size]);
69 if (icon == null || typeof icon === "boolean") {
70 return null;
71 }
72 else if (typeof icon !== "string") {
73 return icon;
74 }
75 if (iconPaths == null) {
76 // fall back to icon font if unloaded or unable to load SVG implementation
77 var sizeClass = size === IconSize.STANDARD
78 ? Classes.ICON_STANDARD
79 : size === IconSize.LARGE
80 ? Classes.ICON_LARGE
81 : undefined;
82 return React.createElement(tagName, __assign(__assign({}, removeNonHTMLProps(htmlProps)), { "aria-hidden": title ? undefined : true, className: classNames(Classes.ICON, sizeClass, Classes.iconClass(icon), Classes.intentClass(intent), className), "data-icon": icon, ref: ref, title: htmlTitle }));
83 }
84 else {
85 var pathElements = iconPaths.map(function (d, i) { return React.createElement("path", { d: d, key: i, fillRule: "evenodd" }); });
86 // HACKHACK: there is no good way to narrow the type of SVGIconContainerProps here because of the use
87 // of a conditional type within the type union that defines that interface. So we cast to <any>.
88 // see https://github.com/microsoft/TypeScript/issues/24929, https://github.com/microsoft/TypeScript/issues/33014
89 return (React.createElement(SVGIconContainer, __assign({ children: pathElements,
90 // don't forward Classes.iconClass(icon) here, since the container will render that class
91 className: classNames(Classes.intentClass(intent), className), color: color, htmlTitle: htmlTitle, iconName: icon, ref: ref, size: size, svgProps: svgProps, tagName: tagName, title: title }, removeNonHTMLProps(htmlProps))));
92 }
93});
94Icon.defaultProps = {
95 autoLoad: true,
96 tagName: "span",
97};
98Icon.displayName = "".concat(DISPLAYNAME_PREFIX, ".Icon");
99//# sourceMappingURL=icon.js.map
\No newline at end of file