Repository: gregberge/svgr Branch: main Commit: 975215efe858 Files: 270 Total size: 506.3 KB Directory structure: gitextract_w9d7ejze/ ├── .eslintignore ├── .eslintrc.json ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug.md │ │ ├── feature.md │ │ ├── question.md │ │ └── regression.md │ ├── ISSUE_TEMPLATE.md │ ├── PULL_REQUEST_TEMPLATE.md │ ├── SUPPORT.md │ ├── opencollective.yml │ ├── stale.yml │ └── workflows/ │ └── ci.yml ├── .gitignore ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── BACKERS.md ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── __fixtures__/ │ ├── custom-index-template.js │ ├── custom-index.config.js │ ├── overrides.config.js │ ├── simple-existing/ │ │ ├── File..js │ │ ├── File.js │ │ └── index..js │ ├── template.js │ ├── withPrettierRc/ │ │ └── .prettierrc │ ├── withSvgoConfig/ │ │ ├── svgo.config.cjs │ │ └── svgo.config.js │ └── withSvgrRc/ │ └── .svgrrc ├── api/ │ ├── api/ │ │ └── svgr.js │ ├── package.json │ ├── pnpm-workspace.yaml │ └── vercel.json ├── babel.config.js ├── build/ │ └── rollup.config.mjs ├── deprecated-packages/ │ └── svgr/ │ ├── message.js │ └── package.json ├── examples/ │ ├── mocha-esm/ │ │ ├── CHANGELOG.md │ │ ├── __mocks__/ │ │ │ └── svg.js │ │ ├── example.js │ │ ├── example.test.js │ │ ├── mock-loader.js │ │ └── package.json │ └── webpack/ │ ├── .gitignore │ ├── CHANGELOG.md │ ├── package.json │ ├── src/ │ │ └── index.js │ └── webpack.config.js ├── jest.config.js ├── lerna.json ├── package.json ├── packages/ │ ├── babel-plugin-add-jsx-attribute/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── babel-plugin-remove-jsx-attribute/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── babel-plugin-remove-jsx-empty-expression/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── babel-plugin-replace-jsx-attribute-value/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── babel-plugin-svg-dynamic-title/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── babel-plugin-svg-em-dimensions/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── babel-plugin-transform-react-native-svg/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── babel-plugin-transform-svg-component/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── __snapshots__/ │ │ │ │ └── index.test.ts.snap │ │ │ ├── defaultTemplate.ts │ │ │ ├── index.test.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── variables.ts │ │ └── tsconfig.json │ ├── babel-preset/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── cli/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── bin/ │ │ │ └── svgr │ │ ├── package.json │ │ ├── src/ │ │ │ ├── __snapshots__/ │ │ │ │ ├── index.test.ts.snap │ │ │ │ └── util.test.ts.snap │ │ │ ├── dirCommand.ts │ │ │ ├── fileCommand.ts │ │ │ ├── index.test.ts │ │ │ ├── index.ts │ │ │ ├── util.test.ts │ │ │ └── util.ts │ │ └── tsconfig.json │ ├── core/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── __fixtures__/ │ │ │ │ ├── svgo/ │ │ │ │ │ └── svgo.config.js │ │ │ │ └── svgr/ │ │ │ │ └── .svgrrc │ │ │ ├── __snapshots__/ │ │ │ │ ├── config.test.ts.snap │ │ │ │ └── transform.test.ts.snap │ │ │ ├── config.test.ts │ │ │ ├── config.ts │ │ │ ├── index.ts │ │ │ ├── plugins.test.ts │ │ │ ├── plugins.ts │ │ │ ├── state.test.ts │ │ │ ├── state.ts │ │ │ ├── transform.test.ts │ │ │ └── transform.ts │ │ └── tsconfig.json │ ├── hast-util-to-babel-ast/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── __snapshots__/ │ │ │ │ └── index.test.ts.snap │ │ │ ├── all.ts │ │ │ ├── getAttributes.ts │ │ │ ├── handlers.ts │ │ │ ├── helpers.ts │ │ │ ├── index.test.ts │ │ │ ├── index.ts │ │ │ ├── mappings.ts │ │ │ ├── one.ts │ │ │ ├── stringToObjectStyle.ts │ │ │ └── util.ts │ │ └── tsconfig.json │ ├── plugin-jsx/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── plugin-prettier/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── plugin-svgo/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── __snapshots__/ │ │ │ │ └── index.test.ts.snap │ │ │ ├── config.test.ts │ │ │ ├── config.ts │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── rollup/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── __snapshots__/ │ │ │ │ └── index.test.ts.snap │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ └── webpack/ │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src/ │ │ ├── __snapshots__/ │ │ │ └── index.test.ts.snap │ │ ├── index.test.ts │ │ └── index.ts │ └── tsconfig.json ├── pnpm-workspace.yaml ├── public/ │ └── .exists ├── resources/ │ └── svgr-logo.sketch ├── tsconfig.json └── website/ ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmrc ├── .nvmrc ├── README.md ├── _redirects ├── gatsby-config.js ├── netlify.toml ├── package.json ├── pages/ │ ├── docs/ │ │ ├── cli.mdx │ │ ├── configuration-files.mdx │ │ ├── custom-templates.mdx │ │ ├── custom-transformations.mdx │ │ ├── ecosystem.mdx │ │ ├── getting-started.mdx │ │ ├── index.mdx │ │ ├── jest.mdx │ │ ├── migrate.mdx │ │ ├── mocha.mdx │ │ ├── next.mdx │ │ ├── node-api.mdx │ │ ├── options.mdx │ │ ├── parcel.mdx │ │ ├── remix.mdx │ │ ├── rollup.mdx │ │ ├── supporting-svgr.mdx │ │ ├── webpack.mdx │ │ └── what-is-svgr.mdx │ ├── index.mdx │ └── playground.mdx └── src/ ├── components/ │ ├── Home.js │ └── playground/ │ ├── Ad.js │ ├── CheckGroup.js │ ├── DropArea.js │ ├── Editor.js │ ├── Loading.js │ ├── Playground.js │ ├── Query.js │ ├── Settings.js │ ├── SettingsFieldBoolean.js │ ├── SettingsFieldEnum.js │ ├── SettingsFieldInteger.js │ ├── SettingsFieldString.js │ ├── SettingsGroup.js │ ├── SmallLabel.js │ ├── config/ │ │ └── settings.js │ ├── controls/ │ │ ├── CheckboxControl.js │ │ ├── InputControl.js │ │ ├── RadioControl.js │ │ └── TextareaControl.js │ ├── defaultSVG.js │ ├── icons/ │ │ └── ChevronLeft.js │ └── modules/ │ └── svgr.js └── smooth-doc/ └── theme.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .eslintignore ================================================ node_modules/ __fixtures__/ __fixtures_build__/ coverage/ examples/ svgr.now.sh/ /website/ dist/ ================================================ FILE: .eslintrc.json ================================================ { "root": true, "env": { "node": true }, "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint"], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:react-hooks/recommended", "plugin:react/recommended" ], "rules": { "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-empty-function": "warn", "@typescript-eslint/ban-types": "warn", "react/prop-types": "off" }, "settings": { "react": { "version": "detect" } } } ================================================ FILE: .github/FUNDING.yml ================================================ github: gregberge open_collective: svgr ================================================ FILE: .github/ISSUE_TEMPLATE/bug.md ================================================ --- name: 🐛 Bug report about: Create a report to help us improve --- ## 🐛 Bug Report A clear and concise description of what the bug is. ## To Reproduce Steps to reproduce the behavior: ## Expected behavior A clear and concise description of what you expected to happen. ## Link to repl or repo (highly encouraged) Please provide a minimal repository on GitHub. Issues without a reproduction link are likely to stall. ## Run `npx envinfo --system --binaries --npmPackages @svgr/core,@svgr/cli,@svgr/webpack,@svgr/rollup --markdown --clipboard` Paste the results here: ```bash ``` ================================================ FILE: .github/ISSUE_TEMPLATE/feature.md ================================================ --- name: 🚀 Feature Proposal about: Submit a proposal for a new feature --- ## 🚀 Feature Proposal A clear and concise description of what the feature is. ## Motivation Please outline the motivation for the proposal. ## Example Please provide an example for how this feature would be used. ## Pitch Why does this feature belong in the SVGR ecosystem? ================================================ FILE: .github/ISSUE_TEMPLATE/question.md ================================================ --- name: 💬 Questions / Help about: If you have questions, please read full readme first --- ## 💬 Questions and Help SVGR project is young, but please before asking your question: - Read carefully the README of the project - Search if your answer has already been answered in old issues After you can submit your question and we will be happy to help you! ================================================ FILE: .github/ISSUE_TEMPLATE/regression.md ================================================ --- name: 💥 Regression Report about: Report unexpected behavior that worked in previous versions --- ## 💥 Regression Report A clear and concise description of what the regression is. ## Last working version Worked up to version: Stopped working in version: ## To Reproduce Steps to reproduce the behavior: ## Expected behavior A clear and concise description of what you expected to happen. ## Link to repl or repo (highly encouraged) Please provide a minimal repository on GitHub. Issues without a reproduction link are likely to stall. ## Run `npx envinfo --system --binaries --npmPackages @svgr/core,@svgr/cli,@svgr/webpack,@svgr/rollup --markdown --clipboard` Paste the results here: ```bash ``` ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ ## 👉 [Please follow one of these issue templates](https://github.com/gregberge/svgr/issues/new/choose) 👈 Note: to keep the backlog clean and actionable, issues may be immediately closed if they do not follow one of the above issue templates. ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ## Summary ## Test plan ================================================ FILE: .github/SUPPORT.md ================================================ Please read carefully the README before asking questions. ================================================ FILE: .github/opencollective.yml ================================================ collective: svgr tiers: - tiers: '*' labels: ['backer'] message: | Hey :wave:, Thank you so much for supporting us on [Open Collective]() :heart:. We'll give a special attention to this issue. invitation: | Hey :wave:, Thank you for opening an issue. We'll get back to you as soon as we can. Please, consider supporting us on [Open Collective](). We give a special attention to issues opened by backers. If you use SVGR at work, you can also ask your company to sponsor us :heart:. ================================================ FILE: .github/stale.yml ================================================ # Number of days of inactivity before an issue becomes stale daysUntilStale: 60 # Number of days of inactivity before a stale issue is closed daysUntilClose: 7 # Label to use when marking an issue as stale staleLabel: wontfix # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI on: push: branches: [main] pull_request: branches: [main] permissions: contents: read # to fetch code (actions/checkout) jobs: build: runs-on: ubuntu-latest strategy: matrix: node-version: [14.x, 16.x, 18.x, 19.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - name: Check out repository code uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 - name: Use latest pnpm run: npm i -g pnpm@latest --registry=https://registry.npmjs.org - name: Install dependencies run: pnpm install - name: Build run: pnpm run build - name: Lint run: pnpm run lint - name: Test run: pnpm run test --ci --coverage - name: Codecov run: npx codecov ================================================ FILE: .gitignore ================================================ node_modules/ lib/ dist/ !svgr.now.sh/lib/ __fixtures_build__/ src/__fixtures__/dist/ coverage/ ================================================ FILE: .nvmrc ================================================ 18 ================================================ FILE: .prettierignore ================================================ __fixtures_build__/ __fixtures__/ CHANGELOG.md package.json lerna.json dist/ .next/ /website/.cache/ /website/public/ pnpm-workspace.yaml pnpm-lock.yaml ================================================ FILE: .prettierrc ================================================ { "singleQuote": true, "trailingComma": "all", "semi": false } ================================================ FILE: BACKERS.md ================================================ # Sponsors & Backers

Support SVGR’s development through donations.

SVGR is an MIT-licensed open source project. Even if it has been created at Smooth Code, SVGR is an independent project with ongoing development made possible thanks to the support of these awesome backers. If you'd like to join them, please consider: - [Become a backer or sponsor on OpenCollective](https://opencollective.com/svgr). ## Gold Sponsors Gold Sponsors are those who have pledged \$100/month and more to SVGR. [![gold-sponsors](https://opencollective.com/svgr/tiers/gold-sponsors.svg?avatarHeight=120&width=600)](https://opencollective.com/svgr/order/6010) ## Silver Sponsors Silver Sponsors are those who have pledged $50/month to$100/month to SVGR. [![silver-sponsors](https://opencollective.com/svgr/tiers/silver-sponsors.svg?avatarHeight=120&width=600)](https://opencollective.com/svgr/order/6008) ## Bronze Sponsors Bronze Sponsors are those who have pledged $50/month to$100/month to SVGR. [![bronze-sponsors](https://opencollective.com/svgr/tiers/bronze-sponsors.svg?avatarHeight=80&width=600)](https://opencollective.com/svgr/order/6009) ## Backers [![backers](https://opencollective.com/svgr/tiers/backer.svg?avatarHeight=50&width=600)](https://opencollective.com/svgr/order/6007) ================================================ FILE: CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.1.0](https://github.com/gregberge/svgr/compare/v8.0.1...v8.1.0) (2023-08-15) ### Bug Fixes * **cli:** fix default dimensions, prettier & svgo ([571d5c8](https://github.com/gregberge/svgr/commit/571d5c8bd18bc13c12eeb27a9052fa065aeb012e)) * **config:** prefer cli config over rc config ([#845](https://github.com/gregberge/svgr/issues/845)) ([8b97248](https://github.com/gregberge/svgr/commit/8b972484266c45c7f8e4acce4fe2930a024fb4bc)) * **react-native:** fix duplicate import ([#894](https://github.com/gregberge/svgr/issues/894)) ([e612b6a](https://github.com/gregberge/svgr/commit/e612b6a1a4e822178f1e15b82bd2991bf1e84cec)) ### Features * **esm:** add support for svgo.config.cjs ([#879](https://github.com/gregberge/svgr/issues/879)) ([ae91e2e](https://github.com/gregberge/svgr/commit/ae91e2eacbe1156480c96219b993000eb1e7b9bf)) ## [8.0.1](https://github.com/gregberge/svgr/compare/v8.0.0...v8.0.1) (2023-05-09) ### Bug Fixes * fix peer dependencies ([2e05255](https://github.com/gregberge/svgr/commit/2e0525546eb21aa4bb790aa4284f4fe34f96d6b9)) # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) ### Bug Fixes * parseObject error causes website broken ([05f2946](https://github.com/gregberge/svgr/commit/05f2946d90b194eac17d51ca0562d13e9ed0c995)) ### Features * add snake_case filename option ([#857](https://github.com/gregberge/svgr/issues/857)) ([428b0c7](https://github.com/gregberge/svgr/commit/428b0c7f4c5205bb67ae3e9e7c7e819ec3fc03ba)) * make index template more flexible ([#861](https://github.com/gregberge/svgr/issues/861)) ([003009c](https://github.com/gregberge/svgr/commit/003009c7b234cfe66686b629d3251edb8d46c759)) * **types:** change `SVGProps` from import to import type ([#853](https://github.com/gregberge/svgr/issues/853)) ([095f021](https://github.com/gregberge/svgr/commit/095f0216288ccb5b96a75f154fe3aead074bfa99)) ### BREAKING CHANGES * index template now receives an array of objects containing both the created component path (`path`) and the original SVG path (`originalPath`) # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) ### Features * allow specifying `jsxRuntimeImport` in config ([86bb86f](https://github.com/gregberge/svgr/commit/86bb86f47748618f729742e56199355d9c0bc518)), closes [#801](https://github.com/gregberge/svgr/issues/801) [#801](https://github.com/gregberge/svgr/issues/801) * remove @svgr/plugin-jsx from core ([a0f078d](https://github.com/gregberge/svgr/commit/a0f078db13936800a32c14ade08b670a14b5a886)) * upgrade to svgo v3 ([#798](https://github.com/gregberge/svgr/issues/798)) ([21b6209](https://github.com/gregberge/svgr/commit/21b6209ef34c51cc0313901f31061afe587ab29b)) ### BREAKING CHANGES * plugin-jsx is no longer included by default in core * svgr now requires Node.js v14+ ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) ### Reverts - Revert "feat(a11y): add attribute role="img" to the svg element (#750)" ([1382232](https://github.com/gregberge/svgr/commit/138223284ad9aebc5bbf94ed3ae7174a66dbc7f5)), closes [#750](https://github.com/gregberge/svgr/issues/750) # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) ### Bug Fixes - fix Yarn peer dependency warning from @babel/core ([#786](https://github.com/gregberge/svgr/issues/786)) ([db35837](https://github.com/gregberge/svgr/commit/db3583751474997dd72a0209ca61daddbac16c46)), closes [#785](https://github.com/gregberge/svgr/issues/785) ### Features - **babel-preset:** fix 'role' attribute on svg element for react native ([#787](https://github.com/gregberge/svgr/issues/787)) ([35d85e0](https://github.com/gregberge/svgr/commit/35d85e069ebfef1b26ba181f443d9377a7bc003e)) # [6.4.0](https://github.com/gregberge/svgr/compare/v6.3.1...v6.4.0) (2022-10-01) ### Bug Fixes - **deps:** add babel-preset to core dependencies ([#782](https://github.com/gregberge/svgr/issues/782)) ([464ec5f](https://github.com/gregberge/svgr/commit/464ec5fe81c6ba98be5a26923f3ad19fc2ef7fc6)) ### Features - **a11y:** add attribute role="img" to the svg element ([#750](https://github.com/gregberge/svgr/issues/750)) ([8b9edc4](https://github.com/gregberge/svgr/commit/8b9edc4e712f3adbd9f9c503dfc5e4d627f763cd)) - support spaces in file names ([#779](https://github.com/gregberge/svgr/issues/779)) ([6ee639a](https://github.com/gregberge/svgr/commit/6ee639a039a0001d3b97fef024f2bd0c3e107182)) ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix duplicate plugin/preset detected error ([#747](https://github.com/gregberge/svgr/issues/747)) ([3c6a54c](https://github.com/gregberge/svgr/commit/3c6a54c494bb8ff15f332ff2d44e9f6465a6c19a)), closes [#746](https://github.com/gregberge/svgr/issues/746) - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **core:** types field in package.json ([#693](https://github.com/gregberge/svgr/issues/693)) ([a491ace](https://github.com/gregberge/svgr/commit/a491acee1b3fbe1cae304dbc399193cdb2148e1d)) - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ### Features - add descProp option ([#729](https://github.com/gregberge/svgr/issues/729)) ([a0637d4](https://github.com/gregberge/svgr/commit/a0637d49b60243bbae461f7b96dab9b47cd82d8f)) - **cli:** output file name when error happen to handling a file ([#702](https://github.com/gregberge/svgr/issues/702)) ([0ec1fbd](https://github.com/gregberge/svgr/commit/0ec1fbd0bf1e020ecd8f53fba38d7e53d2462b27)) ## [6.2.1](https://github.com/gregberge/svgr/compare/v6.2.0...v6.2.1) (2022-01-30) ### Bug Fixes - do not transform mask-type ([#673](https://github.com/gregberge/svgr/issues/673)) ([6e58f2c](https://github.com/gregberge/svgr/commit/6e58f2cb456bf5fbfa011ab8f8154333c0724e34)), closes [#643](https://github.com/gregberge/svgr/issues/643) - use .ts extension for generated index ([#670](https://github.com/gregberge/svgr/issues/670)) ([d19abe2](https://github.com/gregberge/svgr/commit/d19abe207013f4e880a78f236e9f75b0151258da)), closes [#462](https://github.com/gregberge/svgr/issues/462) # [6.2.0](https://github.com/gregberge/svgr/compare/v6.1.2...v6.2.0) (2022-01-10) ### Bug Fixes - **cli:** pass in parser to prettier format to avoid deprecation warning ([#662](https://github.com/gregberge/svgr/issues/662)) ([74fa3ae](https://github.com/gregberge/svgr/commit/74fa3aed2944b63797a6e0e786acd1b51f86550a)) - **plugin-svgo:** handle potential errors from optimize ([#663](https://github.com/gregberge/svgr/issues/663)) ([7582d31](https://github.com/gregberge/svgr/commit/7582d3130e5b6eb0f962e283f956a84552f839a6)) ### Features - support comments in templates ([#661](https://github.com/gregberge/svgr/issues/661)) ([9afb590](https://github.com/gregberge/svgr/commit/9afb590d1094793fca797449fb7017da9fa06b4e)) ## [6.1.2](https://github.com/gregberge/svgr/compare/v6.1.1...v6.1.2) (2021-12-12) ### Bug Fixes - **rollup:** missing dep & missing map return ([#652](https://github.com/gregberge/svgr/issues/652)) ([12627fc](https://github.com/gregberge/svgr/commit/12627fcd91a425361e1fbe825a6668ce9a8b4f3b)) - specify valid peer deps ([45a76ed](https://github.com/gregberge/svgr/commit/45a76ed5f7d433e549c8513c0fdab08eb6c7bc2c)) ## [6.1.1](https://github.com/gregberge/svgr/compare/v6.1.0...v6.1.1) (2021-12-04) ### Bug Fixes - **webpack:** fix double export ([#648](https://github.com/gregberge/svgr/issues/648)) ([7595d37](https://github.com/gregberge/svgr/commit/7595d378b73d4826a4cead165b3f32386b07315b)), closes [#645](https://github.com/gregberge/svgr/issues/645) # [6.1.0](https://github.com/gregberge/svgr/compare/v6.0.0...v6.1.0) (2021-12-01) ### BREAKING CHANGES - svgr v6 is now only compatible with **Webpack v5** and up. See the [migration guide](https://react-svgr.com/docs/migrate/#webpack) ### Bug Fixes - fix previous export system ([1872829](https://github.com/gregberge/svgr/commit/187282977af841cd5a2243a23abba72b20eec2fa)), closes [#635](https://github.com/gregberge/svgr/issues/635) ### Features - **native:** automatically convert inline style in native ([138c493](https://github.com/gregberge/svgr/commit/138c493b2ae0c5c1cef488cf9ff7f94827dc2aa5)), closes [#588](https://github.com/gregberge/svgr/issues/588) ### Performance Improvements - remove useless loader-utils package ([387bc72](https://github.com/gregberge/svgr/commit/387bc727a4e07c2668544e3f5afbefe29a3de909)), closes [#631](https://github.com/gregberge/svgr/issues/631) # [5.5.0](https://github.com/gregberge/svgr/compare/v5.4.0...v5.5.0) (2020-11-15) ### Bug Fixes - **typescript:** fix react-native support [#465](https://github.com/gregberge/svgr/issues/465) ([#488](https://github.com/gregberge/svgr/issues/488)) ([d61e0cf](https://github.com/gregberge/svgr/commit/d61e0cface065afc1478fdb44d87ca8177041eab)) - ensure a valid name for exports ([#489](https://github.com/gregberge/svgr/issues/489)) ([0eb8085](https://github.com/gregberge/svgr/commit/0eb80853e53a55226881f6ae3b50c1afe89f1cfc)) - fix playground ([c7ad69f](https://github.com/gregberge/svgr/commit/c7ad69fff347afdca3410e4fb1da235be01b1ac8)) - prevent removing the namespace by svgr ([[#475](https://github.com/gregberge/svgr/issues/475)](https://github.com/gregberge/svgr/issues/475) ([#498](https://github.com/gregberge/svgr/issues/498)) ([00e84ea](https://github.com/gregberge/svgr/commit/00e84ead96d89bcbd072b9585b4db1365e392d33)) ### Features - allow custom name for named export ([#493](https://github.com/gregberge/svgr/issues/493)) ([16a58d6](https://github.com/gregberge/svgr/commit/16a58d6e817c065f72a68be91600a1a360205f44)) - **svgo:** add .svgorc.js config file support ([#451](https://github.com/gregberge/svgr/issues/451)) ([8049b1a](https://github.com/gregberge/svgr/commit/8049b1a63603672096892b6ab3d303580c2f303f)), closes [#412](https://github.com/gregberge/svgr/issues/412) ### Performance Improvements - **cli:** use fs.promises ([#459](https://github.com/gregberge/svgr/issues/459)) ([af294ac](https://github.com/gregberge/svgr/commit/af294ac3b86e7c39e78fc8b348110baf8c690949)) - replace merge-deep with smaller deepmerge ([#463](https://github.com/gregberge/svgr/issues/463)) ([1f015eb](https://github.com/gregberge/svgr/commit/1f015eb16fca093a08b012236dc83623f7bcce55)) # [5.4.0](https://github.com/gregberge/svgr/compare/v5.3.1...v5.4.0) (2020-04-27) ### Bug Fixes - wrap svg component directly with memo/forwardRef ([#440](https://github.com/gregberge/svgr/issues/440)) ([#441](https://github.com/gregberge/svgr/issues/441)) ([a6de2da](https://github.com/gregberge/svgr/commit/a6de2dacb63e36572a2167b928418bdc39f3a9c2)) - **cli:** fix index generation ([#443](https://github.com/gregberge/svgr/issues/443)) ([7c46ad7](https://github.com/gregberge/svgr/commit/7c46ad73695c42e6153761c931377d65b71835ea)), closes [#433](https://github.com/gregberge/svgr/issues/433) ### Features - add `ForeignObject` support for react native ([#430](https://github.com/gregberge/svgr/issues/430)) ([1b56b85](https://github.com/gregberge/svgr/commit/1b56b851478803d40105ce63c70e457bd3183da6)) - **cli:** make all CLI options available in config ([a23a186](https://github.com/gregberge/svgr/commit/a23a18675c0dd4a461d2fcbdc72a305cabd32a13)), closes [#431](https://github.com/gregberge/svgr/issues/431) [#437](https://github.com/gregberge/svgr/issues/437) ## [5.3.1](https://github.com/gregberge/svgr/compare/v5.3.0...v5.3.1) (2020-04-05) ### Bug Fixes - fix typescript types (ref, title) ([#419](https://github.com/gregberge/svgr/issues/419)) ([6e7e6b2](https://github.com/gregberge/svgr/commit/6e7e6b2e73d26d30f64604e0fc627f9ff94079c2)) # [5.3.0](https://github.com/gregberge/svgr/compare/v5.2.0...v5.3.0) (2020-03-22) ### Bug Fixes - **cli:** remove confusion between {keep,ignore}-existing ([#413](https://github.com/gregberge/svgr/issues/413)) ([c5430f9](https://github.com/gregberge/svgr/commit/c5430f97b053a7d2d85c85c56b87dfc8c9c1f09a)), closes [#390](https://github.com/gregberge/svgr/issues/390) - **parcel-plugin:** support "parcel" and "parcel-bundler" ([853db4e](https://github.com/gregberge/svgr/commit/853db4ef0e9da4952e8189e3f86fb62e6c506693)), closes [#410](https://github.com/gregberge/svgr/issues/410) - **svgo:** support any SVGO config format ([#412](https://github.com/gregberge/svgr/issues/412)) ([f2b2367](https://github.com/gregberge/svgr/commit/f2b2367389fda20baba6e0a5e884e7f7fe29a3ed)), closes [#400](https://github.com/gregberge/svgr/issues/400) ### Features - add typescript option ([4596d7b](https://github.com/gregberge/svgr/commit/4596d7bb470babb5ec4b87f5281174fb182bd9c7)), closes [#373](https://github.com/gregberge/svgr/issues/373) # [5.2.0](https://github.com/smooth-code/svgr/compare/v5.1.0...v5.2.0) (2020-02-23) ### Bug Fixes - verify that `svgoConfig.plugins` is an array ([#397](https://github.com/smooth-code/svgr/issues/397)) ([88110b6](https://github.com/smooth-code/svgr/commit/88110b6eb4d93ded68ca2de05cc82654dfac977d)) ### Features - **parcel-plugin:** replace `parcel-bundler` with `parcel` ([#387](https://github.com/smooth-code/svgr/issues/387)) ([d09bcd5](https://github.com/smooth-code/svgr/commit/d09bcd5d7ba21c8845c6042928bbdf14165e787b)) # [5.1.0](https://github.com/smooth-code/svgr/compare/v5.0.1...v5.1.0) (2020-01-20) ### Bug Fixes - fix merging svgo plugins in config ([#384](https://github.com/smooth-code/svgr/issues/384)) ([c9d2dfc](https://github.com/smooth-code/svgr/commit/c9d2dfcb8d4da55eb21a13507c87d9e549a86e7e)) ### Features - add Svg prefix to exports that starts with a number ([#383](https://github.com/smooth-code/svgr/issues/383)) ([fd120d1](https://github.com/smooth-code/svgr/commit/fd120d11c81395353f300da487295b769f6b9501)), closes [#379](https://github.com/smooth-code/svgr/issues/379) - allow to provide custom index.js template ([#378](https://github.com/smooth-code/svgr/issues/378)) ([f734dda](https://github.com/smooth-code/svgr/commit/f734ddac8e639ad213a3ce09689e46226fd5c1e0)) ## [5.0.1](https://github.com/smooth-code/svgr/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/smooth-code/svgr/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) ## [4.3.3](https://github.com/gregberge/svgr/compare/v4.3.2...v4.3.3) (2019-09-24) ### Bug Fixes - **babel-plugin-svg-dynamic-title:** dont render empty title ([#341](https://github.com/gregberge/svgr/issues/341)) ([88b24c5](https://github.com/gregberge/svgr/commit/88b24c5)), closes [#333](https://github.com/gregberge/svgr/issues/333) - invalid characters in component name ([#332](https://github.com/gregberge/svgr/issues/332)) ([4b4bd2c](https://github.com/gregberge/svgr/commit/4b4bd2c)), closes [#331](https://github.com/gregberge/svgr/issues/331) ## [4.3.2](https://github.com/gregberge/svgr/compare/v4.3.1...v4.3.2) (2019-07-15) ### Performance Improvements - replace rehype with svg-parser ([#321](https://github.com/gregberge/svgr/issues/321)) ([7eb5ef6](https://github.com/gregberge/svgr/commit/7eb5ef6)) ## [4.3.1](https://github.com/gregberge/svgr/compare/v4.3.0...v4.3.1) (2019-07-01) ### Bug Fixes - **titleProp:** handle the existing title case by using element instead of value (children) ([#315](https://github.com/gregberge/svgr/issues/315)) ([065e7a9](https://github.com/gregberge/svgr/commit/065e7a9)) # [4.3.0](https://github.com/gregberge/svgr/compare/v4.2.0...v4.3.0) (2019-05-28) ### Features - **cli:** output relative destination paths ([#312](https://github.com/gregberge/svgr/issues/312)) ([b78e471](https://github.com/gregberge/svgr/commit/b78e471)) - titleProps fallbacks to svg's title ([#311](https://github.com/gregberge/svgr/issues/311)) ([8f92366](https://github.com/gregberge/svgr/commit/8f92366)) # [4.2.0](https://github.com/gregberge/svgr/compare/v4.1.0...v4.2.0) (2019-04-11) ### Bug Fixes - keep viewBox when dimensions are removed ([#281](https://github.com/gregberge/svgr/issues/281)) ([f476c8e](https://github.com/gregberge/svgr/commit/f476c8e)) - **babel-preset:** expandProps + icon option ([ddfae22](https://github.com/gregberge/svgr/commit/ddfae22)), closes [#277](https://github.com/gregberge/svgr/issues/277) - **cli:** fix kebab case transformation with "\_" ([39c24c5](https://github.com/gregberge/svgr/commit/39c24c5)), closes [#280](https://github.com/gregberge/svgr/issues/280) - **hast-util-to-babel-ast:** correctly handle aria attributes ([23d12aa](https://github.com/gregberge/svgr/commit/23d12aa)), closes [#279](https://github.com/gregberge/svgr/issues/279) - **plugin-prettier:** fix prettier warning ([d01d33f](https://github.com/gregberge/svgr/commit/d01d33f)) ### Features - add expo option ([#289](https://github.com/gregberge/svgr/issues/289)) ([978db3e](https://github.com/gregberge/svgr/commit/978db3e)) # [4.1.0](https://github.com/gregberge/svgr/compare/v4.0.4...v4.1.0) (2018-11-24) ### Features - add parcel plugin ([#235](https://github.com/gregberge/svgr/issues/235)) ([144dbe3](https://github.com/gregberge/svgr/commit/144dbe3)), closes [#215](https://github.com/gregberge/svgr/issues/215) ## [4.0.4](https://github.com/gregberge/svgr/compare/v4.0.3...v4.0.4) (2018-11-24) ### Bug Fixes - **webpack:** use static babel config ([#240](https://github.com/gregberge/svgr/issues/240)) ([d67af31](https://github.com/gregberge/svgr/commit/d67af31)), closes [#232](https://github.com/gregberge/svgr/issues/232) ## [4.0.3](https://github.com/gregberge/svgr/compare/v4.0.2...v4.0.3) (2018-11-13) ### Bug Fixes - **babel-plugin:** fix usage of spread attribute([#231](https://github.com/gregberge/svgr/issues/231)) ([4186953](https://github.com/gregberge/svgr/commit/4186953)) - upgrade dependencies ([7e2195f](https://github.com/gregberge/svgr/commit/7e2195f)) ## [4.0.2](https://github.com/gregberge/svgr/compare/v4.0.1...v4.0.2) (2018-11-08) ### Bug Fixes - **hast-util-to-babel-ast:** replace tabs by spaces in attributes ([b0f3d19](https://github.com/gregberge/svgr/commit/b0f3d19)), closes [#219](https://github.com/gregberge/svgr/issues/219) ## [4.0.1](https://github.com/gregberge/svgr/compare/v4.0.0...v4.0.1) (2018-11-08) ### Bug Fixes - **babel-plugin-transform-svg:** support template that only return a single node ([80ac40f](https://github.com/gregberge/svgr/commit/80ac40f)), closes [#223](https://github.com/gregberge/svgr/issues/223) - **babel-plugin-transform-svg-component:** parsing error of JSX template exports defs ([#225](https://github.com/gregberge/svgr/issues/225)) ([1e56309](https://github.com/gregberge/svgr/commit/1e56309)), closes [/github.com/gregberge/svgr/blob/master/packages/babel-plugin-transform-svg-component/src/util.js#L61](https://github.com//github.com/gregberge/svgr/blob/master/packages/babel-plugin-transform-svg-component/src/util.js/issues/L61) - **hast-util-to-babel-ast:** correctly transforms data & aria attributes ([99711c4](https://github.com/gregberge/svgr/commit/99711c4)), closes [#221](https://github.com/gregberge/svgr/issues/221) - **hast-util-to-babel-ast:** replace line-breaks in attributes ([00a2625](https://github.com/gregberge/svgr/commit/00a2625)), closes [#219](https://github.com/gregberge/svgr/issues/219) # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Bug Fixes - prevent babel read babel.config.js ([#206](https://github.com/gregberge/svgr/issues/206)) ([514d43d](https://github.com/gregberge/svgr/commit/514d43d)) - **cli:** fix --out-dir usage with absolute path ([#208](https://github.com/gregberge/svgr/issues/208)) ([c922e2e](https://github.com/gregberge/svgr/commit/c922e2e)) ### Features - **svgo:** prefix ids by default ([06c338d](https://github.com/gregberge/svgr/commit/06c338d)), closes [#210](https://github.com/gregberge/svgr/issues/210) - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) - allow dynamic properties in replaceAttrValues option ([15f55fe](https://github.com/gregberge/svgr/commit/15f55fe)), closes [#205](https://github.com/gregberge/svgr/issues/205) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default # [3.1.0](https://github.com/gregberge/svgr/compare/v3.0.0...v3.1.0) (2018-10-05) ### Bug Fixes - style & custom SVG properties ([#203](https://github.com/gregberge/svgr/issues/203)) ([f8b2212](https://github.com/gregberge/svgr/commit/f8b2212)), closes [#199](https://github.com/gregberge/svgr/issues/199) [#201](https://github.com/gregberge/svgr/issues/201) ### Features - allow Mask & Image on React Native ([#202](https://github.com/gregberge/svgr/issues/202)) ([0256bc0](https://github.com/gregberge/svgr/commit/0256bc0)) # [3.0.0](https://github.com/gregberge/svgr/compare/v2.4.1...v3.0.0) (2018-10-01) ### Bug Fixes - **rollup:** forward filePath in rollup plugin ([461492b](https://github.com/gregberge/svgr/commit/461492b)), closes [#177](https://github.com/gregberge/svgr/issues/177) [#188](https://github.com/gregberge/svgr/issues/188) - **webpack:** forward filePath in webpack loader ([b7a108e](https://github.com/gregberge/svgr/commit/b7a108e)), closes [#177](https://github.com/gregberge/svgr/issues/177) [#188](https://github.com/gregberge/svgr/issues/188) - fix --icon + --no-dimensions ([7535693](https://github.com/gregberge/svgr/commit/7535693)), closes [#141](https://github.com/gregberge/svgr/issues/141) - fix expandProps when position is not allowed ([45522fc](https://github.com/gregberge/svgr/commit/45522fc)) ### Features - **config:** improve runtime config ([e52cdce](https://github.com/gregberge/svgr/commit/e52cdce)), closes [#192](https://github.com/gregberge/svgr/issues/192) - **template:** expose `getProps` util for template ([5cb238e](https://github.com/gregberge/svgr/commit/5cb238e)), closes [#187](https://github.com/gregberge/svgr/issues/187) - add synchronous API ([169eb2f](https://github.com/gregberge/svgr/commit/169eb2f)), closes [#185](https://github.com/gregberge/svgr/issues/185) - always prefix component name with "Svg" ([f71aa7a](https://github.com/gregberge/svgr/commit/f71aa7a)), closes [#190](https://github.com/gregberge/svgr/issues/190) - do not remove style tag ([a4ce09a](https://github.com/gregberge/svgr/commit/a4ce09a)), closes [#191](https://github.com/gregberge/svgr/issues/191) - new "expandProps" option ([bb95828](https://github.com/gregberge/svgr/commit/bb95828)), closes [#170](https://github.com/gregberge/svgr/issues/170) - remove "svgAttributes" option ([4e46a5d](https://github.com/gregberge/svgr/commit/4e46a5d)), closes [#173](https://github.com/gregberge/svgr/issues/173) - use forwardRef on React Native ([4bdd989](https://github.com/gregberge/svgr/commit/4bdd989)), closes [#184](https://github.com/gregberge/svgr/issues/184) - use React.forwardRef ([cbee51c](https://github.com/gregberge/svgr/commit/cbee51c)), closes [#184](https://github.com/gregberge/svgr/issues/184) ### BREAKING CHANGES - "--no-expand-props" is now replaced by "--expand-props none". You can now specify a position "start" or "end" for "expandProps" property. - `svgAttributes` has been removed, please use `svgProps` instead. - "ref" option now uses `React.forwardRef`. You don't have to use "svgRef" prop, just use "ref" and it will work. `React.forwardRef` requires React > 16.3. - Style tag will no longer be automatically removed. SVGO should handle it correctly using "inlineStyles" plugin. If you want to remove them, enable "removeStyleElement" plugin in your SVGO config. - **rollup:** runtime configuration is now loaded using rollup plugin. - **webpack:** runtime configuration is now loaded using webpack loader. - **config:** - Runtime configuration is always loaded (even with Node API `convert`) * In CLI, "--config" is now "--config-file"; this new option can be used everywhere ## [2.4.1](https://github.com/gregberge/svgr/compare/v2.4.0...v2.4.1) (2018-09-16) ### Bug Fixes - **config:** fix custom config & default options ([#176](https://github.com/gregberge/svgr/issues/176)) ([9a6c40b](https://github.com/gregberge/svgr/commit/9a6c40b)) # [2.4.0](https://github.com/gregberge/svgr/compare/v2.3.0...v2.4.0) (2018-09-16) ### Bug Fixes - use literal instead of litteral ([7849fd4](https://github.com/gregberge/svgr/commit/7849fd4)) ### Features - allow to spread props at the start ([#166](https://github.com/gregberge/svgr/issues/166)) ([cd659dc](https://github.com/gregberge/svgr/commit/cd659dc)) - **upgrade:** h2x@1.1.0 (jsdom@12.0.0) & others ([2d9b7bd](https://github.com/gregberge/svgr/commit/2d9b7bd)) - new option "svgProps" ([#172](https://github.com/gregberge/svgr/issues/172)) ([9657110](https://github.com/gregberge/svgr/commit/9657110)) # [2.3.0](https://github.com/gregberge/svgr/compare/v2.2.1...v2.3.0) (2018-09-03) ### Features - upgrade to Babel v7 ([7bc908d](https://github.com/gregberge/svgr/commit/7bc908d)) ## [2.2.1](https://github.com/gregberge/svgr/compare/v2.2.0...v2.2.1) (2018-08-16) ### Bug Fixes - **rollup:** fix to work with rollup-plugin-typescript2 ([#147](https://github.com/gregberge/svgr/issues/147)) ([4b3737e](https://github.com/gregberge/svgr/commit/4b3737e)) # [2.2.0](https://github.com/gregberge/svgr/compare/v2.1.1...v2.2.0) (2018-08-13) ### Bug Fixes - remove null-byte characters ([#154](https://github.com/gregberge/svgr/issues/154)) ([de7f8a7](https://github.com/gregberge/svgr/commit/de7f8a7)), closes [#153](https://github.com/gregberge/svgr/issues/153) - **webpack:** use source when possible ([#139](https://github.com/gregberge/svgr/issues/139)) ([ae9965d](https://github.com/gregberge/svgr/commit/ae9965d)) ### Features - **core:** pass info to SVGO ([2b2353b](https://github.com/gregberge/svgr/commit/2b2353b)), closes [#152](https://github.com/gregberge/svgr/issues/152) ## [2.1.1](https://github.com/gregberge/svgr/compare/v2.1.0...v2.1.1) (2018-07-11) ### Bug Fixes - **core:** config conflict with icon option ([#137](https://github.com/gregberge/svgr/issues/137)) ([e13a99a](https://github.com/gregberge/svgr/commit/e13a99a)) # [2.1.0](https://github.com/gregberge/svgr/compare/v2.0.0...v2.1.0) (2018-07-08) ### Features - add .editorconfig support ([#129](https://github.com/gregberge/svgr/issues/129)) ([968fd82](https://github.com/gregberge/svgr/commit/968fd82)) - **cli:** support custom filename cases ([#136](https://github.com/gregberge/svgr/issues/136)) ([4922f7a](https://github.com/gregberge/svgr/commit/4922f7a)), closes [#118](https://github.com/gregberge/svgr/issues/118) # [2.0.0](https://github.com/gregberge/svgr/compare/v1.10.0...v2.0.0) (2018-06-12) ### Features #### Project configurations SVGR now supports Prettier (`.prettierc`) and SVGO (`.svgo.yml`) configurations. It also supports a new `.svgrrc` configuration. See the readme for more detail. #### Rollup plugin Rollup has now an official SVGR plugin available under `@svgr/rollup`. #### Split into several modules SVGR is now an ecosystem of four modules: - `@svgr/core`: Core of SVGR, it exposes the Node API - `@svgr/cli`: Command Line Interface - `@svgr/webpack`: webpack loader - `@svgr/rollup`: a fresh new Rollup plugin #### `svgAttributes` and `titleProp` options Two new options appears, the first one `svgAttributes` gives you the opportunity to add attribute on the root `svg` tag without creating a custom template: Command: ``` svgr --svg-attributes focusable=true foo.svg ``` Output: ```js ;(props) => ``` The second one, `titleProp`, adds a custom property `title` to specify the title of the SVG. Command: ``` svgr --title-prop foo.svg ``` Output: ```js ;({ title }) => ( {title} ) ``` ### Breaking changes #### Node version Node v6 support has been dropped, you need Node >= 8 to run SVGR. #### Prettier options All Prettier options have been removed: - `jsx-bracket-same-line` - `no-bracket-spacing` - `no-semi` - `single-quote` - `tab-width` - `trailing-comma` - `use-tabs` If you used it, use a `.prettierrc` instead of use the new option `--prettier-config`: v1.x: ``` svgr --no-semi file.svg ``` v2.x: ``` svgr --prettier-config '{"semi": true}' file.svg ``` #### SVGO options All SVGO options have been removed: - `ids` - `keep-useless-defs` - `no-title` - `no-view-box` - `precision` If you used it, use a `.svgo.yml` instead of use the new option `--svgo-config`: v1.x: ``` svgr --ids file.svg ``` v2.x: ``` svgr --svgo-config '{"plugins": [{"cleanupIDs": {"remove": false, "minify": false}}]}' file.svg ``` #### Other options - `replace-attr-value` has been renamed into `replace-attr-values` In API, `replaceAttrValues` is now an object instead of an array. #### Node API changes - `rawConvert` method has been dropped - Templates now receive three arguments: `code`, `config` and `state` - `componentName` must now be passed in state ### Thanks Thanks to [@MarquesDev](https://github.com/MarquesDev) and [@lifeiscontent](https://github.com/lifeiscontent). # [1.10.0](https://github.com/gregberge/svgr/compare/v1.9.2...v1.10.0) (2018-05-28) ### Features - upgrade Prettier (v1.13) ([2f50403](https://github.com/gregberge/svgr/commit/2f50403)), closes [#108](https://github.com/gregberge/svgr/issues/108) ## [1.9.2](https://github.com/gregberge/svgr/compare/v1.9.1...v1.9.2) (2018-05-14) ### Bug Fixes - **ids:** do not minify them ([538b73f](https://github.com/gregberge/svgr/commit/538b73f)) ## [1.9.1](https://github.com/gregberge/svgr/compare/v1.9.0...v1.9.1) (2018-03-25) ### Bug Fixes - fix width / height override ([1f91705](https://github.com/gregberge/svgr/commit/1f91705)), closes [#issuecomment-375467614](https://github.com/gregberge/svgr/issues/issuecomment-375467614) - handle filename with numbers ([a2387ea](https://github.com/gregberge/svgr/commit/a2387ea)), closes [#62](https://github.com/gregberge/svgr/issues/62) [#64](https://github.com/gregberge/svgr/issues/64) # [1.9.0](https://github.com/gregberge/svgr/compare/v1.8.1...v1.9.0) (2018-03-08) ### Features - add option to removeDimensions ([#58](https://github.com/gregberge/svgr/issues/58)) ([7357e7c](https://github.com/gregberge/svgr/commit/7357e7c)) ## [1.8.1](https://github.com/gregberge/svgr/compare/v1.8.0...v1.8.1) (2018-01-31) ### Bug Fixes - **loader:** add missing babel-plugin ([#50](https://github.com/gregberge/svgr/issues/50)) ([c49b627](https://github.com/gregberge/svgr/commit/c49b627)) # [1.8.0](https://github.com/gregberge/svgr/compare/v1.7.0...v1.8.0) (2018-01-31) ### Bug Fixes - fix tabWidth option ([#49](https://github.com/gregberge/svgr/issues/49)) ([a863280](https://github.com/gregberge/svgr/commit/a863280)), closes [#33](https://github.com/gregberge/svgr/issues/33) ### Features - support custom file extension ([#47](https://github.com/gregberge/svgr/issues/47)) ([56a111f](https://github.com/gregberge/svgr/commit/56a111f)), closes [#31](https://github.com/gregberge/svgr/issues/31) - **webpack:** include Babel transformation ([#48](https://github.com/gregberge/svgr/issues/48)) ([dfecd39](https://github.com/gregberge/svgr/commit/dfecd39)), closes [#45](https://github.com/gregberge/svgr/issues/45) # [1.7.0](https://github.com/gregberge/svgr/compare/v1.6.0...v1.7.0) (2018-01-23) ### Features - **emSize:** add support for missing width/height ([2eacfd8](https://github.com/gregberge/svgr/commit/2eacfd8)) - add option keepUselessDefs ([3d03510](https://github.com/gregberge/svgr/commit/3d03510)), closes [#36](https://github.com/gregberge/svgr/issues/36) ### Performance Improvements - refactor emSize to reduce iterations ([3c9d8b4](https://github.com/gregberge/svgr/commit/3c9d8b4)) # [1.6.0](https://github.com/gregberge/svgr/compare/v1.5.0...v1.6.0) (2018-01-08) ### Features - support url-loader & file-loader ([b95ed07](https://github.com/gregberge/svgr/commit/b95ed07)) # [1.5.0](https://github.com/gregberge/svgr/compare/v1.4.0...v1.5.0) (2017-12-12) ### Features - add ref option ([#29](https://github.com/gregberge/svgr/issues/29)) ([86e0bda](https://github.com/gregberge/svgr/commit/86e0bda)) # [1.4.0](https://github.com/gregberge/svgr/compare/v1.3.0...v1.4.0) (2017-12-07) ### Features - add "-native" option to target React Native ([76fd6f5](https://github.com/gregberge/svgr/commit/76fd6f5)) - **native:** import only relevant components ([fcd4229](https://github.com/gregberge/svgr/commit/fcd4229)) - **native:** log unsupported components ([888d968](https://github.com/gregberge/svgr/commit/888d968)) # [1.3.0](https://github.com/gregberge/svgr/compare/v1.1.0...v1.3.0) (2017-12-05) ### Features - add option to keeps IDs from SVG ([bfd4066](https://github.com/gregberge/svgr/commit/bfd4066)) # [1.2.0](https://github.com/gregberge/svgr/compare/v1.1.0...v1.2.0) (2017-12-04) ### Features - simplify webpack usage ([7ac643e](https://github.com/gregberge/svgr/commit/7ac643e)) # [1.1.0](https://github.com/gregberge/svgr/compare/v1.0.0...v1.1.0) (2017-11-24) ### Features - add viewBox option that default to true ([ba2be3a](https://github.com/gregberge/svgr/commit/ba2be3a)) # [1.0.0](https://github.com/gregberge/svgr/compare/v0.5.0...v1.0.0) (2017-11-07) ### Features - upgrade svgo & prettier ([fd66885](https://github.com/gregberge/svgr/commit/fd66885)) ### BREAKING CHANGES - SVGO now removes viewBox automatically. ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: - Using welcoming and inclusive language - Being respectful of differing viewpoints and experiences - Gracefully accepting constructive criticism - Focusing on what is best for the community - Showing empathy towards other community members Examples of unacceptable behavior by participants include: - The use of sexualized language or imagery and unwelcome sexual attention or advances - Trolling, insulting/derogatory comments, and personal or political attacks - Public or private harassment - Publishing others' private information, such as a physical or electronic address, without explicit permission - Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hey@gregberge.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ ================================================ FILE: CONTRIBUTING.md ================================================ # How to Contribute SVGR is a small project, it is widely used but has not a lot of contributors. We're still working out the kinks to make contributing to this project as easy and transparent as possible, but we're not quite there yet. Hopefully this document makes the process for contributing clear and answers some questions that you may have. ## [Code of Conduct](https://github.com/gregberge/svgr/blob/master/CODE_OF_CONDUCT.md) We expect project participants to adhere to our Code of Conduct. Please read [the full text](https://github.com/gregberge/svgr/blob/master/CODE_OF_CONDUCT.md) so that you can understand what actions will and will not be tolerated. ## Open Development All work on SVGR happens directly on [GitHub](/). Both core team members and external contributors send pull requests which go through the same review process. The SVGR repo is a monorepo using pnpm workspaces and [Lerna](https://lerna.js.org/docs/recipes/using-pnpm-with-lerna). The package manager used to install and link dependencies must be [pnpm](https://pnpm.io/). Note that website still uses npm, as there are some errors reported when using pnpm in gatsby. ### Online one click Setup You can use Gitpod(An Online Open Source VS Code like IDE which is free for Open Source) for contributing online. With a single click it will start a workspace and automatically: - clone the `svgr` repo. - install dependencies in '/': `pnpm install` - install dependencies in '/website': `npm install` - run `pnpm run dev` in `/`. - run `npm run dev` in `/website` to start the dev server. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) ### Workflow and Pull Requests _Before_ submitting a pull request, please make sure the following is done… 1. Fork the repo and create your branch from `main`. A guide on how to fork a repository: https://help.github.com/articles/fork-a-repo/ Open terminal (e.g. Terminal, iTerm, Git Bash or Git Shell) and type: ```sh-session $ git clone https://github.com//svgr $ cd svgr $ git checkout -b my_branch ``` Note: Replace `` with your GitHub username 2. Run `pnpm install` and `pnpm run build`. 3. If you've added code that should be tested, add tests. You can use watch mode that continuously transforms changed files to make your life easier. ```sh # in the background pnpm run dev ``` 4. If you've changed APIs, update the documentation. 5. Ensure the linting is good via `npm run lint`. ```sh-session $ pnpm run lint ``` 6. Ensure the test suite passes via `npm run test`. ```sh-session $ pnpm run test ``` ## Bugs ### Where to Find Known Issues We will be using GitHub Issues for our public bugs. We will keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new issue, try to make sure your problem doesn't already exist. ### Reporting New Issues The best way to get your bug fixed is to provide a reduced test case. Please provide a public repository with a runnable example. ## Code Conventions Please follow the `.prettierrc` in the project. ## Credits This project exists thanks to all the people who [contribute](CONTRIBUTING.md). ### [Backers](https://opencollective.com/svgr#backer) Thank you to all our backers! 🙏 ### [Sponsors](https://opencollective.com/svgr#sponsor) Support this project by becoming a sponsor. Your logo will show up here with a link to your website. ## License By contributing to SVGR, you agree that your contributions will be licensed under its MIT license. ================================================ FILE: LICENSE ================================================ Copyright 2017 Smooth Code Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================

svgr

Transform SVGs into React components 🦁

[![License](https://img.shields.io/npm/l/@svgr/core.svg)](https://github.com/gregberge/svgr/blob/master/LICENSE) [![Donate](https://opencollective.com/svgr/backers/badge.svg)](https://opencollective.com/svgr/donate) [![npm package](https://img.shields.io/npm/v/@svgr/core/latest.svg)](https://www.npmjs.com/package/@svgr/core) [![npm downloads](https://img.shields.io/npm/dm/@svgr/core.svg)](https://www.npmjs.com/package/@svgr/core) [![CI](https://github.com/gregberge/svgr/actions/workflows/ci.yml/badge.svg)](https://github.com/gregberge/svgr/actions/workflows/ci.yml) [![Code Coverage](https://img.shields.io/codecov/c/github/gregberge/svgr.svg)](https://codecov.io/github/gregberge/svgr) [**Try it out online!**](https://react-svgr.com/playground) [**Watch the talk at React Europe**](https://www.youtube.com/watch?v=geKCzi7ZPkA) SVGR is an universal tool to transform SVG into React components. SVGR takes a raw SVG and transforms it into a ready-to-use React component. ## [Docs](https://react-svgr.com) **See the documentation at [react-svgr.com](https://react-svgr.com)** for more information about using `svgr`! Quicklinks to some of the most-visited pages: - [**Playground**](https://react-svgr.com/playground/) - [**Getting started**](https://react-svgr.com/docs/getting-started/) - [CLI usage](https://react-svgr.com/docs/cli/) - [Webpack usage](https://react-svgr.com/docs/webpack/) - [Node.js usage](https://react-svgr.com/docs/node-api/) ## Example **Take a SVG**: ```html Rectangle 5 Created with Sketch. ``` **Run SVGR** ```sh npx @svgr/cli --icon --replace-attr-values "#063855=currentColor" -- icon.svg ``` **Get an optimized React component** ```js import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent ``` ## Supporting SVGR SVGR is a MIT-licensed open source project. It's an independent project with ongoing development made possible thanks to the support of these awesome [backers](/BACKERS.md). If you'd like to join them, please consider: - [Sponsor me on GitHub](https://github.com/sponsors/gregberge) - [Become a backer or sponsor on OpenCollective](https://opencollective.com/svgr) Learn more about [supporting SVGR](https://react-svgr.com/docs/supporting-svgr/). ## Contributing Check out the [contributing guidelines](CONTRIBUTING.md) # License Licensed under the MIT License, Copyright © 2017-present Greg Bergé. See [LICENSE](./LICENSE) for more information. ## Acknowledgements This project has been popularized by [Christopher Chedeau](https://twitter.com/vjeux) and it has been included in [create-react-app](https://github.com/facebook/create-react-app) thanks to [Dan Abramov](https://twitter.com/dan_abramov). We would like to thanks [Sven Sauleau](https://twitter.com/svensauleau) for his help and its intuition. ================================================ FILE: __fixtures__/custom-index-template.js ================================================ const path = require('path') function indexTemplate(files) { const exportEntries = files.map(({path: file}) => { const basename = path.basename(file, path.extname(file)) return `export { ${basename} } from './${basename}';` }) return exportEntries.join('\n') } module.exports = indexTemplate ================================================ FILE: __fixtures__/custom-index.config.js ================================================ const indexTemplate = require('./custom-index-template.js') function template( { imports, componentName, props, jsx, exports }, { tpl } ) { return tpl`${imports} export function ${componentName}(${props}) { return ${jsx}; } ` } module.exports = { template, indexTemplate, } ================================================ FILE: __fixtures__/overrides.config.js ================================================ module.exports = { expandProps: false, dimensions: false, svgo: false, prettier: false, } ================================================ FILE: __fixtures__/simple-existing/File..js ================================================ import * as React from 'react' function SvgFile(props) { return ( ) } export default SvgFile ================================================ FILE: __fixtures__/simple-existing/File.js ================================================ // nothing ================================================ FILE: __fixtures__/simple-existing/index..js ================================================ export { default as File } from './File' ================================================ FILE: __fixtures__/template.js ================================================ module.exports = () => (code, state) => ` import * as React from 'react' export default function ${state.componentName}() { return ${code} } ` ================================================ FILE: __fixtures__/withPrettierRc/.prettierrc ================================================ { "tabWidth": 5 } ================================================ FILE: __fixtures__/withSvgoConfig/svgo.config.cjs ================================================ module.exports = { plugins: [ { name: 'preset-default', params: { overrides: { removeTitle: false, }, }, }, ] } ================================================ FILE: __fixtures__/withSvgoConfig/svgo.config.js ================================================ module.exports = { plugins: [ { name: 'preset-default', params: { overrides: { removeTitle: false, }, }, }, ] } ================================================ FILE: __fixtures__/withSvgrRc/.svgrrc ================================================ { "icon": true } ================================================ FILE: api/api/svgr.js ================================================ /* eslint-disable @typescript-eslint/no-var-requires */ const { transform } = require('@svgr/core') const jsx = require('@svgr/plugin-jsx') const svgo = require('@svgr/plugin-svgo') const prettier = require('@svgr/plugin-prettier') module.exports = (req, res) => { if (!req.body) { res.status(204).send('') return } transform(req.body.code, { ...req.body.options, plugins: [svgo, jsx, prettier], }) .then((output) => { res.status(200).json({ output }) }) .catch((error) => { res.status(400).json({ error: error.message }) }) } ================================================ FILE: api/package.json ================================================ { "private": true, "packageManager": "pnpm@8.1.1", "dependencies": { "@svgr/core": "latest", "@svgr/plugin-jsx": "latest", "@svgr/plugin-prettier": "latest", "@svgr/plugin-svgo": "latest" } } ================================================ FILE: api/pnpm-workspace.yaml ================================================ # https://github.com/pnpm/pnpm/issues/2412 # This is only created so that api package doesn't try to use the virtual store from the repo's root ================================================ FILE: api/vercel.json ================================================ { "public": true, "redirects": [ { "source": "/", "destination": "https://react-svgr.com/playground" } ], "headers": [ { "source": "/api/(.*)", "headers": [ { "key": "Access-Control-Allow-Credentials", "value": "true" }, { "key": "Access-Control-Allow-Origin", "value": "*" }, { "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" }, { "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" } ] } ] } ================================================ FILE: babel.config.js ================================================ module.exports = { presets: [ ['@babel/preset-env', { targets: { node: '12' }, loose: true }], '@babel/preset-typescript', ], } ================================================ FILE: build/rollup.config.mjs ================================================ import { resolve } from 'node:path' import { readFileSync } from 'node:fs' import json from '@rollup/plugin-json' import dts from 'rollup-plugin-dts' import esbuild from 'rollup-plugin-esbuild' // eslint-disable-next-line @typescript-eslint/no-var-requires const pkg = JSON.parse( readFileSync(resolve(process.cwd(), './package.json'), 'utf-8'), ) const name = pkg.main ? pkg.main.replace(/\.js$/, '') : './dist/index' const bundle = (config) => ({ ...config, input: 'src/index.ts', external: (id) => !/^[./]/.test(id), }) export default [ bundle({ plugins: [json(), esbuild()], output: [ { file: `${name}.js`, format: 'cjs', sourcemap: Boolean(pkg.main), exports: 'auto', }, ], }), ...(pkg.main ? [ bundle({ plugins: [ dts({ compilerOptions: { // https://github.com/Swatinem/rollup-plugin-dts/issues/143 preserveSymlinks: false, }, }), ], output: { file: `${name}.d.ts`, format: 'es', }, }), ] : []), ] ================================================ FILE: deprecated-packages/svgr/message.js ================================================ /* eslint-disable @typescript-eslint/no-var-requires */ const githubCurrentUser = require('github-current-user') githubCurrentUser.verify((err, verified, username) => { console.log(`Hello ${username || ''}!`) console.log(`SVGR 🦁 v2.0.0 is released 🎉`) console.log( `It is now splitted into several packages, what are you looking for?\n`, ) console.log(`Command line 👉 @svgr/cli`) console.log(`Node API 👉 @svgr/core`) console.log(`Webpack 👉 @svgr/webpack`) console.log(`Rollup 👉 @svgr/rollup`) console.log(`Pick the one you need!`) }) ================================================ FILE: deprecated-packages/svgr/package.json ================================================ { "name": "svgr", "description": "Convert raw SVG into React components.", "version": "2.0.0", "repository": "git@github.com:gregberge/svgr.git", "author": "Greg Bergé ", "keywords": [ "svg", "h2x", "react", "component", "svg2react", "svg-to-react" ], "engines": { "node": ">=8" }, "license": "MIT", "dependencies": { "github-current-user": "^2.5.0" }, "scripts": { "postinstall": "node message.js; sleep 10; exit 1;" } } ================================================ FILE: examples/mocha-esm/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/mocha-esm-example # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/mocha-esm-example ================================================ FILE: examples/mocha-esm/__mocks__/svg.js ================================================ export default 'Icon' ================================================ FILE: examples/mocha-esm/example.js ================================================ import Icon from './icon.svg' export { Icon } ================================================ FILE: examples/mocha-esm/example.test.js ================================================ import { Icon } from './example.js' it('works', () => { if (Icon !== 'Icon') { throw new Error('Invalid') } }) ================================================ FILE: examples/mocha-esm/mock-loader.js ================================================ import { cwd } from 'node:process' import { pathToFileURL } from 'node:url' const baseURL = pathToFileURL(`${cwd()}/`).href const SVG_REGEX = /^[./a-zA-Z0-9$_-]+\.svg$/ export async function resolve(specifier, context, defaultResolve) { if (SVG_REGEX.test(specifier)) { return { url: new URL('./__mocks__/svg.js', baseURL).href } } return defaultResolve(specifier, context, defaultResolve) } ================================================ FILE: examples/mocha-esm/package.json ================================================ { "name": "@svgr/mocha-esm-example", "private": true, "type": "module", "scripts": { "test": "mocha --loader=./mock-loader.js example.test.js" }, "devDependencies": { "mocha": "^10.2.0" }, "version": "8.0.0" } ================================================ FILE: examples/webpack/.gitignore ================================================ dist/ ================================================ FILE: examples/webpack/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.1.0](https://github.com/gregberge/svgr/compare/v8.0.1...v8.1.0) (2023-08-15) **Note:** Version bump only for package @svgr/webpack-example ## [8.0.1](https://github.com/gregberge/svgr/compare/v8.0.0...v8.0.1) (2023-05-09) **Note:** Version bump only for package @svgr/webpack-example # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/webpack-example # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/webpack-example ================================================ FILE: examples/webpack/package.json ================================================ { "name": "@svgr/webpack-example", "private": true, "scripts": { "start": "webpack serve" }, "devDependencies": { "@svgr/webpack": "^8.1.0", "html-webpack-plugin": "^5.5.0", "url-loader": "^4.1.1", "webpack": "^5.76.3", "webpack-cli": "^5.0.1", "webpack-dev-server": "^4.13.1" }, "version": "8.1.0" } ================================================ FILE: examples/webpack/src/index.js ================================================ import star, { ReactComponent } from './star.url.svg' import Star from './star.simple.svg' console.log('url', typeof star, typeof ReactComponent) console.log('simple', typeof Star) ================================================ FILE: examples/webpack/webpack.config.js ================================================ const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode: 'development', module: { rules: [ { test: /url\.svg$/, use: ['@svgr/webpack', 'url-loader'], }, { test: /simple\.svg$/, use: '@svgr/webpack', }, ], }, plugins: [ new HtmlWebpackPlugin({ title: 'Development', }), ], } ================================================ FILE: jest.config.js ================================================ module.exports = { watchPathIgnorePatterns: ['__fixtures__', '__fixtures__build__'], rootDir: 'packages', transform: { '^.+\\.(j|t)sx?$': ['babel-jest', { root: __dirname }], }, } ================================================ FILE: lerna.json ================================================ { "lerna": "2.9.0", "version": "8.1.0", "npmClient": "pnpm", "useWorkspaces": true } ================================================ FILE: package.json ================================================ { "private": true, "scripts": { "build": "pnpm -r run build", "dev": "pnpm -r --parallel run build --watch", "format": "prettier --write .", "lint": "eslint . && prettier --check .", "release": "lerna publish --conventional-commits && conventional-github-releaser --preset angular", "test": "jest --runInBand" }, "packageManager": "pnpm@8.1.1", "devDependencies": { "@types/babel__core": "^7.20.0", "@types/node": "^18.15.11", "@babel/core": "^7.21.3", "@babel/preset-env": "^7.20.2", "@babel/preset-typescript": "^7.21.0", "@rollup/plugin-json": "^6.0.0", "@types/jest": "^29.5.0", "@typescript-eslint/eslint-plugin": "^5.56.0", "@typescript-eslint/parser": "^5.56.0", "@svgr/plugin-jsx": "workspace:*", "@svgr/plugin-svgo": "workspace:*", "@svgr/plugin-prettier": "workspace:*", "babel-jest": "^29.5.0", "codecov": "^3.8.3", "conventional-github-releaser": "^3.1.5", "esbuild": "^0.17.12", "eslint": "^8.36.0", "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", "jest": "^29.5.0", "lerna": "^6.6.0", "react": "^18.2.0", "rollup": "^3.20.2", "rollup-plugin-dts": "^5.3.0", "rollup-plugin-esbuild": "^5.0.0", "typescript": "^5.0.2" } } ================================================ FILE: packages/babel-plugin-add-jsx-attribute/.npmignore ================================================ src/ .* ================================================ FILE: packages/babel-plugin-add-jsx-attribute/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/babel-plugin-add-jsx-attribute # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/babel-plugin-add-jsx-attribute ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) **Note:** Version bump only for package @svgr/babel-plugin-add-jsx-attribute # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/babel-plugin-add-jsx-attribute ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-add-jsx-attribute/compare/v5.3.1...v5.4.0) (2020-04-27) **Note:** Version bump only for package @svgr/babel-plugin-add-jsx-attribute ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-add-jsx-attribute/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-add-jsx-attribute/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-add-jsx-attribute/compare/v4.1.0...v4.2.0) (2019-04-11) **Note:** Version bump only for package @svgr/babel-plugin-add-jsx-attribute # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/babel-plugin-add-jsx-attribute/README.md ================================================ # @svgr/babel-plugin-add-jsx-attribute ## Install ``` npm install --save-dev @svgr/babel-plugin-add-jsx-attribute ``` ## Usage **.babelrc** ```json { "plugins": [ [ "@svgr/babel-plugin-add-jsx-attribute", { "elements": ["svg"], "attributes": [ { "name": "width", "value": "200", "spread": false, "literal": false, "position": "end" } ] } ] ] } ``` ## License MIT ================================================ FILE: packages/babel-plugin-add-jsx-attribute/package.json ================================================ { "name": "@svgr/babel-plugin-add-jsx-attribute", "description": "Add JSX attribute", "version": "8.0.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/babel-plugin-add-jsx-attribute", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "babel-plugin" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" }, "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" } } ================================================ FILE: packages/babel-plugin-add-jsx-attribute/src/index.test.ts ================================================ import { transform } from '@babel/core' import plugin, { Options } from '.' const testPlugin = (code: string, options: Options) => { const result = transform(code, { plugins: ['@babel/plugin-syntax-jsx', [plugin, options]], configFile: false, }) return result?.code } describe('plugin', () => { it('should add simple attribute', () => { expect( testPlugin('
', { elements: ['div'], attributes: [{ name: 'disabled' }], }), ).toMatchInlineSnapshot(`"
;"`) }) it('should add attribute with value', () => { expect( testPlugin('
', { elements: ['div'], attributes: [{ name: 'disabled', value: true }], }), ).toMatchInlineSnapshot(`"
;"`) expect( testPlugin('
', { elements: ['div'], attributes: [{ name: 'disabled', value: 'true' }], }), ).toMatchInlineSnapshot(`"
;"`) expect( testPlugin('
', { elements: ['div'], attributes: [{ name: 'disabled', value: 200 }], }), ).toMatchInlineSnapshot(`"
;"`) }) it('should add literal attribute', () => { expect( testPlugin('
', { elements: ['div'], attributes: [{ name: 'ref', value: 'ref', literal: true }], }), ).toMatchInlineSnapshot(`"
;"`) expect( testPlugin('
', { elements: ['div'], attributes: [{ name: 'ref', value: 'ref ? ref : null', literal: true }], }), ).toMatchInlineSnapshot(`"
;"`) }) it('should add spread attribute', () => { expect( testPlugin('
', { elements: ['div'], attributes: [ { spread: true, name: 'props', position: 'start', }, ], }), ).toMatchInlineSnapshot(`"
;"`) expect( testPlugin('
', { elements: ['span'], attributes: [ { spread: true, name: 'props', position: 'end', }, ], }), ).toMatchInlineSnapshot(`"
;"`) }) it('should replace attribute', () => { expect( testPlugin('
', { elements: ['div'], attributes: [{ name: 'disabled', value: false }], }), ).toMatchInlineSnapshot(`"
;"`) }) }) ================================================ FILE: packages/babel-plugin-add-jsx-attribute/src/index.ts ================================================ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { ConfigAPI, types as t, NodePath, template } from '@babel/core' export interface Attribute { name: string value?: boolean | number | string | null spread?: boolean literal?: boolean position?: 'start' | 'end' } export interface Options { elements: string[] attributes: Attribute[] } const positionMethod = { start: 'unshiftContainer', end: 'pushContainer', } as const const addJSXAttribute = (_: ConfigAPI, opts: Options) => { function getAttributeValue({ literal, value, }: { literal?: Attribute['literal'] value: Attribute['value'] }) { if (typeof value === 'boolean') { return t.jsxExpressionContainer(t.booleanLiteral(value)) } if (typeof value === 'number') { return t.jsxExpressionContainer(t.numericLiteral(value)) } if (typeof value === 'string' && literal) { return t.jsxExpressionContainer( (template.ast(value) as t.ExpressionStatement).expression, ) } if (typeof value === 'string') { return t.stringLiteral(value) } return null } function getAttribute({ spread, name, value, literal }: Attribute) { if (spread) { return t.jsxSpreadAttribute(t.identifier(name)) } return t.jsxAttribute( t.jsxIdentifier(name), getAttributeValue({ value, literal }), ) } return { visitor: { JSXOpeningElement(path: NodePath) { if (!t.isJSXIdentifier(path.node.name)) return if (!opts.elements.includes(path.node.name.name)) return opts.attributes.forEach( ({ name, value = null, spread = false, literal = false, position = 'end', }) => { const method = positionMethod[position] const newAttribute = getAttribute({ spread, name, value, literal }) const attributes = path.get('attributes') const isEqualAttribute = ( attribute: NodePath, ) => { if (spread) return ( attribute.isJSXSpreadAttribute() && attribute.get('argument').isIdentifier({ name }) ) return ( attribute.isJSXAttribute() && attribute.get('name').isJSXIdentifier({ name }) ) } const replaced = attributes.some((attribute) => { if (!isEqualAttribute(attribute)) return false attribute.replaceWith(newAttribute) return true }) if (!replaced) { path[method]('attributes', newAttribute) } }, ) }, }, } } export default addJSXAttribute ================================================ FILE: packages/babel-plugin-add-jsx-attribute/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/babel-plugin-remove-jsx-attribute/.npmignore ================================================ /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/babel-plugin-remove-jsx-attribute/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/babel-plugin-remove-jsx-attribute # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/babel-plugin-remove-jsx-attribute # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/babel-plugin-remove-jsx-attribute ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes * fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes * **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-remove-jsx-attribute/compare/v5.3.1...v5.4.0) (2020-04-27) **Note:** Version bump only for package @svgr/babel-plugin-remove-jsx-attribute ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-remove-jsx-attribute/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes * fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-remove-jsx-attribute/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-remove-jsx-attribute/compare/v4.1.0...v4.2.0) (2019-04-11) **Note:** Version bump only for package @svgr/babel-plugin-remove-jsx-attribute ## [4.0.3](https://github.com/gregberge/svgr/compare/v4.0.2...v4.0.3) (2018-11-13) ### Bug Fixes * **babel-plugin:** fix usage of spread attribute([#231](https://github.com/gregberge/svgr/issues/231)) ([4186953](https://github.com/gregberge/svgr/commit/4186953)) # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features * **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES * **v4:** - `template` option must now returns a Babel AST - `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/babel-plugin-remove-jsx-attribute/README.md ================================================ # @svgr/babel-plugin-remove-jsx-attribute ## Install ``` npm install --save-dev @svgr/babel-plugin-remove-jsx-attribute ``` ## Usage **.babelrc** ```json { "plugins": [ [ "@svgr/babel-plugin-remove-jsx-attribute", { "elements": ["svg"], "attributes": ["width", "height"] } ] ] } ``` ## License MIT ================================================ FILE: packages/babel-plugin-remove-jsx-attribute/package.json ================================================ { "name": "@svgr/babel-plugin-remove-jsx-attribute", "description": "Remove JSX attribute", "version": "8.0.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/babel-plugin-remove-jsx-attribute", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "babel-plugin" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" }, "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" } } ================================================ FILE: packages/babel-plugin-remove-jsx-attribute/src/index.test.ts ================================================ import { transform } from '@babel/core' import plugin, { Options } from '.' const testPlugin = (code: string, options: Options) => { const result = transform(code, { plugins: ['@babel/plugin-syntax-jsx', [plugin, options]], configFile: false, }) return result?.code } describe('plugin', () => { it('should remove attributes from an element', () => { expect( testPlugin('
', { elements: ['span'], attributes: ['foo'], }), ).toMatchInlineSnapshot(`"
;"`) }) it('should not throw error when spread operator is used', () => { expect( testPlugin('
', { elements: ['span'], attributes: ['foo'], }), ).toMatchInlineSnapshot(`"
;"`) }) }) ================================================ FILE: packages/babel-plugin-remove-jsx-attribute/src/index.ts ================================================ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { ConfigAPI, types as t, NodePath } from '@babel/core' export interface Options { elements: string[] attributes: string[] } const removeJSXAttribute = (_: ConfigAPI, opts: Options) => ({ visitor: { JSXOpeningElement(path: NodePath) { if (!t.isJSXIdentifier(path.node.name)) return if (!opts.elements.includes(path.node.name.name)) return // @ts-ignore path.get('attributes').forEach((attribute) => { if ( t.isJSXAttribute(attribute.node) && t.isJSXIdentifier(attribute.node.name) && opts.attributes.includes(attribute.node.name.name) ) { attribute.remove() } }) }, }, }) export default removeJSXAttribute ================================================ FILE: packages/babel-plugin-remove-jsx-attribute/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/babel-plugin-remove-jsx-empty-expression/.npmignore ================================================ /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/babel-plugin-remove-jsx-empty-expression/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/babel-plugin-remove-jsx-empty-expression # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/babel-plugin-remove-jsx-empty-expression # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/babel-plugin-remove-jsx-empty-expression ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes * fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes * **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-remove-jsx-empty-expression/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes * fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-remove-jsx-empty-expression/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-remove-jsx-empty-expression/compare/v4.1.0...v4.2.0) (2019-04-11) **Note:** Version bump only for package @svgr/babel-plugin-remove-jsx-empty-expression # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features * **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES * **v4:** - `template` option must now returns a Babel AST - `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/babel-plugin-remove-jsx-empty-expression/README.md ================================================ # @svgr/babel-plugin-remove-jsx-empty-expression ## Install ``` npm install --save-dev @svgr/babel-plugin-remove-jsx-empty-expression ``` ## Usage **.babelrc** ```json { "plugins": ["@svgr/babel-plugin-remove-jsx-empty-expression"] } ``` ## License MIT ================================================ FILE: packages/babel-plugin-remove-jsx-empty-expression/package.json ================================================ { "name": "@svgr/babel-plugin-remove-jsx-empty-expression", "description": "Remove JSX empty expression", "version": "8.0.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/babel-plugin-remove-jsx-empty-expression", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "babel-plugin" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" }, "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" } } ================================================ FILE: packages/babel-plugin-remove-jsx-empty-expression/src/index.test.ts ================================================ import { transform } from '@babel/core' import plugin from '.' const testPlugin = (code: string) => { const result = transform(code, { plugins: ['@babel/plugin-syntax-jsx', plugin], configFile: false, }) return result?.code } describe('plugin', () => { it('should remove empty expression', () => { expect(testPlugin('
{/* Hello */}
')).toMatchInlineSnapshot( `"
;"`, ) }) }) ================================================ FILE: packages/babel-plugin-remove-jsx-empty-expression/src/index.ts ================================================ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { types as t, NodePath } from '@babel/core' const removeJSXEmptyExpression = () => ({ visitor: { JSXExpressionContainer(path: NodePath) { if (t.isJSXEmptyExpression(path.get('expression'))) { path.remove() } }, }, }) export default removeJSXEmptyExpression ================================================ FILE: packages/babel-plugin-remove-jsx-empty-expression/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/babel-plugin-replace-jsx-attribute-value/.npmignore ================================================ src/ .* /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/babel-plugin-replace-jsx-attribute-value/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/babel-plugin-replace-jsx-attribute-value # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/babel-plugin-replace-jsx-attribute-value ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) **Note:** Version bump only for package @svgr/babel-plugin-replace-jsx-attribute-value # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/babel-plugin-replace-jsx-attribute-value ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-replace-jsx-attribute-value/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-replace-jsx-attribute-value/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-replace-jsx-attribute-value/compare/v4.1.0...v4.2.0) (2019-04-11) **Note:** Version bump only for package @svgr/babel-plugin-replace-jsx-attribute-value # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) - allow dynamic properties in replaceAttrValues option ([15f55fe](https://github.com/gregberge/svgr/commit/15f55fe)), closes [#205](https://github.com/gregberge/svgr/issues/205) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/babel-plugin-replace-jsx-attribute-value/README.md ================================================ # @svgr/babel-plugin-replace-jsx-attribute-value ## Install ``` npm install --save-dev @svgr/babel-plugin-replace-jsx-attribute-value ``` ## Usage **.babelrc** ```json { "plugins": [ [ "@svgr/babel-plugin-replace-jsx-attribute-value", { "values": [ { "value": "#000", "newValue": "#fff" }, { "value": "blue", "newValue": "props.color", "literal": true } ] } ] ] } ``` ## License MIT ================================================ FILE: packages/babel-plugin-replace-jsx-attribute-value/package.json ================================================ { "name": "@svgr/babel-plugin-replace-jsx-attribute-value", "description": "Replace JSX attribute value", "version": "8.0.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/babel-plugin-replace-jsx-attribute-value", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "babel-plugin" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" }, "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" } } ================================================ FILE: packages/babel-plugin-replace-jsx-attribute-value/src/index.test.ts ================================================ import { transform } from '@babel/core' import plugin, { Options } from '.' const testPlugin = (code: string, options: Options) => { const result = transform(code, { plugins: ['@babel/plugin-syntax-jsx', [plugin, options]], configFile: false, }) return result?.code } describe('plugin', () => { it('should replace attribute values', () => { expect( testPlugin('
', { values: [{ value: 'cool', newValue: 'not cool' }], }), ).toMatchInlineSnapshot(`"
;"`) expect( testPlugin('
', { values: [{ value: 'cool', newValue: 'props.color', literal: true }], }), ).toMatchInlineSnapshot(`"
;"`) }) }) ================================================ FILE: packages/babel-plugin-replace-jsx-attribute-value/src/index.ts ================================================ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { ConfigAPI, types as t, NodePath, template } from '@babel/core' export interface Value { value: string newValue: string | boolean | number literal?: boolean } export interface Options { values: Value[] } const addJSXAttribute = (api: ConfigAPI, opts: Options) => { const getAttributeValue = ( value: string | boolean | number, literal?: boolean, ) => { if (typeof value === 'string' && literal) { return t.jsxExpressionContainer( (template.ast(value) as t.ExpressionStatement).expression, ) } if (typeof value === 'string') { return t.stringLiteral(value) } if (typeof value === 'boolean') { return t.jsxExpressionContainer(t.booleanLiteral(value)) } if (typeof value === 'number') { return t.jsxExpressionContainer(t.numericLiteral(value)) } return null } return { visitor: { JSXAttribute(path: NodePath) { const valuePath = path.get('value') if (!valuePath.isStringLiteral()) return opts.values.forEach(({ value, newValue, literal }) => { if (!valuePath.isStringLiteral({ value })) return const attributeValue = getAttributeValue(newValue, literal) if (attributeValue) { valuePath.replaceWith(attributeValue) } }) }, }, } } export default addJSXAttribute ================================================ FILE: packages/babel-plugin-replace-jsx-attribute-value/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/babel-plugin-svg-dynamic-title/.npmignore ================================================ /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/babel-plugin-svg-dynamic-title/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/babel-plugin-svg-dynamic-title # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/babel-plugin-svg-dynamic-title ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) **Note:** Version bump only for package @svgr/babel-plugin-svg-dynamic-title # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/babel-plugin-svg-dynamic-title ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ### Features - add descProp option ([#729](https://github.com/gregberge/svgr/issues/729)) ([a0637d4](https://github.com/gregberge/svgr/commit/a0637d49b60243bbae461f7b96dab9b47cd82d8f)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/compare/v5.3.1...v5.4.0) (2020-04-27) **Note:** Version bump only for package @svgr/babel-plugin-svg-dynamic-title ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) ## [4.3.3](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/compare/v4.3.2...v4.3.3) (2019-09-24) ### Bug Fixes - **babel-plugin-svg-dynamic-title:** dont render empty title ([#341](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/issues/341)) ([88b24c5](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/commit/88b24c5)), closes [#333](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/issues/333) ## [4.3.1](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/compare/v4.3.0...v4.3.1) (2019-07-01) ### Bug Fixes - **titleProp:** handle the existing title case by using element instead of value (children) ([#315](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/issues/315)) ([065e7a9](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/commit/065e7a9)) # [4.3.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/compare/v4.2.0...v4.3.0) (2019-05-28) ### Features - titleProps fallbacks to svg's title ([#311](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/issues/311)) ([8f92366](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/commit/8f92366)) # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-dynamic-title/compare/v4.1.0...v4.2.0) (2019-04-11) **Note:** Version bump only for package @svgr/babel-plugin-svg-dynamic-title # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/babel-plugin-svg-dynamic-title/README.md ================================================ # @svgr/babel-plugin-svg-dynamic-title ## Install ``` npm install --save-dev @svgr/babel-plugin-svg-dynamic-title ``` ## Usage **.babelrc** ```json { "plugins": ["@svgr/babel-plugin-svg-dynamic-title"] } ``` ## Note This plugin handles both the titleProp and descProp options. By default, it will handle titleProp only. ## License MIT ================================================ FILE: packages/babel-plugin-svg-dynamic-title/package.json ================================================ { "name": "@svgr/babel-plugin-svg-dynamic-title", "description": "Transform SVG by adding a dynamic title element", "version": "8.0.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/babel-plugin-svg-dynamic-title", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "babel-plugin" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" }, "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" } } ================================================ FILE: packages/babel-plugin-svg-dynamic-title/src/index.test.ts ================================================ import { transform } from '@babel/core' import plugin, { Options } from '.' const testPlugin = (code: string, options: Options = { tag: 'title' }) => { const result = transform(code, { plugins: ['@babel/plugin-syntax-jsx', [plugin, options]], configFile: false, }) return result?.code } describe('title plugin', () => { it('should add title attribute if not present', () => { expect(testPlugin('')).toMatchInlineSnapshot( `"{title ? {title} : null};"`, ) }) it('should add title element and fallback to existing title', () => { // testing when the existing title contains a simple string expect(testPlugin(`Hello`)).toMatchInlineSnapshot( `"{title === undefined ? Hello : title ? {title} : null};"`, ) // testing when the existing title contains an JSXExpression expect( testPlugin(`{"Hello"}`), ).toMatchInlineSnapshot( `"{title === undefined ? {"Hello"} : title ? {title} : null};"`, ) }) it('should preserve any existing title attributes', () => { // testing when the existing title contains a simple string expect( testPlugin(`Hello`), ).toMatchInlineSnapshot( `"{title === undefined ? Hello : title ? {title} : null};"`, ) }) it('should support empty title', () => { expect(testPlugin('')).toMatchInlineSnapshot( `"{title ? {title} : null};"`, ) }) it('should support self closing title', () => { expect(testPlugin('')).toMatchInlineSnapshot( `"{title ? {title} : null};"`, ) }) it('should work if an attribute is already present', () => { expect(testPlugin('')).toMatchInlineSnapshot( `"{title ? {title} : null};"`, ) }) }) describe('desc plugin', () => { it('should add desc attribute if not present', () => { expect(testPlugin('', { tag: 'desc' })).toMatchInlineSnapshot( `"{desc ? {desc} : null};"`, ) }) it('should add desc element and fallback to existing desc', () => { // testing when the existing desc contains a simple string expect( testPlugin(`Hello`, { tag: 'desc' }), ).toMatchInlineSnapshot( `"{desc === undefined ? Hello : desc ? {desc} : null};"`, ) // testing when the existing desc contains an JSXExpression expect( testPlugin(`{"Hello"}`, { tag: 'desc' }), ).toMatchInlineSnapshot( `"{desc === undefined ? {"Hello"} : desc ? {desc} : null};"`, ) }) it('should preserve any existing desc attributes', () => { // testing when the existing desc contains a simple string expect( testPlugin(`Hello`, { tag: 'desc' }), ).toMatchInlineSnapshot( `"{desc === undefined ? Hello : desc ? {desc} : null};"`, ) }) it('should support empty desc', () => { expect( testPlugin('', { tag: 'desc' }), ).toMatchInlineSnapshot( `"{desc ? {desc} : null};"`, ) }) it('should support self closing desc', () => { expect( testPlugin('', { tag: 'desc' }), ).toMatchInlineSnapshot( `"{desc ? {desc} : null};"`, ) }) it('should work if an attribute is already present', () => { expect( testPlugin('', { tag: 'desc' }), ).toMatchInlineSnapshot( `"{desc ? {desc} : null};"`, ) }) }) ================================================ FILE: packages/babel-plugin-svg-dynamic-title/src/index.ts ================================================ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { NodePath, types as t } from '@babel/core' const elements = ['svg', 'Svg'] type tag = 'title' | 'desc' export interface Options { tag: tag | null } interface State { opts: Options } const createTagElement = ( tag: tag, children: t.JSXExpressionContainer[] = [], attributes: (t.JSXAttribute | t.JSXSpreadAttribute)[] = [], ) => { const eleName = t.jsxIdentifier(tag) return t.jsxElement( t.jsxOpeningElement(eleName, attributes), t.jsxClosingElement(eleName), children, ) } const createTagIdAttribute = (tag: tag) => t.jsxAttribute( t.jsxIdentifier('id'), t.jsxExpressionContainer(t.identifier(`${tag}Id`)), ) const addTagIdAttribute = ( tag: tag, attributes: (t.JSXAttribute | t.JSXSpreadAttribute)[], ) => { const existingId = attributes.find( (attribute) => t.isJSXAttribute(attribute) && attribute.name.name === 'id', ) as t.JSXAttribute | undefined if (!existingId) { return [...attributes, createTagIdAttribute(tag)] } existingId.value = t.jsxExpressionContainer( t.isStringLiteral(existingId.value) ? t.logicalExpression('||', t.identifier(`${tag}Id`), existingId.value) : t.identifier(`${tag}Id`), ) return attributes } const plugin = () => ({ visitor: { JSXElement(path: NodePath, state: State) { const tag = state.opts.tag || 'title' if (!elements.length) return const openingElement = path.get('openingElement') const openingElementName = openingElement.get('name') if ( !elements.some((element) => openingElementName.isJSXIdentifier({ name: element }), ) ) { return } const getTagElement = ( existingTitle?: t.JSXElement, ): t.JSXExpressionContainer => { const tagExpression = t.identifier(tag) if (existingTitle) { existingTitle.openingElement.attributes = addTagIdAttribute( tag, existingTitle.openingElement.attributes, ) } const conditionalTitle = t.conditionalExpression( tagExpression, createTagElement( tag, [t.jsxExpressionContainer(tagExpression)], existingTitle ? existingTitle.openingElement.attributes : [createTagIdAttribute(tag)], ), t.nullLiteral(), ) if (existingTitle?.children?.length) { // If title already exists render as follows // `{title === undefined ? fallbackTitleElement : titleElement}` return t.jsxExpressionContainer( t.conditionalExpression( t.binaryExpression( '===', tagExpression, t.identifier('undefined'), ), existingTitle, conditionalTitle, ), ) } return t.jsxExpressionContainer(conditionalTitle) } // store the title element let tagElement: t.JSXExpressionContainer | null = null const hasTitle = path.get('children').some((childPath) => { if (childPath.node === tagElement) return false if (!childPath.isJSXElement()) return false const name = childPath.get('openingElement').get('name') if (!name.isJSXIdentifier()) return false if (name.node.name !== tag) return false tagElement = getTagElement(childPath.node) childPath.replaceWith(tagElement) return true }) // create a title element if not already create tagElement = tagElement || getTagElement() if (!hasTitle) { // path.unshiftContainer is not working well :( // path.unshiftContainer('children', titleElement) path.node.children.unshift(tagElement) path.replaceWith(path.node) } }, }, }) export default plugin ================================================ FILE: packages/babel-plugin-svg-dynamic-title/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/babel-plugin-svg-em-dimensions/.npmignore ================================================ src/ .* /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/babel-plugin-svg-em-dimensions/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/babel-plugin-svg-em-dimensions # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/babel-plugin-svg-em-dimensions ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) **Note:** Version bump only for package @svgr/babel-plugin-svg-em-dimensions # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/babel-plugin-svg-em-dimensions ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-em-dimensions/compare/v5.3.1...v5.4.0) (2020-04-27) **Note:** Version bump only for package @svgr/babel-plugin-svg-em-dimensions ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-em-dimensions/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-em-dimensions/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-svg-em-dimensions/compare/v4.1.0...v4.2.0) (2019-04-11) **Note:** Version bump only for package @svgr/babel-plugin-svg-em-dimensions # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/babel-plugin-svg-em-dimensions/README.md ================================================ # @svgr/babel-plugin-svg-em-dimensions ## Install ``` npm install --save-dev @svgr/babel-plugin-svg-em-dimensions ``` ## Usage **.babelrc** ```json { "plugins": [ ["@svgr/babel-plugin-svg-em-dimensions", { "width": 24, "height": 24 }] ] } ``` ## License MIT ================================================ FILE: packages/babel-plugin-svg-em-dimensions/package.json ================================================ { "name": "@svgr/babel-plugin-svg-em-dimensions", "description": "Transform SVG to use em-based dimensions", "version": "8.0.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/babel-plugin-svg-em-dimensions", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "babel-plugin" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" }, "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" } } ================================================ FILE: packages/babel-plugin-svg-em-dimensions/src/index.test.ts ================================================ import { transform } from '@babel/core' import plugin, { Options } from '.' const testPlugin = (code: string, options?: Options) => { const result = transform(code, { plugins: ['@babel/plugin-syntax-jsx', [plugin, options]], configFile: false, }) return result?.code } describe('plugin', () => { it('replaces width / height attributes', () => { expect( testPlugin(''), ).toMatchInlineSnapshot(`";"`) }) it('adds theme if they are not present', () => { expect(testPlugin('')).toMatchInlineSnapshot( `";"`, ) }) it('accepts numeric values', () => { expect( testPlugin('', { width: 24, height: 24 }), ).toMatchInlineSnapshot(`";"`) }) it('accepts string values', () => { expect( testPlugin('', { width: '2em', height: '2em' }), ).toMatchInlineSnapshot(`";"`) }) }) ================================================ FILE: packages/babel-plugin-svg-em-dimensions/src/index.ts ================================================ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { types as t, NodePath, ConfigAPI } from '@babel/core' const elements = ['svg', 'Svg'] export interface Options { width: number | string height: number | string } const getValue = (raw: undefined | number | string) => { if (raw === undefined) return t.stringLiteral('1em') switch (typeof raw) { case 'number': return t.jsxExpressionContainer(t.numericLiteral(raw)) case 'string': return t.stringLiteral(raw) default: return t.stringLiteral('1em') } } const plugin = (_: ConfigAPI, opts: Options) => ({ visitor: { JSXOpeningElement(path: NodePath) { if ( !elements.some((element) => path.get('name').isJSXIdentifier({ name: element }), ) ) return const values = { width: getValue(opts.width), height: getValue(opts.height), } const requiredAttributes = Object.keys(values) path.get('attributes').forEach((attributePath) => { if (!attributePath.isJSXAttribute()) return const namePath = attributePath.get('name') if (!namePath.isJSXIdentifier()) return const index = requiredAttributes.indexOf(namePath.node.name) if (index === -1) return const valuePath = attributePath.get('value') valuePath.replaceWith(values[namePath.node.name as 'width' | 'height']) requiredAttributes.splice(index, 1) }) path.pushContainer( 'attributes', requiredAttributes.map((attr) => t.jsxAttribute( t.jsxIdentifier(attr), values[attr as 'width' | 'height'], ), ), ) }, }, }) export default plugin ================================================ FILE: packages/babel-plugin-svg-em-dimensions/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/babel-plugin-transform-react-native-svg/.npmignore ================================================ src/ .* /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/babel-plugin-transform-react-native-svg/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.1.0](https://github.com/gregberge/svgr/compare/v8.0.1...v8.1.0) (2023-08-15) ### Bug Fixes * **react-native:** fix duplicate import ([#894](https://github.com/gregberge/svgr/issues/894)) ([e612b6a](https://github.com/gregberge/svgr/commit/e612b6a1a4e822178f1e15b82bd2991bf1e84cec)) # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/babel-plugin-transform-react-native-svg # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/babel-plugin-transform-react-native-svg ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) **Note:** Version bump only for package @svgr/babel-plugin-transform-react-native-svg # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/babel-plugin-transform-react-native-svg ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-react-native-svg/compare/v5.3.1...v5.4.0) (2020-04-27) ### Features - add `ForeignObject` support for react native ([#430](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-react-native-svg/issues/430)) ([1b56b85](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-react-native-svg/commit/1b56b851478803d40105ce63c70e457bd3183da6)) ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-react-native-svg/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-react-native-svg/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-react-native-svg/compare/v4.1.0...v4.2.0) (2019-04-11) ### Features - add expo option ([#289](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-react-native-svg/issues/289)) ([978db3e](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-react-native-svg/commit/978db3e)) # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/babel-plugin-transform-react-native-svg/README.md ================================================ # @svgr/babel-plugin-transform-react-native-svg ## Install ``` npm install --save-dev @svgr/babel-plugin-transform-react-native-svg ``` ## Usage **.babelrc** ```json { "plugins": ["@svgr/babel-plugin-transform-react-native-svg"] } ``` ## License MIT ================================================ FILE: packages/babel-plugin-transform-react-native-svg/package.json ================================================ { "name": "@svgr/babel-plugin-transform-react-native-svg", "description": "Transform DOM elements into react-native-svg components", "version": "8.1.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/babel-plugin-transform-react-native-svg", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "babel-plugin" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" }, "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" } } ================================================ FILE: packages/babel-plugin-transform-react-native-svg/src/index.test.ts ================================================ import { transform } from '@babel/core' import plugin from '.' const testPlugin = (code: string) => { const result = transform(code, { plugins: ['@babel/plugin-syntax-jsx', plugin], configFile: false, }) return result?.code } describe('plugin', () => { it('should transform elements', () => { const code = testPlugin('
') expect(code).toMatchInlineSnapshot(`";"`) }) it('should add import', () => { const code = testPlugin( `import Svg from 'react-native-svg';
;`, ) expect(code).toMatchInlineSnapshot(` "import Svg, { G } from 'react-native-svg'; /* SVGR has dropped some elements not supported by react-native-svg: div */ ;" `) }) it('should add deal with type imports properly', () => { const code = transform( ` import Svg from 'react-native-svg'; import type { SvgProps } from "react-native-svg"; const ComponentSvg = () => ; `, { plugins: [ '@babel/plugin-syntax-jsx', ['@babel/plugin-syntax-typescript', { isTSX: true }], plugin, ], configFile: false, }, )?.code expect(code).toMatchInlineSnapshot(` "import Svg, { G } from 'react-native-svg'; import type { SvgProps } from "react-native-svg"; const ComponentSvg = () => ;" `) }) }) ================================================ FILE: packages/babel-plugin-transform-react-native-svg/src/index.ts ================================================ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { NodePath, types as t } from '@babel/core' interface State { replacedComponents: Set unsupportedComponents: Set } const elementToComponent: { [key: string]: string } = { svg: 'Svg', circle: 'Circle', clipPath: 'ClipPath', ellipse: 'Ellipse', g: 'G', linearGradient: 'LinearGradient', radialGradient: 'RadialGradient', line: 'Line', path: 'Path', pattern: 'Pattern', polygon: 'Polygon', polyline: 'Polyline', rect: 'Rect', symbol: 'Symbol', text: 'Text', textPath: 'TextPath', tspan: 'TSpan', use: 'Use', defs: 'Defs', stop: 'Stop', mask: 'Mask', image: 'Image', foreignObject: 'ForeignObject', } const plugin = () => { function replaceElement(path: NodePath, state: State) { const namePath = path.get('openingElement').get('name') if (!namePath.isJSXIdentifier()) return const { name } = namePath.node // Replace element by react-native-svg components const component = elementToComponent[name] if (component) { namePath.replaceWith(t.jsxIdentifier(component)) if (path.has('closingElement')) { const closingNamePath = path .get('closingElement') .get('name') as NodePath closingNamePath.replaceWith(t.jsxIdentifier(component)) } state.replacedComponents.add(component) return } // Remove element if not supported state.unsupportedComponents.add(name) path.remove() } const svgElementVisitor = { JSXElement(path: NodePath, state: State) { if ( !path.get('openingElement').get('name').isJSXIdentifier({ name: 'svg' }) ) { return } replaceElement(path, state) path.traverse(jsxElementVisitor, state) }, } const jsxElementVisitor = { JSXElement(path: NodePath, state: State) { replaceElement(path, state) }, } const importDeclarationVisitor = { ImportDeclaration(path: NodePath, state: State) { const isNotTypeImport = !path.get('importKind').hasNode() || path.node.importKind == null || path.node.importKind === 'value' if ( path.get('source').isStringLiteral({ value: 'react-native-svg' }) && isNotTypeImport ) { state.replacedComponents.forEach((component) => { if ( path .get('specifiers') .some((specifier) => specifier.get('local').isIdentifier({ name: component }), ) ) { return } path.pushContainer( 'specifiers', t.importSpecifier(t.identifier(component), t.identifier(component)), ) }) } else if (path.get('source').isStringLiteral({ value: 'expo' })) { path.pushContainer( 'specifiers', t.importSpecifier(t.identifier('Svg'), t.identifier('Svg')), ) } else { return } if (state.unsupportedComponents.size && !path.has('trailingComments')) { const componentList = [...state.unsupportedComponents].join(', ') path.addComment( 'trailing', ` SVGR has dropped some elements not supported by react-native-svg: ${componentList} `, ) } }, } return { visitor: { Program(path: NodePath, state: Partial) { state.replacedComponents = new Set() state.unsupportedComponents = new Set() path.traverse(svgElementVisitor, state as State) path.traverse(importDeclarationVisitor, state as State) }, }, } } export default plugin ================================================ FILE: packages/babel-plugin-transform-react-native-svg/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/babel-plugin-transform-svg-component/.npmignore ================================================ /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/babel-plugin-transform-svg-component/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) ### Features * **types:** change `SVGProps` from import to import type ([#853](https://github.com/gregberge/svgr/issues/853)) ([095f021](https://github.com/gregberge/svgr/commit/095f0216288ccb5b96a75f154fe3aead074bfa99)) # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) ### Features * allow specifying `jsxRuntimeImport` in config ([86bb86f](https://github.com/gregberge/svgr/commit/86bb86f47748618f729742e56199355d9c0bc518)), closes [#801](https://github.com/gregberge/svgr/issues/801) [#801](https://github.com/gregberge/svgr/issues/801) ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) **Note:** Version bump only for package @svgr/babel-plugin-transform-svg-component # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/babel-plugin-transform-svg-component ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ### Features - add descProp option ([#729](https://github.com/gregberge/svgr/issues/729)) ([a0637d4](https://github.com/gregberge/svgr/commit/a0637d49b60243bbae461f7b96dab9b47cd82d8f)) # [6.2.0](https://github.com/gregberge/svgr/compare/v6.1.2...v6.2.0) (2022-01-10) ### Features - support comments in templates ([#661](https://github.com/gregberge/svgr/issues/661)) ([9afb590](https://github.com/gregberge/svgr/commit/9afb590d1094793fca797449fb7017da9fa06b4e)) # [6.1.0](https://github.com/gregberge/svgr/compare/v6.0.0...v6.1.0) (2021-12-01) ### Bug Fixes - fix previous export system ([1872829](https://github.com/gregberge/svgr/commit/187282977af841cd5a2243a23abba72b20eec2fa)), closes [#635](https://github.com/gregberge/svgr/issues/635) # [5.5.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/compare/v5.4.0...v5.5.0) (2020-11-15) ### Bug Fixes - **typescript:** fix react-native support [#465](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/issues/465) ([#488](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/issues/488)) ([d61e0cf](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/commit/d61e0cface065afc1478fdb44d87ca8177041eab)) ### Features - allow custom name for named export ([#493](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/issues/493)) ([16a58d6](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/commit/16a58d6e817c065f72a68be91600a1a360205f44)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/compare/v5.3.1...v5.4.0) (2020-04-27) ### Bug Fixes - wrap svg component directly with memo/forwardRef ([#440](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/issues/440)) ([#441](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/issues/441)) ([a6de2da](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/commit/a6de2dacb63e36572a2167b928418bdc39f3a9c2)) ## [5.3.1](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/compare/v5.3.0...v5.3.1) (2020-04-05) ### Bug Fixes - fix typescript types (ref, title) ([#419](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/issues/419)) ([6e7e6b2](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/commit/6e7e6b2e73d26d30f64604e0fc627f9ff94079c2)) # [5.3.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/compare/v5.2.0...v5.3.0) (2020-03-22) ### Features - add typescript option ([4596d7b](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/commit/4596d7bb470babb5ec4b87f5281174fb182bd9c7)), closes [#373](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/issues/373) # [5.2.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/compare/v5.1.0...v5.2.0) (2020-02-23) **Note:** Version bump only for package @svgr/babel-plugin-transform-svg-component ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/compare/v4.1.0...v4.2.0) (2019-04-11) ### Features - add expo option ([#289](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/issues/289)) ([978db3e](https://github.com/gregberge/svgr/tree/master/packages/babel-plugin-transform-svg-component/commit/978db3e)) # [4.1.0](https://github.com/gregberge/svgr/compare/v4.0.4...v4.1.0) (2018-11-24) **Note:** Version bump only for package @svgr/babel-plugin-transform-svg-component ## [4.0.1](https://github.com/gregberge/svgr/compare/v4.0.0...v4.0.1) (2018-11-08) ### Bug Fixes - **babel-plugin-transform-svg:** support template that only return a single node ([80ac40f](https://github.com/gregberge/svgr/commit/80ac40f)), closes [#223](https://github.com/gregberge/svgr/issues/223) - **babel-plugin-transform-svg-component:** parsing error of JSX template exports defs ([#225](https://github.com/gregberge/svgr/issues/225)) ([1e56309](https://github.com/gregberge/svgr/commit/1e56309)), closes [/github.com/gregberge/svgr/blob/master/packages/babel-plugin-transform-svg-component/src/util.js#L61](https://github.com//github.com/gregberge/svgr/blob/master/packages/babel-plugin-transform-svg-component/src/util.js/issues/L61) # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/babel-plugin-transform-svg-component/README.md ================================================ # @svgr/babel-plugin-transform-svg-component ## Install ``` npm install --save-dev @svgr/babel-plugin-transform-svg-component ``` ## Usage **.babelrc** ```json { "plugins": [ ["@svgr/babel-plugin-transform-svg-component", { "titleProp": true }] ] } ``` ## License MIT ================================================ FILE: packages/babel-plugin-transform-svg-component/package.json ================================================ { "name": "@svgr/babel-plugin-transform-svg-component", "description": "Transform SVG into component", "version": "8.0.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/babel-plugin-transform-svg-component", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "babel-plugin" ], "engines": { "node": ">=12" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" }, "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" }, "devDependencies": { "@types/babel__template": "^7.4.1" } } ================================================ FILE: packages/babel-plugin-transform-svg-component/src/__snapshots__/index.test.ts.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`plugin javascript #jsxRuntime allows to specify a custom "classic" jsxRuntime using "defaultSpecifier" 1`] = ` "import h from "hyperapp-jsx-pragma"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin javascript #jsxRuntime allows to specify a custom "classic" jsxRuntime using "namespace" 1`] = ` "import * as Preact from "preact"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin javascript #jsxRuntime allows to specify a custom "classic" jsxRuntime using "specifiers" 1`] = ` "import { h } from "preact"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin javascript #jsxRuntime supports "automatic" jsxRuntime 1`] = ` "const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin javascript #jsxRuntime supports "classic" jsxRuntime 1`] = ` "import * as React from "react"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin javascript allows to specify a different import source 1`] = ` "import { h } from "preact"; import { forwardRef, memo } from "preact/compat"; const SvgComponent = (_, ref) => ; const ForwardRef = forwardRef(SvgComponent); const Memo = memo(ForwardRef); export default Memo;" `; exports[`plugin javascript custom templates support basic template 1`] = ` "import * as React from 'react'; const MyComponent = () => ; export default MyComponent;" `; exports[`plugin javascript custom templates supports JSX template 1`] = ` "import * as React from 'react'; const MyComponent = () =>
{}
; export default MyComponent;" `; exports[`plugin javascript custom templates supports TypeScript template 1`] = ` "import * as React from 'react'; const MyComponent = (props: React.SVGProps) => ; export default MyComponent;" `; exports[`plugin javascript custom templates supports comments in templates 1`] = ` "/** * Comment */ const MyComponent = () => ; export default MyComponent;" `; exports[`plugin javascript custom templates supports template that does not return an array 1`] = `";"`; exports[`plugin javascript custom templates supports type annotation on component 1`] = ` "import * as React from "react"; interface Props { x?: string; } export const SvgComponent:React.FC = ({ x }) => { return ; }; export default SvgComponent;" `; exports[`plugin javascript transforms whole program 1`] = ` "import * as React from "react"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin javascript with "descProp" adds "desc" and "descId" prop 1`] = ` "import * as React from "react"; const SvgComponent = ({ desc, descId }) => ; export default SvgComponent;" `; exports[`plugin javascript with "descProp" and "expandProps" adds "desc", "descId" props and expands props 1`] = ` "import * as React from "react"; const SvgComponent = ({ desc, descId, ...props }) => ; export default SvgComponent;" `; exports[`plugin javascript with "expandProps" add props 1`] = ` "import * as React from "react"; const SvgComponent = props => ; export default SvgComponent;" `; exports[`plugin javascript with "memo" option wrap component in "React.memo" 1`] = ` "import * as React from "react"; import { memo } from "react"; const SvgComponent = () => ; const Memo = memo(SvgComponent); export default Memo;" `; exports[`plugin javascript with "namedExport" and "exportType" option and without "previousExport" state exports via named export 1`] = ` "import * as React from "react"; const SvgComponent = () => ; export { SvgComponent as ReactComponent };" `; exports[`plugin javascript with "namedExport" option and "previousExport" state has custom named export 1`] = ` "import * as React from "react"; const SvgComponent = () => ; export { SvgComponent as Component }; var img = new Image(); img.src = '...'; export default img;" `; exports[`plugin javascript with "native" and "expandProps" option adds import from "react-native-svg" and adds props 1`] = ` "import * as React from "react"; import Svg from "react-native-svg"; const SvgComponent = props => ; export default SvgComponent;" `; exports[`plugin javascript with "native" option adds import from "react-native-svg" 1`] = ` "import * as React from "react"; import Svg from "react-native-svg"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin javascript with "native", "ref" and "expandProps" option adds import from "react-native-svg" and adds props and adds ForwardRef component 1`] = ` "import * as React from "react"; import Svg from "react-native-svg"; import { forwardRef } from "react"; const SvgComponent = (props, ref) => ; const ForwardRef = forwardRef(SvgComponent); export default ForwardRef;" `; exports[`plugin javascript with "native", "ref" option adds import from "react-native-svg" and adds ForwardRef component 1`] = ` "import * as React from "react"; import Svg from "react-native-svg"; import { forwardRef } from "react"; const SvgComponent = (_, ref) => ; const ForwardRef = forwardRef(SvgComponent); export default ForwardRef;" `; exports[`plugin javascript with "ref" and "expandProps" option expands props 1`] = ` "import * as React from "react"; import { forwardRef } from "react"; const SvgComponent = (props, ref) => ; const ForwardRef = forwardRef(SvgComponent); export default ForwardRef;" `; exports[`plugin javascript with "ref" option adds ForwardRef component 1`] = ` "import * as React from "react"; import { forwardRef } from "react"; const SvgComponent = (_, ref) => ; const ForwardRef = forwardRef(SvgComponent); export default ForwardRef;" `; exports[`plugin javascript with "titleProp" "descProp" and "expandProps" adds "title", "titleId", "desc", "descId" props and expands props 1`] = ` "import * as React from "react"; const SvgComponent = ({ title, titleId, desc, descId, ...props }) => ; export default SvgComponent;" `; exports[`plugin javascript with "titleProp" adds "title" and "titleId" prop 1`] = ` "import * as React from "react"; const SvgComponent = ({ title, titleId }) => ; export default SvgComponent;" `; exports[`plugin javascript with "titleProp" and "descProp" adds "title", "titleId", "desc", and "descId prop 1`] = ` "import * as React from "react"; const SvgComponent = ({ title, titleId, desc, descId }) => ; export default SvgComponent;" `; exports[`plugin javascript with "titleProp" and "expandProps" adds "title", "titleId" props and expands props 1`] = ` "import * as React from "react"; const SvgComponent = ({ title, titleId, ...props }) => ; export default SvgComponent;" `; exports[`plugin javascript with both "memo" and "ref" option wrap component in "React.memo" and "React.forwardRef" 1`] = ` "import * as React from "react"; import { forwardRef, memo } from "react"; const SvgComponent = (_, ref) => ; const ForwardRef = forwardRef(SvgComponent); const Memo = memo(ForwardRef); export default Memo;" `; exports[`plugin typescript #jsxRuntime allows to specify a custom "classic" jsxRuntime using "defaultSpecifier" 1`] = ` "import h from "hyperapp-jsx-pragma"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin typescript #jsxRuntime allows to specify a custom "classic" jsxRuntime using "namespace" 1`] = ` "import * as Preact from "preact"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin typescript #jsxRuntime allows to specify a custom "classic" jsxRuntime using "specifiers" 1`] = ` "import { h } from "preact"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin typescript #jsxRuntime supports "automatic" jsxRuntime 1`] = ` "const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin typescript #jsxRuntime supports "classic" jsxRuntime 1`] = ` "import * as React from "react"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin typescript allows to specify a different import source 1`] = ` "import { h } from "preact"; import { Ref, forwardRef, memo } from "preact/compat"; const SvgComponent = (_, ref: Ref) => ; const ForwardRef = forwardRef(SvgComponent); const Memo = memo(ForwardRef); export default Memo;" `; exports[`plugin typescript custom templates support basic template 1`] = ` "import * as React from 'react'; const MyComponent = () => ; export default MyComponent;" `; exports[`plugin typescript custom templates supports JSX template 1`] = ` "import * as React from 'react'; const MyComponent = () =>
{}
; export default MyComponent;" `; exports[`plugin typescript custom templates supports TypeScript template 1`] = ` "import * as React from 'react'; const MyComponent = (props: React.SVGProps) => ; export default MyComponent;" `; exports[`plugin typescript custom templates supports comments in templates 1`] = ` "/** * Comment */ const MyComponent = () => ; export default MyComponent;" `; exports[`plugin typescript custom templates supports template that does not return an array 1`] = `";"`; exports[`plugin typescript custom templates supports type annotation on component 1`] = ` "import * as React from "react"; interface Props { x?: string; } export const SvgComponent:React.FC = ({ x }) => { return ; }; export default SvgComponent;" `; exports[`plugin typescript transforms whole program 1`] = ` "import * as React from "react"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin typescript with "descProp" adds "desc" and "descId" prop 1`] = ` "import * as React from "react"; interface SVGRProps { desc?: string; descId?: string; } const SvgComponent = ({ desc, descId }: SVGRProps) => ; export default SvgComponent;" `; exports[`plugin typescript with "descProp" and "expandProps" adds "desc", "descId" props and expands props 1`] = ` "import * as React from "react"; import type { SVGProps } from "react"; interface SVGRProps { desc?: string; descId?: string; } const SvgComponent = ({ desc, descId, ...props }: SVGProps & SVGRProps) => ; export default SvgComponent;" `; exports[`plugin typescript with "expandProps" add props 1`] = ` "import * as React from "react"; import type { SVGProps } from "react"; const SvgComponent = (props: SVGProps) => ; export default SvgComponent;" `; exports[`plugin typescript with "memo" option wrap component in "React.memo" 1`] = ` "import * as React from "react"; import { memo } from "react"; const SvgComponent = () => ; const Memo = memo(SvgComponent); export default Memo;" `; exports[`plugin typescript with "namedExport" and "exportType" option and without "previousExport" state exports via named export 1`] = ` "import * as React from "react"; const SvgComponent = () => ; export { SvgComponent as ReactComponent };" `; exports[`plugin typescript with "namedExport" option and "previousExport" state has custom named export 1`] = ` "import * as React from "react"; const SvgComponent = () => ; export { SvgComponent as Component }; var img = new Image(); img.src = '...'; export default img;" `; exports[`plugin typescript with "native" and "expandProps" option adds import from "react-native-svg" and adds props 1`] = ` "import * as React from "react"; import Svg from "react-native-svg"; import type { SvgProps } from "react-native-svg"; const SvgComponent = (props: SvgProps) => ; export default SvgComponent;" `; exports[`plugin typescript with "native" option adds import from "react-native-svg" 1`] = ` "import * as React from "react"; import Svg from "react-native-svg"; const SvgComponent = () => ; export default SvgComponent;" `; exports[`plugin typescript with "native", "ref" and "expandProps" option adds import from "react-native-svg" and adds props and adds ForwardRef component 1`] = ` "import * as React from "react"; import Svg from "react-native-svg"; import type { SvgProps } from "react-native-svg"; import { Ref, forwardRef } from "react"; const SvgComponent = (props: SvgProps, ref: Ref) => ; const ForwardRef = forwardRef(SvgComponent); export default ForwardRef;" `; exports[`plugin typescript with "native", "ref" option adds import from "react-native-svg" and adds ForwardRef component 1`] = ` "import * as React from "react"; import Svg from "react-native-svg"; import { Ref, forwardRef } from "react"; const SvgComponent = (_, ref: Ref) => ; const ForwardRef = forwardRef(SvgComponent); export default ForwardRef;" `; exports[`plugin typescript with "ref" and "expandProps" option expands props 1`] = ` "import * as React from "react"; import type { SVGProps } from "react"; import { Ref, forwardRef } from "react"; const SvgComponent = (props: SVGProps, ref: Ref) => ; const ForwardRef = forwardRef(SvgComponent); export default ForwardRef;" `; exports[`plugin typescript with "ref" option adds ForwardRef component 1`] = ` "import * as React from "react"; import { Ref, forwardRef } from "react"; const SvgComponent = (_, ref: Ref) => ; const ForwardRef = forwardRef(SvgComponent); export default ForwardRef;" `; exports[`plugin typescript with "titleProp" "descProp" and "expandProps" adds "title", "titleId", "desc", "descId" props and expands props 1`] = ` "import * as React from "react"; import type { SVGProps } from "react"; interface SVGRProps { title?: string; titleId?: string; desc?: string; descId?: string; } const SvgComponent = ({ title, titleId, desc, descId, ...props }: SVGProps & SVGRProps) => ; export default SvgComponent;" `; exports[`plugin typescript with "titleProp" adds "title" and "titleId" prop 1`] = ` "import * as React from "react"; interface SVGRProps { title?: string; titleId?: string; } const SvgComponent = ({ title, titleId }: SVGRProps) => ; export default SvgComponent;" `; exports[`plugin typescript with "titleProp" and "descProp" adds "title", "titleId", "desc", and "descId prop 1`] = ` "import * as React from "react"; interface SVGRProps { title?: string; titleId?: string; desc?: string; descId?: string; } const SvgComponent = ({ title, titleId, desc, descId }: SVGRProps) => ; export default SvgComponent;" `; exports[`plugin typescript with "titleProp" and "expandProps" adds "title", "titleId" props and expands props 1`] = ` "import * as React from "react"; import type { SVGProps } from "react"; interface SVGRProps { title?: string; titleId?: string; } const SvgComponent = ({ title, titleId, ...props }: SVGProps & SVGRProps) => ; export default SvgComponent;" `; exports[`plugin typescript with both "memo" and "ref" option wrap component in "React.memo" and "React.forwardRef" 1`] = ` "import * as React from "react"; import { Ref, forwardRef, memo } from "react"; const SvgComponent = (_, ref: Ref) => ; const ForwardRef = forwardRef(SvgComponent); const Memo = memo(ForwardRef); export default Memo;" `; ================================================ FILE: packages/babel-plugin-transform-svg-component/src/defaultTemplate.ts ================================================ import type { Template } from './types' export const defaultTemplate: Template = (variables, { tpl }) => { return tpl` ${variables.imports}; ${variables.interfaces}; const ${variables.componentName} = (${variables.props}) => ( ${variables.jsx} ); ${variables.exports}; ` } ================================================ FILE: packages/babel-plugin-transform-svg-component/src/index.test.ts ================================================ import { transform } from '@babel/core' import plugin, { Options } from '.' const defaultOptions = { namedExport: 'ReactComponent', state: { componentName: 'SvgComponent' }, } const testPlugin = (language: string) => (code: string, options: Partial = {}) => { const result = transform(code, { plugins: [ '@babel/plugin-syntax-jsx', [ plugin, { typescript: language === 'typescript', ...defaultOptions, ...options, }, ], ], configFile: false, }) if (!result) { throw new Error(`No result`) } return result } describe('plugin', () => { describe.each(['javascript', 'typescript'])('%s', (language) => { it('transforms whole program', () => { const { code } = testPlugin(language)('') expect(code).toMatchSnapshot() }) describe('with "native" option', () => { it('adds import from "react-native-svg"', () => { const { code } = testPlugin(language)('', { native: true, }) expect(code).toMatchSnapshot() }) }) describe('with "ref" option', () => { it('adds ForwardRef component', () => { const { code } = testPlugin(language)('', { ref: true, }) expect(code).toMatchSnapshot() }) }) describe('with "titleProp"', () => { it('adds "title" and "titleId" prop', () => { const { code } = testPlugin(language)('', { titleProp: true, }) expect(code).toMatchSnapshot() }) }) describe('with "titleProp" and "expandProps"', () => { it('adds "title", "titleId" props and expands props', () => { const { code } = testPlugin(language)('', { ...defaultOptions, expandProps: true, titleProp: true, }) expect(code).toMatchSnapshot() }) }) describe('with "descProp"', () => { it('adds "desc" and "descId" prop', () => { const { code } = testPlugin(language)('', { descProp: true, }) expect(code).toMatchSnapshot() }) }) describe('with "descProp" and "expandProps"', () => { it('adds "desc", "descId" props and expands props', () => { const { code } = testPlugin(language)('', { ...defaultOptions, expandProps: true, descProp: true, }) expect(code).toMatchSnapshot() }) }) describe('with "titleProp" and "descProp"', () => { it('adds "title", "titleId", "desc", and "descId prop', () => { const { code } = testPlugin(language)('', { titleProp: true, descProp: true, }) expect(code).toMatchSnapshot() }) }) describe('with "titleProp" "descProp" and "expandProps"', () => { it('adds "title", "titleId", "desc", "descId" props and expands props', () => { const { code } = testPlugin(language)('', { ...defaultOptions, expandProps: true, titleProp: true, descProp: true, }) expect(code).toMatchSnapshot() }) }) describe('with "expandProps"', () => { it('add props', () => { const { code } = testPlugin(language)('', { ...defaultOptions, state: { componentName: 'SvgComponent' }, expandProps: true, }) expect(code).toMatchSnapshot() }) }) describe('with "ref" and "expandProps" option', () => { it('expands props', () => { const { code } = testPlugin(language)('', { state: { componentName: 'SvgComponent' }, expandProps: true, ref: true, }) expect(code).toMatchSnapshot() }) }) describe('with "native", "ref" option', () => { it('adds import from "react-native-svg" and adds ForwardRef component', () => { const { code } = testPlugin(language)('', { state: { componentName: 'SvgComponent' }, native: true, ref: true, }) expect(code).toMatchSnapshot() }) }) describe('with "native" and "expandProps" option', () => { it('adds import from "react-native-svg" and adds props', () => { const { code } = testPlugin(language)('', { state: { componentName: 'SvgComponent' }, native: true, expandProps: true, }) expect(code).toMatchSnapshot() }) }) describe('with "native", "ref" and "expandProps" option', () => { it('adds import from "react-native-svg" and adds props and adds ForwardRef component', () => { const { code } = testPlugin(language)('', { state: { componentName: 'SvgComponent' }, native: true, expandProps: true, ref: true, }) expect(code).toMatchSnapshot() }) }) describe('with "memo" option', () => { it('wrap component in "React.memo"', () => { const { code } = testPlugin(language)('', { state: { componentName: 'SvgComponent' }, memo: true, }) expect(code).toMatchSnapshot() }) }) describe('with both "memo" and "ref" option', () => { it('wrap component in "React.memo" and "React.forwardRef"', () => { const { code } = testPlugin(language)('', { state: { componentName: 'SvgComponent' }, memo: true, ref: true, }) expect(code).toMatchSnapshot() }) }) describe('with "namedExport" option and "previousExport" state', () => { it('has custom named export', () => { const { code } = testPlugin(language)('', { state: { componentName: 'SvgComponent', caller: { previousExport: `var img = new Image(); img.src = '...'; export default img;`, }, }, namedExport: 'Component', }) expect(code).toMatchSnapshot() }) }) describe('with "namedExport" and "exportType" option and without "previousExport" state', () => { it('exports via named export', () => { const { code } = testPlugin(language)('', { state: { componentName: 'SvgComponent', caller: { previousExport: null }, }, namedExport: 'ReactComponent', exportType: 'named', }) expect(code).toMatchSnapshot() }) }) describe('custom templates', () => { it('support basic template', () => { const { code } = testPlugin(language)('', { template: ({ jsx }, { tpl }) => tpl`import * as React from 'react'; const MyComponent = () => ${jsx} export default MyComponent `, state: { componentName: 'SvgComponent' }, }) expect(code).toMatchSnapshot() }) it('supports JSX template', () => { const { code } = testPlugin(language)('', { template: ({ jsx }, { tpl }) => { return tpl`import * as React from 'react'; const MyComponent = () =>
{${jsx}}
export default MyComponent ` }, state: { componentName: 'SvgComponent' }, }) expect(code).toMatchSnapshot() }) it('supports TypeScript template', () => { const { code } = testPlugin(language)('', { template: ({ jsx }, { tpl }) => { return tpl` import * as React from 'react'; const MyComponent = (props: React.SVGProps) => ${jsx}; export default MyComponent; ` }, typescript: true, state: { componentName: 'SvgComponent' }, }) expect(code).toMatchSnapshot() }) it('supports template that does not return an array', () => { const { code } = testPlugin(language)('', { template: ({ jsx }, { tpl }) => tpl`${jsx}`, state: { componentName: 'SvgComponent' }, }) expect(code).toMatchSnapshot() }) it('supports type annotation on component', () => { const { code } = testPlugin(language)('', { typescript: true, template: ( { jsx, imports, interfaces, componentName, exports }, { tpl }, ) => tpl` ${imports} ${interfaces} interface Props { x?: string } export const ${`${componentName}:React.FC`} = ({ x }) => { return (${jsx}); } ${exports}`, state: { componentName: 'SvgComponent' }, }) expect(code).toMatchSnapshot() }) it('supports comments in templates', () => { const { code } = testPlugin(language)('', { template: ({ jsx }, { tpl }) => tpl` /** * Comment */ const MyComponent = () => ${jsx} export default MyComponent; `, state: { componentName: 'SvgComponent' }, }) expect(code).toMatchSnapshot() }) }) describe('#jsxRuntime', () => { it('supports "automatic" jsxRuntime', () => { const { code } = testPlugin(language)('', { jsxRuntime: 'automatic', }) expect(code).toMatchSnapshot() }) it('supports "classic" jsxRuntime', () => { const { code } = testPlugin(language)('', { jsxRuntime: 'classic', }) expect(code).toMatchSnapshot() }) it('allows to specify a custom "classic" jsxRuntime using "specifiers"', () => { const { code } = testPlugin(language)('', { jsxRuntime: 'classic', jsxRuntimeImport: { specifiers: ['h'], source: 'preact' }, }) expect(code).toMatchSnapshot() }) it('allows to specify a custom "classic" jsxRuntime using "namespace"', () => { const { code } = testPlugin(language)('', { jsxRuntime: 'classic', jsxRuntimeImport: { namespace: 'Preact', source: 'preact' }, }) expect(code).toMatchSnapshot() }) it('allows to specify a custom "classic" jsxRuntime using "defaultSpecifier"', () => { const { code } = testPlugin(language)('', { jsxRuntime: 'classic', jsxRuntimeImport: { defaultSpecifier: 'h', source: 'hyperapp-jsx-pragma', }, }) expect(code).toMatchSnapshot() }) it('throws with invalid configuration', () => { expect(() => { testPlugin(language)('', { jsxRuntime: 'classic', jsxRuntimeImport: { source: 'preact' }, }) }).toThrow( 'Specify "namespace", "defaultSpecifier", or "specifiers" in "jsxRuntimeImport" option', ) }) }) it('allows to specify a different import source', () => { const { code } = testPlugin(language)('', { memo: true, ref: true, importSource: 'preact/compat', jsxRuntimeImport: { specifiers: ['h'], source: 'preact' }, }) expect(code).toMatchSnapshot() }) }) }) ================================================ FILE: packages/babel-plugin-transform-svg-component/src/index.ts ================================================ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { ConfigAPI, NodePath, types as t, template as babelTemplate, ParserOptions, } from '@babel/core' import type { Options } from './types' import { defaultTemplate } from './defaultTemplate' import { getVariables } from './variables' export type { Options, Template } from './types' const plugin = (_: ConfigAPI, opts: Options) => { const template = opts.template || defaultTemplate const plugins: ParserOptions['plugins'] = opts.typescript ? ['jsx', 'typescript'] : ['jsx'] const tpl = babelTemplate.smart({ plugins, preserveComments: true }).ast return { visitor: { Program(path: NodePath) { const jsx = (path.node.body[0] as t.ExpressionStatement) .expression as t.JSXElement const variables = getVariables({ opts, jsx, }) const body = template(variables, { options: opts, tpl }) path.node.body = Array.isArray(body) ? body : [body] path.replaceWith(path.node) }, }, } } export default plugin ================================================ FILE: packages/babel-plugin-transform-svg-component/src/types.ts ================================================ import type { types as t } from '@babel/core' import type { TemplateBuilder } from '@babel/template' export interface TemplateVariables { componentName: string interfaces: t.TSInterfaceDeclaration[] props: (t.ObjectPattern | t.Identifier)[] imports: t.ImportDeclaration[] exports: (t.VariableDeclaration | t.ExportDeclaration | t.Statement)[] jsx: t.JSXElement } interface TemplateContext { options: Options tpl: TemplateBuilder['ast'] } export interface Template { (variables: TemplateVariables, context: TemplateContext): | t.Statement | t.Statement[] } interface State { componentName: string caller?: { previousExport?: string | null } } export interface JSXRuntimeImport { source: string namespace?: string defaultSpecifier?: string specifiers?: string[] } export interface Options { typescript?: boolean titleProp?: boolean descProp?: boolean expandProps?: boolean | 'start' | 'end' ref?: boolean template?: Template state: State native?: boolean memo?: boolean exportType?: 'named' | 'default' namedExport?: string jsxRuntime?: 'automatic' | 'classic' jsxRuntimeImport?: JSXRuntimeImport importSource?: string } ================================================ FILE: packages/babel-plugin-transform-svg-component/src/variables.ts ================================================ import { types as t, template } from '@babel/core' import type { Options, TemplateVariables, JSXRuntimeImport } from './types' import type { ImportDeclaration } from '@babel/types' const tsOptionalPropertySignature = ( ...args: Parameters ) => { return { ...t.tsPropertySignature(...args), optional: true, } as t.TSPropertySignature } interface Context { opts: Options interfaces: t.TSInterfaceDeclaration[] props: (t.Identifier | t.ObjectPattern)[] imports: t.ImportDeclaration[] importSource: string } const getOrCreateImport = ( { imports }: Context, sourceValue: string, importKind: ImportDeclaration['importKind'] = undefined, ) => { const existing = imports.find( (imp) => imp.source.value === sourceValue && imp.importKind === importKind && !imp.specifiers.some( (specifier) => specifier.type === 'ImportNamespaceSpecifier', ), ) if (existing) return existing const imp = t.importDeclaration([], t.stringLiteral(sourceValue)) if (importKind !== undefined) { imp.importKind = importKind } imports.push(imp) return imp } const tsTypeReferenceSVGProps = (ctx: Context) => { if (ctx.opts.native) { const identifier = t.identifier('SvgProps') getOrCreateImport(ctx, 'react-native-svg', 'type').specifiers.push( t.importSpecifier(identifier, identifier), ) return t.tsTypeReference(identifier) } const identifier = t.identifier('SVGProps') getOrCreateImport(ctx, ctx.importSource, 'type').specifiers.push( t.importSpecifier(identifier, identifier), ) return t.tsTypeReference( identifier, t.tsTypeParameterInstantiation([ t.tsTypeReference(t.identifier('SVGSVGElement')), ]), ) } const tsTypeReferenceSVGRef = (ctx: Context) => { const identifier = t.identifier('Ref') getOrCreateImport(ctx, ctx.importSource).specifiers.push( t.importSpecifier(identifier, identifier), ) return t.tsTypeReference( identifier, t.tsTypeParameterInstantiation([ t.tsTypeReference(t.identifier('SVGSVGElement')), ]), ) } const getJsxRuntimeImport = (cfg: JSXRuntimeImport) => { const specifiers = (() => { if (cfg.namespace) return [t.importNamespaceSpecifier(t.identifier(cfg.namespace))] if (cfg.defaultSpecifier) { const identifier = t.identifier(cfg.defaultSpecifier) return [t.importDefaultSpecifier(identifier)] } if (cfg.specifiers) return cfg.specifiers.map((specifier) => { const identifier = t.identifier(specifier) return t.importSpecifier(identifier, identifier) }) throw new Error( `Specify "namespace", "defaultSpecifier", or "specifiers" in "jsxRuntimeImport" option`, ) })() return t.importDeclaration(specifiers, t.stringLiteral(cfg.source)) } const defaultJsxRuntimeImport: JSXRuntimeImport = { source: 'react', namespace: 'React', } const defaultImportSource = 'react' export const getVariables = ({ opts, jsx, }: { opts: Options jsx: t.JSXElement }): TemplateVariables => { const interfaces: t.TSInterfaceDeclaration[] = [] const props: (t.Identifier | t.ObjectPattern)[] = [] const imports: t.ImportDeclaration[] = [] const exports: (t.VariableDeclaration | t.ExportDeclaration | t.Statement)[] = [] const ctx = { importSource: opts.importSource ?? defaultImportSource, exportIdentifier: t.identifier(opts.state.componentName), opts, interfaces, props, imports, exports, } if (opts.jsxRuntime !== 'automatic') { imports.push( getJsxRuntimeImport(opts.jsxRuntimeImport ?? defaultJsxRuntimeImport), ) } if (opts.native) { getOrCreateImport(ctx, 'react-native-svg').specifiers.push( t.importDefaultSpecifier(t.identifier('Svg')), ) } if (opts.titleProp || opts.descProp) { const properties = [] const propertySignatures = [] const createProperty = (attr: string) => { return t.objectProperty( t.identifier(attr), t.identifier(attr), false, true, ) } const createSignature = (attr: string) => { return tsOptionalPropertySignature( t.identifier(attr), t.tsTypeAnnotation(t.tsStringKeyword()), ) } if (opts.titleProp) { properties.push(createProperty('title'), createProperty('titleId')) if (opts.typescript) { propertySignatures.push( createSignature('title'), createSignature('titleId'), ) } } if (opts.descProp) { properties.push(createProperty('desc'), createProperty('descId')) if (opts.typescript) { propertySignatures.push( createSignature('desc'), createSignature('descId'), ) } } const prop = t.objectPattern(properties) props.push(prop) if (opts.typescript) { interfaces.push( t.tsInterfaceDeclaration( t.identifier('SVGRProps'), null, null, t.tSInterfaceBody(propertySignatures), ), ) prop.typeAnnotation = t.tsTypeAnnotation( t.tsTypeReference(t.identifier('SVGRProps')), ) } } if (opts.expandProps) { const identifier = t.identifier('props') if (t.isObjectPattern(props[0])) { props[0].properties.push(t.restElement(identifier)) if (opts.typescript) { props[0].typeAnnotation = t.tsTypeAnnotation( t.tsIntersectionType([ tsTypeReferenceSVGProps(ctx), (props[0].typeAnnotation as t.TSTypeAnnotation).typeAnnotation, ]), ) } } else { props.push(identifier) if (opts.typescript) { identifier.typeAnnotation = t.tsTypeAnnotation( tsTypeReferenceSVGProps(ctx), ) } } } if (opts.ref) { if (props.length === 0) { props.push(t.identifier('_')) } const prop = t.identifier('ref') props.push(prop) if (opts.typescript) { prop.typeAnnotation = t.tsTypeAnnotation(tsTypeReferenceSVGRef(ctx)) } const forwardRef = t.identifier('forwardRef') const ForwardRef = t.identifier('ForwardRef') getOrCreateImport(ctx, ctx.importSource).specifiers.push( t.importSpecifier(forwardRef, forwardRef), ) exports.push( t.variableDeclaration('const', [ t.variableDeclarator( ForwardRef, t.callExpression(forwardRef, [ctx.exportIdentifier]), ), ]), ) ctx.exportIdentifier = ForwardRef } if (opts.memo) { const memo = t.identifier('memo') const Memo = t.identifier('Memo') getOrCreateImport(ctx, ctx.importSource).specifiers.push( t.importSpecifier(memo, memo), ) exports.push( t.variableDeclaration('const', [ t.variableDeclarator( Memo, t.callExpression(memo, [ctx.exportIdentifier]), ), ]), ) ctx.exportIdentifier = Memo } if (opts.state.caller?.previousExport || opts.exportType === 'named') { if (!opts.namedExport) { throw new Error(`"namedExport" not specified`) } exports.push( t.exportNamedDeclaration(null, [ t.exportSpecifier(ctx.exportIdentifier, t.identifier(opts.namedExport)), ]), ) if (opts.state.caller?.previousExport) { const previousExportAst = template.ast(opts.state.caller.previousExport) exports.push( ...(Array.isArray(previousExportAst) ? previousExportAst : [previousExportAst]), ) } } else { exports.push(t.exportDefaultDeclaration(ctx.exportIdentifier)) } return { componentName: opts.state.componentName, props, interfaces, imports, exports, jsx, } } ================================================ FILE: packages/babel-plugin-transform-svg-component/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/babel-preset/.npmignore ================================================ /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/babel-preset/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.1.0](https://github.com/gregberge/svgr/compare/v8.0.1...v8.1.0) (2023-08-15) **Note:** Version bump only for package @svgr/babel-preset # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/babel-preset # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/babel-preset ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) ### Reverts - Revert "feat(a11y): add attribute role="img" to the svg element (#750)" ([1382232](https://github.com/gregberge/svgr/commit/138223284ad9aebc5bbf94ed3ae7174a66dbc7f5)), closes [#750](https://github.com/gregberge/svgr/issues/750) # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) ### Features - **babel-preset:** fix 'role' attribute on svg element for react native ([#787](https://github.com/gregberge/svgr/issues/787)) ([35d85e0](https://github.com/gregberge/svgr/commit/35d85e069ebfef1b26ba181f443d9377a7bc003e)) # [6.4.0](https://github.com/gregberge/svgr/compare/v6.3.1...v6.4.0) (2022-10-01) ### Features - **a11y:** add attribute role="img" to the svg element ([#750](https://github.com/gregberge/svgr/issues/750)) ([8b9edc4](https://github.com/gregberge/svgr/commit/8b9edc4e712f3adbd9f9c503dfc5e4d627f763cd)) ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix duplicate plugin/preset detected error ([#747](https://github.com/gregberge/svgr/issues/747)) ([3c6a54c](https://github.com/gregberge/svgr/commit/3c6a54c494bb8ff15f332ff2d44e9f6465a6c19a)), closes [#746](https://github.com/gregberge/svgr/issues/746) - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ### Features - add descProp option ([#729](https://github.com/gregberge/svgr/issues/729)) ([a0637d4](https://github.com/gregberge/svgr/commit/a0637d49b60243bbae461f7b96dab9b47cd82d8f)) # [6.2.0](https://github.com/gregberge/svgr/compare/v6.1.2...v6.2.0) (2022-01-10) **Note:** Version bump only for package @svgr/babel-preset # [6.1.0](https://github.com/gregberge/svgr/compare/v6.0.0...v6.1.0) (2021-12-01) **Note:** Version bump only for package @svgr/babel-preset # [5.5.0](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/compare/v5.4.0...v5.5.0) (2020-11-15) ### Bug Fixes - prevent removing the namespace by svgr ([[#475](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/issues/475)](https://github.com/gregberge/svgr/issues/475) ([#498](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/issues/498)) ([00e84ea](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/commit/00e84ead96d89bcbd072b9585b4db1365e392d33)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/compare/v5.3.1...v5.4.0) (2020-04-27) **Note:** Version bump only for package @svgr/babel-preset ## [5.3.1](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/compare/v5.3.0...v5.3.1) (2020-04-05) **Note:** Version bump only for package @svgr/babel-preset # [5.3.0](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/compare/v5.2.0...v5.3.0) (2020-03-22) **Note:** Version bump only for package @svgr/babel-preset # [5.2.0](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/compare/v5.1.0...v5.2.0) (2020-02-23) **Note:** Version bump only for package @svgr/babel-preset ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) ## [4.3.3](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/compare/v4.3.2...v4.3.3) (2019-09-24) ### Bug Fixes - **babel-plugin-svg-dynamic-title:** dont render empty title ([#341](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/issues/341)) ([88b24c5](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/commit/88b24c5)), closes [#333](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/issues/333) ## [4.3.1](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/compare/v4.3.0...v4.3.1) (2019-07-01) ### Bug Fixes - **titleProp:** handle the existing title case by using element instead of value (children) ([#315](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/issues/315)) ([065e7a9](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/commit/065e7a9)) # [4.3.0](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/compare/v4.2.0...v4.3.0) (2019-05-28) ### Features - titleProps fallbacks to svg's title ([#311](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/issues/311)) ([8f92366](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/commit/8f92366)) # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/compare/v4.1.0...v4.2.0) (2019-04-11) ### Bug Fixes - **babel-preset:** expandProps + icon option ([ddfae22](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/commit/ddfae22)), closes [#277](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/issues/277) ### Features - add expo option ([#289](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/issues/289)) ([978db3e](https://github.com/gregberge/svgr/tree/master/packages/babel-preset/commit/978db3e)) # [4.1.0](https://github.com/gregberge/svgr/compare/v4.0.4...v4.1.0) (2018-11-24) **Note:** Version bump only for package @svgr/babel-preset ## [4.0.3](https://github.com/gregberge/svgr/compare/v4.0.2...v4.0.3) (2018-11-13) **Note:** Version bump only for package @svgr/babel-preset ## [4.0.1](https://github.com/gregberge/svgr/compare/v4.0.0...v4.0.1) (2018-11-08) **Note:** Version bump only for package @svgr/babel-preset # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) - allow dynamic properties in replaceAttrValues option ([15f55fe](https://github.com/gregberge/svgr/commit/15f55fe)), closes [#205](https://github.com/gregberge/svgr/issues/205) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/babel-preset/README.md ================================================ # @svgr/babel-preset ## Install ``` npm install --save-dev @svgr/babel-preset ``` ## Usage **.babelrc** ```json { "presets": [["@svgr/babel-preset", { "svgProps": { "width": 200 } }]] } ``` ## License MIT ================================================ FILE: packages/babel-preset/package.json ================================================ { "name": "@svgr/babel-preset", "description": "SVGR preset that apply transformations from config", "version": "8.1.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/babel-preset", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "babel-plugin", "babel-preset" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "dependencies": { "@svgr/babel-plugin-add-jsx-attribute": "workspace:*", "@svgr/babel-plugin-remove-jsx-attribute": "workspace:*", "@svgr/babel-plugin-remove-jsx-empty-expression": "workspace:*", "@svgr/babel-plugin-replace-jsx-attribute-value": "workspace:*", "@svgr/babel-plugin-svg-dynamic-title": "workspace:*", "@svgr/babel-plugin-svg-em-dimensions": "workspace:*", "@svgr/babel-plugin-transform-react-native-svg": "workspace:*", "@svgr/babel-plugin-transform-svg-component": "workspace:*" }, "peerDependencies": { "@babel/core": "^7.0.0-0" }, "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" } } ================================================ FILE: packages/babel-preset/src/index.test.ts ================================================ import { transform } from '@babel/core' import preset, { Options } from '.' const defaultOptions = { namedExport: 'ReactComponent', state: { componentName: 'SvgComponent' }, } const testPreset = (code: string, options: Partial) => { const result = transform(code, { plugins: ['@babel/plugin-syntax-jsx'], presets: [[preset, { ...defaultOptions, ...options }]], configFile: false, }) return result?.code } describe('preset', () => { it('handles svgProps', () => { expect( testPreset('', { svgProps: { foo: 'bar', x: '{y}', }, }), ).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = () => ; export default SvgComponent;" `) }) it('handles titleProp', () => { expect( testPreset('', { titleProp: true, }), ).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = ({ title, titleId }) => {title ? {title} : null}; export default SvgComponent;" `) }) it('handles titleProp and fallback on existing title', () => { // testing when existing title has string as chilren expect( testPreset(`Hello`, { titleProp: true, }), ).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = ({ title, titleId }) => {title === undefined ? Hello : title ? {title} : null}; export default SvgComponent;" `) // testing when existing title has JSXExpression as children expect( testPreset(`{"Hello"}`, { titleProp: true, }), ).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = ({ title, titleId }) => {title === undefined ? {"Hello"} : title ? {title} : null}; export default SvgComponent;" `) }) it('handles descProp', () => { expect( testPreset('', { descProp: true, }), ).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = ({ desc, descId }) => {desc ? {desc} : null}; export default SvgComponent;" `) }) it('handles descProp and fallback on existing desc', () => { // testing when existing desc has string as chilren expect( testPreset(`Hello`, { descProp: true, }), ).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = ({ desc, descId }) => {desc === undefined ? Hello : desc ? {desc} : null}; export default SvgComponent;" `) // testing when existing desc has JSXExpression as children expect( testPreset(`{"Hello"}`, { descProp: true, }), ).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = ({ desc, descId }) => {desc === undefined ? {"Hello"} : desc ? {desc} : null}; export default SvgComponent;" `) }) it('handles descProp and titleProp', () => { expect( testPreset('', { titleProp: true, descProp: true, }), ).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = ({ title, titleId, desc, descId }) => {desc ? {desc} : null}{title ? {title} : null}; export default SvgComponent;" `) }) it('handles replaceAttrValues', () => { expect( testPreset('', { replaceAttrValues: { '#000': 'black', '#fff': '{props.white}', }, }), ).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = () => ; export default SvgComponent;" `) }) it('handles expandProps & icon & dimensions', () => { expect( testPreset('', { expandProps: 'end', icon: true, dimensions: true, }), ).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = props => ; export default SvgComponent;" `) }) it('handles custom icon size', () => { expect( testPreset('', { expandProps: 'end', icon: 24, dimensions: true, }), ).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = props => ; export default SvgComponent;" `) }) it('defaults to 24 on native', () => { expect( testPreset('', { expandProps: 'end', icon: true, native: true, dimensions: true, }), ).toMatchInlineSnapshot(` "import * as React from "react"; import Svg from "react-native-svg"; const SvgComponent = props => ; export default SvgComponent;" `) }) }) ================================================ FILE: packages/babel-preset/src/index.ts ================================================ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { ConfigAPI } from '@babel/core' import addJSXAttribute, { Attribute, } from '@svgr/babel-plugin-add-jsx-attribute' import removeJSXAttribute from '@svgr/babel-plugin-remove-jsx-attribute' import removeJSXEmptyExpression from '@svgr/babel-plugin-remove-jsx-empty-expression' import replaceJSXAttributeValue, { Value, } from '@svgr/babel-plugin-replace-jsx-attribute-value' import svgDynamicTitle from '@svgr/babel-plugin-svg-dynamic-title' import svgEmDimensions from '@svgr/babel-plugin-svg-em-dimensions' import transformReactNativeSVG from '@svgr/babel-plugin-transform-react-native-svg' import transformSvgComponent, { Options as TransformOptions, } from '@svgr/babel-plugin-transform-svg-component' export interface Options extends TransformOptions { ref?: boolean titleProp?: boolean descProp?: boolean expandProps?: boolean | 'start' | 'end' dimensions?: boolean icon?: boolean | string | number native?: boolean svgProps?: { [key: string]: string } replaceAttrValues?: { [key: string]: string } } const getAttributeValue = (value: string) => { const literal = typeof value === 'string' && value.startsWith('{') && value.endsWith('}') return { value: literal ? value.slice(1, -1) : value, literal } } const propsToAttributes = (props: { [key: string]: string }): Attribute[] => { return Object.keys(props).map((name) => { const { literal, value } = getAttributeValue(props[name]) return { name, literal, value } }) } function replaceMapToValues(replaceMap: { [key: string]: string }): Value[] { return Object.keys(replaceMap).map((value) => { const { literal, value: newValue } = getAttributeValue(replaceMap[value]) return { value, newValue, literal } }) } const plugin = (_: ConfigAPI, opts: Options) => { let toRemoveAttributes = ['version'] let toAddAttributes: Attribute[] = [] if (opts.svgProps) { toAddAttributes = [...toAddAttributes, ...propsToAttributes(opts.svgProps)] } if (opts.ref) { toAddAttributes = [ ...toAddAttributes, { name: 'ref', value: 'ref', literal: true, }, ] } if (opts.titleProp) { toAddAttributes = [ ...toAddAttributes, { name: 'aria-labelledby', value: 'titleId', literal: true, }, ] } if (opts.descProp) { toAddAttributes = [ ...toAddAttributes, { name: 'aria-describedby', value: 'descId', literal: true, }, ] } if (opts.expandProps) { toAddAttributes = [ ...toAddAttributes, { name: 'props', spread: true, position: opts.expandProps === 'start' || opts.expandProps === 'end' ? opts.expandProps : undefined, }, ] } if (!opts.dimensions) { toRemoveAttributes = [...toRemoveAttributes, 'width', 'height'] } const plugins: any[] = [ [transformSvgComponent, opts], ...(opts.icon !== false && opts.dimensions ? [ [ svgEmDimensions, opts.icon !== true ? { width: opts.icon, height: opts.icon } : opts.native ? { width: 24, height: 24 } : {}, ], ] : []), [ removeJSXAttribute, { elements: ['svg', 'Svg'], attributes: toRemoveAttributes }, ], [ addJSXAttribute, { elements: ['svg', 'Svg'], attributes: toAddAttributes }, ], removeJSXEmptyExpression, ] if (opts.replaceAttrValues) { plugins.push([ replaceJSXAttributeValue, { values: replaceMapToValues(opts.replaceAttrValues) }, ]) } if (opts.titleProp) { plugins.push(svgDynamicTitle) } if (opts.descProp) { plugins.push([svgDynamicTitle, { tag: 'desc' }, 'desc']) } if (opts.native) { plugins.push(transformReactNativeSVG) } return { plugins } } export default plugin ================================================ FILE: packages/babel-preset/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/cli/.npmignore ================================================ /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map !/bin/svgr ================================================ FILE: packages/cli/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.1.0](https://github.com/gregberge/svgr/compare/v8.0.1...v8.1.0) (2023-08-15) ### Bug Fixes * **cli:** fix default dimensions, prettier & svgo ([571d5c8](https://github.com/gregberge/svgr/commit/571d5c8bd18bc13c12eeb27a9052fa065aeb012e)) ### Features * **esm:** add support for svgo.config.cjs ([#879](https://github.com/gregberge/svgr/issues/879)) ([ae91e2e](https://github.com/gregberge/svgr/commit/ae91e2eacbe1156480c96219b993000eb1e7b9bf)) ## [8.0.1](https://github.com/gregberge/svgr/compare/v8.0.0...v8.0.1) (2023-05-09) **Note:** Version bump only for package @svgr/cli # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) ### Features * add snake_case filename option ([#857](https://github.com/gregberge/svgr/issues/857)) ([428b0c7](https://github.com/gregberge/svgr/commit/428b0c7f4c5205bb67ae3e9e7c7e819ec3fc03ba)) * make index template more flexible ([#861](https://github.com/gregberge/svgr/issues/861)) ([003009c](https://github.com/gregberge/svgr/commit/003009c7b234cfe66686b629d3251edb8d46c759)) * **types:** change `SVGProps` from import to import type ([#853](https://github.com/gregberge/svgr/issues/853)) ([095f021](https://github.com/gregberge/svgr/commit/095f0216288ccb5b96a75f154fe3aead074bfa99)) ### BREAKING CHANGES * index template now receives an array of objects containing both the created component path (`path`) and the original SVG path (`originalPath`) # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) ### Features * upgrade to svgo v3 ([#798](https://github.com/gregberge/svgr/issues/798)) ([21b6209](https://github.com/gregberge/svgr/commit/21b6209ef34c51cc0313901f31061afe587ab29b)) ### BREAKING CHANGES * svgr now requires Node.js v14+ ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) ### Reverts - Revert "feat(a11y): add attribute role="img" to the svg element (#750)" ([1382232](https://github.com/gregberge/svgr/commit/138223284ad9aebc5bbf94ed3ae7174a66dbc7f5)), closes [#750](https://github.com/gregberge/svgr/issues/750) # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/cli # [6.4.0](https://github.com/gregberge/svgr/compare/v6.3.1...v6.4.0) (2022-10-01) ### Features - **a11y:** add attribute role="img" to the svg element ([#750](https://github.com/gregberge/svgr/issues/750)) ([8b9edc4](https://github.com/gregberge/svgr/commit/8b9edc4e712f3adbd9f9c503dfc5e4d627f763cd)) ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) **Note:** Version bump only for package @svgr/cli # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Features - add descProp option ([#729](https://github.com/gregberge/svgr/issues/729)) ([a0637d4](https://github.com/gregberge/svgr/commit/a0637d49b60243bbae461f7b96dab9b47cd82d8f)) - **cli:** output file name when error happen to handling a file ([#702](https://github.com/gregberge/svgr/issues/702)) ([0ec1fbd](https://github.com/gregberge/svgr/commit/0ec1fbd0bf1e020ecd8f53fba38d7e53d2462b27)) ## [6.2.1](https://github.com/gregberge/svgr/compare/v6.2.0...v6.2.1) (2022-01-30) ### Bug Fixes - use .ts extension for generated index ([#670](https://github.com/gregberge/svgr/issues/670)) ([d19abe2](https://github.com/gregberge/svgr/commit/d19abe207013f4e880a78f236e9f75b0151258da)), closes [#462](https://github.com/gregberge/svgr/issues/462) # [6.2.0](https://github.com/gregberge/svgr/compare/v6.1.2...v6.2.0) (2022-01-10) ### Bug Fixes - **cli:** pass in parser to prettier format to avoid deprecation warning ([#662](https://github.com/gregberge/svgr/issues/662)) ([74fa3ae](https://github.com/gregberge/svgr/commit/74fa3aed2944b63797a6e0e786acd1b51f86550a)) ## [6.1.2](https://github.com/gregberge/svgr/compare/v6.1.1...v6.1.2) (2021-12-12) **Note:** Version bump only for package @svgr/cli ## [6.1.1](https://github.com/gregberge/svgr/compare/v6.1.0...v6.1.1) (2021-12-04) **Note:** Version bump only for package @svgr/cli # [6.1.0](https://github.com/gregberge/svgr/compare/v6.0.0...v6.1.0) (2021-12-01) **Note:** Version bump only for package @svgr/cli # [5.5.0](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v5.4.0...v5.5.0) (2020-11-15) ### Bug Fixes - ensure a valid name for exports ([#489](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/489)) ([0eb8085](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/0eb80853e53a55226881f6ae3b50c1afe89f1cfc)) - prevent removing the namespace by svgr ([[#475](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/475)](https://github.com/gregberge/svgr/issues/475) ([#498](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/498)) ([00e84ea](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/00e84ead96d89bcbd072b9585b4db1365e392d33)) ### Performance Improvements - **cli:** use fs.promises ([#459](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/459)) ([af294ac](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/af294ac3b86e7c39e78fc8b348110baf8c690949)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v5.3.1...v5.4.0) (2020-04-27) ### Bug Fixes - wrap svg component directly with memo/forwardRef ([#440](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/440)) ([#441](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/441)) ([a6de2da](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/a6de2dacb63e36572a2167b928418bdc39f3a9c2)) - **cli:** fix index generation ([#443](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/443)) ([7c46ad7](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/7c46ad73695c42e6153761c931377d65b71835ea)), closes [#433](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/433) ### Features - **cli:** make all CLI options available in config ([a23a186](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/a23a18675c0dd4a461d2fcbdc72a305cabd32a13)), closes [#431](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/431) [#437](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/437) ## [5.3.1](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v5.3.0...v5.3.1) (2020-04-05) ### Bug Fixes - fix typescript types (ref, title) ([#419](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/419)) ([6e7e6b2](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/6e7e6b2e73d26d30f64604e0fc627f9ff94079c2)) # [5.3.0](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v5.2.0...v5.3.0) (2020-03-22) ### Bug Fixes - **cli:** remove confusion between {keep,ignore}-existing ([#413](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/413)) ([c5430f9](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/c5430f97b053a7d2d85c85c56b87dfc8c9c1f09a)), closes [#390](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/390) ### Features - add typescript option ([4596d7b](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/4596d7bb470babb5ec4b87f5281174fb182bd9c7)), closes [#373](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/373) # [5.2.0](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v5.1.0...v5.2.0) (2020-02-23) **Note:** Version bump only for package @svgr/cli # [5.1.0](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v5.0.1...v5.1.0) (2020-01-20) ### Features - add Svg prefix to exports that starts with a number ([#383](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/383)) ([fd120d1](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/fd120d11c81395353f300da487295b769f6b9501)), closes [#379](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/379) - allow to provide custom index.js template ([#378](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/378)) ([f734dda](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/f734ddac8e639ad213a3ce09689e46226fd5c1e0)) ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) ## [4.3.3](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v4.3.2...v4.3.3) (2019-09-24) ### Bug Fixes - **babel-plugin-svg-dynamic-title:** dont render empty title ([#341](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/341)) ([88b24c5](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/88b24c5)), closes [#333](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/333) ## [4.3.2](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v4.3.1...v4.3.2) (2019-07-15) **Note:** Version bump only for package @svgr/cli ## [4.3.1](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v4.3.0...v4.3.1) (2019-07-01) **Note:** Version bump only for package @svgr/cli # [4.3.0](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v4.2.0...v4.3.0) (2019-05-28) ### Features - **cli:** output relative destination paths ([#312](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/312)) ([b78e471](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/b78e471)) # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/cli/compare/v4.1.0...v4.2.0) (2019-04-11) ### Bug Fixes - keep viewBox when dimensions are removed ([#281](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/281)) ([f476c8e](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/f476c8e)) - **cli:** fix kebab case transformation with "\_" ([39c24c5](https://github.com/gregberge/svgr/tree/master/packages/cli/commit/39c24c5)), closes [#280](https://github.com/gregberge/svgr/tree/master/packages/cli/issues/280) # [4.1.0](https://github.com/gregberge/svgr/compare/v4.0.4...v4.1.0) (2018-11-24) **Note:** Version bump only for package @svgr/cli ## [4.0.3](https://github.com/gregberge/svgr/compare/v4.0.2...v4.0.3) (2018-11-13) **Note:** Version bump only for package @svgr/cli ## [4.0.2](https://github.com/gregberge/svgr/compare/v4.0.1...v4.0.2) (2018-11-08) **Note:** Version bump only for package @svgr/cli ## [4.0.1](https://github.com/gregberge/svgr/compare/v4.0.0...v4.0.1) (2018-11-08) **Note:** Version bump only for package @svgr/cli # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Bug Fixes - **cli:** fix --out-dir usage with absolute path ([#208](https://github.com/gregberge/svgr/issues/208)) ([c922e2e](https://github.com/gregberge/svgr/commit/c922e2e)) ### Features - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default # [3.1.0](https://github.com/gregberge/svgr/compare/v3.0.0...v3.1.0) (2018-10-05) ### Bug Fixes - style & custom SVG properties ([#203](https://github.com/gregberge/svgr/issues/203)) ([f8b2212](https://github.com/gregberge/svgr/commit/f8b2212)), closes [#199](https://github.com/gregberge/svgr/issues/199) [#201](https://github.com/gregberge/svgr/issues/201)
# [3.0.0](https://github.com/gregberge/svgr/compare/v2.4.1...v3.0.0) (2018-10-01) ### Features - **config:** improve runtime config ([e52cdce](https://github.com/gregberge/svgr/commit/e52cdce)), closes [#192](https://github.com/gregberge/svgr/issues/192) - always prefix component name with "Svg" ([f71aa7a](https://github.com/gregberge/svgr/commit/f71aa7a)), closes [#190](https://github.com/gregberge/svgr/issues/190) - new "expandProps" option ([bb95828](https://github.com/gregberge/svgr/commit/bb95828)), closes [#170](https://github.com/gregberge/svgr/issues/170) - remove "svgAttributes" option ([4e46a5d](https://github.com/gregberge/svgr/commit/4e46a5d)), closes [#173](https://github.com/gregberge/svgr/issues/173) - use forwardRef on React Native ([4bdd989](https://github.com/gregberge/svgr/commit/4bdd989)), closes [#184](https://github.com/gregberge/svgr/issues/184) - use React.forwardRef ([cbee51c](https://github.com/gregberge/svgr/commit/cbee51c)), closes [#184](https://github.com/gregberge/svgr/issues/184) ### BREAKING CHANGES - "--no-expand-props" is now replaced by "--expand-props none". You can now specify a position "start" or "end" for "expandProps" property. - `svgAttributes` has been removed, please use `svgProps` instead. - "ref" option now uses `React.forwardRef`. You don't have to use "svgRef" prop, just use "ref" and it will work. `React.forwardRef` requires React > 16.3. - **config:** - Runtime configuration is always loaded (even with Node API `convert`) * In CLI, "--config" is now "--config-file"; this new option can be used everywhere ## [2.4.1](https://github.com/gregberge/svgr/compare/v2.4.0...v2.4.1) (2018-09-16) ### Bug Fixes - **config:** fix custom config & default options ([#176](https://github.com/gregberge/svgr/issues/176)) ([9a6c40b](https://github.com/gregberge/svgr/commit/9a6c40b)) # [2.4.0](https://github.com/gregberge/svgr/compare/v2.3.0...v2.4.0) (2018-09-16) ### Features - **upgrade:** h2x@1.1.0 (jsdom@12.0.0) & others ([2d9b7bd](https://github.com/gregberge/svgr/commit/2d9b7bd)) - new option "svgProps" ([#172](https://github.com/gregberge/svgr/issues/172)) ([9657110](https://github.com/gregberge/svgr/commit/9657110)) # [2.3.0](https://github.com/gregberge/svgr/compare/v2.2.1...v2.3.0) (2018-09-03) ### Features - upgrade to Babel v7 ([7bc908d](https://github.com/gregberge/svgr/commit/7bc908d)) # [2.2.0](https://github.com/gregberge/svgr/compare/v2.1.1...v2.2.0) (2018-08-13) **Note:** Version bump only for package @svgr/cli ## [2.1.1](https://github.com/gregberge/svgr/compare/v2.1.0...v2.1.1) (2018-07-11) **Note:** Version bump only for package @svgr/cli # [2.1.0](https://github.com/gregberge/svgr/compare/v2.0.0...v2.1.0) (2018-07-08) ### Features - **cli:** support custom filename cases ([#136](https://github.com/gregberge/svgr/issues/136)) ([4922f7a](https://github.com/gregberge/svgr/commit/4922f7a)), closes [#118](https://github.com/gregberge/svgr/issues/118) ================================================ FILE: packages/cli/README.md ================================================ # @svgr/cli [![Build Status][build-badge]][build] [![version][version-badge]][package] [![MIT License][license-badge]][license] Command Line Interface for SVGR. ``` npm install @svgr/cli --save-dev ``` ## Usage ``` Usage: svgr [options] Options: -V, --version output the version number --config-file specify the path of the svgr config --no-runtime-config disable runtime config (".svgrrc", ".svgo.yml", ".prettierrc") -d, --out-dir output files into a directory --ignore-existing ignore existing files when used with --out-dir --ext specify a custom file extension (default: "js") --filename-case specify filename case ("pascal", "kebab", "camel", "snake") (default: "pascal") --icon use "1em" as width and height --native add react-native support with react-native-svg --memo add React.memo into the result component --ref forward ref to SVG root element --no-dimensions remove width and height from root SVG tag --expand-props [position] disable props expanding ("start", "end", "none") (default: "end") --svg-props add props to the svg element --replace-attr-values replace an attribute value --template specify a custom template to use --index-template specify a custom index.js template to use --no-index disable index file generation --title-prop create a title element linked with props --desc-prop create a desc element linked with props --prettier-config Prettier config --no-prettier disable Prettier --svgo-config SVGO config --no-svgo disable SVGO --silent suppress output --stdin force reading input from stdin --stdin-filepath path to the file to pretend that stdin comesfrom -h, --help output usage information Examples: svgr --replace-attr-values "#fff=currentColor" icon.svg ``` ## License MIT [build-badge]: https://img.shields.io/travis/smooth-code/svgr.svg?style=flat-square [build]: https://travis-ci.org/smooth-code/svgr [version-badge]: https://img.shields.io/npm/v/@svgr/core.svg?style=flat-square [package]: https://www.npmjs.com/package/@svgr/core [license-badge]: https://img.shields.io/npm/l/@svgr/core.svg?style=flat-square [license]: https://github.com/smooth-code/svgr/blob/master/LICENSE ================================================ FILE: packages/cli/bin/svgr ================================================ #!/usr/bin/env node require('../dist/index') ================================================ FILE: packages/cli/package.json ================================================ { "name": "@svgr/cli", "description": "SVGR command line.", "version": "8.1.0", "repository": "https://github.com/gregberge/svgr/tree/main/packages/cli", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "svgr", "svg", "react", "cli" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "bin": { "svgr": "./bin/svgr" }, "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" }, "dependencies": { "@svgr/core": "workspace:*", "@svgr/plugin-jsx": "workspace:*", "@svgr/plugin-prettier": "workspace:*", "@svgr/plugin-svgo": "workspace:*", "camelcase": "^6.2.0", "chalk": "^4.1.2", "commander": "^9.4.1", "dashify": "^2.0.0", "glob": "^8.0.3", "snake-case": "^3.0.4" }, "devDependencies": { "@types/glob": "^8.1.0", "del": "^6.1.1" } } ================================================ FILE: packages/cli/src/__snapshots__/index.test.ts.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`cli should add Svg prefix to index.js exports staring with number 1`] = ` "export { default as Svg2File } from './2File' export { default as File } from './File' " `; exports[`cli should not override config with cli defaults 1`] = ` "import * as React from "react"; const SvgFile = () => {"Rectangle 5"}{"Created with Sketch."}; export default SvgFile; " `; exports[`cli should support --index-template in cli 1`] = ` "export { File } from './File' " `; exports[`cli should support --no-index 1`] = ` [ "File.js", ] `; exports[`cli should support --prettier-config as file 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support --prettier-config as json 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support --svgo-config as file 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( {'Rectangle 5'} ) export default SvgFile " `; exports[`cli should support --svgo-config as file with .cjs extension 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( {'Rectangle 5'} ) export default SvgFile " `; exports[`cli should support --svgo-config as json 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( {'Rectangle 5'} ) export default SvgFile " `; exports[`cli should support custom file extension 1`] = ` [ "File.ts", "index.ts", ] `; exports[`cli should support custom index.js with directory output 1`] = ` "export { File } from './File' " `; exports[`cli should support different filename cases with directory output 1`] = ` [ "CamelCase.js", "KebabCase.js", "MultipleDashes.js", "PascalCase.js", "index.js", ] `; exports[`cli should support different filename cases with directory output: --filename-case=camel 1`] = ` [ "camelCase.js", "index.js", "kebabCase.js", "multipleDashes.js", "pascalCase.js", ] `; exports[`cli should support different filename cases with directory output: --filename-case=kebab 1`] = ` [ "camel-case.js", "index.js", "kebab-case.js", "multiple-dashes.js", "pascal-case.js", ] `; exports[`cli should support different filename cases with directory output: --filename-case=pascal 1`] = ` [ "CamelCase.js", "KebabCase.js", "MultipleDashes.js", "PascalCase.js", "index.js", ] `; exports[`cli should support different filename cases with directory output: --filename-case=snake 1`] = ` [ "camel_case.js", "index.js", "kebab_case.js", "multiple_dashes.js", "pascal_case.js", ] `; exports[`cli should support stdin filepath 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --desc-prop 1`] = ` "import * as React from 'react' const SvgFile = ({ desc, descId, ...props }) => ( {desc ? {desc} : null} ) export default SvgFile " `; exports[`cli should support various args: --expand-props none 1`] = ` "import * as React from 'react' const SvgFile = () => ( ) export default SvgFile " `; exports[`cli should support various args: --expand-props start 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --icon 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --icon 2em 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --icon 24 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --jsx-runtime automatic 1`] = ` "const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --jsx-runtime classic-preact 1`] = ` "import { h } from 'preact' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --native --expand-props none 1`] = ` "import * as React from 'react' import Svg, { Path } from 'react-native-svg' const SvgFile = () => ( ) export default SvgFile " `; exports[`cli should support various args: --native --icon 1`] = ` "import * as React from 'react' import Svg, { Path } from 'react-native-svg' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --native --ref 1`] = ` "import * as React from 'react' import Svg, { Path } from 'react-native-svg' import { forwardRef } from 'react' const SvgFile = (props, ref) => ( ) const ForwardRef = forwardRef(SvgFile) export default ForwardRef " `; exports[`cli should support various args: --native 1`] = ` "import * as React from 'react' import Svg, { Path } from 'react-native-svg' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --no-dimensions 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --no-prettier 1`] = ` "import * as React from "react"; const SvgFile = props => ; export default SvgFile; " `; exports[`cli should support various args: --no-svgo 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( {'Rectangle 5'} {'Created with Sketch.'} ) export default SvgFile " `; exports[`cli should support various args: --ref 1`] = ` "import * as React from 'react' import { forwardRef } from 'react' const SvgFile = (props, ref) => ( ) const ForwardRef = forwardRef(SvgFile) export default ForwardRef " `; exports[`cli should support various args: --replace-attr-values "#063855=currentColor" 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --svg-props "hidden={true},id=hello" 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should support various args: --title-prop 1`] = ` "import * as React from 'react' const SvgFile = ({ title, titleId, ...props }) => ( {title ? {title} : null} ) export default SvgFile " `; exports[`cli should support various args: --typescript --ref --desc-prop 1`] = ` "import * as React from 'react' import type { SVGProps } from 'react' import { Ref, forwardRef } from 'react' interface SVGRProps { desc?: string; descId?: string; } const SvgFile = ( { desc, descId, ...props }: SVGProps & SVGRProps, ref: Ref, ) => ( {desc ? {desc} : null} ) const ForwardRef = forwardRef(SvgFile) export default ForwardRef " `; exports[`cli should support various args: --typescript --ref --title-prop 1`] = ` "import * as React from 'react' import type { SVGProps } from 'react' import { Ref, forwardRef } from 'react' interface SVGRProps { title?: string; titleId?: string; } const SvgFile = ( { title, titleId, ...props }: SVGProps & SVGRProps, ref: Ref, ) => ( {title ? {title} : null} ) const ForwardRef = forwardRef(SvgFile) export default ForwardRef " `; exports[`cli should support various args: --typescript --ref 1`] = ` "import * as React from 'react' import type { SVGProps } from 'react' import { Ref, forwardRef } from 'react' const SvgFile = (props: SVGProps, ref: Ref) => ( ) const ForwardRef = forwardRef(SvgFile) export default ForwardRef " `; exports[`cli should support various args: --typescript 1`] = ` "import * as React from 'react' import type { SVGProps } from 'react' const SvgFile = (props: SVGProps) => ( ) export default SvgFile " `; exports[`cli should suppress output when transforming a directory with a --silent option 1`] = `""`; exports[`cli should transform a whole directory and output relative destination paths 1`] = ` " __fixtures__/cased/camelcase.svg -> __fixtures_build__/whole/cased/camelcase.js __fixtures__/cased/kebab-case.svg -> __fixtures_build__/whole/cased/kebabcase.js __fixtures__/cased/multiple---dashes.svg -> __fixtures_build__/whole/cased/multipledashes.js __fixtures__/cased/pascalcase.svg -> __fixtures_build__/whole/cased/pascalcase.js __fixtures__/complex/skype.svg -> __fixtures_build__/whole/complex/skype.js __fixtures__/complex/telegram.svg -> __fixtures_build__/whole/complex/telegram.js __fixtures__/nesting/a/c/three.svg -> __fixtures_build__/whole/nesting/a/c/three.js __fixtures__/nesting/a/two.svg -> __fixtures_build__/whole/nesting/a/two.js __fixtures__/nesting/one.svg -> __fixtures_build__/whole/nesting/one.js __fixtures__/numeric/2.file.svg -> __fixtures_build__/whole/numeric/2file.js __fixtures__/numeric/file.svg -> __fixtures_build__/whole/numeric/file.js __fixtures__/simple/file.svg -> __fixtures_build__/whole/simple/file.js __fixtures__/withprettierrc/file.svg -> __fixtures_build__/whole/withprettierrc/file.js __fixtures__/withsvgoconfig/file.svg -> __fixtures_build__/whole/withsvgoconfig/file.js __fixtures__/withsvgrrc/file.svg -> __fixtures_build__/whole/withsvgrrc/file.js" `; exports[`cli should transform a whole directory with --typescript 1`] = ` " __fixtures__/cased/camelcase.svg -> __fixtures_build__/whole/cased/camelcase.tsx __fixtures__/cased/kebab-case.svg -> __fixtures_build__/whole/cased/kebabcase.tsx __fixtures__/cased/multiple---dashes.svg -> __fixtures_build__/whole/cased/multipledashes.tsx __fixtures__/cased/pascalcase.svg -> __fixtures_build__/whole/cased/pascalcase.tsx __fixtures__/complex/skype.svg -> __fixtures_build__/whole/complex/skype.tsx __fixtures__/complex/telegram.svg -> __fixtures_build__/whole/complex/telegram.tsx __fixtures__/nesting/a/c/three.svg -> __fixtures_build__/whole/nesting/a/c/three.tsx __fixtures__/nesting/a/two.svg -> __fixtures_build__/whole/nesting/a/two.tsx __fixtures__/nesting/one.svg -> __fixtures_build__/whole/nesting/one.tsx __fixtures__/numeric/2.file.svg -> __fixtures_build__/whole/numeric/2file.tsx __fixtures__/numeric/file.svg -> __fixtures_build__/whole/numeric/file.tsx __fixtures__/simple/file.svg -> __fixtures_build__/whole/simple/file.tsx __fixtures__/withprettierrc/file.svg -> __fixtures_build__/whole/withprettierrc/file.tsx __fixtures__/withsvgoconfig/file.svg -> __fixtures_build__/whole/withsvgoconfig/file.tsx __fixtures__/withsvgrrc/file.svg -> __fixtures_build__/whole/withsvgrrc/file.tsx" `; exports[`cli should work with a simple file 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`cli should work with stdin 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`cli using typescript option, it creates index with \`.ts\` extension 1`] = ` "export { default as File } from './File' " `; ================================================ FILE: packages/cli/src/__snapshots__/util.test.ts.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`util #convertFile should convert a file 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; exports[`util #convertFile should support a custom config path 1`] = ` "import * as React from 'react' const SvgFile = (props) => ( ) export default SvgFile " `; ================================================ FILE: packages/cli/src/dirCommand.ts ================================================ /* eslint-disable no-underscore-dangle, no-console */ import { promises as fs } from 'fs' import * as path from 'path' import { grey, white } from 'chalk' import { loadConfig, Config } from '@svgr/core' import { format, resolveConfig } from 'prettier' import { convertFile, transformFilename, politeWrite, formatExportName, } from './util' import type { Options, SvgrCommand } from './index' const exists = async (filepath: string) => { try { await fs.access(filepath) return true } catch (error) { return false } } const rename = (relative: string, ext: string, filenameCase: string) => { const relativePath = path.parse(relative) relativePath.ext = `.${ext}` relativePath.base = '' relativePath.name = transformFilename(relativePath.name, filenameCase) return path.format(relativePath) } export const isCompilable = (filename: string): boolean => { const ext = path.extname(filename) return ext === '.svg' || ext == '.SVG' } export interface IndexTemplate { (paths: FileInfo[]): string } interface FileInfo { path: string originalPath: string } const defaultIndexTemplate: IndexTemplate = (paths: FileInfo[]) => { const exportEntries = paths.map(({ path: filePath }) => { const basename = path.basename(filePath, path.extname(filePath)) const exportName = formatExportName(basename) return `export { default as ${exportName} } from './${basename}'` }) return exportEntries.join('\n') } const resolveExtension = ( config: Config, ext: string | null | undefined, jsx: boolean, ) => ext || (config.typescript ? (jsx ? 'tsx' : 'ts') : 'js') export const dirCommand: SvgrCommand = async ( opts, _, filenames, ): Promise => { const { ext: extOpt, filenameCase = 'pascal', ignoreExisting, silent, configFile, outDir, } = opts const ext = resolveExtension(opts, extOpt, true) const write = async (src: string, dest: string) => { if (!isCompilable(src)) { return { transformed: false, dest: null } } dest = rename(dest, ext, filenameCase) const code = await convertFile(src, opts) const cwdRelative = path.relative(process.cwd(), dest) const logOutput = `${src} -> ${cwdRelative}\n` if (ignoreExisting && (await exists(dest))) { politeWrite(grey(logOutput), silent) return { transformed: false, dest } } await fs.mkdir(path.dirname(dest), { recursive: true }) await fs.writeFile(dest, code) politeWrite(white(logOutput), silent) return { transformed: true, dest } } const generateIndex = async ( dest: string, files: FileInfo[], opts: Options, ) => { const ext = resolveExtension(opts, extOpt, false) const filepath = path.join(dest, `index.${ext}`) const indexTemplate = opts.indexTemplate || defaultIndexTemplate const fileContent = indexTemplate(files) const prettyContent = await (async () => { if (!opts.prettier) return fileContent const prettierRcConfig = opts.runtimeConfig ? await resolveConfig(filepath, { editorconfig: true }) : {} return format(fileContent, { filepath, ...prettierRcConfig, ...opts.prettierConfig, }) })() await fs.writeFile(filepath, prettyContent) } async function handle(filename: string, root: string) { const stats = await fs.stat(filename) if (stats.isDirectory()) { const dirname = filename const files = await fs.readdir(dirname) const results = (await Promise.all( files.map(async (relativeFile) => { const absFile = path.join(dirname, relativeFile) return [absFile, await handle(absFile, root)] }), )) as [ string, { dest: string | null transformed: boolean }, ][] const transformed = results.filter(([, result]) => result.transformed) if (transformed.length) { const destFiles = results .filter(([, result]) => result.dest) .map(([originalPath, result]) => ({ path: result.dest, originalPath, })) .filter(({ path }) => path) as FileInfo[] const dest = path.resolve( outDir as string, path.relative(root, dirname), ) const resolvedConfig = loadConfig.sync( { configFile, ...opts }, { filePath: dest }, ) as Options if (resolvedConfig.index) { await generateIndex(dest, destFiles, opts) } } return { transformed: false, dest: null } } const dest = path.resolve(outDir as string, path.relative(root, filename)) return write(filename, dest).catch((err) => { console.error('Failed to handle file: ', filename) throw err }) } await Promise.all( filenames.map(async (file) => { const stats = await fs.stat(file) const root = stats.isDirectory() ? file : path.dirname(file) await handle(file, root) }), ) } ================================================ FILE: packages/cli/src/fileCommand.ts ================================================ /* eslint-disable no-underscore-dangle */ import { promises as fs } from 'fs' import { convert, convertFile, exitError } from './util' import type { SvgrCommand } from './index' const readStdin = async () => { return new Promise((resolve) => { let code = '' process.stdin.setEncoding('utf8') process.stdin.on('readable', () => { const chunk = process.stdin.read() if (chunk !== null) code += chunk }) process.stdin.on('end', () => { resolve(code) }) }) } export const fileCommand: SvgrCommand = async ( opts, program, filenames, ): Promise => { if (opts.stdin || (filenames.length === 0 && !process.stdin.isTTY)) { const input = await readStdin() const output = convert(input, opts, { filePath: opts.stdinFilepath }) process.stdout.write(`${output}\n`) return } if (filenames.length === 0) { process.stdout.write(`${program.helpInformation()}\n`) return } if (filenames.length > 1) { exitError('Please specify only one filename or use `--out-dir` option.') } const [filename] = filenames const stats = await fs.stat(filename) if (stats.isDirectory()) { exitError('Directory are not supported without `--out-dir` option instead.') } const output = await convertFile(filename, opts) process.stdout.write(`${output}\n`) } ================================================ FILE: packages/cli/src/index.test.ts ================================================ import { promises as fs } from 'fs' import * as path from 'path' import { exec as execCb } from 'child_process' import { promisify } from 'util' // @ts-ignore import del from 'del' const exec = promisify(execCb) const svgr = path.join(__dirname, '../bin/svgr') const sortCliResult = (result: string) => { return result .split(/\n/) .sort((a, b) => a.localeCompare(b)) .map((x) => x.toLowerCase()) .join('\n') } describe('cli', () => { const cli = async (args: string) => { const { stdout } = await exec(`${svgr} ${args}`) return stdout } it('should work with a simple file', async () => { const result = await cli('__fixtures__/simple/file.svg') expect(result).toMatchSnapshot() }) it('should not work with a directory without --out-dir option', async () => { expect.assertions(1) try { await cli('__fixtures__/nesting') } catch (error: any) { expect(error.message).toMatch( 'Directory are not supported without `--out-dir` option instead', ) } }) it('should not work with several files without destination', async () => { expect.assertions(1) try { await cli('__fixtures__/simple/file.svg __fixtures__/nesting/one.svg') } catch (error: any) { expect(error.message).toMatch( 'Please specify only one filename or use `--out-dir` option', ) } }) it('should work with stdin', async () => { const result = await cli('< __fixtures__/simple/file.svg') expect(result).toMatchSnapshot() }) it('should support stdin filepath', async () => { const result = await cli( '--stdin-filepath __fixtures__/simple/file.svg < __fixtures__/simple/file.svg', ) expect(result).toMatchSnapshot() }) it('should transform a whole directory and output relative destination paths', async () => { const result = await cli('--out-dir __fixtures_build__/whole __fixtures__') expect(sortCliResult(result)).toMatchSnapshot() }) it('should transform a whole directory with --typescript', async () => { const result = await cli( '--typescript --out-dir __fixtures_build__/whole __fixtures__', ) expect(sortCliResult(result)).toMatchSnapshot() }) it('should suppress output when transforming a directory with a --silent option', async () => { const result = await cli( '--silent --out-dir __fixtures_build__/whole __fixtures__', ) expect(sortCliResult(result)).toMatchSnapshot() }) it('should support --prettier-config as json', async () => { const result = await cli( `--prettier-config '{"tabWidth": 5}' __fixtures__/simple/file.svg`, ) expect(result).toMatchSnapshot() }) it('should support --prettier-config as file', async () => { const result = await cli( `--prettier-config __fixtures__/withPrettierRc/.prettierrc __fixtures__/simple/file.svg`, ) expect(result).toMatchSnapshot() }) it('should support --svgo-config as json', async () => { const result = await cli( `--svgo-config '{"plugins":[{"name":"preset-default","params":{"overrides":{"removeTitle":false}}}]}' __fixtures__/simple/file.svg`, ) expect(result).toMatchSnapshot() }) it('should support --svgo-config as file', async () => { const result = await cli( `--svgo-config __fixtures__/withSvgoConfig/svgo.config.js __fixtures__/simple/file.svg`, ) expect(result).toMatchSnapshot() }) it('should support --svgo-config as file with .cjs extension', async () => { const result = await cli( `--svgo-config __fixtures__/withSvgoConfig/svgo.config.cjs __fixtures__/simple/file.svg`, ) expect(result).toMatchSnapshot() }) it.each([ ['--no-dimensions'], ['--jsx-runtime classic-preact'], ['--jsx-runtime automatic'], ['--expand-props none'], ['--expand-props start'], ['--icon'], ['--icon 24'], ['--icon 2em'], ['--native'], ['--native --icon'], ['--native --expand-props none'], ['--native --ref'], ['--ref'], ['--replace-attr-values "#063855=currentColor"'], [`--svg-props "hidden={true},id=hello"`], ['--no-svgo'], ['--no-prettier'], ['--title-prop'], ['--desc-prop'], ['--typescript'], ['--typescript --ref'], ['--typescript --ref --title-prop'], ['--typescript --ref --desc-prop'], ])( 'should support various args', async (args) => { const result = await cli(`${args} -- __fixtures__/simple/file.svg`) expect(result).toMatchSnapshot(args) }, 10000, ) it.each([ [0, ''], [1, '--filename-case=camel'], [2, '--filename-case=pascal'], [3, '--filename-case=kebab'], [4, '--filename-case=snake'], ])( 'should support different filename cases with directory output', async (index, args) => { const inDir = '__fixtures__/cased' const outDir = `__fixtures_build__/filename-case-${index}` await del(outDir) await cli(`${args} ${inDir} --out-dir=${outDir}`) expect(await fs.readdir(outDir)).toMatchSnapshot(args) }, 10000, ) it('should support custom file extension', async () => { const inDir = '__fixtures__/simple' const outDir = '__fixtures_build__/ext' await del(outDir) await cli(`--ext=ts ${inDir} --out-dir=${outDir}`) expect(await fs.readdir(outDir)).toMatchSnapshot() }) it('should support "--ignore-existing"', async () => { const inDir = '__fixtures__/simple' const outDir = '__fixtures__/simple-existing' await cli(`${inDir} --out-dir=${outDir} --ignore-existing`) const content = await fs.readFile(path.join(outDir, 'File.js'), 'utf-8') expect(content).toBe('// nothing') }) it('should not override config with cli defaults', async () => { const result = await cli( '__fixtures__/simple/file.svg --config-file=__fixtures__/overrides.config.js', ) expect(result).toMatchSnapshot() }) it('should add Svg prefix to index.js exports staring with number', async () => { const inDir = '__fixtures__/numeric' const outDir = `__fixtures_build__/prefix-exports` await del(outDir) await cli(`${inDir} --out-dir=${outDir}`) const content = await fs.readFile(path.join(outDir, 'index.js'), 'utf-8') expect(content).toMatchSnapshot() }) it('should support custom index.js with directory output', async () => { const inDir = '__fixtures__/simple' const outDir = `__fixtures_build__/custom-index` await del(outDir) await cli( `${inDir} --out-dir=${outDir} --config-file=__fixtures__/custom-index.config.js`, ) const content = await fs.readFile(path.join(outDir, 'index.js'), 'utf-8') expect(content).toMatchSnapshot() }) it('using typescript option, it creates index with `.ts` extension', async () => { const inDir = '__fixtures__/simple' const outDir = `__fixtures_build__/ts-index` await del(outDir) await cli(`${inDir} --out-dir=${outDir} --typescript`) const content = await fs.readFile(path.join(outDir, 'index.ts'), 'utf-8') expect(content).toMatchSnapshot() }) it('should support --index-template in cli', async () => { const inDir = '__fixtures__/simple' const outDir = `__fixtures_build__/custom-index-arg` await del(outDir) await cli( `${inDir} --out-dir=${outDir} --index-template=__fixtures__/custom-index-template.js`, ) const content = await fs.readFile(path.join(outDir, 'index.js'), 'utf-8') expect(content).toMatchSnapshot() }) it('should support --no-index', async () => { const inDir = '__fixtures__/simple' const outDir = `__fixtures_build__/no-index-case` await del(outDir) await cli(`--no-index ${inDir} --out-dir=${outDir}`) expect(await fs.readdir(outDir)).toMatchSnapshot() }) }) ================================================ FILE: packages/cli/src/index.ts ================================================ /* eslint-disable no-console */ import { program, Command } from 'commander' import * as path from 'path' import { glob } from 'glob' import { readFileSync, promises as fsPromises } from 'fs' import { loadConfig, Config } from '@svgr/core' import { fileCommand } from './fileCommand' import { dirCommand } from './dirCommand' import { exitError } from './util' import type { IndexTemplate } from './dirCommand' import { version } from '../package.json' const noUndefinedKeys = >(obj: T): T => { return Object.entries(obj).reduce((obj, [key, value]) => { if (value !== undefined) { // @ts-ignore obj[key] = value } return obj }, {} as T) } const parseObject = (arg: string, accumulation = {}) => { const [name, value] = arg.split('=') return { ...accumulation, [name]: value } } const parseObjectList = (arg: string, accumulation = {}) => { const args = arg.split(',').map((str) => str.trim()) return args.reduce((acc, arg) => parseObject(arg, acc), accumulation) } const parseConfig = (name: string) => (arg: string) => { try { if (arg.endsWith('rc')) { const content = readFileSync(arg, 'utf-8') return JSON.parse(content) } const ext = path.extname(arg) if (ext === '.js' || ext === '.json' || ext === '.cjs') { return require(path.join(process.cwd(), arg)) } return JSON.parse(arg) } catch (error) { exitError( `"${name}" is not valid, please specify a valid file or use a inline JSON.`, ) } } const parseExpandProps = (arg: string) => (arg === 'none' ? false : arg) const parseTemplate = (name: string) => (arg: string) => { try { // eslint-disable-next-line @typescript-eslint/no-var-requires const template = require(path.join(process.cwd(), arg)) const resolved = template.default || template if (typeof resolved !== 'function') { throw new Error(`${name} file must export a function`) } return resolved } catch (error: any) { console.error(`Error when loading "${name}": ${arg}\n`) console.error(error.stack) process.exit(2) } } const parseIconSize = (arg: string) => { const num = Number(arg) return Number.isNaN(num) ? arg : num } export interface Options extends Config { configFile?: string runtimeConfig?: boolean outDir?: string ignoreExisting?: boolean ext?: string filenameCase?: string silent?: boolean stdin?: boolean stdinFilepath?: string indexTemplate?: IndexTemplate } export interface SvgrCommand { (opts: Options, program: Command, filenames: string[]): Promise } program .version(version) .usage('[options] ') .option('--config-file ', 'specify the path of the svgr config') .option( '--no-runtime-config', 'disable runtime config (".svgrrc", ".svgo.yml", ".prettierrc")', ) .option('-d, --out-dir ', 'output files into a directory') .option('--ignore-existing', 'ignore existing files when used with --out-dir') .option('--ext ', 'specify a custom file extension (default: "js")') .option( '--filename-case ', 'specify filename case ("pascal", "kebab", "camel", "snake") (default: "pascal")', ) .option( '--icon [size]', 'specify width and height (default to "1em" or 24dp (native))', parseIconSize, ) .option( '--jsx-runtime ', 'specify JSX runtime ("automatic", "classic", "classic-preact") (default: "classic")', ) .option('--typescript', 'transform svg into typescript') .option('--native', 'add react-native support with react-native-svg') .option('--memo', 'add React.memo into the result component') .option('--ref', 'forward ref to SVG root element') .option('--no-dimensions', 'remove width and height from root SVG tag') .option( '--expand-props [position]', 'disable props expanding ("start", "end", "none") (default: "end")', parseExpandProps, ) .option( '--svg-props ', 'add props to the svg element', parseObjectList, ) .option( '--replace-attr-values ', 'replace an attribute value', parseObjectList, ) .option( '--template ', 'specify a custom template to use', parseTemplate('--template'), ) .option( '--index-template ', 'specify a custom index.js template to use', parseTemplate('--index-template'), ) .option('--no-index', 'disable index file generation') .option('--title-prop', 'create a title element linked with props') .option('--desc-prop', 'create a desc element linked with props') .option( '--prettier-config ', 'Prettier config', parseConfig('--prettier-config'), ) .option('--no-prettier', 'disable Prettier') .option( '--svgo-config ', 'SVGO config', parseConfig('--svgo-config'), ) .option('--no-svgo', 'disable SVGO') .option('--silent', 'suppress output') .option('--stdin', 'force reading input from stdin') .option( '--stdin-filepath', 'path to the file to pretend that stdin comes from', ) program.on('--help', () => { console.log(` Examples: svgr --replace-attr-values "#fff=currentColor" icon.svg `) }) program.parse(process.argv) async function run() { const errors: string[] = [] const filenames = program.args.reduce((globbed, input) => { let files = glob.sync(input) if (!files.length) files = [input] return [...globbed, ...files] }, [] as string[]) await Promise.all( filenames.map(async (filename) => { try { await fsPromises.stat(filename) } catch (error) { errors.push(`${filename} does not exist`) } }), ) if (errors.length) { console.error(errors.join('. ')) process.exit(2) } const programOpts = noUndefinedKeys(program.opts()) if (programOpts.dimensions) delete programOpts.dimensions if (programOpts.svgo) delete programOpts.svgo if (programOpts.prettier) delete programOpts.prettier const opts = (await loadConfig(programOpts, { filePath: process.cwd(), })) as Options const command = opts.outDir ? dirCommand : fileCommand await command(opts, program, filenames) } run().catch((error) => { setTimeout(() => { throw error }) }) ================================================ FILE: packages/cli/src/util.test.ts ================================================ import * as path from 'path' import { convertFile, transformFilename, formatExportName } from './util' const FIXTURES = path.join(__dirname, '../../../__fixtures__') describe('util', () => { describe('#convertFile', () => { it('should convert a file', async () => { const file = path.join(FIXTURES, 'simple/file.svg') const result = await convertFile(file) expect(result).toMatchSnapshot() }) it('should support a custom config path', async () => { const file = path.join(FIXTURES, 'simple/file.svg') const result = await convertFile(file, { configFile: '__fixtures__/withSvgrRc/.svgrrc', }) expect(result).toMatchSnapshot() }) }) describe('#transformFilename', () => { it('should transform filename', () => { expect(transformFilename('FooBar', 'camel')).toBe('fooBar') expect(transformFilename('FooBar', 'kebab')).toBe('foo-bar') expect(transformFilename('FooBar', 'pascal')).toBe('FooBar') expect(transformFilename('FooBar', 'snake')).toBe('foo_bar') expect(transformFilename('foo_bar', 'camel')).toBe('fooBar') expect(transformFilename('foo_bar', 'kebab')).toBe('foo-bar') expect(transformFilename('foo_bar', 'pascal')).toBe('FooBar') expect(transformFilename('foo_bar', 'snake')).toBe('foo_bar') }) }) describe('#formatExportName', () => { it('should ensure a valid export name', () => { expect(formatExportName('foo')).toBe('Foo') expect(formatExportName('foo-bar')).toBe('FooBar') expect(formatExportName('2foo')).toBe('Svg2foo') expect(formatExportName('2foo-bar')).toBe('Svg2FooBar') }) }) }) ================================================ FILE: packages/cli/src/util.ts ================================================ /* eslint-disable no-console */ import { promises as fs } from 'fs' import { red } from 'chalk' import { transform, Config, State } from '@svgr/core' import svgo from '@svgr/plugin-svgo' import jsx from '@svgr/plugin-jsx' import prettier from '@svgr/plugin-prettier' // @ts-ignore import camelCase from 'camelcase' // @ts-ignore import dashify from 'dashify' import { snakeCase } from 'snake-case' export function transformFilename( filename: string, filenameCase: string, ): string { switch (filenameCase) { case 'kebab': return dashify(filename.replace(/_/g, '-'), { condense: true }) case 'camel': return camelCase(filename) case 'pascal': return camelCase(filename, { pascalCase: true }) case 'snake': return snakeCase(filename) default: throw new Error(`Unknown --filename-case ${filenameCase}`) } } export const convert = ( code: string, config: Config, state: Partial, ): string => { return transform.sync(code, config, { ...state, caller: { name: '@svgr/cli', defaultPlugins: [svgo, jsx, prettier], }, }) } export const convertFile = async ( filePath: string, config: Config = {}, ): Promise => { const code = await fs.readFile(filePath, 'utf-8') return convert(code, config, { filePath }) } export const exitError = (error: string): never => { console.error(red(error)) process.exit(1) } export const politeWrite = (data: string, silent?: boolean): void => { if (!silent) { process.stdout.write(data) } } export const formatExportName = (name: string): string => { if (/[-]/g.test(name) && /^\d/.test(name)) { return `Svg${camelCase(name, { pascalCase: true })}` } if (/^\d/.test(name)) { return `Svg${name}` } return camelCase(name, { pascalCase: true }) } ================================================ FILE: packages/cli/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/core/.npmignore ================================================ /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/core/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.1.0](https://github.com/gregberge/svgr/compare/v8.0.1...v8.1.0) (2023-08-15) ### Bug Fixes * **config:** prefer cli config over rc config ([#845](https://github.com/gregberge/svgr/issues/845)) ([8b97248](https://github.com/gregberge/svgr/commit/8b972484266c45c7f8e4acce4fe2930a024fb4bc)) # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) ### Features * add snake_case filename option ([#857](https://github.com/gregberge/svgr/issues/857)) ([428b0c7](https://github.com/gregberge/svgr/commit/428b0c7f4c5205bb67ae3e9e7c7e819ec3fc03ba)) # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) ### Features * allow specifying `jsxRuntimeImport` in config ([86bb86f](https://github.com/gregberge/svgr/commit/86bb86f47748618f729742e56199355d9c0bc518)), closes [#801](https://github.com/gregberge/svgr/issues/801) [#801](https://github.com/gregberge/svgr/issues/801) * remove @svgr/plugin-jsx from core ([a0f078d](https://github.com/gregberge/svgr/commit/a0f078db13936800a32c14ade08b670a14b5a886)) * upgrade to svgo v3 ([#798](https://github.com/gregberge/svgr/issues/798)) ([21b6209](https://github.com/gregberge/svgr/commit/21b6209ef34c51cc0313901f31061afe587ab29b)) ### BREAKING CHANGES * plugin-jsx is no longer included by default in core * svgr now requires Node.js v14+ ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) ### Reverts - Revert "feat(a11y): add attribute role="img" to the svg element (#750)" ([1382232](https://github.com/gregberge/svgr/commit/138223284ad9aebc5bbf94ed3ae7174a66dbc7f5)), closes [#750](https://github.com/gregberge/svgr/issues/750) # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) ### Bug Fixes - fix Yarn peer dependency warning from @babel/core ([#786](https://github.com/gregberge/svgr/issues/786)) ([db35837](https://github.com/gregberge/svgr/commit/db3583751474997dd72a0209ca61daddbac16c46)), closes [#785](https://github.com/gregberge/svgr/issues/785) # [6.4.0](https://github.com/gregberge/svgr/compare/v6.3.1...v6.4.0) (2022-10-01) ### Bug Fixes - **deps:** add babel-preset to core dependencies ([#782](https://github.com/gregberge/svgr/issues/782)) ([464ec5f](https://github.com/gregberge/svgr/commit/464ec5fe81c6ba98be5a26923f3ad19fc2ef7fc6)) ### Features - **a11y:** add attribute role="img" to the svg element ([#750](https://github.com/gregberge/svgr/issues/750)) ([8b9edc4](https://github.com/gregberge/svgr/commit/8b9edc4e712f3adbd9f9c503dfc5e4d627f763cd)) - support spaces in file names ([#779](https://github.com/gregberge/svgr/issues/779)) ([6ee639a](https://github.com/gregberge/svgr/commit/6ee639a039a0001d3b97fef024f2bd0c3e107182)) ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **core:** types field in package.json ([#693](https://github.com/gregberge/svgr/issues/693)) ([a491ace](https://github.com/gregberge/svgr/commit/a491acee1b3fbe1cae304dbc399193cdb2148e1d)) - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ### Features - add descProp option ([#729](https://github.com/gregberge/svgr/issues/729)) ([a0637d4](https://github.com/gregberge/svgr/commit/a0637d49b60243bbae461f7b96dab9b47cd82d8f)) ## [6.2.1](https://github.com/gregberge/svgr/compare/v6.2.0...v6.2.1) (2022-01-30) **Note:** Version bump only for package @svgr/core # [6.2.0](https://github.com/gregberge/svgr/compare/v6.1.2...v6.2.0) (2022-01-10) **Note:** Version bump only for package @svgr/core ## [6.1.2](https://github.com/gregberge/svgr/compare/v6.1.1...v6.1.2) (2021-12-12) **Note:** Version bump only for package @svgr/core ## [6.1.1](https://github.com/gregberge/svgr/compare/v6.1.0...v6.1.1) (2021-12-04) ### Bug Fixes - **webpack:** fix double export ([#648](https://github.com/gregberge/svgr/issues/648)) ([7595d37](https://github.com/gregberge/svgr/commit/7595d378b73d4826a4cead165b3f32386b07315b)), closes [#645](https://github.com/gregberge/svgr/issues/645) # [6.1.0](https://github.com/gregberge/svgr/compare/v6.0.0...v6.1.0) (2021-12-01) **Note:** Version bump only for package @svgr/core # [5.5.0](https://github.com/gregberge/svgr/tree/master/packages/core/compare/v5.4.0...v5.5.0) (2020-11-15) ### Bug Fixes - **typescript:** fix react-native support [#465](https://github.com/gregberge/svgr/tree/master/packages/core/issues/465) ([#488](https://github.com/gregberge/svgr/tree/master/packages/core/issues/488)) ([d61e0cf](https://github.com/gregberge/svgr/tree/master/packages/core/commit/d61e0cface065afc1478fdb44d87ca8177041eab)) - prevent removing the namespace by svgr ([[#475](https://github.com/gregberge/svgr/tree/master/packages/core/issues/475)](https://github.com/gregberge/svgr/issues/475) ([#498](https://github.com/gregberge/svgr/tree/master/packages/core/issues/498)) ([00e84ea](https://github.com/gregberge/svgr/tree/master/packages/core/commit/00e84ead96d89bcbd072b9585b4db1365e392d33)) ### Features - allow custom name for named export ([#493](https://github.com/gregberge/svgr/tree/master/packages/core/issues/493)) ([16a58d6](https://github.com/gregberge/svgr/tree/master/packages/core/commit/16a58d6e817c065f72a68be91600a1a360205f44)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/core/compare/v5.3.1...v5.4.0) (2020-04-27) ### Bug Fixes - wrap svg component directly with memo/forwardRef ([#440](https://github.com/gregberge/svgr/tree/master/packages/core/issues/440)) ([#441](https://github.com/gregberge/svgr/tree/master/packages/core/issues/441)) ([a6de2da](https://github.com/gregberge/svgr/tree/master/packages/core/commit/a6de2dacb63e36572a2167b928418bdc39f3a9c2)) ### Features - **cli:** make all CLI options available in config ([a23a186](https://github.com/gregberge/svgr/tree/master/packages/core/commit/a23a18675c0dd4a461d2fcbdc72a305cabd32a13)), closes [#431](https://github.com/gregberge/svgr/tree/master/packages/core/issues/431) [#437](https://github.com/gregberge/svgr/tree/master/packages/core/issues/437) ## [5.3.1](https://github.com/gregberge/svgr/tree/master/packages/core/compare/v5.3.0...v5.3.1) (2020-04-05) **Note:** Version bump only for package @svgr/core # [5.3.0](https://github.com/gregberge/svgr/tree/master/packages/core/compare/v5.2.0...v5.3.0) (2020-03-22) ### Features - add typescript option ([4596d7b](https://github.com/gregberge/svgr/tree/master/packages/core/commit/4596d7bb470babb5ec4b87f5281174fb182bd9c7)), closes [#373](https://github.com/gregberge/svgr/tree/master/packages/core/issues/373) # [5.2.0](https://github.com/gregberge/svgr/tree/master/packages/core/compare/v5.1.0...v5.2.0) (2020-02-23) **Note:** Version bump only for package @svgr/core ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/core/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/core/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) ## [4.3.3](https://github.com/gregberge/svgr/tree/master/packages/core/compare/v4.3.2...v4.3.3) (2019-09-24) ### Bug Fixes - **babel-plugin-svg-dynamic-title:** dont render empty title ([#341](https://github.com/gregberge/svgr/tree/master/packages/core/issues/341)) ([88b24c5](https://github.com/gregberge/svgr/tree/master/packages/core/commit/88b24c5)), closes [#333](https://github.com/gregberge/svgr/tree/master/packages/core/issues/333) - invalid characters in component name ([#332](https://github.com/gregberge/svgr/tree/master/packages/core/issues/332)) ([4b4bd2c](https://github.com/gregberge/svgr/tree/master/packages/core/commit/4b4bd2c)), closes [#331](https://github.com/gregberge/svgr/tree/master/packages/core/issues/331) ## [4.3.2](https://github.com/gregberge/svgr/tree/master/packages/core/compare/v4.3.1...v4.3.2) (2019-07-15) **Note:** Version bump only for package @svgr/core ## [4.3.1](https://github.com/gregberge/svgr/tree/master/packages/core/compare/v4.3.0...v4.3.1) (2019-07-01) **Note:** Version bump only for package @svgr/core # [4.3.0](https://github.com/gregberge/svgr/tree/master/packages/core/compare/v4.2.0...v4.3.0) (2019-05-28) **Note:** Version bump only for package @svgr/core # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/core/compare/v4.1.0...v4.2.0) (2019-04-11) ### Bug Fixes - keep viewBox when dimensions are removed ([#281](https://github.com/gregberge/svgr/tree/master/packages/core/issues/281)) ([f476c8e](https://github.com/gregberge/svgr/tree/master/packages/core/commit/f476c8e)) ### Features - add expo option ([#289](https://github.com/gregberge/svgr/tree/master/packages/core/issues/289)) ([978db3e](https://github.com/gregberge/svgr/tree/master/packages/core/commit/978db3e)) # [4.1.0](https://github.com/gregberge/svgr/compare/v4.0.4...v4.1.0) (2018-11-24) **Note:** Version bump only for package @svgr/core ## [4.0.3](https://github.com/gregberge/svgr/compare/v4.0.2...v4.0.3) (2018-11-13) ### Bug Fixes - upgrade dependencies ([7e2195f](https://github.com/gregberge/svgr/commit/7e2195f)) ## [4.0.2](https://github.com/gregberge/svgr/compare/v4.0.1...v4.0.2) (2018-11-08) **Note:** Version bump only for package @svgr/core ## [4.0.1](https://github.com/gregberge/svgr/compare/v4.0.0...v4.0.1) (2018-11-08) **Note:** Version bump only for package @svgr/core # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **svgo:** prefix ids by default ([06c338d](https://github.com/gregberge/svgr/commit/06c338d)), closes [#210](https://github.com/gregberge/svgr/issues/210) - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) - allow dynamic properties in replaceAttrValues option ([15f55fe](https://github.com/gregberge/svgr/commit/15f55fe)), closes [#205](https://github.com/gregberge/svgr/issues/205) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default # [3.1.0](https://github.com/gregberge/svgr/compare/v3.0.0...v3.1.0) (2018-10-05) ### Bug Fixes - style & custom SVG properties ([#203](https://github.com/gregberge/svgr/issues/203)) ([f8b2212](https://github.com/gregberge/svgr/commit/f8b2212)), closes [#199](https://github.com/gregberge/svgr/issues/199) [#201](https://github.com/gregberge/svgr/issues/201) ### Features - allow Mask & Image on React Native ([#202](https://github.com/gregberge/svgr/issues/202)) ([0256bc0](https://github.com/gregberge/svgr/commit/0256bc0)) # [3.0.0](https://github.com/gregberge/svgr/compare/v2.4.1...v3.0.0) (2018-10-01) ### Bug Fixes - fix --icon + --no-dimensions ([7535693](https://github.com/gregberge/svgr/commit/7535693)), closes [#141](https://github.com/gregberge/svgr/issues/141) - fix expandProps when position is not allowed ([45522fc](https://github.com/gregberge/svgr/commit/45522fc)) ### Features - **config:** improve runtime config ([e52cdce](https://github.com/gregberge/svgr/commit/e52cdce)), closes [#192](https://github.com/gregberge/svgr/issues/192) - **template:** expose `getProps` util for template ([5cb238e](https://github.com/gregberge/svgr/commit/5cb238e)), closes [#187](https://github.com/gregberge/svgr/issues/187) - add synchronous API ([169eb2f](https://github.com/gregberge/svgr/commit/169eb2f)), closes [#185](https://github.com/gregberge/svgr/issues/185) - always prefix component name with "Svg" ([f71aa7a](https://github.com/gregberge/svgr/commit/f71aa7a)), closes [#190](https://github.com/gregberge/svgr/issues/190) - do not remove style tag ([a4ce09a](https://github.com/gregberge/svgr/commit/a4ce09a)), closes [#191](https://github.com/gregberge/svgr/issues/191) - new "expandProps" option ([bb95828](https://github.com/gregberge/svgr/commit/bb95828)), closes [#170](https://github.com/gregberge/svgr/issues/170) - remove "svgAttributes" option ([4e46a5d](https://github.com/gregberge/svgr/commit/4e46a5d)), closes [#173](https://github.com/gregberge/svgr/issues/173) - use forwardRef on React Native ([4bdd989](https://github.com/gregberge/svgr/commit/4bdd989)), closes [#184](https://github.com/gregberge/svgr/issues/184) - use React.forwardRef ([cbee51c](https://github.com/gregberge/svgr/commit/cbee51c)), closes [#184](https://github.com/gregberge/svgr/issues/184) ### BREAKING CHANGES - "--no-expand-props" is now replaced by "--expand-props none". You can now specify a position "start" or "end" for "expandProps" property. - `svgAttributes` has been removed, please use `svgProps` instead. - "ref" option now uses `React.forwardRef`. You don't have to use "svgRef" prop, just use "ref" and it will work. `React.forwardRef` requires React > 16.3. - Style tag will no longer be automatically removed. SVGO should handle it correctly using "inlineStyles" plugin. If you want to remove them, enable "removeStyleElement" plugin in your SVGO config. - **config:** - Runtime configuration is always loaded (even with Node API `convert`) * In CLI, "--config" is now "--config-file"; this new option can be used everywhere ## [2.4.1](https://github.com/gregberge/svgr/compare/v2.4.0...v2.4.1) (2018-09-16) ### Bug Fixes - **config:** fix custom config & default options ([#176](https://github.com/gregberge/svgr/issues/176)) ([9a6c40b](https://github.com/gregberge/svgr/commit/9a6c40b)) # [2.4.0](https://github.com/gregberge/svgr/compare/v2.3.0...v2.4.0) (2018-09-16) ### Bug Fixes - use literal instead of litteral ([7849fd4](https://github.com/gregberge/svgr/commit/7849fd4)) ### Features - allow to spread props at the start ([#166](https://github.com/gregberge/svgr/issues/166)) ([cd659dc](https://github.com/gregberge/svgr/commit/cd659dc)) - **upgrade:** h2x@1.1.0 (jsdom@12.0.0) & others ([2d9b7bd](https://github.com/gregberge/svgr/commit/2d9b7bd)) - new option "svgProps" ([#172](https://github.com/gregberge/svgr/issues/172)) ([9657110](https://github.com/gregberge/svgr/commit/9657110)) # [2.2.0](https://github.com/gregberge/svgr/compare/v2.1.1...v2.2.0) (2018-08-13) ### Bug Fixes - remove null-byte characters ([#154](https://github.com/gregberge/svgr/issues/154)) ([de7f8a7](https://github.com/gregberge/svgr/commit/de7f8a7)), closes [#153](https://github.com/gregberge/svgr/issues/153) ### Features - **core:** pass info to SVGO ([2b2353b](https://github.com/gregberge/svgr/commit/2b2353b)), closes [#152](https://github.com/gregberge/svgr/issues/152) ## [2.1.1](https://github.com/gregberge/svgr/compare/v2.1.0...v2.1.1) (2018-07-11) ### Bug Fixes - **core:** config conflict with icon option ([#137](https://github.com/gregberge/svgr/issues/137)) ([e13a99a](https://github.com/gregberge/svgr/commit/e13a99a)) # [2.1.0](https://github.com/gregberge/svgr/compare/v2.0.0...v2.1.0) (2018-07-08) ### Features - add .editorconfig support ([#129](https://github.com/gregberge/svgr/issues/129)) ([968fd82](https://github.com/gregberge/svgr/commit/968fd82)) - **cli:** support custom filename cases ([#136](https://github.com/gregberge/svgr/issues/136)) ([4922f7a](https://github.com/gregberge/svgr/commit/4922f7a)), closes [#118](https://github.com/gregberge/svgr/issues/118) ================================================ FILE: packages/core/README.md ================================================ # @svgr/core [![Build Status][build-badge]][build] [![version][version-badge]][package] [![MIT License][license-badge]][license] Node API of SVGR. ``` npm install @svgr/core ``` ## Usage ```js import { transform } from '@svgr/core' const svgCode = ` ` transform(svgCode, { icon: true }, { componentName: 'MyComponent' }).then( (jsCode) => { console.log(jsCode) }, ) ``` Use `svgr.sync(code, config, state)` if you would like to use sync version. ### Plugins By default `@svgr/core` doesn't include any plugin, if you want them, you have to install them and include them in config. ```js svgr(svgCode, { plugins: ['@svgr/plugin-svgo', '@svgr/plugin-jsx', '@svgr/plugin-prettier'], }).then((jsCode) => { console.log(jsCode) }) ``` ## License MIT [build-badge]: https://img.shields.io/travis/smooth-code/svgr.svg?style=flat-square [build]: https://travis-ci.org/smooth-code/svgr [version-badge]: https://img.shields.io/npm/v/@svgr/core.svg?style=flat-square [package]: https://www.npmjs.com/package/@svgr/core [license-badge]: https://img.shields.io/npm/l/@svgr/core.svg?style=flat-square [license]: https://github.com/smooth-code/svgr/blob/master/LICENSE ================================================ FILE: packages/core/package.json ================================================ { "name": "@svgr/core", "description": "Transform SVG into React Components.", "version": "8.1.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/core", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "svgr", "svg", "react", "core", "api" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "npm run reset && npm run build" }, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "workspace:*", "camelcase": "^6.2.0", "cosmiconfig": "^8.3.6", "snake-case": "^3.0.4" }, "devDependencies": { "svgo": "^3.0.2" } } ================================================ FILE: packages/core/src/__fixtures__/svgo/svgo.config.js ================================================ module.exports = { plugins: [ { name: 'preset-default', params: { overrides: { removeDesc: false, }, }, }, ] } ================================================ FILE: packages/core/src/__fixtures__/svgr/.svgrrc ================================================ { noSemi: true, icon: true, replaceAttrValues: [["#063855", "currentColor"]] } ================================================ FILE: packages/core/src/__snapshots__/config.test.ts.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`svgo async #loadConfig [async] should load config using filePath 1`] = ` { "descProp": false, "dimensions": true, "expandProps": "end", "exportType": "default", "icon": true, "index": false, "memo": false, "namedExport": "ReactComponent", "native": false, "noSemi": true, "prettier": true, "prettierConfig": undefined, "ref": false, "replaceAttrValues": [ [ "#063855", "currentColor", ], ], "runtimeConfig": true, "svgProps": undefined, "svgo": true, "svgoConfig": undefined, "template": undefined, "titleProp": false, "typescript": false, } `; exports[`svgo async #loadConfig [async] should not load config with "runtimeConfig: false 1`] = ` { "descProp": false, "dimensions": true, "expandProps": "end", "exportType": "default", "icon": true, "index": false, "memo": false, "namedExport": "ReactComponent", "native": false, "noSemi": true, "prettier": true, "prettierConfig": undefined, "ref": false, "replaceAttrValues": [ [ "#063855", "currentColor", ], ], "runtimeConfig": true, "svgProps": undefined, "svgo": true, "svgoConfig": undefined, "template": undefined, "titleProp": false, "typescript": false, "useRuntimeConfig": false, } `; exports[`svgo async #loadConfig [async] should use default config without state.filePath 1`] = ` { "descProp": false, "dimensions": false, "expandProps": "end", "exportType": "default", "icon": false, "index": false, "memo": false, "namedExport": "ReactComponent", "native": false, "prettier": true, "prettierConfig": undefined, "ref": false, "replaceAttrValues": undefined, "runtimeConfig": true, "svgProps": undefined, "svgo": true, "svgoConfig": undefined, "template": undefined, "titleProp": false, "typescript": false, } `; exports[`svgo async #loadConfig [async] should work with custom config path 1`] = ` { "descProp": false, "dimensions": true, "expandProps": "end", "exportType": "default", "icon": true, "index": false, "memo": false, "namedExport": "ReactComponent", "native": false, "noSemi": true, "prettier": true, "prettierConfig": undefined, "ref": false, "replaceAttrValues": [ [ "#063855", "currentColor", ], ], "runtimeConfig": true, "svgProps": undefined, "svgo": true, "svgoConfig": undefined, "template": undefined, "titleProp": false, "typescript": false, } `; exports[`svgo sync #loadConfig [sync] should load config using filePath 1`] = ` { "descProp": false, "dimensions": true, "expandProps": "end", "exportType": "default", "icon": true, "index": false, "memo": false, "namedExport": "ReactComponent", "native": false, "noSemi": true, "prettier": true, "prettierConfig": undefined, "ref": false, "replaceAttrValues": [ [ "#063855", "currentColor", ], ], "runtimeConfig": true, "svgProps": undefined, "svgo": true, "svgoConfig": undefined, "template": undefined, "titleProp": false, "typescript": false, } `; exports[`svgo sync #loadConfig [sync] should not load config with "runtimeConfig: false 1`] = ` { "descProp": false, "dimensions": true, "expandProps": "end", "exportType": "default", "icon": true, "index": false, "memo": false, "namedExport": "ReactComponent", "native": false, "noSemi": true, "prettier": true, "prettierConfig": undefined, "ref": false, "replaceAttrValues": [ [ "#063855", "currentColor", ], ], "runtimeConfig": true, "svgProps": undefined, "svgo": true, "svgoConfig": undefined, "template": undefined, "titleProp": false, "typescript": false, "useRuntimeConfig": false, } `; exports[`svgo sync #loadConfig [sync] should use default config without state.filePath 1`] = ` { "descProp": false, "dimensions": false, "expandProps": "end", "exportType": "default", "icon": false, "index": false, "memo": false, "namedExport": "ReactComponent", "native": false, "prettier": true, "prettierConfig": undefined, "ref": false, "replaceAttrValues": undefined, "runtimeConfig": true, "svgProps": undefined, "svgo": true, "svgoConfig": undefined, "template": undefined, "titleProp": false, "typescript": false, } `; exports[`svgo sync #loadConfig [sync] should work with custom config path 1`] = ` { "descProp": false, "dimensions": true, "expandProps": "end", "exportType": "default", "icon": true, "index": false, "memo": false, "namedExport": "ReactComponent", "native": false, "noSemi": true, "prettier": true, "prettierConfig": undefined, "ref": false, "replaceAttrValues": [ [ "#063855", "currentColor", ], ], "runtimeConfig": true, "svgProps": undefined, "svgo": true, "svgoConfig": undefined, "template": undefined, "titleProp": false, "typescript": false, } `; ================================================ FILE: packages/core/src/__snapshots__/transform.test.ts.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`convert config accepts options {"descProp":true} 1`] = ` "import * as React from 'react' const SvgComponent = ({ desc, descId, ...props }) => ( {desc ? {desc} : null} ) export default SvgComponent " `; exports[`convert config accepts options {"dimensions":false} 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert config accepts options {"expandProps":"start"} 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert config accepts options {"expandProps":false} 1`] = ` "import * as React from 'react' const SvgComponent = () => ( ) export default SvgComponent " `; exports[`convert config accepts options {"exportType":"named"} 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export { SvgComponent as ReactComponent } " `; exports[`convert config accepts options {"icon":"2em"} 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert config accepts options {"icon":24} 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert config accepts options {"icon":true} 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert config accepts options {"memo":true} 1`] = ` "import * as React from 'react' import { memo } from 'react' const SvgComponent = (props) => ( ) const Memo = memo(SvgComponent) export default Memo " `; exports[`convert config accepts options {"namedExport":"Component","state":{"caller":{"previousExport":"export default \\"logo.svg\\";"}}} 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export { SvgComponent as Component } export default 'logo.svg' " `; exports[`convert config accepts options {"native":true,"expandProps":false} 1`] = ` "import * as React from 'react' import Svg, { G, Path } from 'react-native-svg' const SvgComponent = () => ( ) export default SvgComponent " `; exports[`convert config accepts options {"native":true,"icon":true} 1`] = ` "import * as React from 'react' import Svg, { G, Path } from 'react-native-svg' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert config accepts options {"native":true,"ref":true} 1`] = ` "import * as React from 'react' import Svg, { G, Path } from 'react-native-svg' import { forwardRef } from 'react' const SvgComponent = (props, ref) => ( ) const ForwardRef = forwardRef(SvgComponent) export default ForwardRef " `; exports[`convert config accepts options {"native":true} 1`] = ` "import * as React from 'react' import Svg, { G, Path } from 'react-native-svg' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert config accepts options {"prettier":false} 1`] = ` "import * as React from "react"; const SvgComponent = props => ; export default SvgComponent;" `; exports[`convert config accepts options {"ref":true} 1`] = ` "import * as React from 'react' import { forwardRef } from 'react' const SvgComponent = (props, ref) => ( ) const ForwardRef = forwardRef(SvgComponent) export default ForwardRef " `; exports[`convert config accepts options {"replaceAttrValues":{"none":"{black}"}} 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert config accepts options {"replaceAttrValues":{"none":"black"}} 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert config accepts options {"svgProps":{"a":"b","b":"{props.b}"}} 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert config accepts options {"svgo":false} 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( {'Dismiss'} {'Created with Sketch.'} ) export default SvgComponent " `; exports[`convert config accepts options {"titleProp":true} 1`] = ` "import * as React from 'react' const SvgComponent = ({ title, titleId, ...props }) => ( {title ? {title} : null} ) export default SvgComponent " `; exports[`convert config accepts options {} 1`] = ` "const noop = () => null export default noop " `; exports[`convert config descProp: without desc added 1`] = ` "import * as React from 'react' const SvgComponent = ({ desc, descId, ...props }) => ( {desc ? {desc} : null} ) export default SvgComponent " `; exports[`convert config titleProp: without title added 1`] = ` "import * as React from 'react' const SvgComponent = ({ title, titleId, ...props }) => ( {title ? {title} : null} ) export default SvgComponent " `; exports[`convert should convert 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert should convert style attribute 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert should handle special SVG attributes 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert should not remove all style tags 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert should remove null characters 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; exports[`convert should remove style tags 1`] = ` "import * as React from 'react' const SvgComponent = (props) => ( ) export default SvgComponent " `; ================================================ FILE: packages/core/src/config.test.ts ================================================ import * as path from 'path' import { resolveConfig, resolveConfigFile, loadConfig } from './config' const getMethod = (method: any, mode: string) => mode === 'sync' ? method.sync : method describe('svgo', () => { describe.each([['sync'], ['async']])('%s', (mode) => { describe(`#resolveConfig [${mode}]`, () => { it('should return null if no config found', async () => { const config = await getMethod(resolveConfig, mode)('/tmp') expect(config).toBe(null) }) it('should return config if found', async () => { const config = await getMethod( resolveConfig, mode, )(path.join(__dirname, '__fixtures__/svgr')) expect(config).toEqual({ icon: true, noSemi: true, replaceAttrValues: [['#063855', 'currentColor']], }) }) }) describe(`#resolveConfigFile [${mode}]`, () => { it('should return null if no config found', async () => { const config = await getMethod(resolveConfigFile, mode)('/tmp') expect(config).toBe(null) }) it('should return config path if found', async () => { const config = await getMethod( resolveConfigFile, mode, )(path.join(__dirname, '__fixtures__/svgr')) expect(config).toMatch(/__fixtures__(\/|\\)svgr(\/|\\)\.svgrrc$/) }) }) describe(`#loadConfig [${mode}]`, () => { it('should use default config without state.filePath', async () => { const config = await getMethod(loadConfig, mode)({ dimensions: false }) expect(config).toMatchSnapshot() }) it('should load config using filePath', async () => { const config = await getMethod(loadConfig, mode)( {}, { filePath: path.join(__dirname, '__fixtures__/svgr/icon.svg') }, ) expect(config).toMatchSnapshot() }) it('should not load config with "runtimeConfig: false', async () => { const config = await getMethod(loadConfig, mode)( { useRuntimeConfig: false }, { filePath: path.join(__dirname, '__fixtures__/svgr/icon.svg') }, ) expect(config).toMatchSnapshot() }) it('should work with custom config path', async () => { const config = await getMethod(loadConfig, mode)( { configFile: path.join(__dirname, '__fixtures__/svgr/.svgrrc') }, { filePath: __dirname }, ) expect(config).toMatchSnapshot() }) }) }) }) ================================================ FILE: packages/core/src/config.ts ================================================ import { cosmiconfig, cosmiconfigSync } from 'cosmiconfig' import type { Options as PrettierOptions } from 'prettier' import type { Config as SvgoConfig } from 'svgo' import type { Options as TransformOptions } from '@svgr/babel-preset' import type { TransformOptions as BabelTransformOptions } from '@babel/core' import type { ConfigPlugin } from './plugins' import type { State } from './state' export interface Config { ref?: boolean titleProp?: boolean descProp?: boolean expandProps?: boolean | 'start' | 'end' dimensions?: boolean icon?: boolean | string | number native?: boolean svgProps?: { [key: string]: string } replaceAttrValues?: { [key: string]: string } runtimeConfig?: boolean typescript?: boolean prettier?: boolean prettierConfig?: PrettierOptions svgo?: boolean svgoConfig?: SvgoConfig configFile?: string template?: TransformOptions['template'] memo?: boolean exportType?: 'named' | 'default' namedExport?: string jsxRuntime?: 'classic' | 'classic-preact' | 'automatic' jsxRuntimeImport?: { source: string namespace?: string specifiers?: string[] defaultSpecifier?: string } // CLI only index?: boolean plugins?: ConfigPlugin[] // JSX jsx?: { babelConfig?: BabelTransformOptions } } export const DEFAULT_CONFIG: Config = { dimensions: true, expandProps: 'end', icon: false, native: false, typescript: false, prettier: true, prettierConfig: undefined, memo: false, ref: false, replaceAttrValues: undefined, svgProps: undefined, svgo: true, svgoConfig: undefined, template: undefined, index: false, titleProp: false, descProp: false, runtimeConfig: true, namedExport: 'ReactComponent', exportType: 'default', } const explorer = cosmiconfig('svgr') const explorerSync = cosmiconfigSync('svgr') export const resolveConfig = async ( searchFrom?: string, configFile?: string, ): Promise => { if (configFile == null) { const result = await explorer.search(searchFrom) return result ? result.config : null } const result = await explorer.load(configFile) return result ? result.config : null } resolveConfig.sync = ( searchFrom?: string, configFile?: string, ): Config | null => { if (configFile == null) { const result = explorerSync.search(searchFrom) return result ? result.config : null } const result = explorerSync.load(configFile) return result ? result.config : null } export const resolveConfigFile = async ( filePath: string, ): Promise => { const result = await explorer.search(filePath) return result ? result.filepath : null } resolveConfigFile.sync = (filePath: string): string | null => { const result = explorerSync.search(filePath) return result ? result.filepath : null } export const loadConfig = async ( { configFile, ...baseConfig }: Config, state: Pick = {}, ): Promise => { const rcConfig = state.filePath && baseConfig.runtimeConfig !== false ? await resolveConfig(state.filePath, configFile) : {} return { ...DEFAULT_CONFIG, ...baseConfig, ...rcConfig } } loadConfig.sync = ( { configFile, ...baseConfig }: Config, state: Pick = {}, ): Config => { const rcConfig = state.filePath && baseConfig.runtimeConfig !== false ? resolveConfig.sync(state.filePath, configFile) : {} return { ...DEFAULT_CONFIG, ...baseConfig, ...rcConfig } } ================================================ FILE: packages/core/src/index.ts ================================================ export { transform } from './transform' export * from './config' export type { State } from './state' export type { Plugin, ConfigPlugin } from './plugins' ================================================ FILE: packages/core/src/plugins.test.ts ================================================ import jsx from '@svgr/plugin-jsx' import { getPlugins, resolvePlugin } from './plugins' import { State, Config } from '.' describe('#getPlugins', () => { const state: Partial = { caller: { defaultPlugins: ['from-state-plugin'] }, } const config: Config = { plugins: ['from-config'] } it('should use config if plugins are specified in', () => { expect(getPlugins(config, state)).toEqual(['from-config']) }) it('should use caller.defaultPlugins in second choice', () => { expect(getPlugins({}, state)).toEqual(['from-state-plugin']) }) it('should default to []', () => { expect(getPlugins({}, {})).toEqual([]) }) it('should support caller with "defaultPlugins" in second choice', () => { expect(getPlugins({}, { caller: {} })).toEqual([]) }) }) describe('#resolvePlugin', () => { it('should use function', () => { expect(resolvePlugin(jsx)).toBe(jsx) }) it('should throw if not found', () => { expect(() => resolvePlugin('not-found-plugin')).toThrow( 'Module "not-found-plugin" missing. Maybe `npm install not-found-plugin` could help!', ) }) it('should load plugin', () => { expect(resolvePlugin('@svgr/plugin-jsx')).toBe(jsx) }) }) ================================================ FILE: packages/core/src/plugins.ts ================================================ import { Config } from './config' import type { State } from './state' export interface Plugin { (code: string, config: Config, state: State): string } export type ConfigPlugin = string | Plugin const DEFAULT_PLUGINS: Plugin[] = [] export const getPlugins = ( config: Config, state: Partial, ): ConfigPlugin[] => { if (config.plugins) { return config.plugins } if (state.caller?.defaultPlugins) { return state.caller.defaultPlugins } return DEFAULT_PLUGINS } export const resolvePlugin = (plugin: ConfigPlugin): Plugin => { if (typeof plugin === 'function') { return plugin } if (typeof plugin === 'string') { return loadPlugin(plugin) } throw new Error(`Invalid plugin "${plugin}"`) } const pluginCache: Record = {} const resolveModule = (m: any) => (m ? m.default || m : null) export const loadPlugin = (moduleName: string): Plugin => { if (pluginCache[moduleName]) { return pluginCache[moduleName] } try { // eslint-disable-next-line const plugin = resolveModule(require(moduleName)) if (!plugin) { throw new Error(`Invalid plugin "${moduleName}"`) } pluginCache[moduleName] = plugin return pluginCache[moduleName] } catch (error) { console.log(error) throw new Error( `Module "${moduleName}" missing. Maybe \`npm install ${moduleName}\` could help!`, ) } } ================================================ FILE: packages/core/src/state.test.ts ================================================ import { expandState } from './state' describe('state', () => { describe('#expandState', () => { it('should transform filePath into a component name', () => { expect(expandState({})).toEqual({ componentName: 'SvgComponent' }) expect(expandState({ filePath: 'hello.svg' })).toEqual({ filePath: 'hello.svg', componentName: 'SvgHello', }) expect(expandState({ filePath: 'hello-you.svg' })).toEqual({ filePath: 'hello-you.svg', componentName: 'SvgHelloYou', }) expect(expandState({ filePath: 'hello_you.svg' })).toEqual({ filePath: 'hello_you.svg', componentName: 'SvgHelloYou', }) expect(expandState({ filePath: '1_big_svg.svg' })).toEqual({ filePath: '1_big_svg.svg', componentName: 'Svg1BigSvg', }) expect(expandState({ filePath: 'a&b~c-d_e.svg' })).toEqual({ filePath: 'a&b~c-d_e.svg', componentName: 'SvgAbcDE', }) expect(expandState({ filePath: 'Arrow up.svg' })).toEqual({ filePath: 'Arrow up.svg', componentName: 'SvgArrowUp', }) }) }) }) ================================================ FILE: packages/core/src/state.ts ================================================ import { parse as parsePath } from 'path' // @ts-ignore import camelCase from 'camelcase' import type { ConfigPlugin } from './plugins' export interface State { filePath?: string componentName: string caller?: { name?: string previousExport?: string | null defaultPlugins?: ConfigPlugin[] } } const VALID_CHAR_REGEX = /[^a-zA-Z0-9 _-]/g const getComponentName = (filePath?: string): string => { if (!filePath) return 'SvgComponent' const pascalCaseFileName = camelCase( parsePath(filePath).name.replace(VALID_CHAR_REGEX, ''), { pascalCase: true, }, ) return `Svg${pascalCaseFileName}` } export const expandState = (state: Partial): State => { return { componentName: state.componentName || getComponentName(state.filePath), ...state, } } ================================================ FILE: packages/core/src/transform.test.ts ================================================ import { transform, Config, State } from '.' function convertWithAllPlugins( code: string, config?: Config, state?: Partial, ) { return transform( code, { plugins: [ '@svgr/plugin-svgo', '@svgr/plugin-jsx', '@svgr/plugin-prettier', ], ...config, }, state, ) } function convertSyncWithAllPlugins( code: string, config?: Config, state?: Partial, ) { return transform.sync( code, { plugins: [ '@svgr/plugin-svgo', '@svgr/plugin-jsx', '@svgr/plugin-prettier', ], ...config, }, state, ) } const svgBaseCode = ` Dismiss Created with Sketch. ` describe('convert', () => { it('should convert', async () => { const result = await convertWithAllPlugins(svgBaseCode) expect(result).toMatchSnapshot() }) it('should work synchronously', async () => { const syncResult = convertSyncWithAllPlugins(svgBaseCode) const asyncResult = await convertWithAllPlugins(svgBaseCode) expect(syncResult).toEqual(asyncResult) }) it('should remove style tags', async () => { const result = await convertWithAllPlugins( ` Dismiss Created with Sketch. `, ) expect(result).toMatchSnapshot() }) it('should not remove all style tags', async () => { const result = await convertWithAllPlugins( ` Dismiss Created with Sketch. `, ) expect(result).toMatchSnapshot() }) it('should handle special SVG attributes', async () => { const result = await convertWithAllPlugins( ` `, ) expect(result).toMatchSnapshot() }) it('should convert style attribute', async () => { const result = await convertWithAllPlugins( ` image/svg+xml `, ) expect(result).toMatchSnapshot() }) it('should remove null characters', async () => { const result = await convertWithAllPlugins( ` \0`, ) expect(result).toMatchSnapshot() expect(result).not.toContain('\0') }) describe('config', () => { const configs: (Config & { state?: Partial })[] = [ { dimensions: false }, { expandProps: false }, { expandProps: 'start' }, { icon: true }, { icon: 24 }, { icon: '2em' }, { native: true }, { native: true, icon: true }, { native: true, expandProps: false }, { native: true, ref: true }, { ref: true }, { svgProps: { a: 'b', b: '{props.b}' } }, { replaceAttrValues: { none: 'black' } }, { replaceAttrValues: { none: '{black}' } }, { svgo: false }, { prettier: false }, { template: (_, { tpl }) => tpl`const noop = () => null; export default noop;`, }, { titleProp: true }, { descProp: true }, { memo: true }, { namedExport: 'Component', state: { caller: { previousExport: 'export default "logo.svg";' } }, }, { exportType: 'named' }, ] test.each(configs)('accepts options %j', async ({ state, ...config }) => { const result = await convertWithAllPlugins(svgBaseCode, config, state) expect(result).toMatchSnapshot() }) it('titleProp: without title added', async () => { const svg = ` ` expect( await convertWithAllPlugins(svg, { titleProp: true }), ).toMatchSnapshot() }) it('descProp: without desc added', async () => { const svg = ` ` expect( await convertWithAllPlugins(svg, { descProp: true }), ).toMatchSnapshot() }) }) }) ================================================ FILE: packages/core/src/transform.ts ================================================ import { expandState } from './state' import { loadConfig } from './config' import { resolvePlugin, getPlugins } from './plugins' import type { Config } from './config' import type { State } from './state' const run = (code: string, config: Config, state: Partial): string => { const expandedState = expandState(state) const plugins = getPlugins(config, state).map(resolvePlugin) let nextCode = String(code).replace('\0', '') // eslint-disable-next-line no-restricted-syntax for (const plugin of plugins) { nextCode = plugin(nextCode, config, expandedState) } return nextCode } export const transform = async ( code: string, config: Config = {}, state: Partial = {}, ): Promise => { config = await loadConfig(config, state) return run(code, config, state) } transform.sync = ( code: string, config: Config = {}, state: Partial = {}, ): string => { config = loadConfig.sync(config, state) return run(code, config, state) } ================================================ FILE: packages/core/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/hast-util-to-babel-ast/.npmignore ================================================ src/ .* /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/hast-util-to-babel-ast/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/hast-util-to-babel-ast # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/hast-util-to-babel-ast ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) **Note:** Version bump only for package @svgr/hast-util-to-babel-ast # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/hast-util-to-babel-ast # [6.4.0](https://github.com/gregberge/svgr/compare/v6.3.1...v6.4.0) (2022-10-01) **Note:** Version bump only for package @svgr/hast-util-to-babel-ast ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ## [6.2.1](https://github.com/gregberge/svgr/compare/v6.2.0...v6.2.1) (2022-01-30) ### Bug Fixes - do not transform mask-type ([#673](https://github.com/gregberge/svgr/issues/673)) ([6e58f2c](https://github.com/gregberge/svgr/commit/6e58f2cb456bf5fbfa011ab8f8154333c0724e34)), closes [#643](https://github.com/gregberge/svgr/issues/643) # [5.5.0](https://github.com/gregberge/svgr/tree/master/packages/hast-util-to-babel-ast/compare/v5.4.0...v5.5.0) (2020-11-15) **Note:** Version bump only for package @svgr/hast-util-to-babel-ast # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/hast-util-to-babel-ast/compare/v5.3.1...v5.4.0) (2020-04-27) **Note:** Version bump only for package @svgr/hast-util-to-babel-ast ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/hast-util-to-babel-ast/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/hast-util-to-babel-ast/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) ## [4.3.2](https://github.com/gregberge/svgr/tree/master/packages/hast-util-to-babel-ast/compare/v4.3.1...v4.3.2) (2019-07-15) ### Performance Improvements - replace rehype with svg-parser ([#321](https://github.com/gregberge/svgr/tree/master/packages/hast-util-to-babel-ast/issues/321)) ([7eb5ef6](https://github.com/gregberge/svgr/tree/master/packages/hast-util-to-babel-ast/commit/7eb5ef6)) ## [4.3.1](https://github.com/gregberge/svgr/tree/master/packages/hast-util-to-babel-ast/compare/v4.3.0...v4.3.1) (2019-07-01) **Note:** Version bump only for package @svgr/hast-util-to-babel-ast # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/hast-util-to-babel-ast/compare/v4.1.0...v4.2.0) (2019-04-11) ### Bug Fixes - **hast-util-to-babel-ast:** correctly handle aria attributes ([23d12aa](https://github.com/gregberge/svgr/tree/master/packages/hast-util-to-babel-ast/commit/23d12aa)), closes [#279](https://github.com/gregberge/svgr/tree/master/packages/hast-util-to-babel-ast/issues/279) # [4.1.0](https://github.com/gregberge/svgr/compare/v4.0.4...v4.1.0) (2018-11-24) **Note:** Version bump only for package @svgr/hast-util-to-babel-ast ## [4.0.3](https://github.com/gregberge/svgr/compare/v4.0.2...v4.0.3) (2018-11-13) ### Bug Fixes - upgrade dependencies ([7e2195f](https://github.com/gregberge/svgr/commit/7e2195f)) ## [4.0.2](https://github.com/gregberge/svgr/compare/v4.0.1...v4.0.2) (2018-11-08) ### Bug Fixes - **hast-util-to-babel-ast:** replace tabs by spaces in attributes ([b0f3d19](https://github.com/gregberge/svgr/commit/b0f3d19)), closes [#219](https://github.com/gregberge/svgr/issues/219) ## [4.0.1](https://github.com/gregberge/svgr/compare/v4.0.0...v4.0.1) (2018-11-08) ### Bug Fixes - **hast-util-to-babel-ast:** correctly transforms data & aria attributes ([99711c4](https://github.com/gregberge/svgr/commit/99711c4)), closes [#221](https://github.com/gregberge/svgr/issues/221) - **hast-util-to-babel-ast:** replace line-breaks in attributes ([00a2625](https://github.com/gregberge/svgr/commit/00a2625)), closes [#219](https://github.com/gregberge/svgr/issues/219) # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/hast-util-to-babel-ast/README.md ================================================ # @svgr/hast-util-to-babel-ast [![Build Status](https://img.shields.io/travis/smooth-code/svgr.svg)](https://travis-ci.org/smooth-code/svgr) [![Version](https://img.shields.io/npm/v/@svgr/hast-util-to-babel-ast.svg)](https://www.npmjs.com/package/@svgr/hast-util-to-babel-ast) [![MIT License](https://img.shields.io/npm/l/@svgr/hast-util-to-babel-ast.svg)](https://github.com/smooth-code/svgr/blob/master/LICENSE) Transforms HAST into Babel AST. ## Install ``` npm install --save-dev @svgr/hast-util-to-babel-ast ``` ## Usage ```js import { parse } from 'svg-parser' import hastToBabelAst from '@svgr/hast-util-to-babel-ast' const hastTree = parse(``) const babelTree = hastToBabelAst(hastTree) ``` ## License MIT ================================================ FILE: packages/hast-util-to-babel-ast/package.json ================================================ { "name": "@svgr/hast-util-to-babel-ast", "description": "Transform HAST to Babel AST (JSX)", "version": "8.0.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/hast-util-to-babel-ast", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "html", "hast", "babel", "hast-util", "unist-util", "unist" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "dependencies": { "@babel/types": "^7.21.3", "entities": "^4.4.0" }, "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "npm run reset && npm run build" }, "devDependencies": { "@types/svg-parser": "^2.0.3" } } ================================================ FILE: packages/hast-util-to-babel-ast/src/__snapshots__/index.test.ts.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`hast-util-to-babel-ast should handle spaces and tab 1`] = `";"`; exports[`hast-util-to-babel-ast transforms SVG 1`] = `"{"Dismiss"}{"Created with Sketch."};"`; ================================================ FILE: packages/hast-util-to-babel-ast/src/all.ts ================================================ import { one } from './one' import type * as t from '@babel/types' import type { RootNode, ElementNode } from 'svg-parser' import type { Helpers } from './helpers' /* Transform the children of `parent`. */ export const all = ( helpers: Helpers, parent: RootNode | ElementNode, ): (t.JSXElement | t.JSXExpressionContainer)[] => { const nodes = parent.children || [] const { length } = nodes const values = [] let index = -1 while (++index < length) { const node = nodes[index] if (typeof node !== 'string') { const result = one(helpers, node, parent) values.push(result) } } return values.filter(Boolean) as (t.JSXElement | t.JSXExpressionContainer)[] } ================================================ FILE: packages/hast-util-to-babel-ast/src/getAttributes.ts ================================================ import * as t from '@babel/types' import type { ElementNode } from 'svg-parser' import { isNumeric, kebabCase, replaceSpaces } from './util' import { stringToObjectStyle } from './stringToObjectStyle' import { ATTRIBUTE_MAPPING, ELEMENT_ATTRIBUTE_MAPPING } from './mappings' const convertAriaAttribute = (kebabKey: string) => { const [aria, ...parts] = kebabKey.split('-') return `${aria}-${parts.join('').toLowerCase()}` } const getKey = (key: string, node: ElementNode) => { const lowerCaseKey = key.toLowerCase() const mappedElementAttribute = // @ts-ignore ELEMENT_ATTRIBUTE_MAPPING[node.name] && // @ts-ignore ELEMENT_ATTRIBUTE_MAPPING[node.name][lowerCaseKey] // @ts-ignore const mappedAttribute = ATTRIBUTE_MAPPING[lowerCaseKey] if (mappedElementAttribute || mappedAttribute) { return t.jsxIdentifier(mappedElementAttribute || mappedAttribute) } const kebabKey = kebabCase(key) if (kebabKey.startsWith('aria-')) { return t.jsxIdentifier(convertAriaAttribute(kebabKey)) } if (kebabKey.startsWith('data-')) { return t.jsxIdentifier(kebabKey) } return t.jsxIdentifier(key) } const getValue = (key: string, value: string[] | string | number) => { // Handle className if (Array.isArray(value)) { return t.stringLiteral(replaceSpaces(value.join(' '))) } if (key === 'style') { return t.jsxExpressionContainer(stringToObjectStyle(value as string)) } if (typeof value === 'number' || isNumeric(value)) { return t.jsxExpressionContainer(t.numericLiteral(Number(value))) } return t.stringLiteral(replaceSpaces(value)) } export const getAttributes = (node: ElementNode): t.JSXAttribute[] => { if (!node.properties) return [] const keys = Object.keys(node.properties) const attributes = [] let index = -1 while (++index < keys.length) { const key = keys[index] const value = node.properties[key] const attribute = t.jsxAttribute(getKey(key, node), getValue(key, value)) attributes.push(attribute) } return attributes } ================================================ FILE: packages/hast-util-to-babel-ast/src/handlers.ts ================================================ import * as t from '@babel/types' import { decodeXML } from 'entities' import { all } from './all' import { getAttributes } from './getAttributes' import { ELEMENT_TAG_NAME_MAPPING } from './mappings' import type { RootNode, ElementNode, TextNode } from 'svg-parser' import type { Helpers } from './helpers' export const root = (h: Helpers, node: RootNode): t.Program => // @ts-ignore t.program(all(h, node)) export const comment = ( _: Helpers, node: ElementNode, parent: RootNode | ElementNode, ): t.JSXExpressionContainer | null => { if (parent.type === 'root' || !node.value) return null const expression = t.jsxEmptyExpression() t.addComment(expression, 'inner', node.value) return t.jsxExpressionContainer(expression) } const SPACE_REGEX = /^\s+$/ export const text = ( h: Helpers, node: TextNode, parent: RootNode | ElementNode, ): t.JSXExpressionContainer | null => { if (parent.type === 'root') return null if (typeof node.value === 'string' && SPACE_REGEX.test(node.value)) return null return t.jsxExpressionContainer( t.stringLiteral(decodeXML(String(node.value))), ) } export const element = ( h: Helpers, node: ElementNode, parent: RootNode | ElementNode, ): t.JSXElement | t.ExpressionStatement | null => { if (!node.tagName) return null const children = all(h, node) const selfClosing = children.length === 0 const name = ELEMENT_TAG_NAME_MAPPING[node.tagName] || node.tagName const openingElement = t.jsxOpeningElement( t.jsxIdentifier(name), getAttributes(node), selfClosing, ) const closingElement = !selfClosing ? t.jsxClosingElement(t.jsxIdentifier(name)) : null const jsxElement = t.jsxElement(openingElement, closingElement, children) if (parent.type === 'root') { return t.expressionStatement(jsxElement) } return jsxElement } ================================================ FILE: packages/hast-util-to-babel-ast/src/helpers.ts ================================================ import * as handlers from './handlers' export const helpers = { handlers } export type Helpers = typeof helpers ================================================ FILE: packages/hast-util-to-babel-ast/src/index.test.ts ================================================ import { parse } from 'svg-parser' import generate from '@babel/generator' import hastToBabelAst from './index' function transform(code: string) { const hastTree = parse(code) const babelTree = hastToBabelAst(hastTree) const { code: generatedCode } = generate(babelTree) return generatedCode } describe('hast-util-to-babel-ast', () => { it('transforms SVG', () => { const code = ` Dismiss Created with Sketch. ` expect(transform(code)).toMatchSnapshot() }) it('transforms "aria-x"', () => { const code = `` expect(transform(code)).toMatchInlineSnapshot( `";"`, ) }) it('transforms "aria-xxxXxx"', () => { const code = `` expect(transform(code)).toMatchInlineSnapshot( `";"`, ) }) it('transformss "data-x"', () => { const code = `` expect(transform(code)).toMatchInlineSnapshot( `";"`, ) }) it('preserves "mask-type"', () => { const code = `` expect(transform(code)).toBe(';') }) it('should handle spaces and tab', () => { const code = ` ` expect(transform(code)).toMatchSnapshot() }) it('string literals children of text nodes should have decoded XML entities', () => { const code = `<` expect(transform(code)).toMatchInlineSnapshot( `"{"<"};"`, ) }) it('string literals children of tspan nodes should have decoded XML entities', () => { const code = `<` expect(transform(code)).toMatchInlineSnapshot( `"{"<"};"`, ) }) it('properly converts style with variables', () => { const code = `` expect(transform(code)).toMatchInlineSnapshot(` ";" `) }) }) ================================================ FILE: packages/hast-util-to-babel-ast/src/index.ts ================================================ import type { RootNode } from 'svg-parser' import type * as t from '@babel/types' import { root } from './handlers' import { helpers } from './helpers' const toBabelAST = (tree: RootNode): t.Program => root(helpers, tree) export default toBabelAST ================================================ FILE: packages/hast-util-to-babel-ast/src/mappings.ts ================================================ // From https://raw.githubusercontent.com/facebook/react/master/packages/react-dom/src/shared/possibleStandardNames.js export const ATTRIBUTE_MAPPING = { // HTML accept: 'accept', acceptcharset: 'acceptCharset', 'accept-charset': 'acceptCharset', accesskey: 'accessKey', action: 'action', allowfullscreen: 'allowFullScreen', alt: 'alt', as: 'as', async: 'async', autocapitalize: 'autoCapitalize', autocomplete: 'autoComplete', autocorrect: 'autoCorrect', autofocus: 'autoFocus', autoplay: 'autoPlay', autosave: 'autoSave', capture: 'capture', cellpadding: 'cellPadding', cellspacing: 'cellSpacing', challenge: 'challenge', charset: 'charSet', checked: 'checked', children: 'children', cite: 'cite', class: 'className', classid: 'classID', classname: 'className', cols: 'cols', colspan: 'colSpan', content: 'content', contenteditable: 'contentEditable', contextmenu: 'contextMenu', controls: 'controls', controlslist: 'controlsList', coords: 'coords', crossorigin: 'crossOrigin', dangerouslysetinnerhtml: 'dangerouslySetInnerHTML', data: 'data', datetime: 'dateTime', default: 'default', defaultchecked: 'defaultChecked', defaultvalue: 'defaultValue', defer: 'defer', dir: 'dir', disabled: 'disabled', download: 'download', draggable: 'draggable', enctype: 'encType', for: 'htmlFor', form: 'form', formmethod: 'formMethod', formaction: 'formAction', formenctype: 'formEncType', formnovalidate: 'formNoValidate', formtarget: 'formTarget', frameborder: 'frameBorder', headers: 'headers', height: 'height', hidden: 'hidden', high: 'high', href: 'href', hreflang: 'hrefLang', htmlfor: 'htmlFor', httpequiv: 'httpEquiv', 'http-equiv': 'httpEquiv', icon: 'icon', id: 'id', innerhtml: 'innerHTML', inputmode: 'inputMode', integrity: 'integrity', is: 'is', itemid: 'itemID', itemprop: 'itemProp', itemref: 'itemRef', itemscope: 'itemScope', itemtype: 'itemType', keyparams: 'keyParams', keytype: 'keyType', kind: 'kind', label: 'label', lang: 'lang', list: 'list', loop: 'loop', low: 'low', manifest: 'manifest', marginwidth: 'marginWidth', marginheight: 'marginHeight', max: 'max', maxlength: 'maxLength', media: 'media', mediagroup: 'mediaGroup', method: 'method', min: 'min', minlength: 'minLength', multiple: 'multiple', muted: 'muted', name: 'name', nomodule: 'noModule', nonce: 'nonce', novalidate: 'noValidate', open: 'open', optimum: 'optimum', pattern: 'pattern', placeholder: 'placeholder', playsinline: 'playsInline', poster: 'poster', preload: 'preload', profile: 'profile', radiogroup: 'radioGroup', readonly: 'readOnly', referrerpolicy: 'referrerPolicy', rel: 'rel', required: 'required', reversed: 'reversed', role: 'role', rows: 'rows', rowspan: 'rowSpan', sandbox: 'sandbox', scope: 'scope', scoped: 'scoped', scrolling: 'scrolling', seamless: 'seamless', selected: 'selected', shape: 'shape', size: 'size', sizes: 'sizes', span: 'span', spellcheck: 'spellCheck', src: 'src', srcdoc: 'srcDoc', srclang: 'srcLang', srcset: 'srcSet', start: 'start', step: 'step', style: 'style', summary: 'summary', tabindex: 'tabIndex', target: 'target', title: 'title', type: 'type', usemap: 'useMap', value: 'value', width: 'width', wmode: 'wmode', wrap: 'wrap', // SVG about: 'about', accentheight: 'accentHeight', 'accent-height': 'accentHeight', accumulate: 'accumulate', additive: 'additive', alignmentbaseline: 'alignmentBaseline', 'alignment-baseline': 'alignmentBaseline', allowreorder: 'allowReorder', alphabetic: 'alphabetic', amplitude: 'amplitude', arabicform: 'arabicForm', 'arabic-form': 'arabicForm', ascent: 'ascent', attributename: 'attributeName', attributetype: 'attributeType', autoreverse: 'autoReverse', azimuth: 'azimuth', basefrequency: 'baseFrequency', baselineshift: 'baselineShift', 'baseline-shift': 'baselineShift', baseprofile: 'baseProfile', bbox: 'bbox', begin: 'begin', bias: 'bias', by: 'by', calcmode: 'calcMode', capheight: 'capHeight', 'cap-height': 'capHeight', clip: 'clip', clippath: 'clipPath', 'clip-path': 'clipPath', clippathunits: 'clipPathUnits', cliprule: 'clipRule', 'clip-rule': 'clipRule', color: 'color', colorinterpolation: 'colorInterpolation', 'color-interpolation': 'colorInterpolation', colorinterpolationfilters: 'colorInterpolationFilters', 'color-interpolation-filters': 'colorInterpolationFilters', colorprofile: 'colorProfile', 'color-profile': 'colorProfile', colorrendering: 'colorRendering', 'color-rendering': 'colorRendering', contentscripttype: 'contentScriptType', contentstyletype: 'contentStyleType', cursor: 'cursor', cx: 'cx', cy: 'cy', d: 'd', datatype: 'datatype', decelerate: 'decelerate', descent: 'descent', diffuseconstant: 'diffuseConstant', direction: 'direction', display: 'display', divisor: 'divisor', dominantbaseline: 'dominantBaseline', 'dominant-baseline': 'dominantBaseline', dur: 'dur', dx: 'dx', dy: 'dy', edgemode: 'edgeMode', elevation: 'elevation', enablebackground: 'enableBackground', 'enable-background': 'enableBackground', end: 'end', exponent: 'exponent', externalresourcesrequired: 'externalResourcesRequired', fill: 'fill', fillopacity: 'fillOpacity', 'fill-opacity': 'fillOpacity', fillrule: 'fillRule', 'fill-rule': 'fillRule', filter: 'filter', filterres: 'filterRes', filterunits: 'filterUnits', floodopacity: 'floodOpacity', 'flood-opacity': 'floodOpacity', floodcolor: 'floodColor', 'flood-color': 'floodColor', focusable: 'focusable', fontfamily: 'fontFamily', 'font-family': 'fontFamily', fontsize: 'fontSize', 'font-size': 'fontSize', fontsizeadjust: 'fontSizeAdjust', 'font-size-adjust': 'fontSizeAdjust', fontstretch: 'fontStretch', 'font-stretch': 'fontStretch', fontstyle: 'fontStyle', 'font-style': 'fontStyle', fontvariant: 'fontVariant', 'font-variant': 'fontVariant', fontweight: 'fontWeight', 'font-weight': 'fontWeight', format: 'format', from: 'from', fx: 'fx', fy: 'fy', g1: 'g1', g2: 'g2', glyphname: 'glyphName', 'glyph-name': 'glyphName', glyphorientationhorizontal: 'glyphOrientationHorizontal', 'glyph-orientation-horizontal': 'glyphOrientationHorizontal', glyphorientationvertical: 'glyphOrientationVertical', 'glyph-orientation-vertical': 'glyphOrientationVertical', glyphref: 'glyphRef', gradienttransform: 'gradientTransform', gradientunits: 'gradientUnits', hanging: 'hanging', horizadvx: 'horizAdvX', 'horiz-adv-x': 'horizAdvX', horizoriginx: 'horizOriginX', 'horiz-origin-x': 'horizOriginX', ideographic: 'ideographic', imagerendering: 'imageRendering', 'image-rendering': 'imageRendering', in2: 'in2', in: 'in', inlist: 'inlist', intercept: 'intercept', k1: 'k1', k2: 'k2', k3: 'k3', k4: 'k4', k: 'k', kernelmatrix: 'kernelMatrix', kernelunitlength: 'kernelUnitLength', kerning: 'kerning', keypoints: 'keyPoints', keysplines: 'keySplines', keytimes: 'keyTimes', lengthadjust: 'lengthAdjust', letterspacing: 'letterSpacing', 'letter-spacing': 'letterSpacing', lightingcolor: 'lightingColor', 'lighting-color': 'lightingColor', limitingconeangle: 'limitingConeAngle', local: 'local', markerend: 'markerEnd', 'marker-end': 'markerEnd', markerheight: 'markerHeight', markermid: 'markerMid', 'marker-mid': 'markerMid', markerstart: 'markerStart', 'marker-start': 'markerStart', markerunits: 'markerUnits', markerwidth: 'markerWidth', mask: 'mask', maskcontentunits: 'maskContentUnits', maskunits: 'maskUnits', mathematical: 'mathematical', mode: 'mode', numoctaves: 'numOctaves', offset: 'offset', opacity: 'opacity', operator: 'operator', order: 'order', orient: 'orient', orientation: 'orientation', origin: 'origin', overflow: 'overflow', overlineposition: 'overlinePosition', 'overline-position': 'overlinePosition', overlinethickness: 'overlineThickness', 'overline-thickness': 'overlineThickness', paintorder: 'paintOrder', 'paint-order': 'paintOrder', panose1: 'panose1', 'panose-1': 'panose1', pathlength: 'pathLength', patterncontentunits: 'patternContentUnits', patterntransform: 'patternTransform', patternunits: 'patternUnits', pointerevents: 'pointerEvents', 'pointer-events': 'pointerEvents', points: 'points', pointsatx: 'pointsAtX', pointsaty: 'pointsAtY', pointsatz: 'pointsAtZ', prefix: 'prefix', preservealpha: 'preserveAlpha', preserveaspectratio: 'preserveAspectRatio', primitiveunits: 'primitiveUnits', property: 'property', r: 'r', radius: 'radius', refx: 'refX', refy: 'refY', renderingintent: 'renderingIntent', 'rendering-intent': 'renderingIntent', repeatcount: 'repeatCount', repeatdur: 'repeatDur', requiredextensions: 'requiredExtensions', requiredfeatures: 'requiredFeatures', resource: 'resource', restart: 'restart', result: 'result', results: 'results', rotate: 'rotate', rx: 'rx', ry: 'ry', scale: 'scale', security: 'security', seed: 'seed', shaperendering: 'shapeRendering', 'shape-rendering': 'shapeRendering', slope: 'slope', spacing: 'spacing', specularconstant: 'specularConstant', specularexponent: 'specularExponent', speed: 'speed', spreadmethod: 'spreadMethod', startoffset: 'startOffset', stddeviation: 'stdDeviation', stemh: 'stemh', stemv: 'stemv', stitchtiles: 'stitchTiles', stopcolor: 'stopColor', 'stop-color': 'stopColor', stopopacity: 'stopOpacity', 'stop-opacity': 'stopOpacity', strikethroughposition: 'strikethroughPosition', 'strikethrough-position': 'strikethroughPosition', strikethroughthickness: 'strikethroughThickness', 'strikethrough-thickness': 'strikethroughThickness', string: 'string', stroke: 'stroke', strokedasharray: 'strokeDasharray', 'stroke-dasharray': 'strokeDasharray', strokedashoffset: 'strokeDashoffset', 'stroke-dashoffset': 'strokeDashoffset', strokelinecap: 'strokeLinecap', 'stroke-linecap': 'strokeLinecap', strokelinejoin: 'strokeLinejoin', 'stroke-linejoin': 'strokeLinejoin', strokemiterlimit: 'strokeMiterlimit', 'stroke-miterlimit': 'strokeMiterlimit', strokewidth: 'strokeWidth', 'stroke-width': 'strokeWidth', strokeopacity: 'strokeOpacity', 'stroke-opacity': 'strokeOpacity', suppresscontenteditablewarning: 'suppressContentEditableWarning', suppresshydrationwarning: 'suppressHydrationWarning', surfacescale: 'surfaceScale', systemlanguage: 'systemLanguage', tablevalues: 'tableValues', targetx: 'targetX', targety: 'targetY', textanchor: 'textAnchor', 'text-anchor': 'textAnchor', textdecoration: 'textDecoration', 'text-decoration': 'textDecoration', textlength: 'textLength', textrendering: 'textRendering', 'text-rendering': 'textRendering', to: 'to', transform: 'transform', typeof: 'typeof', u1: 'u1', u2: 'u2', underlineposition: 'underlinePosition', 'underline-position': 'underlinePosition', underlinethickness: 'underlineThickness', 'underline-thickness': 'underlineThickness', unicode: 'unicode', unicodebidi: 'unicodeBidi', 'unicode-bidi': 'unicodeBidi', unicoderange: 'unicodeRange', 'unicode-range': 'unicodeRange', unitsperem: 'unitsPerEm', 'units-per-em': 'unitsPerEm', unselectable: 'unselectable', valphabetic: 'vAlphabetic', 'v-alphabetic': 'vAlphabetic', values: 'values', vectoreffect: 'vectorEffect', 'vector-effect': 'vectorEffect', version: 'version', vertadvy: 'vertAdvY', 'vert-adv-y': 'vertAdvY', vertoriginx: 'vertOriginX', 'vert-origin-x': 'vertOriginX', vertoriginy: 'vertOriginY', 'vert-origin-y': 'vertOriginY', vhanging: 'vHanging', 'v-hanging': 'vHanging', videographic: 'vIdeographic', 'v-ideographic': 'vIdeographic', viewbox: 'viewBox', viewtarget: 'viewTarget', visibility: 'visibility', vmathematical: 'vMathematical', 'v-mathematical': 'vMathematical', vocab: 'vocab', widths: 'widths', wordspacing: 'wordSpacing', 'word-spacing': 'wordSpacing', writingmode: 'writingMode', 'writing-mode': 'writingMode', x1: 'x1', x2: 'x2', x: 'x', xchannelselector: 'xChannelSelector', xheight: 'xHeight', 'x-height': 'xHeight', xlinkactuate: 'xlinkActuate', 'xlink:actuate': 'xlinkActuate', xlinkarcrole: 'xlinkArcrole', 'xlink:arcrole': 'xlinkArcrole', xlinkhref: 'xlinkHref', 'xlink:href': 'xlinkHref', xlinkrole: 'xlinkRole', 'xlink:role': 'xlinkRole', xlinkshow: 'xlinkShow', 'xlink:show': 'xlinkShow', xlinktitle: 'xlinkTitle', 'xlink:title': 'xlinkTitle', xlinktype: 'xlinkType', 'xlink:type': 'xlinkType', xmlbase: 'xmlBase', 'xml:base': 'xmlBase', xmllang: 'xmlLang', 'xml:lang': 'xmlLang', xmlns: 'xmlns', 'xml:space': 'xmlSpace', xmlnsxlink: 'xmlnsXlink', 'xmlns:xlink': 'xmlnsXlink', xmlspace: 'xmlSpace', y1: 'y1', y2: 'y2', y: 'y', ychannelselector: 'yChannelSelector', z: 'z', zoomandpan: 'zoomAndPan', } export const ELEMENT_ATTRIBUTE_MAPPING = { input: { checked: 'defaultChecked', value: 'defaultValue', maxlength: 'maxLength', }, form: { enctype: 'encType', }, } // Reference: https://developer.mozilla.org/en-US/docs/Web/SVG/Element#SVG_elements export const ELEMENT_TAG_NAME_MAPPING: Record = { a: 'a', altglyph: 'altGlyph', altglyphdef: 'altGlyphDef', altglyphitem: 'altGlyphItem', animate: 'animate', animatecolor: 'animateColor', animatemotion: 'animateMotion', animatetransform: 'animateTransform', audio: 'audio', canvas: 'canvas', circle: 'circle', clippath: 'clipPath', 'color-profile': 'colorProfile', cursor: 'cursor', defs: 'defs', desc: 'desc', discard: 'discard', ellipse: 'ellipse', feblend: 'feBlend', fecolormatrix: 'feColorMatrix', fecomponenttransfer: 'feComponentTransfer', fecomposite: 'feComposite', feconvolvematrix: 'feConvolveMatrix', fediffuselighting: 'feDiffuseLighting', fedisplacementmap: 'feDisplacementMap', fedistantlight: 'feDistantLight', fedropshadow: 'feDropShadow', feflood: 'feFlood', fefunca: 'feFuncA', fefuncb: 'feFuncB', fefuncg: 'feFuncG', fefuncr: 'feFuncR', fegaussianblur: 'feGaussianBlur', feimage: 'feImage', femerge: 'feMerge', femergenode: 'feMergeNode', femorphology: 'feMorphology', feoffset: 'feOffset', fepointlight: 'fePointLight', fespecularlighting: 'feSpecularLighting', fespotlight: 'feSpotLight', fetile: 'feTile', feturbulence: 'feTurbulence', filter: 'filter', font: 'font', 'font-face': 'fontFace', 'font-face-format': 'fontFaceFormat', 'font-face-name': 'fontFaceName', 'font-face-src': 'fontFaceSrc', 'font-face-uri': 'fontFaceUri', foreignobject: 'foreignObject', g: 'g', glyph: 'glyph', glyphref: 'glyphRef', hatch: 'hatch', hatchpath: 'hatchpath', hkern: 'hkern', iframe: 'iframe', image: 'image', line: 'line', lineargradient: 'linearGradient', marker: 'marker', mask: 'mask', mesh: 'mesh', meshgradient: 'meshgradient', meshpatch: 'meshpatch', meshrow: 'meshrow', metadata: 'metadata', 'missing-glyph': 'missingGlyph', mpath: 'mpath', path: 'path', pattern: 'pattern', polygon: 'polygon', polyline: 'polyline', radialgradient: 'radialGradient', rect: 'rect', script: 'script', set: 'set', solidcolor: 'solidcolor', stop: 'stop', style: 'style', svg: 'svg', switch: 'switch', symbol: 'symbol', text: 'text', textpath: 'textPath', title: 'title', tref: 'tref', tspan: 'tspan', unknown: 'unknown', use: 'use', video: 'video', view: 'view', vkern: 'vkern', } ================================================ FILE: packages/hast-util-to-babel-ast/src/one.ts ================================================ import type { Node, RootNode, ElementNode } from 'svg-parser' import type { Helpers } from './helpers' import type * as t from '@babel/types' export const one = ( h: Helpers, node: Node, parent?: RootNode | ElementNode, ): t.JSXElement | t.ExpressionStatement | t.JSXExpressionContainer | null => { const type = node && node.type const fn = h.handlers[type] /* Fail on non-nodes. */ if (!type) { throw new Error(`Expected node, got \`${node}\``) } if (!fn) { throw new Error(`Node of type ${type} is unknown`) } // @ts-ignore return fn(h, node, parent) } ================================================ FILE: packages/hast-util-to-babel-ast/src/stringToObjectStyle.ts ================================================ // Inspired by https://github.com/reactjs/react-magic/blob/master/src/htmltojsx.js import * as t from '@babel/types' import { hyphenToCamelCase, isNumeric, trimEnd } from './util' const PX_REGEX = /^\d+px$/ const MS_REGEX = /^-ms-/ const VAR_REGEX = /^--/ /** * Determines if the CSS value can be converted from a * 'px' suffixed string to a numeric value. */ const isConvertiblePixelValue = (value: string) => { return PX_REGEX.test(value) } /** * Format style key into JSX style object key. */ const formatKey = (key: string) => { if (VAR_REGEX.test(key)) { return t.stringLiteral(key) } key = key.toLowerCase() // Don't capitalize -ms- prefix if (MS_REGEX.test(key)) key = key.substr(1) return t.identifier(hyphenToCamelCase(key)) } /** * Format style value into JSX style object value. */ const formatValue = (value: string) => { if (isNumeric(value)) return t.numericLiteral(Number(value)) if (isConvertiblePixelValue(value)) return t.numericLiteral(Number(trimEnd(value, 'px'))) return t.stringLiteral(value) } /** * Handle parsing of inline styles. */ export const stringToObjectStyle = (rawStyle: string): t.ObjectExpression => { const entries = rawStyle.split(';') const properties = [] let index = -1 while (++index < entries.length) { const entry = entries[index] const style = entry.trim() const firstColon = style.indexOf(':') const value = style.substr(firstColon + 1).trim() const key = style.substr(0, firstColon) if (key !== '') { const property = t.objectProperty(formatKey(key), formatValue(value)) properties.push(property) } } return t.objectExpression(properties) } ================================================ FILE: packages/hast-util-to-babel-ast/src/util.ts ================================================ /** * Determines if the specified string consists entirely of numeric characters. */ export const isNumeric = (value: number | string): boolean => { // @ts-ignore return !Number.isNaN(value - parseFloat(value)) } /** * Convert a hyphenated string to camelCase. */ export const hyphenToCamelCase = (string: string): string => { return string.replace(/-(.)/g, (_, chr) => chr.toUpperCase()) } /** * Trim the specified substring off the string. If the string does not end * with the specified substring, this is a no-op. * * @param {string} haystack String to search in * @param {string} needle String to search for */ export const trimEnd = (haystack: string, needle: string): string => { return haystack.endsWith(needle) ? haystack.slice(0, -needle.length) : haystack } const KEBAB_REGEX = /[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g export const kebabCase = (str: string): string => { return str.replace(KEBAB_REGEX, (match) => `-${match.toLowerCase()}`) } const SPACES_REGEXP = /[\t\r\n\u0085\u2028\u2029]+/g export const replaceSpaces = (str: string): string => { return str.replace(SPACES_REGEXP, ' ') } ================================================ FILE: packages/hast-util-to-babel-ast/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/plugin-jsx/.npmignore ================================================ /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/plugin-jsx/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.1.0](https://github.com/gregberge/svgr/compare/v8.0.1...v8.1.0) (2023-08-15) **Note:** Version bump only for package @svgr/plugin-jsx ## [8.0.1](https://github.com/gregberge/svgr/compare/v8.0.0...v8.0.1) (2023-05-09) ### Bug Fixes * fix peer dependencies ([2e05255](https://github.com/gregberge/svgr/commit/2e0525546eb21aa4bb790aa4284f4fe34f96d6b9)) # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/plugin-jsx # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) ### Features * allow specifying `jsxRuntimeImport` in config ([86bb86f](https://github.com/gregberge/svgr/commit/86bb86f47748618f729742e56199355d9c0bc518)), closes [#801](https://github.com/gregberge/svgr/issues/801) [#801](https://github.com/gregberge/svgr/issues/801) ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) ### Reverts - Revert "feat(a11y): add attribute role="img" to the svg element (#750)" ([1382232](https://github.com/gregberge/svgr/commit/138223284ad9aebc5bbf94ed3ae7174a66dbc7f5)), closes [#750](https://github.com/gregberge/svgr/issues/750) # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/plugin-jsx # [6.4.0](https://github.com/gregberge/svgr/compare/v6.3.1...v6.4.0) (2022-10-01) ### Features - **a11y:** add attribute role="img" to the svg element ([#750](https://github.com/gregberge/svgr/issues/750)) ([8b9edc4](https://github.com/gregberge/svgr/commit/8b9edc4e712f3adbd9f9c503dfc5e4d627f763cd)) ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ### Features - add descProp option ([#729](https://github.com/gregberge/svgr/issues/729)) ([a0637d4](https://github.com/gregberge/svgr/commit/a0637d49b60243bbae461f7b96dab9b47cd82d8f)) ## [6.2.1](https://github.com/gregberge/svgr/compare/v6.2.0...v6.2.1) (2022-01-30) **Note:** Version bump only for package @svgr/plugin-jsx # [6.2.0](https://github.com/gregberge/svgr/compare/v6.1.2...v6.2.0) (2022-01-10) **Note:** Version bump only for package @svgr/plugin-jsx ## [6.1.2](https://github.com/gregberge/svgr/compare/v6.1.1...v6.1.2) (2021-12-12) ### Bug Fixes - specify valid peer deps ([45a76ed](https://github.com/gregberge/svgr/commit/45a76ed5f7d433e549c8513c0fdab08eb6c7bc2c)) # [6.1.0](https://github.com/gregberge/svgr/compare/v6.0.0...v6.1.0) (2021-12-01) **Note:** Version bump only for package @svgr/plugin-jsx # [5.5.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/compare/v5.4.0...v5.5.0) (2020-11-15) ### Bug Fixes - prevent removing the namespace by svgr ([[#475](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/issues/475)](https://github.com/gregberge/svgr/issues/475) ([#498](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/issues/498)) ([00e84ea](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/commit/00e84ead96d89bcbd072b9585b4db1365e392d33)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/compare/v5.3.1...v5.4.0) (2020-04-27) **Note:** Version bump only for package @svgr/plugin-jsx ## [5.3.1](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/compare/v5.3.0...v5.3.1) (2020-04-05) **Note:** Version bump only for package @svgr/plugin-jsx # [5.3.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/compare/v5.2.0...v5.3.0) (2020-03-22) **Note:** Version bump only for package @svgr/plugin-jsx # [5.2.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/compare/v5.1.0...v5.2.0) (2020-02-23) **Note:** Version bump only for package @svgr/plugin-jsx ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) ## [4.3.3](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/compare/v4.3.2...v4.3.3) (2019-09-24) **Note:** Version bump only for package @svgr/plugin-jsx ## [4.3.2](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/compare/v4.3.1...v4.3.2) (2019-07-15) ### Performance Improvements - replace rehype with svg-parser ([#321](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/issues/321)) ([7eb5ef6](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/commit/7eb5ef6)) ## [4.3.1](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/compare/v4.3.0...v4.3.1) (2019-07-01) **Note:** Version bump only for package @svgr/plugin-jsx # [4.3.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/compare/v4.2.0...v4.3.0) (2019-05-28) **Note:** Version bump only for package @svgr/plugin-jsx # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-jsx/compare/v4.1.0...v4.2.0) (2019-04-11) **Note:** Version bump only for package @svgr/plugin-jsx # [4.1.0](https://github.com/gregberge/svgr/compare/v4.0.4...v4.1.0) (2018-11-24) **Note:** Version bump only for package @svgr/plugin-jsx ## [4.0.3](https://github.com/gregberge/svgr/compare/v4.0.2...v4.0.3) (2018-11-13) ### Bug Fixes - upgrade dependencies ([7e2195f](https://github.com/gregberge/svgr/commit/7e2195f)) ## [4.0.2](https://github.com/gregberge/svgr/compare/v4.0.1...v4.0.2) (2018-11-08) **Note:** Version bump only for package @svgr/plugin-jsx ## [4.0.1](https://github.com/gregberge/svgr/compare/v4.0.0...v4.0.1) (2018-11-08) **Note:** Version bump only for package @svgr/plugin-jsx # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **svgo:** prefix ids by default ([06c338d](https://github.com/gregberge/svgr/commit/06c338d)), closes [#210](https://github.com/gregberge/svgr/issues/210) - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/plugin-jsx/README.md ================================================ # @svgr/plugin-jsx [![Build Status](https://img.shields.io/travis/smooth-code/svgr.svg)](https://travis-ci.org/smooth-code/svgr) [![Version](https://img.shields.io/npm/v/@svgr/plugin-jsx.svg)](https://www.npmjs.com/package/@svgr/plugin-jsx) [![MIT License](https://img.shields.io/npm/l/@svgr/plugin-jsx.svg)](https://github.com/smooth-code/svgr/blob/master/LICENSE) Transforms SVG into JSX. ## Install ``` npm install --save-dev @svgr/plugin-jsx ``` ## Usage **.svgrrc** ```json { "plugins": ["@svgr/plugin-jsx"] } ``` ## How does it work? `@svgr/plugin-jsx` consists in three phases: - Parsing the SVG code using [svg-parser](https://github.com/Rich-Harris/svg-parser) - Converting the [HAST](https://github.com/syntax-tree/hast) into a [Babel AST](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md) - Applying [`@svgr/babel-preset`](../babel-preset/README.md) transformations ## Applying custom transformations You can extend the Babel config applied in this plugin using `jsx.babelConfig` config path: ```js // .svgrrc.js module.exports = { jsx: { babelConfig: { plugins: [ // For an example, this plugin will remove "id" attribute from "svg" tag [ '@svgr/babel-plugin-remove-jsx-attribute', { elements: ['svg'], attributes: ['id'], }, ], ], }, }, } ``` Several Babel plugins are available: - [`@svgr/babel-plugin-add-jsx-attribute`](../babel-plugin-add-jsx-attribute/README.md) - [`@svgr/babel-plugin-remove-jsx-attribute`](../babel-plugin-remove-jsx-attribute/README.md) - [`@svgr/babel-plugin-remove-jsx-empty-expression`](../babel-plugin-remove-jsx-empty-expression/README.md) - [`@svgr/babel-plugin-replace-jsx-attribute-value`](../babel-plugin-replace-jsx-attribute-value/README.md) - [`@svgr/babel-plugin-svg-dynamic-title`](../babel-plugin-svg-dynamic-title/README.md) - [`@svgr/babel-plugin-svg-em-dimensions`](../babel-plugin-svg-em-dimensions/README.md) - [`@svgr/babel-plugin-transform-react-native-svg`](../babel-plugin-transform-react-native-svg/README.md) - [`@svgr/babel-plugin-transform-svg-component`](../babel-plugin-transform-svg-component/README.md) If you want to create your own, reading [Babel Handbook](https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md) is a good start! ## License MIT ================================================ FILE: packages/plugin-jsx/package.json ================================================ { "name": "@svgr/plugin-jsx", "description": "Transform SVG into JSX", "version": "8.1.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/plugin-jsx", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "svgr-plugin" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" }, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "workspace:*", "@svgr/hast-util-to-babel-ast": "workspace:*", "svg-parser": "^2.0.4" }, "devDependencies": { "@svgr/core": "workspace:*", "@types/svg-parser": "^2.0.3" }, "peerDependencies": { "@svgr/core": "*" } } ================================================ FILE: packages/plugin-jsx/src/index.test.ts ================================================ import jsx from '.' const svgBaseCode = ` Dismiss Created with Sketch. ` describe('plugin', () => { it('transforms code', () => { const result = jsx(svgBaseCode, {}, { componentName: 'SvgComponent' }) expect(result).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = () => {"Dismiss"}{"Created with Sketch."}; export default SvgComponent;" `) }) it('supports "automatic" runtime', () => { const result = jsx( svgBaseCode, { jsxRuntime: 'automatic' }, { componentName: 'SvgComponent' }, ) expect(result).toMatchInlineSnapshot(` "const SvgComponent = () => {"Dismiss"}{"Created with Sketch."}; export default SvgComponent;" `) }) it('supports "preact" preset', () => { const result = jsx( svgBaseCode, { jsxRuntime: 'classic-preact' }, { componentName: 'SvgComponent' }, ) expect(result).toMatchInlineSnapshot(` "import { h } from "preact"; const SvgComponent = () => {"Dismiss"}{"Created with Sketch."}; export default SvgComponent;" `) }) it('accepts jsx config', () => { const dropTitle = () => ({ visitor: { JSXElement(path: any) { if ( path.get('openingElement.name').isJSXIdentifier({ name: 'title' }) ) { path.remove() } }, }, }) const result = jsx( svgBaseCode, { jsx: { babelConfig: { plugins: [dropTitle] } } }, { componentName: 'SvgComponent' }, ) expect(result).toMatchInlineSnapshot(` "import * as React from "react"; const SvgComponent = () => {"Created with Sketch."}; export default SvgComponent;" `) }) }) ================================================ FILE: packages/plugin-jsx/src/index.ts ================================================ import { parse } from 'svg-parser' import hastToBabelAst from '@svgr/hast-util-to-babel-ast' import { transformFromAstSync, createConfigItem } from '@babel/core' import svgrBabelPreset, { Options as SvgrPresetOptions, } from '@svgr/babel-preset' import type { Plugin, Config } from '@svgr/core' const getJsxRuntimeOptions = (config: Config): Partial => { if (config.jsxRuntimeImport) { return { importSource: config.jsxRuntimeImport.source, jsxRuntimeImport: config.jsxRuntimeImport, } } switch (config.jsxRuntime) { case null: case undefined: case 'classic': return { jsxRuntime: 'classic', importSource: 'react', jsxRuntimeImport: { namespace: 'React', source: 'react' }, } case 'classic-preact': return { jsxRuntime: 'classic', importSource: 'preact/compat', jsxRuntimeImport: { specifiers: ['h'], source: 'preact' }, } case 'automatic': return { jsxRuntime: 'automatic' } default: throw new Error(`Unsupported "jsxRuntime" "${config.jsxRuntime}"`) } } const jsxPlugin: Plugin = (code, config, state) => { const filePath = state.filePath || 'unknown' const hastTree = parse(code) const babelTree = hastToBabelAst(hastTree) const svgPresetOptions: SvgrPresetOptions = { ref: config.ref, titleProp: config.titleProp, descProp: config.descProp, expandProps: config.expandProps, dimensions: config.dimensions, icon: config.icon, native: config.native, svgProps: config.svgProps, replaceAttrValues: config.replaceAttrValues, typescript: config.typescript, template: config.template, memo: config.memo, exportType: config.exportType, namedExport: config.namedExport, ...getJsxRuntimeOptions(config), state, } const result = transformFromAstSync(babelTree, code, { caller: { name: 'svgr', }, presets: [ createConfigItem([svgrBabelPreset, svgPresetOptions], { type: 'preset', }), ], filename: filePath, babelrc: false, configFile: false, code: true, ast: false, // @ts-ignore inputSourceMap: false, ...(config.jsx && config.jsx.babelConfig), }) if (!result?.code) { throw new Error(`Unable to generate SVG file`) } return result.code } export default jsxPlugin ================================================ FILE: packages/plugin-jsx/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/plugin-prettier/.npmignore ================================================ src/ .* ================================================ FILE: packages/plugin-prettier/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.1.0](https://github.com/gregberge/svgr/compare/v8.0.1...v8.1.0) (2023-08-15) **Note:** Version bump only for package @svgr/plugin-prettier ## [8.0.1](https://github.com/gregberge/svgr/compare/v8.0.0...v8.0.1) (2023-05-09) ### Bug Fixes * fix peer dependencies ([2e05255](https://github.com/gregberge/svgr/commit/2e0525546eb21aa4bb790aa4284f4fe34f96d6b9)) # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/plugin-prettier # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) **Note:** Version bump only for package @svgr/plugin-prettier ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) **Note:** Version bump only for package @svgr/plugin-prettier # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/plugin-prettier ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ## [6.1.2](https://github.com/gregberge/svgr/compare/v6.1.1...v6.1.2) (2021-12-12) ### Bug Fixes - specify valid peer deps ([45a76ed](https://github.com/gregberge/svgr/commit/45a76ed5f7d433e549c8513c0fdab08eb6c7bc2c)) # [5.5.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/compare/v5.4.0...v5.5.0) (2020-11-15) ### Performance Improvements - replace merge-deep with smaller deepmerge ([#463](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/issues/463)) ([1f015eb](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/commit/1f015eb16fca093a08b012236dc83623f7bcce55)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/compare/v5.3.1...v5.4.0) (2020-04-27) **Note:** Version bump only for package @svgr/plugin-prettier ## [5.3.1](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/compare/v5.3.0...v5.3.1) (2020-04-05) **Note:** Version bump only for package @svgr/plugin-prettier # [5.3.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/compare/v5.2.0...v5.3.0) (2020-03-22) **Note:** Version bump only for package @svgr/plugin-prettier ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) ## [4.3.2](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/compare/v4.3.1...v4.3.2) (2019-07-15) **Note:** Version bump only for package @svgr/plugin-prettier ## [4.3.1](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/compare/v4.3.0...v4.3.1) (2019-07-01) **Note:** Version bump only for package @svgr/plugin-prettier # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/compare/v4.1.0...v4.2.0) (2019-04-11) ### Bug Fixes - **plugin-prettier:** fix prettier warning ([d01d33f](https://github.com/gregberge/svgr/tree/master/packages/plugin-prettier/commit/d01d33f)) ## [4.0.3](https://github.com/gregberge/svgr/compare/v4.0.2...v4.0.3) (2018-11-13) ### Bug Fixes - upgrade dependencies ([7e2195f](https://github.com/gregberge/svgr/commit/7e2195f)) # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/plugin-prettier/README.md ================================================ # @svgr/plugin-prettier [![Build Status](https://img.shields.io/travis/smooth-code/svgr.svg)](https://travis-ci.org/smooth-code/svgr) [![Version](https://img.shields.io/npm/v/@svgr/plugin-prettier.svg)](https://www.npmjs.com/package/@svgr/plugin-prettier) [![MIT License](https://img.shields.io/npm/l/@svgr/plugin-prettier.svg)](https://github.com/smooth-code/svgr/blob/master/LICENSE) Format SVG code using Prettier. ## Install ``` npm install --save-dev @svgr/plugin-prettier ``` ## Usage **.svgrrc** ```json { "plugins": ["@svgr/plugin-prettier"] } ``` ## License MIT ================================================ FILE: packages/plugin-prettier/package.json ================================================ { "name": "@svgr/plugin-prettier", "description": "Format code using Prettier", "version": "8.1.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/plugin-prettier", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "svgr-plugin" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" }, "peerDependencies": { "@svgr/core": "*" }, "dependencies": { "deepmerge": "^4.3.1", "prettier": "^2.8.7" }, "devDependencies": { "@svgr/core": "workspace:*" } } ================================================ FILE: packages/plugin-prettier/src/index.test.ts ================================================ /* eslint-disable @typescript-eslint/no-var-requires */ import prettier from '.' const state = { componentName: 'Foo' } describe('prettier', () => { it('should prettify code', () => { const result = prettier( `const foo =
`, { prettier: true, runtimeConfig: true, }, state, ) expect(result).toBe('const foo =
\n') }) it('should support config.prettierConfig', () => { const result = prettier( `const foo =
`, { prettier: true, runtimeConfig: true, prettierConfig: { semi: true }, }, state, ) expect(result).toBe('const foo =
;\n') }) it('should use state.filePath to detect configuration', () => { const result = prettier( `const foo =
`, { prettier: true, runtimeConfig: true }, { ...state, filePath: '/tmp' }, ) expect(result).toBe('const foo =
;\n') }) it('should resolve the prettier config with the editorconfig option', () => { jest.resetModules() jest.doMock('prettier') /* eslint-disable global-require */ const prettierPlugin = require('.').default const { resolveConfig } = require('prettier') /* eslint-enable global-require */ prettierPlugin( `const foo =
`, { prettier: true, runtimeConfig: true, }, {}, ) expect(resolveConfig.sync).toHaveBeenCalledWith(expect.any(String), { editorconfig: true, }) }) it('should not load runtime configuration with `runtimeConfig: false`', () => { jest.resetModules() jest.doMock('prettier') /* eslint-disable global-require */ const prettierPlugin = require('.').default const { resolveConfig } = require('prettier') /* eslint-enable global-require */ prettierPlugin( `const foo =
`, { prettier: true, runtimeConfig: false, }, {}, ) expect(resolveConfig.sync).not.toHaveBeenCalled() }) }) ================================================ FILE: packages/plugin-prettier/src/index.ts ================================================ import { format, resolveConfig } from 'prettier' // @ts-ignore import deepmerge from 'deepmerge' import type { Plugin } from '@svgr/core' const prettierPlugin: Plugin = (code, config, state) => { if (!config.prettier) return code const filePath = state.filePath || process.cwd() const prettierRcConfig = config.runtimeConfig ? resolveConfig.sync(filePath, { editorconfig: true }) : {} return format( code, deepmerge.all([ { parser: 'babel' }, prettierRcConfig || {}, config.prettierConfig || {}, ]), ) } export default prettierPlugin ================================================ FILE: packages/plugin-prettier/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/plugin-svgo/.npmignore ================================================ /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/plugin-svgo/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.1.0](https://github.com/gregberge/svgr/compare/v8.0.1...v8.1.0) (2023-08-15) ### Features * **esm:** add support for svgo.config.cjs ([#879](https://github.com/gregberge/svgr/issues/879)) ([ae91e2e](https://github.com/gregberge/svgr/commit/ae91e2eacbe1156480c96219b993000eb1e7b9bf)) ## [8.0.1](https://github.com/gregberge/svgr/compare/v8.0.0...v8.0.1) (2023-05-09) ### Bug Fixes * fix peer dependencies ([2e05255](https://github.com/gregberge/svgr/commit/2e0525546eb21aa4bb790aa4284f4fe34f96d6b9)) # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/plugin-svgo # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) ### Features * upgrade to svgo v3 ([#798](https://github.com/gregberge/svgr/issues/798)) ([21b6209](https://github.com/gregberge/svgr/commit/21b6209ef34c51cc0313901f31061afe587ab29b)) ### BREAKING CHANGES * svgr now requires Node.js v14+ ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) **Note:** Version bump only for package @svgr/plugin-svgo # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/plugin-svgo ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) # [6.2.0](https://github.com/gregberge/svgr/compare/v6.1.2...v6.2.0) (2022-01-10) ### Bug Fixes - **plugin-svgo:** handle potential errors from optimize ([#663](https://github.com/gregberge/svgr/issues/663)) ([7582d31](https://github.com/gregberge/svgr/commit/7582d3130e5b6eb0f962e283f956a84552f839a6)) ## [6.1.2](https://github.com/gregberge/svgr/compare/v6.1.1...v6.1.2) (2021-12-12) ### Bug Fixes - specify valid peer deps ([45a76ed](https://github.com/gregberge/svgr/commit/45a76ed5f7d433e549c8513c0fdab08eb6c7bc2c)) # [6.1.0](https://github.com/gregberge/svgr/compare/v6.0.0...v6.1.0) (2021-12-01) ### Features - **native:** automatically convert inline style in native ([138c493](https://github.com/gregberge/svgr/commit/138c493b2ae0c5c1cef488cf9ff7f94827dc2aa5)), closes [#588](https://github.com/gregberge/svgr/issues/588) # [5.5.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/compare/v5.4.0...v5.5.0) (2020-11-15) ### Features - **svgo:** add .svgorc.js config file support ([#451](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/issues/451)) ([8049b1a](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/commit/8049b1a63603672096892b6ab3d303580c2f303f)), closes [#412](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/issues/412) ### Performance Improvements - replace merge-deep with smaller deepmerge ([#463](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/issues/463)) ([1f015eb](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/commit/1f015eb16fca093a08b012236dc83623f7bcce55)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/compare/v5.3.1...v5.4.0) (2020-04-27) **Note:** Version bump only for package @svgr/plugin-svgo # [5.3.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/compare/v5.2.0...v5.3.0) (2020-03-22) ### Bug Fixes - **svgo:** support any SVGO config format ([#412](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/issues/412)) ([f2b2367](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/commit/f2b2367389fda20baba6e0a5e884e7f7fe29a3ed)), closes [#400](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/issues/400) # [5.2.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/compare/v5.1.0...v5.2.0) (2020-02-23) ### Bug Fixes - verify that `svgoConfig.plugins` is an array ([#397](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/issues/397)) ([88110b6](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/commit/88110b6eb4d93ded68ca2de05cc82654dfac977d)) # [5.1.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/compare/v5.0.1...v5.1.0) (2020-01-20) ### Bug Fixes - fix merging svgo plugins in config ([#384](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/issues/384)) ([c9d2dfc](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/commit/c9d2dfcb8d4da55eb21a13507c87d9e549a86e7e)) ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) ## [4.3.1](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/compare/v4.3.0...v4.3.1) (2019-07-01) **Note:** Version bump only for package @svgr/plugin-svgo # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/compare/v4.1.0...v4.2.0) (2019-04-11) ### Bug Fixes - keep viewBox when dimensions are removed ([#281](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/issues/281)) ([f476c8e](https://github.com/gregberge/svgr/tree/master/packages/plugin-svgo/commit/f476c8e)) ## [4.0.3](https://github.com/gregberge/svgr/compare/v4.0.2...v4.0.3) (2018-11-13) ### Bug Fixes - upgrade dependencies ([7e2195f](https://github.com/gregberge/svgr/commit/7e2195f)) # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **svgo:** prefix ids by default ([06c338d](https://github.com/gregberge/svgr/commit/06c338d)), closes [#210](https://github.com/gregberge/svgr/issues/210) - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default ================================================ FILE: packages/plugin-svgo/README.md ================================================ # @svgr/plugin-svgo [![Build Status](https://img.shields.io/travis/smooth-code/svgr.svg)](https://travis-ci.org/smooth-code/svgr) [![Version](https://img.shields.io/npm/v/@svgr/plugin-svgo.svg)](https://www.npmjs.com/package/@svgr/plugin-svgo) [![MIT License](https://img.shields.io/npm/l/@svgr/plugin-svgo.svg)](https://github.com/smooth-code/svgr/blob/master/LICENSE) Optimize SVG using SVGO. ## Install ``` npm install --save-dev @svgr/plugin-svgo ``` ## Usage **.svgrrc** ```json { "plugins": ["@svgr/plugin-svgo"] } ``` ## License MIT ================================================ FILE: packages/plugin-svgo/package.json ================================================ { "name": "@svgr/plugin-svgo", "description": "Optimize SVG", "version": "8.1.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/plugin-svgo", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "svgr-plugin" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" }, "peerDependencies": { "@svgr/core": "*" }, "dependencies": { "cosmiconfig": "^8.1.3", "deepmerge": "^4.3.1", "svgo": "^3.0.2" }, "devDependencies": { "@svgr/core": "workspace:*" } } ================================================ FILE: packages/plugin-svgo/src/__snapshots__/index.test.ts.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`svgo does not load runtime configuration with \`runtimeConfig: false\` 1`] = `""`; exports[`svgo does not remove viewBox with \`icon\` option 1`] = `""`; exports[`svgo does not remove viewBox with when \`dimensions\` is false 1`] = `""`; exports[`svgo does remove style when \`native\` is true 1`] = `""`; exports[`svgo optimizes svg 1`] = `""`; exports[`svgo supports \`config.svgoConfig\` 1`] = `"Created with Sketch."`; exports[`svgo uses \`state.filePath\` to detect configuration 1`] = `""`; ================================================ FILE: packages/plugin-svgo/src/config.test.ts ================================================ import { getSvgoConfig } from './config' const state = { componentName: 'Icon' } describe('#getSvgoConfig', () => { describe('with no specific config', () => { it('returns config with `prefixIds: true`', async () => { const config = {} expect(await getSvgoConfig(config, state)).toEqual({ plugins: [ { name: 'preset-default', params: { overrides: {} }, }, 'prefixIds', ], }) }) }) describe('with `config.icons` enabled', () => { it('returns config with `removeViewBox: false`', async () => { const config = { icon: true } expect(await getSvgoConfig(config, state)).toEqual({ plugins: [ { name: 'preset-default', params: { overrides: { removeViewBox: false } }, }, 'prefixIds', ], }) }) }) describe('with `config.dimensions` disabled', () => { it('returns config with `removeViewBox: false`', async () => { const config = { dimensions: false } expect(await getSvgoConfig(config, state)).toEqual({ plugins: [ { name: 'preset-default', params: { overrides: { removeViewBox: false } }, }, 'prefixIds', ], }) }) }) }) ================================================ FILE: packages/plugin-svgo/src/config.ts ================================================ import { cosmiconfigSync } from 'cosmiconfig' import type { Config, State } from '@svgr/core' const explorer = cosmiconfigSync('svgo', { searchPlaces: [ 'package.json', '.svgorc', '.svgorc.js', '.svgorc.json', '.svgorc.yaml', '.svgorc.yml', 'svgo.config.js', 'svgo.config.cjs', '.svgo.yml', ], transform: (result) => result && result.config, cache: true, }) const getSvgoConfigFromSvgrConfig = (config: Config): any => { const params = { overrides: {} as any } if (config.icon || config.dimensions === false) { params.overrides.removeViewBox = false } if (config.native) { params.overrides.inlineStyles = { onlyMatchedOnce: false, } } return { plugins: [ { name: 'preset-default', params, }, 'prefixIds', ], } } export const getSvgoConfig = (config: Config, state: State): any => { const cwd = state.filePath || process.cwd() if (config.svgoConfig) return config.svgoConfig if (config.runtimeConfig) { const userConfig = explorer.search(cwd) if (userConfig) return userConfig } return getSvgoConfigFromSvgrConfig(config) } ================================================ FILE: packages/plugin-svgo/src/index.test.ts ================================================ import * as path from 'path' import svgo from '.' const state = { componentName: 'SvgComponent' } const baseSvg = ` Dismiss Created with Sketch. ` describe('svgo', () => { it('optimizes svg', () => { const result = svgo(baseSvg, { svgo: true, runtimeConfig: true }, state) expect(result).toMatchSnapshot() }) it('supports `config.svgoConfig`', () => { const result = svgo( baseSvg, { svgo: true, runtimeConfig: true, svgoConfig: { plugins: [ { name: 'preset-default', params: { overrides: { removeDesc: false, }, }, }, ], }, }, state, ) expect(result).toMatchSnapshot() }) it('throws error on invalid svg input', () => { const errorSvg = ` ` expect(() => svgo( errorSvg, { svgo: true, runtimeConfig: true }, { ...state, filePath: path.join(__dirname, '../__fixtures__/svgo') }, ), ).toThrowError() }) it('uses `state.filePath` to detect configuration', () => { const result = svgo( baseSvg, { svgo: true, runtimeConfig: true }, { ...state, filePath: path.join(__dirname, '../__fixtures__/svgo') }, ) expect(result).toMatchSnapshot() }) it('does not load runtime configuration with `runtimeConfig: false`', () => { const result = svgo( baseSvg, { svgo: true, runtimeConfig: false }, { ...state, filePath: path.join(__dirname, '../__fixtures__/svgo') }, ) expect(result).toMatchSnapshot() }) it('does not remove viewBox with `icon` option', () => { const result = svgo(baseSvg, { svgo: true, icon: true }, state) expect(result).toMatchSnapshot() }) it('does not remove viewBox with when `dimensions` is false', () => { const result = svgo(baseSvg, { svgo: true, dimensions: false }, state) expect(result).toMatchSnapshot() }) it('does remove style when `native` is true', () => { const result = svgo(baseSvg, { svgo: true, native: true }, state) expect(result).toMatchSnapshot() }) }) ================================================ FILE: packages/plugin-svgo/src/index.ts ================================================ import { optimize } from 'svgo' import { getSvgoConfig } from './config' import type { Plugin } from '@svgr/core' const svgoPlugin: Plugin = (code, config, state) => { if (!config.svgo) return code const svgoConfig = getSvgoConfig(config, state) const result = optimize(code, { ...svgoConfig, path: state.filePath }) // @ts-ignore if (result.modernError) { // @ts-ignore throw result.modernError } return result.data } export default svgoPlugin ================================================ FILE: packages/plugin-svgo/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/rollup/.npmignore ================================================ /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/rollup/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.1.0](https://github.com/gregberge/svgr/compare/v8.0.1...v8.1.0) (2023-08-15) **Note:** Version bump only for package @svgr/rollup ## [8.0.1](https://github.com/gregberge/svgr/compare/v8.0.0...v8.0.1) (2023-05-09) **Note:** Version bump only for package @svgr/rollup # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/rollup # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) ### Features * upgrade to svgo v3 ([#798](https://github.com/gregberge/svgr/issues/798)) ([21b6209](https://github.com/gregberge/svgr/commit/21b6209ef34c51cc0313901f31061afe587ab29b)) ### BREAKING CHANGES * svgr now requires Node.js v14+ ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) ### Reverts - Revert "feat(a11y): add attribute role="img" to the svg element (#750)" ([1382232](https://github.com/gregberge/svgr/commit/138223284ad9aebc5bbf94ed3ae7174a66dbc7f5)), closes [#750](https://github.com/gregberge/svgr/issues/750) # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/rollup # [6.4.0](https://github.com/gregberge/svgr/compare/v6.3.1...v6.4.0) (2022-10-01) ### Features - **a11y:** add attribute role="img" to the svg element ([#750](https://github.com/gregberge/svgr/issues/750)) ([8b9edc4](https://github.com/gregberge/svgr/commit/8b9edc4e712f3adbd9f9c503dfc5e4d627f763cd)) ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ## [6.2.1](https://github.com/gregberge/svgr/compare/v6.2.0...v6.2.1) (2022-01-30) **Note:** Version bump only for package @svgr/rollup # [6.2.0](https://github.com/gregberge/svgr/compare/v6.1.2...v6.2.0) (2022-01-10) **Note:** Version bump only for package @svgr/rollup ## [6.1.2](https://github.com/gregberge/svgr/compare/v6.1.1...v6.1.2) (2021-12-12) ### Bug Fixes - **rollup:** missing dep & missing map return ([#652](https://github.com/gregberge/svgr/issues/652)) ([12627fc](https://github.com/gregberge/svgr/commit/12627fcd91a425361e1fbe825a6668ce9a8b4f3b)) ## [6.1.1](https://github.com/gregberge/svgr/compare/v6.1.0...v6.1.1) (2021-12-04) **Note:** Version bump only for package @svgr/rollup # [6.1.0](https://github.com/gregberge/svgr/compare/v6.0.0...v6.1.0) (2021-12-01) ### Bug Fixes - fix previous export system ([1872829](https://github.com/gregberge/svgr/commit/187282977af841cd5a2243a23abba72b20eec2fa)), closes [#635](https://github.com/gregberge/svgr/issues/635) # [5.5.0](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v5.4.0...v5.5.0) (2020-11-15) ### Bug Fixes - prevent removing the namespace by svgr ([[#475](https://github.com/gregberge/svgr/tree/master/packages/rollup/issues/475)](https://github.com/gregberge/svgr/issues/475) ([#498](https://github.com/gregberge/svgr/tree/master/packages/rollup/issues/498)) ([00e84ea](https://github.com/gregberge/svgr/tree/master/packages/rollup/commit/00e84ead96d89bcbd072b9585b4db1365e392d33)) ### Features - allow custom name for named export ([#493](https://github.com/gregberge/svgr/tree/master/packages/rollup/issues/493)) ([16a58d6](https://github.com/gregberge/svgr/tree/master/packages/rollup/commit/16a58d6e817c065f72a68be91600a1a360205f44)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v5.3.1...v5.4.0) (2020-04-27) **Note:** Version bump only for package @svgr/rollup ## [5.3.1](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v5.3.0...v5.3.1) (2020-04-05) **Note:** Version bump only for package @svgr/rollup # [5.3.0](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v5.2.0...v5.3.0) (2020-03-22) **Note:** Version bump only for package @svgr/rollup # [5.2.0](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v5.1.0...v5.2.0) (2020-02-23) **Note:** Version bump only for package @svgr/rollup # [5.1.0](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v5.0.1...v5.1.0) (2020-01-20) **Note:** Version bump only for package @svgr/rollup ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/rollup/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) ## [4.3.3](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v4.3.2...v4.3.3) (2019-09-24) **Note:** Version bump only for package @svgr/rollup ## [4.3.2](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v4.3.1...v4.3.2) (2019-07-15) **Note:** Version bump only for package @svgr/rollup ## [4.3.1](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v4.3.0...v4.3.1) (2019-07-01) **Note:** Version bump only for package @svgr/rollup # [4.3.0](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v4.2.0...v4.3.0) (2019-05-28) **Note:** Version bump only for package @svgr/rollup # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/rollup/compare/v4.1.0...v4.2.0) (2019-04-11) **Note:** Version bump only for package @svgr/rollup # [4.1.0](https://github.com/gregberge/svgr/compare/v4.0.4...v4.1.0) (2018-11-24) ### Features - add parcel plugin ([#235](https://github.com/gregberge/svgr/issues/235)) ([144dbe3](https://github.com/gregberge/svgr/commit/144dbe3)), closes [#215](https://github.com/gregberge/svgr/issues/215) ## [4.0.4](https://github.com/gregberge/svgr/compare/v4.0.3...v4.0.4) (2018-11-24) ### Bug Fixes - **webpack:** use static babel config ([#240](https://github.com/gregberge/svgr/issues/240)) ([d67af31](https://github.com/gregberge/svgr/commit/d67af31)), closes [#232](https://github.com/gregberge/svgr/issues/232) ## [4.0.3](https://github.com/gregberge/svgr/compare/v4.0.2...v4.0.3) (2018-11-13) ### Bug Fixes - upgrade dependencies ([7e2195f](https://github.com/gregberge/svgr/commit/7e2195f)) ## [4.0.2](https://github.com/gregberge/svgr/compare/v4.0.1...v4.0.2) (2018-11-08) **Note:** Version bump only for package @svgr/rollup ## [4.0.1](https://github.com/gregberge/svgr/compare/v4.0.0...v4.0.1) (2018-11-08) **Note:** Version bump only for package @svgr/rollup # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Features - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default # [3.1.0](https://github.com/gregberge/svgr/compare/v3.0.0...v3.1.0) (2018-10-05) ### Bug Fixes - style & custom SVG properties ([#203](https://github.com/gregberge/svgr/issues/203)) ([f8b2212](https://github.com/gregberge/svgr/commit/f8b2212)), closes [#199](https://github.com/gregberge/svgr/issues/199) [#201](https://github.com/gregberge/svgr/issues/201) # [3.0.0](https://github.com/gregberge/svgr/compare/v2.4.1...v3.0.0) (2018-10-01) ### Bug Fixes - **rollup:** forward filePath in rollup plugin ([461492b](https://github.com/gregberge/svgr/commit/461492b)), closes [#177](https://github.com/gregberge/svgr/issues/177) [#188](https://github.com/gregberge/svgr/issues/188) ### Features - always prefix component name with "Svg" ([f71aa7a](https://github.com/gregberge/svgr/commit/f71aa7a)), closes [#190](https://github.com/gregberge/svgr/issues/190) ### BREAKING CHANGES - **rollup:** runtime configuration is now loaded using rollup plugin. ## [2.4.1](https://github.com/gregberge/svgr/compare/v2.4.0...v2.4.1) (2018-09-16) **Note:** Version bump only for package @svgr/rollup # [2.4.0](https://github.com/gregberge/svgr/compare/v2.3.0...v2.4.0) (2018-09-16) ### Features - **upgrade:** h2x@1.1.0 (jsdom@12.0.0) & others ([2d9b7bd](https://github.com/gregberge/svgr/commit/2d9b7bd)) # [2.3.0](https://github.com/gregberge/svgr/compare/v2.2.1...v2.3.0) (2018-09-03) ### Features - upgrade to Babel v7 ([7bc908d](https://github.com/gregberge/svgr/commit/7bc908d)) ## [2.2.1](https://github.com/gregberge/svgr/compare/v2.2.0...v2.2.1) (2018-08-16) ### Bug Fixes - **rollup:** fix to work with rollup-plugin-typescript2 ([#147](https://github.com/gregberge/svgr/issues/147)) ([4b3737e](https://github.com/gregberge/svgr/commit/4b3737e)) # [2.2.0](https://github.com/gregberge/svgr/compare/v2.1.1...v2.2.0) (2018-08-13) **Note:** Version bump only for package @svgr/rollup ## [2.1.1](https://github.com/gregberge/svgr/compare/v2.1.0...v2.1.1) (2018-07-11) **Note:** Version bump only for package @svgr/rollup # [2.1.0](https://github.com/gregberge/svgr/compare/v2.0.0...v2.1.0) (2018-07-08) ### Features - **cli:** support custom filename cases ([#136](https://github.com/gregberge/svgr/issues/136)) ([4922f7a](https://github.com/gregberge/svgr/commit/4922f7a)), closes [#118](https://github.com/gregberge/svgr/issues/118) ================================================ FILE: packages/rollup/README.md ================================================ # @svgr/rollup [![Build Status](https://img.shields.io/travis/smooth-code/svgr.svg)](https://travis-ci.org/smooth-code/svgr) [![Version](https://img.shields.io/npm/v/@svgr/rollup.svg)](https://www.npmjs.com/package/@svgr/rollup) [![MIT License](https://img.shields.io/npm/l/@svgr/rollup.svg)](https://github.com/smooth-code/svgr/blob/master/LICENSE) Rollup plugin for SVGR. ``` npm install @svgr/rollup --save-dev ``` In your `rollup.config.js`: ```js { plugins: [svgr()] } ``` In your code: ```js import Star from './star.svg' const App = () => (
) ``` ### Passing options ```js { plugins: [svgr({ native: true })] } ``` ### Using with `url` plugin It is possible to use it with [`url`](https://github.com/rollup/rollup-plugin-url). In your `rollup.config.js`: ```js { plugins: [url(), svgr()] } ``` In your code: ```js import starUrl, { ReactComponent as Star } from './star.svg' const App = () => (
star
) ``` The named export defaults to `ReactComponent`, but can be customized with the `namedExport` option. Please note that by default, `@svgr/rollup` will try to export the React Component via default export if there is no other plugin handling svg files with default export. When there is already any other plugin using default export for svg files, `@svgr/rollup` will always export the React component via named export. If you prefer named export in any case, you may set the `exportType` option to `named`. ### Use your own Babel configuration By default, `@svgr/rollup` applies a babel transformation with [optimized configuration](https://github.com/gregberge/svgr/blob/main/packages/rollup/src/index.ts). In some case you may want to apply a custom one (if you are using Preact for an example). You can turn off Babel transformation by specifying `babel: false` in options. ```js { plugins: [svgr({ babel: false })] } ``` ## License MIT ================================================ FILE: packages/rollup/package.json ================================================ { "name": "@svgr/rollup", "description": "SVGR Rollup plugin.", "version": "8.1.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/rollup", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "svgr", "svg", "react", "rollup", "rollup-plugin" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" }, "dependencies": { "@babel/core": "^7.21.3", "@babel/plugin-transform-react-constant-elements": "^7.21.3", "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@rollup/pluginutils": "^5.0.2", "@svgr/core": "workspace:*", "@svgr/plugin-jsx": "workspace:*", "@svgr/plugin-svgo": "workspace:*" }, "devDependencies": { "rollup": "^3.20.2", "rollup-plugin-image": "^1.0.2", "rollup-plugin-url": "^3.0.1" } } ================================================ FILE: packages/rollup/src/__snapshots__/index.test.ts.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`rollup loader should convert file 1`] = ` "var _path; function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import * as React from "react"; var SvgFile = function SvgFile(props) { return /*#__PURE__*/React.createElement("svg", _extends({ xmlns: "http://www.w3.org/2000/svg", width: 48, height: 1 }, props), _path || (_path = /*#__PURE__*/React.createElement("path", { fill: "#063855", fillRule: "evenodd", d: "M0 0h48v1H0z" }))); }; export default SvgFile;" `; exports[`rollup loader should convert file with previousExport of image plugin 1`] = ` "import * as React from "react"; const SvgFile = props => ; export { SvgFile as ReactComponent }; var img = new Image(); img.src = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNDhweCIgaGVpZ2h0PSIxcHgiIHZpZXdCb3g9IjAgMCA0OCAxIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA0Ni4yICg0NDQ5NikgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+UmVjdGFuZ2xlIDU8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz48L2RlZnM+CiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iMTktU2VwYXJhdG9yIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTI5LjAwMDAwMCwgLTE1Ni4wMDAwMDApIiBmaWxsPSIjMDYzODU1Ij4KICAgICAgICAgICAgPGcgaWQ9IkNvbnRyb2xzL1NldHRpbmdzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg4MC4wMDAwMDAsIDAuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8ZyBpZD0iQ29udGVudCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsIDY0LjAwMDAwMCkiPgogICAgICAgICAgICAgICAgICAgIDxnIGlkPSJHcm91cCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQuMDAwMDAwLCA1Ni4wMDAwMDApIj4KICAgICAgICAgICAgICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwLTIiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZS01IiB4PSIyNSIgeT0iMzYiIHdpZHRoPSI0OCIgaGVpZ2h0PSIxIj48L3JlY3Q+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPgo='; export default img;" `; exports[`rollup loader should convert file with previousExport of url plugin 1`] = ` "import * as React from "react"; const SvgFile = props => ; export { SvgFile as ReactComponent }; export default "data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20width%3D%2248px%22%20height%3D%221px%22%20viewBox%3D%220%200%2048%201%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%20%20%20%20%20%20%20%20%3Ctitle%3ERectangle%205%3C%2Ftitle%3E%20%20%20%20%3Cdesc%3ECreated%20with%20Sketch.%3C%2Fdesc%3E%20%20%20%20%3Cdefs%3E%3C%2Fdefs%3E%20%20%20%20%3Cg%20id%3D%22Page-1%22%20stroke%3D%22none%22%20stroke-width%3D%221%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%20%20%20%20%20%20%20%20%3Cg%20id%3D%2219-Separator%22%20transform%3D%22translate%28-129.000000%2C%20-156.000000%29%22%20fill%3D%22%23063855%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%3Cg%20id%3D%22Controls%2FSettings%22%20transform%3D%22translate%2880.000000%2C%200.000000%29%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cg%20id%3D%22Content%22%20transform%3D%22translate%280.000000%2C%2064.000000%29%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cg%20id%3D%22Group%22%20transform%3D%22translate%2824.000000%2C%2056.000000%29%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cg%20id%3D%22Group-2%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20id%3D%22Rectangle-5%22%20x%3D%2225%22%20y%3D%2236%22%20width%3D%2248%22%20height%3D%221%22%3E%3C%2Frect%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fg%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fg%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fg%3E%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fg%3E%20%20%20%20%20%20%20%20%3C%2Fg%3E%20%20%20%20%3C%2Fg%3E%3C%2Fsvg%3E";" `; exports[`rollup loader should convert file without babel 1`] = ` "import * as React from "react"; const SvgFile = props => ; export default SvgFile;" `; ================================================ FILE: packages/rollup/src/index.test.ts ================================================ import { rollup, RollupBuild } from 'rollup' // @ts-ignore import image from 'rollup-plugin-image' // @ts-ignore import url from 'rollup-plugin-url' import svgr from './index' const compile = (plugins = [svgr()]) => rollup({ input: './__fixtures__/simple/file.svg', plugins, }) const getCode = (bundler: RollupBuild) => bundler.cache?.modules?.find( ({ id }) => id.includes('__fixtures__/simple/file.svg') || id.includes('__fixtures__\\simple\\file.svg'), )?.code describe('rollup loader', () => { it('should convert file', async () => { const code = await compile([svgr()]) expect(getCode(code)).toMatchSnapshot() }) it('should convert file without babel', async () => { const code = await compile([svgr({ babel: false })]) expect(getCode(code)).toMatchSnapshot() }) it('should convert file with previousExport of image plugin', async () => { const code = await compile([image(), svgr({ babel: false })]) expect(getCode(code)).toMatchSnapshot() }) it('should convert file with previousExport of url plugin', async () => { const code = await compile([url(), svgr({ babel: false })]) expect(getCode(code)).toMatchSnapshot() }) }) ================================================ FILE: packages/rollup/src/index.ts ================================================ import * as fs from 'fs' import { transform, Config } from '@svgr/core' import { createFilter, CreateFilter } from '@rollup/pluginutils' import { transformAsync, createConfigItem } from '@babel/core' import svgo from '@svgr/plugin-svgo' import jsx from '@svgr/plugin-jsx' // @ts-ignore import presetReact from '@babel/preset-react' // @ts-ignore import presetEnv from '@babel/preset-env' // @ts-ignore import presetTS from '@babel/preset-typescript' // @ts-ignore import pluginTransformReactConstantElements from '@babel/plugin-transform-react-constant-elements' import type { PluginImpl } from 'rollup' const babelOptions = { babelrc: false, configFile: false, presets: [ createConfigItem(presetReact, { type: 'preset' }), createConfigItem([presetEnv, { modules: false }], { type: 'preset' }), ], plugins: [createConfigItem(pluginTransformReactConstantElements)], } const typeScriptBabelOptions = { ...babelOptions, presets: [ ...babelOptions.presets, createConfigItem( [presetTS, { allowNamespaces: true, allExtensions: true, isTSX: true }], { type: 'preset' }, ), ], } export interface Options extends Config { include?: Parameters[0] exclude?: Parameters[1] babel?: boolean } const plugin: PluginImpl = (options = {}) => { const EXPORT_REGEX = /(module\.exports *= *|export default)/ const filter = createFilter(options.include || '**/*.svg', options.exclude) const { babel = true } = options return { name: 'svgr', async transform(data, id) { if (!filter(id)) return null if (id.slice(-4) !== '.svg') return null const load = fs.readFileSync(id, 'utf8') const previousExport = EXPORT_REGEX.test(data) ? data : null const jsCode = await transform(load, options, { filePath: id, caller: { name: '@svgr/rollup', previousExport, defaultPlugins: [svgo, jsx], }, }) if (babel) { const result = await transformAsync( jsCode, options.typescript ? typeScriptBabelOptions : babelOptions, ) if (!result?.code) { throw new Error(`Error while transforming using Babel`) } return { code: result.code, map: null } } return { ast: { type: 'Program', start: 0, end: 0, sourceType: 'module', body: [], }, code: jsCode, map: null, } }, } } export default plugin ================================================ FILE: packages/rollup/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: packages/webpack/.npmignore ================================================ /* /dist/* !/dist/index.{d.ts,js} !/dist/index.js.map ================================================ FILE: packages/webpack/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. # [8.1.0](https://github.com/gregberge/svgr/compare/v8.0.1...v8.1.0) (2023-08-15) **Note:** Version bump only for package @svgr/webpack ## [8.0.1](https://github.com/gregberge/svgr/compare/v8.0.0...v8.0.1) (2023-05-09) **Note:** Version bump only for package @svgr/webpack # [8.0.0](https://github.com/gregberge/svgr/compare/v7.0.0...v8.0.0) (2023-05-09) **Note:** Version bump only for package @svgr/webpack # [7.0.0](https://github.com/gregberge/svgr/compare/v6.5.1...v7.0.0) (2023-03-24) ### Features * upgrade to svgo v3 ([#798](https://github.com/gregberge/svgr/issues/798)) ([21b6209](https://github.com/gregberge/svgr/commit/21b6209ef34c51cc0313901f31061afe587ab29b)) ### BREAKING CHANGES * svgr now requires Node.js v14+ ## [6.5.1](https://github.com/gregberge/svgr/compare/v6.5.0...v6.5.1) (2022-10-27) ### Reverts - Revert "feat(a11y): add attribute role="img" to the svg element (#750)" ([1382232](https://github.com/gregberge/svgr/commit/138223284ad9aebc5bbf94ed3ae7174a66dbc7f5)), closes [#750](https://github.com/gregberge/svgr/issues/750) # [6.5.0](https://github.com/gregberge/svgr/compare/v6.4.0...v6.5.0) (2022-10-14) **Note:** Version bump only for package @svgr/webpack # [6.4.0](https://github.com/gregberge/svgr/compare/v6.3.1...v6.4.0) (2022-10-01) ### Features - **a11y:** add attribute role="img" to the svg element ([#750](https://github.com/gregberge/svgr/issues/750)) ([8b9edc4](https://github.com/gregberge/svgr/commit/8b9edc4e712f3adbd9f9c503dfc5e4d627f763cd)) ## [6.3.1](https://github.com/gregberge/svgr/compare/v6.3.0...v6.3.1) (2022-07-22) ### Bug Fixes - fix exports compat with ESM ([#749](https://github.com/gregberge/svgr/issues/749)) ([f3e304c](https://github.com/gregberge/svgr/commit/f3e304c166282f042ecd4d6c396a0798a7f0b490)) # [6.3.0](https://github.com/gregberge/svgr/compare/v6.2.1...v6.3.0) (2022-07-18) ### Bug Fixes - **package.json:** fix exports ([#745](https://github.com/gregberge/svgr/issues/745)) ([2a368d1](https://github.com/gregberge/svgr/commit/2a368d1305949ec6426c7c7312c04224071ec2bd)) ## [6.2.1](https://github.com/gregberge/svgr/compare/v6.2.0...v6.2.1) (2022-01-30) **Note:** Version bump only for package @svgr/webpack # [6.2.0](https://github.com/gregberge/svgr/compare/v6.1.2...v6.2.0) (2022-01-10) **Note:** Version bump only for package @svgr/webpack ## [6.1.2](https://github.com/gregberge/svgr/compare/v6.1.1...v6.1.2) (2021-12-12) **Note:** Version bump only for package @svgr/webpack ## [6.1.1](https://github.com/gregberge/svgr/compare/v6.1.0...v6.1.1) (2021-12-04) ### Bug Fixes - **webpack:** fix double export ([#648](https://github.com/gregberge/svgr/issues/648)) ([7595d37](https://github.com/gregberge/svgr/commit/7595d378b73d4826a4cead165b3f32386b07315b)), closes [#645](https://github.com/gregberge/svgr/issues/645) # [6.1.0](https://github.com/gregberge/svgr/compare/v6.0.0...v6.1.0) (2021-12-01) ### Bug Fixes - fix previous export system ([1872829](https://github.com/gregberge/svgr/commit/187282977af841cd5a2243a23abba72b20eec2fa)), closes [#635](https://github.com/gregberge/svgr/issues/635) ### Performance Improvements - remove useless loader-utils package ([387bc72](https://github.com/gregberge/svgr/commit/387bc727a4e07c2668544e3f5afbefe29a3de909)), closes [#631](https://github.com/gregberge/svgr/issues/631) # [5.5.0](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v5.4.0...v5.5.0) (2020-11-15) ### Bug Fixes - prevent removing the namespace by svgr ([[#475](https://github.com/gregberge/svgr/tree/master/packages/webpack/issues/475)](https://github.com/gregberge/svgr/issues/475) ([#498](https://github.com/gregberge/svgr/tree/master/packages/webpack/issues/498)) ([00e84ea](https://github.com/gregberge/svgr/tree/master/packages/webpack/commit/00e84ead96d89bcbd072b9585b4db1365e392d33)) ### Features - allow custom name for named export ([#493](https://github.com/gregberge/svgr/tree/master/packages/webpack/issues/493)) ([16a58d6](https://github.com/gregberge/svgr/tree/master/packages/webpack/commit/16a58d6e817c065f72a68be91600a1a360205f44)) # [5.4.0](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v5.3.1...v5.4.0) (2020-04-27) **Note:** Version bump only for package @svgr/webpack ## [5.3.1](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v5.3.0...v5.3.1) (2020-04-05) **Note:** Version bump only for package @svgr/webpack # [5.3.0](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v5.2.0...v5.3.0) (2020-03-22) **Note:** Version bump only for package @svgr/webpack # [5.2.0](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v5.1.0...v5.2.0) (2020-02-23) **Note:** Version bump only for package @svgr/webpack # [5.1.0](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v5.0.1...v5.1.0) (2020-01-20) **Note:** Version bump only for package @svgr/webpack ## [5.0.1](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v5.0.0...v5.0.1) (2019-12-29) ### Bug Fixes - fix engines in package.json ([a45d6fc](https://github.com/gregberge/svgr/tree/master/packages/webpack/commit/a45d6fc8b43402bec60ed4e9273f90fdc65a23a7)) ## [4.3.3](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v4.3.2...v4.3.3) (2019-09-24) **Note:** Version bump only for package @svgr/webpack ## [4.3.2](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v4.3.1...v4.3.2) (2019-07-15) **Note:** Version bump only for package @svgr/webpack ## [4.3.1](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v4.3.0...v4.3.1) (2019-07-01) **Note:** Version bump only for package @svgr/webpack # [4.3.0](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v4.2.0...v4.3.0) (2019-05-28) **Note:** Version bump only for package @svgr/webpack # [4.2.0](https://github.com/gregberge/svgr/tree/master/packages/webpack/compare/v4.1.0...v4.2.0) (2019-04-11) **Note:** Version bump only for package @svgr/webpack # [4.1.0](https://github.com/gregberge/svgr/compare/v4.0.4...v4.1.0) (2018-11-24) ### Features - add parcel plugin ([#235](https://github.com/gregberge/svgr/issues/235)) ([144dbe3](https://github.com/gregberge/svgr/commit/144dbe3)), closes [#215](https://github.com/gregberge/svgr/issues/215) ## [4.0.4](https://github.com/gregberge/svgr/compare/v4.0.3...v4.0.4) (2018-11-24) ### Bug Fixes - **webpack:** use static babel config ([#240](https://github.com/gregberge/svgr/issues/240)) ([d67af31](https://github.com/gregberge/svgr/commit/d67af31)), closes [#232](https://github.com/gregberge/svgr/issues/232) ## [4.0.3](https://github.com/gregberge/svgr/compare/v4.0.2...v4.0.3) (2018-11-13) ### Bug Fixes - upgrade dependencies ([7e2195f](https://github.com/gregberge/svgr/commit/7e2195f)) ## [4.0.2](https://github.com/gregberge/svgr/compare/v4.0.1...v4.0.2) (2018-11-08) **Note:** Version bump only for package @svgr/webpack ## [4.0.1](https://github.com/gregberge/svgr/compare/v4.0.0...v4.0.1) (2018-11-08) **Note:** Version bump only for package @svgr/webpack # [4.0.0](https://github.com/gregberge/svgr/compare/v3.1.0...v4.0.0) (2018-11-04) ### Bug Fixes - prevent babel read babel.config.js ([#206](https://github.com/gregberge/svgr/issues/206)) ([514d43d](https://github.com/gregberge/svgr/commit/514d43d)) ### Features - **svgo:** prefix ids by default ([06c338d](https://github.com/gregberge/svgr/commit/06c338d)), closes [#210](https://github.com/gregberge/svgr/issues/210) - **v4:** new architecture ([ac8b8ca](https://github.com/gregberge/svgr/commit/ac8b8ca)) ### BREAKING CHANGES - **v4:** - `template` option must now returns a Babel AST * `@svgr/core` does not include svgo & prettier by default # [3.1.0](https://github.com/gregberge/svgr/compare/v3.0.0...v3.1.0) (2018-10-05) **Note:** Version bump only for package @svgr/webpack # [3.0.0](https://github.com/gregberge/svgr/compare/v2.4.1...v3.0.0) (2018-10-01) ### Bug Fixes - **webpack:** forward filePath in webpack loader ([b7a108e](https://github.com/gregberge/svgr/commit/b7a108e)), closes [#177](https://github.com/gregberge/svgr/issues/177) [#188](https://github.com/gregberge/svgr/issues/188) ### Features - always prefix component name with "Svg" ([f71aa7a](https://github.com/gregberge/svgr/commit/f71aa7a)), closes [#190](https://github.com/gregberge/svgr/issues/190) ### BREAKING CHANGES - **webpack:** runtime configuration is now loaded using webpack loader. ## [2.4.1](https://github.com/gregberge/svgr/compare/v2.4.0...v2.4.1) (2018-09-16) **Note:** Version bump only for package @svgr/webpack # [2.4.0](https://github.com/gregberge/svgr/compare/v2.3.0...v2.4.0) (2018-09-16) ### Features - **upgrade:** h2x@1.1.0 (jsdom@12.0.0) & others ([2d9b7bd](https://github.com/gregberge/svgr/commit/2d9b7bd)) # [2.3.0](https://github.com/gregberge/svgr/compare/v2.2.1...v2.3.0) (2018-09-03) ### Features - upgrade to Babel v7 ([7bc908d](https://github.com/gregberge/svgr/commit/7bc908d)) ## [2.2.1](https://github.com/gregberge/svgr/compare/v2.2.0...v2.2.1) (2018-08-16) **Note:** Version bump only for package @svgr/webpack # [2.2.0](https://github.com/gregberge/svgr/compare/v2.1.1...v2.2.0) (2018-08-13) ### Bug Fixes - **webpack:** use source when possible ([#139](https://github.com/gregberge/svgr/issues/139)) ([ae9965d](https://github.com/gregberge/svgr/commit/ae9965d)) ## [2.1.1](https://github.com/gregberge/svgr/compare/v2.1.0...v2.1.1) (2018-07-11) **Note:** Version bump only for package @svgr/webpack # [2.1.0](https://github.com/gregberge/svgr/compare/v2.0.0...v2.1.0) (2018-07-08) **Note:** Version bump only for package @svgr/webpack ================================================ FILE: packages/webpack/README.md ================================================ # @svgr/webpack [![Build Status](https://img.shields.io/travis/gregberge/svgr.svg)](https://travis-ci.org/gregberge/svgr) [![Version](https://img.shields.io/npm/v/@svgr/webpack.svg)](https://www.npmjs.com/package/@svgr/webpack) [![MIT License](https://img.shields.io/npm/l/@svgr/webpack.svg)](https://github.com/gregberge/svgr/blob/master/LICENSE) Webpack loader for SVGR. ``` npm install @svgr/webpack --save-dev ``` ## Usage In your `webpack.config.js`: ```js { test: /\.svg$/, use: ['@svgr/webpack'], } ``` In your code: ```js import Star from './star.svg' const App = () => (
) ``` ### Passing options ```js { test: /\.svg$/, use: [ { loader: '@svgr/webpack', options: { native: true, }, }, ], } ``` ### Using with `url-loader` or `file-loader` It is possible to use it with [`url-loader`](https://github.com/webpack-contrib/url-loader) or [`file-loader`](https://github.com/webpack-contrib/file-loader). In your `webpack.config.js`: ```js { test: /\.svg$/, use: ['@svgr/webpack', 'url-loader'], } ``` In your code: ```js import starUrl, { ReactComponent as Star } from './star.svg' const App = () => (
star
) ``` The named export defaults to `ReactComponent`, but can be customized with the `namedExport` option. Please note that by default, `@svgr/webpack` will try to export the React Component via default export if there is no other loader handling svg files with default export. When there is already any other loader using default export for svg files, `@svgr/webpack` will always export the React component via named export. If you prefer named export in any case, you may set the `exportType` option to `named`. ### Use your own Babel configuration By default, `@svgr/webpack` includes a `babel-loader` with [an optimized configuration](https://github.com/gregberge/svgr/blob/main/packages/webpack/src/index.ts). In some case you may want to apply a custom one (if you are using Preact for an example). You can turn off Babel transformation by specifying `babel: false` in options. ```js // Example using preact { test: /\.svg$/, use: [ { loader: 'babel-loader', options: { presets: ['preact', 'env'], }, }, { loader: '@svgr/webpack', options: { babel: false }, } ], } ``` ### Handle SVG in CSS, Sass or Less It is possible to detect the module that requires your SVG using [`Rule.issuer`](https://webpack.js.org/configuration/module/#ruleissuer) in Webpack 5. Using it you can specify two different configurations for JavaScript and the rest of your files. ```js ;[ { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, issuer: /\.[jt]sx?$/, use: ['babel-loader', '@svgr/webpack', 'url-loader'], }, { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader', }, ] ``` _[Rule.issuer](https://v4.webpack.js.org/configuration/module/#ruleissuer) in Webpack 4 has additional conditions which are not available in Webpack 5._ ## License MIT ================================================ FILE: packages/webpack/package.json ================================================ { "name": "@svgr/webpack", "description": "SVGR webpack loader.", "version": "8.1.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./package.json": "./package.json" }, "repository": "https://github.com/gregberge/svgr/tree/main/packages/webpack", "author": "Greg Bergé ", "publishConfig": { "access": "public" }, "keywords": [ "svgr", "svg", "react", "webpack", "webpack-loader" ], "engines": { "node": ">=14" }, "homepage": "https://react-svgr.com", "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "license": "MIT", "scripts": { "reset": "rm -rf dist", "build": "rollup -c ../../build/rollup.config.mjs", "prepublishOnly": "pnpm run reset && pnpm run build" }, "dependencies": { "@babel/core": "^7.21.3", "@babel/plugin-transform-react-constant-elements": "^7.21.3", "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@svgr/core": "workspace:*", "@svgr/plugin-jsx": "workspace:*", "@svgr/plugin-svgo": "workspace:*" }, "devDependencies": { "babel-loader": "^9.1.2", "memory-fs": "^0.5.0", "url-loader": "^4.1.1", "webpack": "^5.76.3" } } ================================================ FILE: packages/webpack/src/__snapshots__/index.test.ts.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`webpack loader supports url-loader 1`] = ` "var _svg; import * as React from "react"; var SvgIcon = function SvgIcon() { return _svg || (_svg = /*#__PURE__*/React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 88, height: 88 }, /*#__PURE__*/React.createElement("g", { fill: "none", fillRule: "evenodd", stroke: "#063855", strokeLinecap: "square", strokeWidth: 2 }, /*#__PURE__*/React.createElement("path", { d: "M51 37 37 51M51 51 37 37" })))); }; export { SvgIcon as ReactComponent }; export default "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODhweCIgaGVpZ2h0PSI4OHB4IiB2aWV3Qm94PSIwIDAgODggODgiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQ2LjIgKDQ0NDk2KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5EaXNtaXNzPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9IkJsb2NrcyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSI+CiAgICAgICAgPGcgaWQ9IkRpc21pc3MiIHN0cm9rZT0iIzA2Mzg1NSIgc3Ryb2tlLXdpZHRoPSIyIj4KICAgICAgICAgICAgPHBhdGggZD0iTTUxLDM3IEwzNyw1MSIgaWQ9IlNoYXBlIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik01MSw1MSBMMzcsMzciIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+Cg==";" `; exports[`webpack loader transforms file (babel: false) 1`] = ` "import * as React from "react"; const SvgIcon = () => /*#__PURE__*/React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 88, height: 88 }, /*#__PURE__*/React.createElement("g", { fill: "none", fillRule: "evenodd", stroke: "#063855", strokeLinecap: "square", strokeWidth: 2 }, /*#__PURE__*/React.createElement("path", { d: "M51 37 37 51M51 51 37 37" }))); export default SvgIcon;" `; exports[`webpack loader transforms file (typescript: true) 1`] = ` "var _g; function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import * as React from "react"; var SvgIcon = function SvgIcon(props) { return /*#__PURE__*/React.createElement("svg", _extends({ xmlns: "http://www.w3.org/2000/svg", width: 88, height: 88 }, props), _g || (_g = /*#__PURE__*/React.createElement("g", { fill: "none", fillRule: "evenodd", stroke: "#063855", strokeLinecap: "square", strokeWidth: 2 }, /*#__PURE__*/React.createElement("path", { d: "M51 37 37 51M51 51 37 37" })))); }; export default SvgIcon;" `; exports[`webpack loader transforms file 1`] = ` "var _svg; import * as React from "react"; var SvgIcon = function SvgIcon() { return _svg || (_svg = /*#__PURE__*/React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 88, height: 88 }, /*#__PURE__*/React.createElement("g", { fill: "none", fillRule: "evenodd", stroke: "#063855", strokeLinecap: "square", strokeWidth: 2 }, /*#__PURE__*/React.createElement("path", { d: "M51 37 37 51M51 51 37 37" })))); }; export default SvgIcon;" `; exports[`webpack loader transforms file 2`] = ` "var _svg; import * as React from "react"; var SvgIcon = function SvgIcon() { return _svg || (_svg = /*#__PURE__*/React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 88, height: 88 }, /*#__PURE__*/React.createElement("g", { fill: "none", fillRule: "evenodd", stroke: "#063855", strokeLinecap: "square", strokeWidth: 2 }, /*#__PURE__*/React.createElement("path", { d: "M51 37 37 51M51 51 37 37" })))); }; export default SvgIcon;" `; ================================================ FILE: packages/webpack/src/index.test.ts ================================================ import * as path from 'path' import { webpack, ModuleOptions } from 'webpack' // @ts-ignore import MemoryFs from 'memory-fs' function compile(rules: ModuleOptions['rules']) { const compiler = webpack({ mode: 'development', context: __dirname, entry: './__fixtures__/icon.svg', output: { path: __dirname, filename: 'bundle.js', }, module: { rules }, }) compiler.outputFileSystem = new MemoryFs() return new Promise((resolve, reject) => { compiler.run((err, stats) => { if (err) reject(err) else { resolve( stats ?.toJson({ source: true }) ?.modules?.find(({ name }) => name === './__fixtures__/icon.svg') ?.source, ) } }) }) } describe('webpack loader', () => { it('transforms file (typescript: true)', async () => { const source = await compile([ { test: /\.svg$/, use: [ { loader: path.resolve(__dirname, '..'), options: { typescript: true, }, }, ], }, ]) expect(source).toMatchSnapshot() }) it('transforms file', async () => { const source = await compile([ { test: /\.svg$/, use: [ { loader: path.resolve(__dirname, '..'), options: { expandProps: false, }, }, ], }, ]) expect(source).toMatchSnapshot() }) it('transforms file', async () => { const source = await compile([ { test: /\.svg$/, use: [ { loader: path.resolve(__dirname, '..'), options: { expandProps: false, }, }, ], }, ]) expect(source).toMatchSnapshot() }) it('supports url-loader', async () => { const source = await compile([ { test: /\.svg$/, use: [ { loader: path.resolve(__dirname, '..'), options: { expandProps: false, }, }, 'url-loader', ], }, ]) expect(source).toMatchSnapshot() }) it('transforms file (babel: false)', async () => { const source = await compile([ { test: /\.svg$/, use: [ { loader: 'babel-loader', options: { babelrc: false, presets: ['@babel/preset-react'], }, }, { loader: path.resolve(__dirname, '..'), options: { babel: false, expandProps: false, }, }, ], }, ]) expect(source).toMatchSnapshot() }) }) ================================================ FILE: packages/webpack/src/index.ts ================================================ import { callbackify } from 'util' import { transformAsync, createConfigItem } from '@babel/core' import { transform, Config, State } from '@svgr/core' import { normalize } from 'path' import svgo from '@svgr/plugin-svgo' import jsx from '@svgr/plugin-jsx' // @ts-ignore import presetReact from '@babel/preset-react' // @ts-ignore import presetEnv from '@babel/preset-env' // @ts-ignore import presetTS from '@babel/preset-typescript' // @ts-ignore import pluginTransformReactConstantElements from '@babel/plugin-transform-react-constant-elements' import type * as webpack from 'webpack' const babelOptions = { babelrc: false, configFile: false, presets: [ createConfigItem(presetReact, { type: 'preset' }), createConfigItem([presetEnv, { modules: false }], { type: 'preset' }), ], plugins: [createConfigItem(pluginTransformReactConstantElements)], } const typeScriptBabelOptions = { ...babelOptions, presets: [ ...babelOptions.presets, createConfigItem( [presetTS, { allowNamespaces: true, allExtensions: true, isTSX: true }], { type: 'preset' }, ), ], } interface LoaderOptions extends Config { babel?: boolean } const tranformSvg = callbackify( async (contents: string, options: LoaderOptions, state: Partial) => { const { babel = true, ...config } = options const jsCode = await transform(contents, config, state) if (!babel) return jsCode const result = await transformAsync( jsCode, options.typescript ? typeScriptBabelOptions : babelOptions, ) if (!result?.code) { throw new Error(`Error while transforming using Babel`) } return result.code }, ) function svgrLoader( this: webpack.LoaderContext, contents: string, ): void { this.cacheable && this.cacheable() const callback = this.async() const options = this.getOptions() const previousExport = (() => { if (contents.startsWith('export ')) return contents const exportMatches = contents.match(/^module.exports\s*=\s*(.*)/) return exportMatches ? `export default ${exportMatches[1]}` : null })() const state = { caller: { name: '@svgr/webpack', previousExport, defaultPlugins: [svgo, jsx], }, filePath: normalize(this.resourcePath), } if (!previousExport) { tranformSvg(contents, options, state, callback) } else { this.fs.readFile(this.resourcePath, (err, result) => { if (err) { callback(err) return } tranformSvg(String(result), options, state, (err, content) => { if (err) { callback(err) return } callback(null, content) }) }) } } export default svgrLoader ================================================ FILE: packages/webpack/tsconfig.json ================================================ { "extends": "../../tsconfig", "include": ["src"] } ================================================ FILE: pnpm-workspace.yaml ================================================ packages: - 'packages/*' - 'examples/**' ================================================ FILE: public/.exists ================================================ ================================================ FILE: tsconfig.json ================================================ { "compilerOptions": { "moduleResolution": "Node", "target": "es2019", "lib": [ "es2019", "es2020.bigint", "es2020.string", "es2020.symbol.wellknown" ], "module": "ESNext", "strict": true, "sourceMap": true, "declaration": true, "resolveJsonModule": true } } ================================================ FILE: website/.eslintignore ================================================ .cache/ node_modules/ /public/ ================================================ FILE: website/.eslintrc.js ================================================ module.exports = { globals: { __PATH_PREFIX__: true, }, extends: `react-app`, } ================================================ FILE: website/.gitignore ================================================ .cache/ node_modules/ /public/ ================================================ FILE: website/.npmrc ================================================ node-linker=hoisted ================================================ FILE: website/.nvmrc ================================================ 16 ================================================ FILE: website/README.md ================================================ # SVGR documentation website [Documentation site](https://react-svgr.com) for [svgr](https://github.com/gregberge/svgr). `svgr-docs` is running on [gatsbyjs](https://gatsbyjs.org). ## Getting Started To install and run the docs site locally: ```bash npm install npm run dev ``` Then, open your favorite browser to [localhost:8000](http://localhost:8000/). GraphiQL runs at [localhost:8000/\_\_\_graphql](http://localhost:8000/___graphql). ## Contributing Build the site to test locally. ```bash npm run build ``` Serve the build. ```bash npm run serve ``` Then, open your favorite browser to [localhost:9000](http://localhost:9000/) to verify everything looks correct. ================================================ FILE: website/_redirects ================================================ https://svgr.netlify.com/* https://react-svgr.com/:splat 301! ================================================ FILE: website/gatsby-config.js ================================================ const path = require('path') module.exports = { plugins: [ { resolve: 'smooth-doc', options: { name: 'SVGR', author: 'Greg Bergé', description: 'Transforms SVG into React Components.', siteUrl: 'https://react-svgr.com', githubRepositoryURL: 'https://github.com/gregberge/svgr', githubDefaultBranch: 'main', baseDirectory: path.resolve(__dirname, '..'), navItems: [ { title: 'Playground', url: '/playground/' }, { title: 'Docs', url: '/docs/' }, ], sections: ['About', 'Usage', 'Configuring SVGR', 'Advanced'], carbonAdsURL: '//cdn.carbonads.com/carbon.js?serve=CE7I5K3N&placement=react-svgrcom', docSearch: { apiKey: '0c7343afd83c189413499c62c1df6853', indexName: 'smooth-code-svgr', }, }, }, { resolve: `gatsby-plugin-google-analytics`, options: { trackingId: 'UA-154496255-2', }, }, ], } ================================================ FILE: website/netlify.toml ================================================ [build] base = "website/" publish = "public/" command = "npm ci && npm run build" ================================================ FILE: website/package.json ================================================ { "private": true, "dependencies": { "@xstyled/styled-components": "^3.7.3", "ariakit": "^2.0.0-next.43", "brace": "^0.11.1", "final-form": "^4.20.9", "gatsby": "^4.24.5", "gatsby-plugin-google-analytics": "^4.24.0", "history": "^5.3.0", "isomorphic-fetch": "^3.0.0", "react": "^18.2.0", "react-ace": "^10.1.0", "react-dom": "^18.2.0", "react-final-form": "^6.5.9", "react-icons": "^4.8.0", "reakit": "^1.3.11", "smooth-doc": "^10.1.0" }, "scripts": { "build": "gatsby build && cp _redirects public/", "dev": "gatsby develop", "serve": "gatsby serve" }, "devDependencies": { "eslint-config-react-app": "^7.0.1" }, "overrides": { "react": "^18.2.0", "react-dom": "^18.2.0" } } ================================================ FILE: website/pages/docs/cli.mdx ================================================ --- section: Usage title: Command Line slug: /docs/cli/ order: 20 --- # Command Line Use SVGR from command line to transform a single file or a whole directory. ## Install Depending you usage, you can install `@svgr/cli` locally in your project: ```sh npm install --save-dev @svgr/cli # or use yarn yarn add --dev @svgr/cli ``` or use it on the fly using `npx @svgr/cli`. ## Options All [SVGR options](https://react-svgr.com/docs/options/) are available from command line or in configuration. Command line options have precedence over config file options. ## Transform a single file ### From file Transforms a single file by specifying file as the single argument. ```sh npx @svgr/cli -- icons/clock-icon.svg ``` ### From standard input `@svgr/cli` supports standard input, just redirect file contents using `<` operator. ```sh npx @svgr/cli < icons/clock-icon.svg ``` ### Output the result in another file You can easily create another file using `>` operator. ```sh npx @svgr/cli -- icons/clock-icon.svg > dist/ClockIcon.js ``` ## Transform a whole directory Transforms a whole directory using `--out-dir` option. All SVG presents in this directory tree are transformed into React components. ```sh # Usage: npx @svgr/cli [--out-dir dir] [--ignore-existing] [src-dir] $ npx @svgr/cli --out-dir dist -- icons icons/web/clock-icon.svg -> dist/web/ClockIcon.js icons/web/wifi-icon.svg -> dist/web/WifiIcon.js icons/spinner/cog-icon.svg -> dist/spinner/CogIcon.js icons/spinner/spinner-icon.svg -> dist/spinner/SpinnerIcon.js ``` ### Avoid replacing existing files Even if it is not recommended, you may be tempted to modify generated files. If you do so, you should use the `--ignore-existing` option to avoid replacing existing files. ```sh npx @svgr/cli --out-dir dist --ignore-existing -- icons ``` ### Use a different filename case By default, filenames uses "PascalCase", you can specify a different case for generated files using `--filename-case` option. ```sh npx @svgr/cli --out-dir dist --filename-case kebab -- icons ``` ### Disable index generation By default an index is generated, giving you opportunity to import all your components from the directory. If you does not want auto-generated index, turn it off using `--no-index` option. ```sh npx @svgr/cli --out-dir dist --no-index -- icons ``` ### Use a custom index template Advanced use cases could lead you to customize the index template. The `--index-template