Skip to content

Commit

Permalink
feat: allow to transform SVG component name (#55)
Browse files Browse the repository at this point in the history
* build: add `@svgr/babel-plugin-transform-svg-component` dependency

* feat!: provide SVG component name transformer to SVG plugin

* test: add tests for SVG component name transformations

* docs: update `README.md`

* chore: add changesets
  • Loading branch information
demiazz authored Dec 25, 2023
1 parent 013656c commit c223e92
Show file tree
Hide file tree
Showing 33 changed files with 592 additions and 28 deletions.
39 changes: 39 additions & 0 deletions .changeset/long-cows-give.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
'@tabula/forge': minor
---

added support of transformation of SVG component name with `svgrComponentName` option.

By default, SVGR uses `Svg<CamelCaseFileName>` name for components. You can override this behaviour through
`svgrComponentName` options, which should be function of format `(svgrName: string) => string`.

Example:

```js
export default {
// ...
svgrComponentName(name) {
return `Ui${name.slice(3)}Icon`;
},
// ...
};
```

If you have a file `column.svg` then component name is `SvgColumn` by default. But with config from about the name
will be `UiColumnIcon`.

If you use memoization it looks like:

```js
import { memo } from 'react';

const UiColumnIcon = (props) => {
// ...
};

const Memo = memo(UiColumnIcon);

export { Memo as ReactComponent };
```

This option doesn't affect named exports.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ We resolve option in following order:

You can look at the [JSON Schema](https://github.com/ReTable/forge/blob/main/schemas/forgerc.json) for configuration file.

Not all options are available through static files. For example, `svgrComponentName` is available only in JS/TS files.

## Entries

By default, the `forge` looking for `<packageRoot>/src/index.tsx` or `<packageRoot/src/index.ts` file, and bundles it
Expand Down Expand Up @@ -361,6 +363,42 @@ import iconUrl, { ReactComponent as IconUrl } from './icon.svg';

An SVG file already exports React component as `ReactComponent`.

#### SVGR Component Name

By default, SVGR uses `Svg<CamelCaseFileName>` name for components. You can override this behaviour through
`svgrComponentName` options, which should be function of format `(svgrName: string) => string`.

Example:

```js
export default {
// ...
svgrComponentName(name) {
return `Ui${name.slice(3)}Icon`;
},
// ...
};
```

If you have a file `column.svg` then component name is `SvgColumn` by default. But with config from about the name
will be `UiColumnIcon`.

If you use memoization it looks like:

```js
import { memo } from 'react';

const UiColumnIcon = (props) => {
// ...
};

const Memo = memo(UiColumnIcon);

export { Memo as ReactComponent };
```

This option doesn't affect named exports.

### React

We use automatic runtime only for React.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@changesets/cli": "^2.27.1",
"@commitlint/cli": "^18.4.3",
"@commitlint/config-conventional": "^18.4.3",
"@svgr/babel-plugin-transform-svg-component": "^8.0.0",
"@tabula/eslint-config": "^0.1.1",
"@tabula/prettier-config": "^0.1.4",
"@tabula/typescript-config": "^0.2.1",
Expand Down
24 changes: 3 additions & 21 deletions pnpm-lock.yaml

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

3 changes: 3 additions & 0 deletions src/bundle/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Options = {
production: boolean;
storybook: boolean;
cssClassPrefix: boolean | string;
svgrComponentName?: (componentName: string) => string;
target: Target;
typings: boolean;
watch: boolean;
Expand All @@ -28,6 +29,7 @@ export async function bundle({
postBuild,
production,
storybook,
svgrComponentName,
target,
typings,
watch,
Expand Down Expand Up @@ -64,6 +66,7 @@ export async function bundle({
production,
repositoryRoot,
storybook,
svgrComponentName,
target,
typings,
});
Expand Down
15 changes: 13 additions & 2 deletions src/bundle/createBuildOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type BrowserOptions = {
production: boolean;
repositoryRoot: string;
storybook: boolean;
svgrComponentName?: (componentName: string) => string;
};

const extensions = [
Expand Down Expand Up @@ -86,7 +87,14 @@ function getPrefixFrom(cssClassPrefix: boolean | string, packageName: string) {

async function applyBrowserOptions(
buildOptions: BuildOptions,
{ cssClassPrefix, name, production, repositoryRoot, storybook }: BrowserOptions,
{
cssClassPrefix,
name,
production,
repositoryRoot,
storybook,
svgrComponentName,
}: BrowserOptions,
) {
const prefix = getPrefixFrom(cssClassPrefix, name);

Expand Down Expand Up @@ -116,7 +124,7 @@ async function applyBrowserOptions(
buildOptions.plugins = [
cssAutoImportPlugin(),
stylesPlugin({ processCss }),
svgPlugin(),
svgPlugin({ svgrComponentName }),
vanillaExtractPlugin({ isProduction: production, prefix }),
];

Expand All @@ -140,6 +148,7 @@ type Options = {
production: boolean;
repositoryRoot: string;
storybook: boolean;
svgrComponentName?: (componentName: string) => string;
target: Target;
typings: boolean;
};
Expand All @@ -154,6 +163,7 @@ export async function createBuildOptions({
production,
repositoryRoot,
storybook,
svgrComponentName,
target,
typings,
}: Options): Promise<BuildOptions> {
Expand Down Expand Up @@ -186,6 +196,7 @@ export async function createBuildOptions({
production,
repositoryRoot,
storybook,
svgrComponentName,
});

break;
Expand Down
1 change: 1 addition & 0 deletions src/config/initConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export async function initConfig(target: Target): Promise<void> {
if (target === 'node') {
delete config.storybook;
delete config.cssClassPrefix;
delete config.svgrComponentName;
delete config.build?.storybook;
delete config.watch?.storybook;
}
Expand Down
4 changes: 4 additions & 0 deletions src/config/loadConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ type Result = {
typings: boolean;
storybook: boolean;
cssClassPrefix: boolean | string;
svgrComponentName?: (componentName: string) => string;

postBuild: Hook[];

Expand Down Expand Up @@ -160,6 +161,8 @@ export async function loadConfig(options: Options): Promise<Result> {
const cssClassPrefix =
options.cssClassPrefix ?? userConfig?.cssClassPrefix ?? defaults.cssClassPrefix;

const svgrComponentName = userConfig?.svgrComponentName;

let postBuild: Hook | Hook[] = [];

if (options.postBuild != null) {
Expand All @@ -180,6 +183,7 @@ export async function loadConfig(options: Options): Promise<Result> {
typings: check && typings,
storybook: target === 'browser' && storybook,
cssClassPrefix,
svgrComponentName,

postBuild,

Expand Down
Loading

0 comments on commit c223e92

Please sign in to comment.