Skip to content

Commit

Permalink
Merge pull request #19 from author-more/feat/add-icons-core-ui
Browse files Browse the repository at this point in the history
feat: add icons - coreui
  • Loading branch information
Belar authored Oct 7, 2024
2 parents af96231 + 77d7540 commit abbb6ec
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 20 deletions.
17 changes: 16 additions & 1 deletion bin/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
export const iconPackages = [
type IconPackage = {
id: string;
variant?: string;
iconsDir: string;
getVariantFromIconName?: (iconName: string) => string;
normaliseAttributes?: (svg: string) => string;
};

export const iconPackages: IconPackage[] = [
{
id: "lucide",
variant: "regular",
Expand Down Expand Up @@ -50,4 +58,11 @@ export const iconPackages = [
variant: "regular",
iconsDir: "../node_modules/feather-icons/dist/icons",
},
...["free", "flag"].map((variant) => ({
id: `core-ui`,
variant,
iconsDir: `../node_modules/@coreui/icons/svg/${variant}`,
normaliseAttributes: (svg: string) =>
svg.replace(/fill="var\(--ci-primary-color, currentColor\)"/g, ""),
})),
];
6 changes: 4 additions & 2 deletions bin/generateIconSets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ iconPackages.forEach(
iconsDir,
variant,
getVariantFromIconName,
normaliseAttributes,
}: (typeof iconPackages)[number]) => {
const files = getFilesByExtension(iconsDir, ".svg");

const icons: Record<string, Record<string, Icon>> = {};
for (const file of files) {
const svg = readFile(iconsDir, file);

const attributes = svg.match(/<svg([^>]*)>/)?.[1];
const elements = svg.match(/<svg[^>]*>([\s\S]*)<\/svg>/)?.[1];
const svgNormalised = normaliseAttributes?.(svg) || svg;
const attributes = svgNormalised.match(/<svg([^>]*)>/)?.[1];
const elements = svgNormalised.match(/<svg[^>]*>([\s\S]*)<\/svg>/)?.[1];

if (!attributes || !elements) {
throw new Error(`Failed to parse the SVG: ${file}`);
Expand Down
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"generate-data": "tsx ./bin/generateIconSets.ts"
},
"dependencies": {
"@coreui/icons": "^3.0.1",
"@material-design-icons/svg": "^0.14.13",
"@penpot/plugin-styles": "^0.10.0",
"@phosphor-icons/core": "^2.1.1",
Expand Down
25 changes: 17 additions & 8 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ import {
iconLibraries,
defaultIconSetSettings,
getIconSetsByVariant,
DEFAULT_ICON_SIZE,
DATA_KEY_ICON_SETS_SETTINGS,
getNormalisedIconSize,
} from "./icons";
import Select from "./Select";
import LinkTag from "./LinkTag";
import { toSortedBy } from "./sort";
import { Bug, ChevronDown, ChevronRight, Lightbulb } from "lucide-react";
import { sendMessage } from "./window";
import { filterByPhrase } from "./search";
import { parseAttributes } from "./dataStructure";

function App() {
const url = new URL(window.location.href);
Expand Down Expand Up @@ -112,19 +113,23 @@ function App() {
svg: { attributes, elements },
},
]) => {
const parsedAttributes =
parseAttributes(`${attributes} ${customSvgAttributes}`) || {};

const svg = `<svg ${attributes}>${elements}</svg>`;
const icon = (
<Icon
attributes={`${attributes} ${customSvgAttributes}`}
elements={elements}
/>
<Icon attributes={parsedAttributes} elements={elements} />
);
const size = getNormalisedIconSize(
parseInt(parsedAttributes.width, 10),
parseInt(parsedAttributes.height, 10),
);

return (
<IconButton
key={`icon-${name}`}
label={`Insert icon: ${name}`}
onClick={() => handleIconButtonClick(name, svg)}
onClick={() => handleIconButtonClick(name, svg, size)}
onMouseEnter={() => setHoveredIcon({ name, library })}
onMouseLeave={() => setHoveredIcon(null)}
>
Expand All @@ -135,8 +140,12 @@ function App() {
);
}

function handleIconButtonClick(name: string, svg: string) {
sendMessage("insert-icon", { name, svg, size: DEFAULT_ICON_SIZE });
function handleIconButtonClick(
name: string,
svg: string,
size: { width: number; height: number },
) {
sendMessage("insert-icon", { name, svg, size });
}

function toggleShowIcons(id: string) {
Expand Down
3 changes: 3 additions & 0 deletions src/Icon.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
svg {
height: auto;
}
6 changes: 3 additions & 3 deletions src/Icon.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { parseAttributes } from "./dataStructure";
import "./Icon.css";

type IconProps = {
attributes: string;
attributes: Record<string, string>;
elements: string;
};

export default function Icon({ attributes, elements }: IconProps) {
const { class: className, ...rest } = parseAttributes(attributes) || {};
const { class: className, ...rest } = attributes || {};

return (
<svg
Expand Down
28 changes: 28 additions & 0 deletions src/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,22 @@ export const iconLibraries: IconLibrary[] = [
},
icons: generateVariants("feather", ["regular"]),
},
{
id: "core-ui",
name: "CoreUI Free",
website: "https://coreui.io/icons/",
license: {
name: "CC BY 4.0, CC0 1.0 Universal",
url: "https://github.com/coreui/coreui-icons/blob/main/LICENSE",
},
icons: generateVariants("core-ui", ["free", "flag"]),
iconSettings: {
svg: {
attributes: 'fill="currentColor"',
},
},
defaultSettings: { selectedVariant: "free" },
},
];

export const defaultIconSetSettings: Record<string, IconSetSettings> =
Expand Down Expand Up @@ -207,3 +223,15 @@ export function getVariantOptions(icons: IconSetVariant[]) {
value: variant,
}));
}

export function getNormalisedIconSize(
originalWidth: number,
originalHeight: number,
) {
const ratio =
originalWidth && originalHeight ? originalWidth / originalHeight : 1;
const width = DEFAULT_ICON_SIZE;
const height = Math.round(width / ratio);

return { width, height };
}
10 changes: 6 additions & 4 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ type InsertIconPluginEvent = {
content: {
name: string;
svg: string;
size: number;
size: IconSize;
};
};

type IconSize = { width: number; height: number };

type SetDataPluginEvent = {
type: "set-plugin-data";
content: PluginData;
Expand Down Expand Up @@ -71,18 +73,18 @@ penpot.ui.onMessage<PluginUIEvent>(({ type, content }) => {
function insertIcon({
name,
svg,
size,
size: { width, height },
}: {
name: string;
svg: string;
size: number;
size: IconSize;
}) {
const icon = penpot.createShapeFromSvg(svg);
if (icon) {
icon.name = name;
icon.x = penpot.viewport.center.x;
icon.y = penpot.viewport.center.y;
icon.resize(size, size);
icon.resize(width, height);
}
}

Expand Down
10 changes: 8 additions & 2 deletions tests/icon.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ const testIcons = [
{
name: "a-arrow-down",
svg: '<svg class="lucide lucide-a-arrow-down" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 13h6" /> <path d="m2 16 4.5-9 4.5 9" /> <path d="M18 7v9" /> <path d="m14 12 4 4 4-4" /></svg>',
size: 24,
size: {
width: 24,
height: 24,
},
},
{
name: "pickaxe",
svg: '<svg class="lucide lucide-pickaxe" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.531 12.469 6.619 20.38a1 1 0 1 1-3-3l7.912-7.912" /> <path d="M15.686 4.314A12.5 12.5 0 0 0 5.461 2.958 1 1 0 0 0 5.58 4.71a22 22 0 0 1 6.318 3.393" /> <path d="M17.7 3.7a1 1 0 0 0-1.4 0l-4.6 4.6a1 1 0 0 0 0 1.4l2.6 2.6a1 1 0 0 0 1.4 0l4.6-4.6a1 1 0 0 0 0-1.4z" /> <path d="M19.686 8.314a12.501 12.501 0 0 1 1.356 10.225 1 1 0 0 1-1.751-.119 22 22 0 0 0-3.393-6.319" /></svg>',
size: 24,
size: {
width: 24,
height: 24,
},
},
];

Expand Down

0 comments on commit abbb6ec

Please sign in to comment.