diff --git a/packages/auto-icons/README.md b/packages/auto-icons/README.md index 60ee8558..32607019 100644 --- a/packages/auto-icons/README.md +++ b/packages/auto-icons/README.md @@ -5,7 +5,7 @@ ## Features - Generate extension icons with the correct sizes -- Make the icon greyscale during development +- Make the icon greyscale or include a visible overlay during development ## Usage diff --git a/packages/auto-icons/src/index.ts b/packages/auto-icons/src/index.ts index 61a766ea..a97aeede 100644 --- a/packages/auto-icons/src/index.ts +++ b/packages/auto-icons/src/index.ts @@ -14,11 +14,24 @@ export default defineWxtModule({ { enabled: true, baseIconPath: resolve(wxt.config.srcDir, 'assets/icon.png'), - grayscaleOnDevelopment: true, + developmentIndicator: 'grayscale', sizes: [128, 48, 32, 16], }, ); + // Backward compatibility for the deprecated option + if (options?.grayscaleOnDevelopment !== undefined) { + wxt.logger.warn( + '`[auto-icons]` "grayscaleOnDevelopment" is deprecated. Use "developmentIndicator" instead.', + ); + + if (options?.developmentIndicator === undefined) { + parsedOptions.developmentIndicator = options!.grayscaleOnDevelopment + ? 'grayscale' + : false; + } + } + const resolvedPath = resolve(wxt.config.srcDir, parsedOptions.baseIconPath); if (!parsedOptions.enabled) @@ -42,21 +55,44 @@ export default defineWxtModule({ }); wxt.hooks.hook('build:done', async (wxt, output) => { - const image = sharp(resolvedPath).png(); - - if ( - wxt.config.mode === 'development' && - parsedOptions.grayscaleOnDevelopment - ) { - image.grayscale(); - } - const outputFolder = wxt.config.outDir; for (const size of parsedOptions.sizes) { - const resized = image.resize(size); + const resizedImage = sharp(resolvedPath).resize(size).png(); + + if (wxt.config.mode === 'development') { + if (parsedOptions.developmentIndicator === 'grayscale') { + resizedImage.grayscale(); + } else if (parsedOptions.developmentIndicator === 'overlay') { + // Helper to build an overlay that places a yellow rectangle at the bottom + // of the icon with the text "DEV" in black. The overlay has the same + // dimensions as the icon so we can composite it with default gravity. + const buildDevOverlay = (size: number) => { + const rectHeight = Math.round(size * 0.5); + const fontSize = Math.round(size * 0.35); + + return Buffer.from(` + + + DEV + `); + }; + const overlayBuffer = await sharp(buildDevOverlay(size)) + .png() + .toBuffer(); + + resizedImage.composite([ + { + input: overlayBuffer, + left: 0, + top: 0, + }, + ]); + } + } + ensureDir(resolve(outputFolder, 'icons')); - await resized.toFile(resolve(outputFolder, `icons/${size}.png`)); + await resizedImage.toFile(resolve(outputFolder, `icons/${size}.png`)); output.publicAssets.push({ type: 'asset', @@ -89,9 +125,20 @@ export interface AutoIconsOptions { * @default "/assets/icon.png" */ baseIconPath?: string; + /** + * Apply a visual indicator to the icon when running in development mode. + * + * "grayscale" converts the icon to grayscale. + * "overlay" covers the bottom half with a yellow rectangle and writes "DEV" in black text. + * Set to `false` to disable any indicator. + * + * @default "grayscale" + */ + developmentIndicator?: 'grayscale' | 'overlay' | false; /** * Grayscale the image when in development mode to indicate development * @default true + * @deprecated Use `developmentIndicator` instead */ grayscaleOnDevelopment?: boolean; /**