8000 v2 - Monicon CLI and Auto-generated files by oktaysenkan · Pull Request #70 · oktaysenkan/monicon · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

v2 - Monicon CLI and Auto-generated files #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open

v2 - Monicon CLI and Auto-generated files #70

wants to merge 27 commits into from

Conversation

oktaysenkan
Copy link
Owner
@oktaysenkan oktaysenkan commented Mar 8, 2025

I will build a CLI tool to automate the generation of icon files in different formats (.tsx, .jsx, .vue, .svg, etc.). This enables fully tree shakable icons.

Core Features:

  • Users can set a custom output path (default: src/components/icon).
  • Supports predefined templates for different frameworks (SVG, React JSX, React TSX, Vue, etc.).
  • Allows users to plugins, similar to a custom loader, making it possible to use Monicon in other programming languages.

fixes: #51 #60 #71 #72

Copy link
changeset-bot bot commented Mar 8, 2025

⚠️ No Changeset found

Latest commit: 9b95a04

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
vercel bot commented Mar 8, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
monicon-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 22, 2025 7:10pm

@oktaysenkan oktaysenkan changed the title v2 - Monicon CLI v2 - Monicon CLI and Auto-generated files Mar 8, 2025
@oktaysenkan
Copy link
Owner Author
oktaysenkan commented Apr 19, 2025

🆕 Plugin System Overview

Monicon now supports a flexible plugin system that enables you to hook into the icon generation lifecycle. You can use plugins to output files, transform icons, generate metadata, or integrate with external tools.


🔧 Interfaces

MoniconPluginPayload

The input passed to all plugins:

export type MoniconPluginPayload = {
  icons: Icon[]; // Fetched and processed icons
};

MoniconPluginFile

Defines an output file:

export type MoniconPluginFile = {
  path: string;
  content: string;
};

MoniconPlugin

The main plugin interface:

export type MoniconPlugin<T = any> = (opts: T) => (
  payload: MoniconPluginPayload
) => {
  name: string;
  generate: (configUpdated: boolean) => PromiseLike<MoniconPluginFile[]>;
  onPluginsLoad?: (plugins: string[]) => PromiseLike<void>;
  beforeGenerate?: (icons: Icon[]) => PromiseLike<void>;
  afterGenerate?: (icons: Icon[]) => PromiseLike<void>;
  beforeWriteFiles?: (files: MoniconPluginFile[]) => PromiseLike<void>;
  afterWriteFiles?: (files: MoniconPluginFile[]) => PromiseLike<void>;
};

🧪 Example Plugin: svg

Outputs each icon as a standalone .svg file:

import path from "path";
import slugify from "slugify";
import type { Icon } from "../../index";
import { MoniconPlugin, MoniconPluginFile } from "../types";

slugify.extend({ ":": "/" });

export type SvgPluginOptions = void | {
  outputPath?: ((icon: Icon) => string | undefined) | string;
  fileName?: ((icon: Icon) => string | undefined) | string;
};

const getFileName = (icon: Icon, options: SvgPluginOptions) => {
  const defaultFileName = slugify(icon.name, { lower: true, remove: /:/g });

  return typeof options?.fileName === "function"
    ? (options.fileName(icon) ?? defaultFileName)
    : (options?.fileName ?? defaultFileName);
};

const getOutputPath = (icon: Icon, options: SvgPluginOptions) => {
  const defaultOutputPath = "src/components/icons";

  if (!options?.outputPath) return defaultOutputPath;

  return typeof options.outputPath === "function"
    ? (options.outputPath(icon) ?? defaultOutputPath)
    : (options.outputPath ?? defaultOutputPath);
};

const generateIconFiles = (icons: Icon[], options: SvgPluginOptions) => {
  return icons.map((icon) => {
    const fileName = getFileName(icon, options);
    const outputPath = getOutputPath(icon, options);
    const filePath = path.join(outputPath, `${fileName}.svg`);

    return {
      path: path.resolve(filePath),
      content: icon.svg,
    };
  });
};

export const svg: MoniconPlugin<SvgPluginOptions> = (options) => (payload) => {
  return {
    name: "monicon-svg-plugin",
    generate: () => generateIconFiles(payload.icons, options),
  };
};

🧩 Basic Plugin

Minimal example that generates a single file:

import type { MoniconPlugin } from "../types";

export const basic: MoniconPlugin<void> = () => () => {
  return {
    name: "monicon-basic-plugin",
    generate: () => [
      {
        path: "/foo/bar/baz.html",
        content: "<h1>Hello World</h1>",
      },
    ],
  };
};

⚙️ monicon.config.ts Example

import { MoniconConfig } from "@monicon/core";
import { svg } from "@monicon/core/plugins";
import { loadJSONCollection, loadLocalCollection, loadRemoteCollection } from "@monicon/core/loaders";

export default {
  icons: [
    "mdi:home",
    "mdi:account",
    "feather:activity",
    "lucide:cloud-download",
  ],
  collections: ["lucide"],
  loaders: {
    local: loadLocalCollection("assets/icons"),
    json: loadJSONCollection(
      "https://gist.githubusercontent.com/oktaysenkan/39681ecdb066dc44c52fa840dacc7562/raw/icons.json"
    ),
    remote: loadRemoteCollection({
      download: "https://api.iconify.design/lucide:cloud-download.svg",
    }),
  },
  plugins: [svg()],
} satisfies MoniconConfig;

@monicon/react @monicon/svelte @monicon/vue @monicon/qwik @monicon/native
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Why don’t you declare the icons as ES Modules, so they’re fully tree-shakable?
1 participant
0