From eedb955685ffb66736f9b648c72c14cc576ed528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oktay=20=C5=9Eenkan?= Date: Tue, 7 Jan 2025 23:10:15 +0300 Subject: [PATCH 1/9] feat(core): implement type generation --- .../docs/pages/troubleshooting/typescript.mdx | 24 +++++++++ apps/vite-react/tsconfig.app.json | 2 +- packages/core/src/index.ts | 50 +++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 apps/docs/pages/troubleshooting/typescript.mdx diff --git a/apps/docs/pages/troubleshooting/typescript.mdx b/apps/docs/pages/troubleshooting/typescript.mdx new file mode 100644 index 0000000..4c29345 --- /dev/null +++ b/apps/docs/pages/troubleshooting/typescript.mdx @@ -0,0 +1,24 @@ +# Typescript + +Monicon uses TypeScript to generate types for the icons. To enable TypeScript type definitions for your icons, add the following configuration to your `tsconfig.json` file: + +```json filename="tsconfig.json" copy {2} +{ + "include": [".monicon/*.d.ts"] +} +``` + +You can also use the `typesFileName` option to specify the name of the file to output the types to. If you want to disable the types file, you can set the `generateTypes` option to `false`. + +```ts filename="apps/vite-react/vite.config.ts" copy {8} +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import monicon from "@monicon/vite"; + +export default defineConfig({ + plugins: [ + react(), + monicon({ typesFileName: "types.d.ts", generateTypes: true }), + ], +}); +``` diff --git a/apps/vite-react/tsconfig.app.json b/apps/vite-react/tsconfig.app.json index f0a2350..f185aad 100644 --- a/apps/vite-react/tsconfig.app.json +++ b/apps/vite-react/tsconfig.app.json @@ -20,5 +20,5 @@ "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, - "include": ["src"] + "include": ["src", ".monicon/*.d.ts"] } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index d61cd48..57c305e 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -54,6 +54,18 @@ export type MoniconOptions = { * @default process.cwd() */ root?: string; + /** + * Whether to generate the types file. + * + * @default true + */ + generateTypes?: boolean; + /** + * The name of the file to output the types to. + * + * @default "types.d.ts" + */ + typesFileName?: string; }; export type Icon = { @@ -69,6 +81,8 @@ const defaultOptions: Required = { collections: [], customCollections: {}, root: process.cwd(), + generateTypes: true, + typesFileName: "types.d.ts", }; export const getResolveAlias = () => { @@ -102,6 +116,14 @@ export const getIconsFilePath = (opts?: MoniconOptions) => { ); }; +const getTypesFilePath = (opts?: MoniconOptions) => { + const options: Required = { ...defaultOptions, ...opts }; + + const autoGeneratedPath = getAutoGeneratedPath(options.root); + + return path.resolve(autoGeneratedPath, options.typesFileName); +}; + export const transformIcon = (svg: string) => { const svgObject = parseSync(svg); @@ -205,9 +227,37 @@ export const loadIcons = async (opts?: MoniconOptions) => { writeIcons(loadedIcons, outputPath, options.type); + if (options.generateTypes) { + const typesOutputPath = getTypesFilePath(options); + + const iconNames = Object.keys(loadedIcons); + + writeTypes(iconNames, typesOutputPath); + } + return loadedIcons; }; +const writeTypes = (iconNames: string[], outputPath: string) => { + const code = `// This file is automatically generated by Monicon. Do not edit this file directly. +import "@monicon/react"; + +declare module "@monicon/react" { + import { MoniconProps as IconProps } from "@monicon/icon-loader"; + + export type MoniconIconName = ${iconNames.map((name) => `\n\t| "${name}"`).join("")}; + + export type MoniconProps = Omit & { + name: MoniconIconName; + }; + + export const Monicon: React.FC; +} +`; + + fs.writeFileSync(outputPath, code); +}; + const writeIcons = ( icons: Record, outputPath: string, From 213fe03c119c353c060f8d1aa90b95164f5e0695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oktay=20=C5=9Eenkan?= Date: Tue, 7 Jan 2025 23:25:57 +0300 Subject: [PATCH 2/9] feat(core): declare module icon-loader instead of react --- packages/core/src/index.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 57c305e..d9b7cf4 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -240,18 +240,17 @@ export const loadIcons = async (opts?: MoniconOptions) => { const writeTypes = (iconNames: string[], outputPath: string) => { const code = `// This file is automatically generated by Monicon. Do not edit this file directly. -import "@monicon/react"; +import "@monicon/icon-loader"; -declare module "@monicon/react" { - import { MoniconProps as IconProps } from "@monicon/icon-loader"; - +declare module "@monicon/icon-loader" { export type MoniconIconName = ${iconNames.map((name) => `\n\t| "${name}"`).join("")}; - export type MoniconProps = Omit & { + export type MoniconProps = { name: MoniconIconName; + size?: number; + color?: string; + strokeWidth?: number; }; - - export const Monicon: React.FC; } `; From 30de5e6c77e0e231009b23acf074f1e999051bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oktay=20=C5=9Eenkan?= Date: Tue, 7 Jan 2025 23:35:24 +0300 Subject: [PATCH 3/9] refactor(core): seperate icon names as variable --- packages/core/src/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index d9b7cf4..b418067 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -239,11 +239,13 @@ export const loadIcons = async (opts?: MoniconOptions) => { }; const writeTypes = (iconNames: string[], outputPath: string) => { + const iconNamesAsCode = iconNames.map((name) => `\n\t| "${name}"`).join(""); + const code = `// This file is automatically generated by Monicon. Do not edit this file directly. import "@monicon/icon-loader"; declare module "@monicon/icon-loader" { - export type MoniconIconName = ${iconNames.map((name) => `\n\t| "${name}"`).join("")}; + export type MoniconIconName = ${iconNamesAsCode}; export type MoniconProps = { name: MoniconIconName; From 441c9a3a07d0d186fa3e5d54a3b7d5f8b520e710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oktay=20=C5=9Eenkan?= Date: Tue, 7 Jan 2025 23:41:12 +0300 Subject: [PATCH 4/9] docs(docs): fix typo --- apps/docs/pages/troubleshooting/typescript.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/troubleshooting/typescript.mdx b/apps/docs/pages/troubleshooting/typescript.mdx index 4c29345..39d84e0 100644 --- a/apps/docs/pages/troubleshooting/typescript.mdx +++ b/apps/docs/pages/troubleshooting/typescript.mdx @@ -1,4 +1,4 @@ -# Typescript +# TypeScript Monicon uses TypeScript to generate types for the icons. To enable TypeScript type definitions for your icons, add the following configuration to your `tsconfig.json` file: From 5fa1612ca3c0b718ec07b9fb5ec5bc118f465fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oktay=20=C5=9Eenkan?= Date: Tue, 7 Jan 2025 23:57:44 +0300 Subject: [PATCH 5/9] refactor: add jsdoc for monicon props --- packages/core/src/index.ts | 20 ++++++++++++++++++++ packages/icon-loader/src/index.ts | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index b418067..40b1922 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -248,9 +248,29 @@ declare module "@monicon/icon-loader" { export type MoniconIconName = ${iconNamesAsCode}; export type MoniconProps = { + /** + * The name of the icon to render. + * + * @example "mdi:home" + * + * For TypeScript users, you must check https://monicon-docs.vercel.app/troubleshooting/typescript for more information. + */ name: MoniconIconName; + /** + * The size of the icon. + * + * @default icon collection size + */ size?: number; + /** + * The color of the icon. + * + * @default "currentColor" + */ color?: string; + /** + * The stroke width of the icon. This feature is only available for limited icon collections. + */ strokeWidth?: number; }; } diff --git a/packages/icon-loader/src/index.ts b/packages/icon-loader/src/index.ts index 422951c..d3e6ce8 100644 --- a/packages/icon-loader/src/index.ts +++ b/packages/icon-loader/src/index.ts @@ -4,9 +4,29 @@ import { parseSync, stringify } from "svgson"; import icons from "@monicon/runtime"; export type MoniconProps = { + /** + * The name of the icon to render. + * + * @example "mdi:home" + * + * For TypeScript users, you must check https://monicon-docs.vercel.app/troubleshooting/typescript for more information. + */ name: string; + /** + * The size of the icon. + * + * @default icon collection size + */ size?: number; + /** + * The color of the icon. + * + * @default "currentColor" + */ color?: string; + /** + * The stroke width of the icon. This feature is only available for limited icon collections. + */ strokeWidth?: number; }; From ad2509156d8e7bb452863fbac9e8bd7e0d632f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oktay=20=C5=9Eenkan?= Date: Wed, 8 Jan 2025 00:07:10 +0300 Subject: [PATCH 6/9] refactor(core): add ".d.ts" suffix to typesFileName --- apps/docs/pages/troubleshooting/typescript.mdx | 5 +---- packages/core/src/index.ts | 6 +++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/docs/pages/troubleshooting/typescript.mdx b/apps/docs/pages/troubleshooting/typescript.mdx index 39d84e0..fc959fb 100644 --- a/apps/docs/pages/troubleshooting/typescript.mdx +++ b/apps/docs/pages/troubleshooting/typescript.mdx @@ -16,9 +16,6 @@ import react from "@vitejs/plugin-react"; import monicon from "@monicon/vite"; export default defineConfig({ - plugins: [ - react(), - monicon({ typesFileName: "types.d.ts", generateTypes: true }), - ], + plugins: [react(), monicon({ typesFileName: "types", generateTypes: true })], }); ``` diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 40b1922..8215fa7 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -63,7 +63,7 @@ export type MoniconOptions = { /** * The name of the file to output the types to. * - * @default "types.d.ts" + * @default "types" */ typesFileName?: string; }; @@ -82,7 +82,7 @@ const defaultOptions: Required = { customCollections: {}, root: process.cwd(), generateTypes: true, - typesFileName: "types.d.ts", + typesFileName: "types", }; export const getResolveAlias = () => { @@ -121,7 +121,7 @@ const getTypesFilePath = (opts?: MoniconOptions) => { const autoGeneratedPath = getAutoGeneratedPath(options.root); - return path.resolve(autoGeneratedPath, options.typesFileName); + return path.resolve(autoGeneratedPath, `${options.typesFileName}.d.ts`); }; export const transformIcon = (svg: string) => { From 1c5d5264b6a0d0a64c359bba3a4bf35eed560b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oktay=20=C5=9Eenkan?= Date: Wed, 8 Jan 2025 00:19:11 +0300 Subject: [PATCH 7/9] feat(core): implement type generation --- packages/core/src/index.ts | 6 ++++-- packages/icon-loader/src/index.ts | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 8215fa7..ee68ea0 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -253,13 +253,15 @@ declare module "@monicon/icon-loader" { * * @example "mdi:home" * - * For TypeScript users, you must check https://monicon-docs.vercel.app/troubleshooting/typescript for more information. + * For TypeScript users, you must check below for more information. + * + * @link https://monicon-docs.vercel.app/troubleshooting/typescript */ name: MoniconIconName; /** * The size of the icon. * - * @default icon collection size + * @default collection's view box size */ size?: number; /** diff --git a/packages/icon-loader/src/index.ts b/packages/icon-loader/src/index.ts index d3e6ce8..d618f4a 100644 --- a/packages/icon-loader/src/index.ts +++ b/packages/icon-loader/src/index.ts @@ -9,13 +9,15 @@ export type MoniconProps = { * * @example "mdi:home" * - * For TypeScript users, you must check https://monicon-docs.vercel.app/troubleshooting/typescript for more information. + * For TypeScript users, you must check below for more information. + * + * @link https://monicon-docs.vercel.app/troubleshooting/typescript */ name: string; /** * The size of the icon. * - * @default icon collection size + * @default collection's view box size */ size?: number; /** From 03d927e9fd0c810ee8e95640271a4c828da38882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oktay=20=C5=9Eenkan?= Date: Wed, 8 Jan 2025 00:26:33 +0300 Subject: [PATCH 8/9] docs(docs): improve typescript docs --- apps/docs/pages/troubleshooting/_meta.tsx | 1 + apps/docs/pages/troubleshooting/typescript.mdx | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/docs/pages/troubleshooting/_meta.tsx b/apps/docs/pages/troubleshooting/_meta.tsx index 0176481..21304b5 100644 --- a/apps/docs/pages/troubleshooting/_meta.tsx +++ b/apps/docs/pages/troubleshooting/_meta.tsx @@ -1,4 +1,5 @@ export default { + typescript: "TypeScript", monorepo: "Monorepo", "module-resolution": "Module Resolution", "bundle-size": "Bundle Size", diff --git a/apps/docs/pages/troubleshooting/typescript.mdx b/apps/docs/pages/troubleshooting/typescript.mdx index fc959fb..a8f88a2 100644 --- a/apps/docs/pages/troubleshooting/typescript.mdx +++ b/apps/docs/pages/troubleshooting/typescript.mdx @@ -10,12 +10,18 @@ Monicon uses TypeScript to generate types for the icons. To enable TypeScript ty You can also use the `typesFileName` option to specify the name of the file to output the types to. If you want to disable the types file, you can set the `generateTypes` option to `false`. -```ts filename="apps/vite-react/vite.config.ts" copy {8} +```ts filename="apps/vite-react/vite.config.ts" copy {9,10} import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import monicon from "@monicon/vite"; export default defineConfig({ - plugins: [react(), monicon({ typesFileName: "types", generateTypes: true })], + plugins: [ + react(), + monicon({ + typesFileName: "types", + generateTypes: true, + }), + ], }); ``` From 6a3a299398311653e7c9f7765572c1bbaf494c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oktay=20=C5=9Eenkan?= Date: Wed, 8 Jan 2025 00:28:53 +0300 Subject: [PATCH 9/9] docs: add release notes --- .changeset/hot-jokes-float.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .changeset/hot-jokes-float.md diff --git a/.changeset/hot-jokes-float.md b/.changeset/hot-jokes-float.md new file mode 100644 index 0000000..7efa7d9 --- /dev/null +++ b/.changeset/hot-jokes-float.md @@ -0,0 +1,20 @@ +--- +"@monicon/icon-loader": minor +"@monicon/core": minor +"@monicon/esbuild": minor +"@monicon/loader": minor +"@monicon/metro": minor +"@monicon/native": minor +"@monicon/nuxt": minor +"@monicon/qwik": minor +"@monicon/react": minor +"@monicon/rollup": minor +"@monicon/rspack": minor +"@monicon/svelte": minor +"@monicon/typescript-config": minor +"@monicon/vite": minor +"@monicon/vue": minor +"@monicon/webpack": minor +--- + +implement type generation