From 8041ea495a5bd8e8e2e2eac114ef3d6bf110ba7e Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Wed, 6 Oct 2021 22:52:00 +0000 Subject: [PATCH 1/2] [v4] [icons] feat: add iconNameToPathsRecordKey utility fn --- packages/core/src/components/icon/icon.tsx | 3 +-- packages/icons/src/iconCodepoints.ts | 18 ++++++++++++++++++ packages/icons/src/iconNames.ts | 12 +++++++++--- .../iconUtils.ts => icons/src/iconSvgPaths.ts} | 6 +++++- packages/icons/src/index.ts | 13 +++---------- 5 files changed, 36 insertions(+), 16 deletions(-) create mode 100644 packages/icons/src/iconCodepoints.ts rename packages/{core/src/components/icon/iconUtils.ts => icons/src/iconSvgPaths.ts} (89%) diff --git a/packages/core/src/components/icon/icon.tsx b/packages/core/src/components/icon/icon.tsx index 5c6a6c43f3..455017d8a2 100644 --- a/packages/core/src/components/icon/icon.tsx +++ b/packages/core/src/components/icon/icon.tsx @@ -17,10 +17,9 @@ import classNames from "classnames"; import * as React from "react"; -import { IconName, IconSvgPaths16, IconSvgPaths20 } from "@blueprintjs/icons"; +import { IconName, IconSvgPaths16, IconSvgPaths20, iconNameToPathsRecordKey } from "@blueprintjs/icons"; import { AbstractPureComponent2, Classes, DISPLAYNAME_PREFIX, IntentProps, Props, MaybeElement } from "../../common"; -import { iconNameToPathsRecordKey } from "./iconUtils"; export { IconName }; diff --git a/packages/icons/src/iconCodepoints.ts b/packages/icons/src/iconCodepoints.ts new file mode 100644 index 0000000000..55d2a3367d --- /dev/null +++ b/packages/icons/src/iconCodepoints.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2021 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// icon sets are identical aside from SVG paths, so we just import the info for the 16px set +export { BLUEPRINT_ICONS_16_CODEPOINTS as IconCodepoints } from "./generated/16px/blueprint-icons-16"; diff --git a/packages/icons/src/iconNames.ts b/packages/icons/src/iconNames.ts index e89829317d..ee3de9612e 100644 --- a/packages/icons/src/iconNames.ts +++ b/packages/icons/src/iconNames.ts @@ -19,9 +19,15 @@ import { snakeCase } from "change-case"; // icon sets are identical aside from SVG paths, so we just import the info for the 16px set -import { BlueprintIcons_16, BlueprintIcons_16Id, BlueprintIcons_16Key } from "./generated/16px/blueprint-icons-16"; +import { + BlueprintIcons_16, + BlueprintIcons_16Id as IconName, + BlueprintIcons_16Key, +} from "./generated/16px/blueprint-icons-16"; -const IconNamesLegacy: Record = {}; +export type { IconName }; + +const IconNamesLegacy: Record = {}; for (const [pascalCaseKey, iconName] of Object.entries(BlueprintIcons_16)) { const screamingSnakeCaseKey = snakeCase(pascalCaseKey).toUpperCase(); @@ -30,7 +36,7 @@ for (const [pascalCaseKey, iconName] of Object.entries(BlueprintIcons_16)) { export const IconNames = { ...BlueprintIcons_16, - ...(IconNamesLegacy as Record), + ...(IconNamesLegacy as Record), }; type ScreamingSnakeCaseIconNames = Uppercase>>; diff --git a/packages/core/src/components/icon/iconUtils.ts b/packages/icons/src/iconSvgPaths.ts similarity index 89% rename from packages/core/src/components/icon/iconUtils.ts rename to packages/icons/src/iconSvgPaths.ts index aafddeb458..881ed65efd 100644 --- a/packages/core/src/components/icon/iconUtils.ts +++ b/packages/icons/src/iconSvgPaths.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -import { IconName, IconSvgPaths16 } from "@blueprintjs/icons"; +import * as IconSvgPaths16 from "./generated/16px/paths"; +import * as IconSvgPaths20 from "./generated/20px/paths"; +import type { IconName } from "./iconNames"; + +export { IconSvgPaths16, IconSvgPaths20 }; export function iconNameToPathsRecordKey(name: IconName): keyof typeof IconSvgPaths16 { return kebabCaseToCamelCase(name); diff --git a/packages/icons/src/index.ts b/packages/icons/src/index.ts index 2b9f66d0b4..05e4a68842 100644 --- a/packages/icons/src/index.ts +++ b/packages/icons/src/index.ts @@ -14,13 +14,6 @@ * limitations under the License. */ -// icon sets are identical aside from SVG paths, so we just import the info for the 16px set -import { - BlueprintIcons_16Id as IconName, - BLUEPRINT_ICONS_16_CODEPOINTS as IconCodepoints, -} from "./generated/16px/blueprint-icons-16"; -import * as IconSvgPaths16 from "./generated/16px/paths"; -import * as IconSvgPaths20 from "./generated/20px/paths"; -import { IconNames } from "./iconNames"; - -export { IconCodepoints, IconName, IconNames, IconSvgPaths16, IconSvgPaths20 }; +export { IconSvgPaths16, IconSvgPaths20, iconNameToPathsRecordKey } from "./iconSvgPaths"; +export { IconCodepoints } from "./iconCodepoints"; +export { IconName, IconNames } from "./iconNames"; From 358beb35b83b050800a1c416729525747055dcee Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Wed, 6 Oct 2021 22:54:33 +0000 Subject: [PATCH 2/2] add JSDoc --- packages/icons/src/iconSvgPaths.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/icons/src/iconSvgPaths.ts b/packages/icons/src/iconSvgPaths.ts index 881ed65efd..2c6391ca88 100644 --- a/packages/icons/src/iconSvgPaths.ts +++ b/packages/icons/src/iconSvgPaths.ts @@ -20,6 +20,13 @@ import type { IconName } from "./iconNames"; export { IconSvgPaths16, IconSvgPaths20 }; +/** + * Type safe string literal conversion of snake-case icon names to camelCase icon names, + * useful for indexing into the SVG paths record to extract a single icon's SVG path definition. + * + * N.B. `IconSvgPaths16` and `IconSvgPaths20` are assignable to each other, so it doesn't matter + * which one is used in the return type definition here. + */ export function iconNameToPathsRecordKey(name: IconName): keyof typeof IconSvgPaths16 { return kebabCaseToCamelCase(name); }