[
  {
    "path": ".editorconfig",
    "content": "# editorconfig.org\nroot = true\n\n[*]\nindent_style = tab\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.{json,yml,md,babelrc,eslintrc,remarkrc,prettierrc}]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".eslintignore",
    "content": "node_modules\nexamples/*/styleguide/*\n# this example contains typescript and has never been linted\n# linting it could take time.\n# TODO: remove this next line and fix all errors\nexamples/styled-components\nlib/*\nsrc/typings/dependencies/*\ncoverage/*\ntravis_phantomjs/*\n# When ESlint looks at imports in .d.ts files,\n# it often duplicates automatically imports\n# @example: this `import { ASTNode } from 'ast-types';`\n# becomes this `import { ASTNode, ASTNode } from 'ast-types';`\n# TODO: fix tamia about this and remove this rule\n*.d.ts\nsite/build/\nsite/.docusaurus/\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"parser\": \"babel-eslint\",\n  \"extends\": [\"tamia/react\", \"plugin:jsx-a11y/recommended\"],\n  \"env\": {\n    \"browser\": true,\n    \"node\": true\n  },\n  \"plugins\": [\"compat\", \"import\", \"jsx-a11y\"],\n  \"settings\": {\n    \"import/resolver\": {\n      \"node\": {\n        \"extensions\": [\".js\", \".json\", \".ts\"]\n      }\n    },\n    \"react\": {\n      \"version\": \"16.6\"\n    }\n  },\n  \"rules\": {\n    \"valid-jsdoc\": 0,\n    \"no-duplicate-imports\": 0,\n    \"compat/compat\": \"error\",\n    \"import/export\": \"error\",\n    \"import/no-named-as-default-member\": \"error\",\n    \"import/no-mutable-exports\": \"error\",\n    \"import/no-amd\": \"error\",\n    \"import/first\": [\"error\", \"absolute-first\"],\n    \"import/no-duplicates\": \"error\",\n    \"import/extensions\": [\n      \"error\",\n      \"always\",\n      {\n        \"js\": \"never\",\n        \"tsx\": \"never\",\n        \"ts\": \"never\",\n        \"mjs\": \"never\"\n      }\n    ],\n    \"import/no-extraneous-dependencies\": \"error\",\n    \"import/newline-after-import\": \"error\",\n    \"import/prefer-default-export\": \"error\",\n    \"import/no-named-default\": \"error\"\n  },\n  \"globals\": {\n    \"System\": false,\n    \"classes\": false,\n    \"shallow\": false,\n    \"render\": false,\n    \"mount\": false,\n    \"cy\": false\n  },\n  \"overrides\": [\n    {\n      \"files\": [\"*.spec.js\"],\n      \"rules\": {\n        \"compat/compat\": 0\n      }\n    },\n    {\n      \"files\": [\"*.ts\", \"*.tsx\"],\n      \"parser\": \"@typescript-eslint/parser\",\n      \"parserOptions\": {\n        \"project\": \"./tsconfig.json\"\n      },\n      \"settings\": {\n        \"import/resolver\": {\n          \"typescript\": {}\n        }\n      },\n      \"plugins\": [\"@typescript-eslint\"],\n      \"extends\": [\"tamia/typescript-react\"]\n    }\n  ]\n}\n"
  },
  {
    "path": ".github/Code_of_Conduct.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn 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.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n- Using welcoming and inclusive language\n- Being respectful of differing viewpoints and experiences\n- Gracefully accepting constructive criticism\n- Focusing on what is best for the community\n- Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n- The use of sexualized language or imagery and unwelcome sexual attention or advances\n- Trolling, insulting/derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or electronic address, without explicit permission\n- Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject 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.\n\nProject 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.\n\n## Scope\n\nThis 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.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at artem@sapegin.ru. 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.\n\nProject 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.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": ".github/Contributing.md",
    "content": "# How to contribute\n\nWe love pull requests. And following these guidelines will make your pull request easier to merge.\n\nIf you want to contribute but don’t know what to do, take a look at these two labels: [help wanted](https://github.com/styleguidist/react-styleguidist/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) and [good first issue](https://github.com/styleguidist/react-styleguidist/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). Our [docs](https://github.com/styleguidist/react-styleguidist/tree/master/docs) and [site](https://github.com/styleguidist/site) are also far from perfect and could use a little love.\n\n## Prerequisites\n\n- If it’s your first pull request, watch [this amazing course](http://makeapullrequest.com/) by [Kent C. Dodds](https://twitter.com/kentcdodds).\n- Install [EditorConfig](http://editorconfig.org/) plugin for your code editor to make sure it uses correct settings.\n- Fork the repository and clone your fork.\n- Install dependencies: `npm install`.\n- Read the [developer guide](https://react-styleguidist.js.org/docs/development).\n\n## Development workflow\n\nRun Babel in watch mode:\n\n```bash\nnpm run compile:watch\n```\n\nThen open a new terminal and start an example style guide:\n\n```bash\nnpm start\n```\n\nOpen [localhost:6060](http://localhost:6060) in a browser.\n\n(There are other example style guides to test particular features too, run `npm run` to see a list.)\n\nRun linters and tests:\n\n```bash\nnpm test\n```\n\nOr run tests in watch mode:\n\n```bash\nnpm run test:watch\n```\n\nTo update Jest snapshots:\n\n```bash\nnpx jest -u\n```\n\n**Don’t forget to add tests and update documentation for your changes.**\n\n**Please update npm lock file (`package-lock.json`) if you add or update dependencies.**\n\n## Integration tests (Cypress)\n\nFirst install dependencies:\n\n```bash\nnpm run test:cypress:pre\n```\n\nThen run Babel in watch mode:\n\n```bash\nnpm run compile:watch\n```\n\nThen open a new terminal and start Styleguidist server:\n\n```bash\nnpm run test:cypress:startServer\n```\n\nAnd, finally, in another separate terminal run tests:\n\n```bash\nnpm run test:cypress:run\n```\n\nOr open Cypress UI:\n\n```bash\nnpm run test:cypress:open\n```\n\n## Other notes\n\n- If you have commit access to repository and want to make big change or not sure about something, make a new branch and open pull request.\n- We’re using [Prettier](https://github.com/prettier/prettier) to format JavaScript, so don’t worry much about code formatting.\n- Don’t commit generated files, like minified JavaScript.\n- Don’t change version number and change log.\n- If you're updating examples other then `examples/basic`, you'll need to modify your start commands:\n\n```bash\nnpm run start:customised # if making changes to examples/customised\nnpm run start:sections # if making changes to examples/sections\n```\n\nSee the `scripts` section of the top level [package.json](https://github.com/styleguidist/react-styleguidist/blob/master/package.json#L135)\n\n. If an example doesn't have a script just point to its config:\n\n```bash\nnode bin/styleguidist.js server --config examples/path/to/example/styleguide.config.js\n```\n\n## Need help?\n\n- Join our [Gitter](https://gitter.im/styleguidist/styleguidist) or [Spectrum](https://spectrum.chat/styleguidist) chats and ask everything you need.\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "open_collective: styleguidist\ngithub: sapegin\nko_fi: sapegin\ncustom: https://www.buymeacoffee.com/sapegin\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Bug_report.md",
    "content": "---\nname: \"\\U0001F41B Bug report\"\nabout: Something isn’t working as expected\n---\n\n**Current behavior**\n\n<!-- A clear and concise description of what the bug is -->\n\n**To reproduce**\n\n<!--\nPost a link to a reproducible demo repository here.\n\n  1. Fork the example project repository: https://github.com/styleguidist/example\n     (please don’t use the main, styleguidist/react-styleguidist, repository).\n  2. Modify it to reproduce the issue.\n  3. Push to GitHub and paste the link here.\n\nMost likely you’ll find an issue yourself, while creating a demo.\n\nMake sure you’re using the latest version of React Styleguidist.\n\n💀 Issues without a demo will be closed! 💀\n-->\n\n**Expected behavior**\n\n<!-- A clear and concise description of what you expected to happen -->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Feature_request.md",
    "content": "---\nname: \"\\U0001F680 Feature request\"\nabout: I have a suggestion (and might want to implement myself)\n---\n\n<!-- Consider opening a pull request instead: it’s a more productive way to discuss new features -->\n\n**The problem**\n\n<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->\n\n**Proposed solution**\n\n<!-- A clear and concise description of what you want to happen. Add any considered drawbacks. -->\n\n**Alternative solutions**\n\n<!-- A clear and concise description of any alternative solutions or features you’ve considered. -->\n\n**Additional context**\n\n<!-- Add any other context or screenshots about the feature request here. -->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Question.md",
    "content": "---\nname: \"\\U0001F914 Support question\"\nabout: I have a question or don’t know how to do something\n---\n\n--------------^ Click “Preview”!\n\nIf you have a support question, ask it on [Stack Overflow](https://stackoverflow.com/questions/tagged/react-styleguidist) using the `react-styleguidist` tag.\n\nBefore submitting a new question, make sure you:\n\n- Searched existing [Stack Overflow questions](https://stackoverflow.com/questions/tagged/react-styleguidist).\n- Searched opened and closed [GitHub issues](https://github.com/styleguidist/react-styleguidist/issues?utf8=%E2%9C%93&q=is%3Aissue).\n- Read [the documentation](https://react-styleguidist.js.org/docs/getting-started).\n- Googled your question.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Support.md",
    "content": "---\nname: \"\\U0001F984 Support Styleguidist development\"\nabout: I want to support efforts in maintaining this community-driven project\n---\n\n--------------^ Click “Preview”!\n\nDeveloping and maintaining an open source project is a big effort. Styleguidist isn’t supported by any big company, and all the contributors are working on it in their free time. We need your help to make it sustainable.\n\nThere are two ways you can help:\n\n1.  Help develop and maintain the project:\n\n- Answer questions in [GitHub issues](https://github.com/styleguidist/react-styleguidist/issues) and [Stack Overflow](https://stackoverflow.com/questions/tagged/react-styleguidist).\n- Review [pull requests](https://github.com/styleguidist/react-styleguidist/pulls).\n- Fix bugs and add new features.\n- Write articles and talk about Styleguidist on conferences and meetups (we’re always happy to review your texts and slides).\n\n2.  Donate via [Open Collective](https://opencollective.com/styleguidist).\n"
  },
  {
    "path": ".github/Issue_Template.md",
    "content": "<!---\n\nThanks for using Styleguidist! Before you submit, please read the following:\n\nSearch open/closed issues before submitting since someone might have asked the same thing before:\nhttps://github.com/styleguidist/react-styleguidist/issues?utf8=%E2%9C%93&q=is%3Aissue\n\nRead essential documentation (all six pages):\nhttps://react-styleguidist.js.org/docs/getting-started\n\nMake sure you’re using the latest versions of React Styleguidist.\n\n💀 Issues without a demo will be closed! 💀\n\nWhen something isn’t working for you, include a reproducible demo:\n  1. Fork the example project repository: https://github.com/styleguidist/example\n     (please don’t use the main, styleguidist/react-styleguidist, repository).\n  2. Modify it to reproduce the issue.\n  3. Push to GitHub and paste the link here.\n\nMost likely you’ll find an issue yourself, while creating a demo.\n\nIf you want to request a feature, consider opening a pull request instead.\n\nLove Styleguidist? Please consider supporting us:\n👉  https://opencollective.com/styleguidist\n\n-->\n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 90\n\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 7\n\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - \"help wanted\"\n\n# Ignore issues with an assignee\nexemptAssignees: true\n\n# Label to use when marking an issue as stale\nstaleLabel: wontfix\n\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: >\n  😴 This issue has been automatically marked as stale because it has not had\n  recent activity. It will be closed in a week without any further activity.\n  Consider opening a pull request if you still have this issue or want this feature.\n\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: false\n"
  },
  {
    "path": ".github/workflows/coverage.yml",
    "content": "name: Codecov\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\n\njobs:\n  report:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: '16'\n          cache: npm\n\n      - run: npm ci\n      - run: npm run test:coverage -- --runInBand\n\n      - uses: codecov/codecov-action@v1\n        with:\n          verbose: true\n"
  },
  {
    "path": ".github/workflows/danger-js.yml",
    "content": "name: Danger JS\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\n\njobs:\n  check:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: '16'\n          cache: npm\n      - uses: danger/danger-js@9.1.8\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/node.js.yml",
    "content": "name: CI\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\n\njobs:\n  lint:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: '16'\n          cache: npm\n\n      - run: npm ci\n      - run: npm run lint\n      - run: npm run typecheck\n\n  integration:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: '16'\n\n      - run: npm ci\n      - run: npm run compile\n\n      - name: Build all examples\n        run: |\n          npm run build:basic\n          npm run build:customised\n          npm run build:sections\n\n      - name: Check that examples really works - no JS errors on load\n        run: |\n          npm run test:browser:pre\n          npm run test:browser:basic\n          npm run test:browser:customised\n          npm run test:browser:sections\n\n      - name: Run Cypress tests\n        run: |\n          npm run test:cypress:pre\n          npm run test:cypress:startServer &\n          npm run test:cypress:startServer:post\n          npm run test:cypress:run\n\n  build:\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node-version:\n          - '16'\n\n    steps:\n      - uses: actions/checkout@v2\n\n      - name: Use Node.js ${{ matrix.node-version }}\n        uses: actions/setup-node@v2\n        with:\n          node-version: ${{ matrix.node-version }}\n\n      - run: npm ci\n      - run: npm run test:jest -- --runInBand\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Semantic Release\n\non:\n  push:\n    branches:\n      - master\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: '20'\n          cache: npm\n\n      - run: npm ci\n\n      - run: npx semantic-release\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules/\n/examples/**/styleguide/build\n/examples/**/styleguide/index.html\n/.publish/\n/lib\n/coverage/\nChangelog.md\n.DS_Store\nThumbs.db\n.idea/\n.vscode/\n*.sublime-project\n*.sublime-workspace\n*.log\n.eslintcache\nyarn.lock\n/cypress/\ntest/cypress/screenshots/\ntest/cypress/videos/\nstats.json\n/site/build/\n/site/.docusaurus/\n/site/docs/\n"
  },
  {
    "path": ".npmignore",
    "content": "__tests__/\n"
  },
  {
    "path": ".nvmrc",
    "content": "v16\n"
  },
  {
    "path": ".prettierignore",
    "content": "examples/*/styleguide/\nlib/\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"printWidth\": 100,\n  \"singleQuote\": true,\n  \"trailingComma\": \"es5\",\n  \"useTabs\": true,\n  \"proseWrap\": \"never\",\n  \"overrides\": [\n    {\n      \"files\": \"*.md\",\n      \"options\": {\n        \"printWidth\": 70,\n        \"useTabs\": false,\n        \"semi\": false,\n        \"trailingComma\": \"none\",\n        \"arrowParens\": \"avoid\",\n        \"proseWrap\": \"never\"\n      }\n    },\n    {\n      \"files\": \"*.{json,babelrc,eslintrc,remarkrc,prettierrc}\",\n      \"options\": {\n        \"useTabs\": false\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "License.md",
    "content": "# The MIT License\n\nCopyright 2017 Artem Sapegin (http://sapegin.me), contributors\n\nPermission 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:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE 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.\n"
  },
  {
    "path": "Readme.md",
    "content": "<div align=\"center\" markdown=\"1\">\n\n<img src=\"https://d3vv6lp55qjaqc.cloudfront.net/items/061f0A2n1B0H3p0T1p1f/react-styleguidist-logo.png\" alt=\"React Styleguidist\" width=\"400\">\n\n**Isolated React component development environment with a living style guide**\n\n [![npm](https://img.shields.io/npm/v/react-styleguidist.svg)](https://www.npmjs.com/package/react-styleguidist) [![CI status](https://github.com/styleguidist/react-styleguidist/workflows/CI/badge.svg)](https://github.com/styleguidist/react-styleguidist.git/actions) [![Codecov](https://codecov.io/gh/styleguidist/react-styleguidist/branch/master/graph/badge.svg)](https://codecov.io/gh/styleguidist/react-styleguidist) [![Join the chat at https://gitter.im/styleguidist/styleguidist](https://badges.gitter.im/styleguidist/styleguidist.svg)](https://gitter.im/styleguidist/styleguidist?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n<a href=\"https://discord.gg/QWsybqJDTA\">![Discord](https://img.shields.io/discord/842832186914635806?logo=discord)</a> [![Open Source Helpers](https://www.codetriage.com/styleguidist/react-styleguidist/badges/users.svg)](https://www.codetriage.com/styleguidist/react-styleguidist)\n\n</div>\n\nReact Styleguidist is a component development environment with hot reloaded dev server and a living style guide that you can share with your team. It lists component `propTypes` and shows live, editable usage examples based on Markdown files. Check out [**the demo style guide**](https://react-styleguidist.js.org/examples/basic/).\n\n![React Styleguidist in action](https://user-images.githubusercontent.com/1703219/74945569-51c6ad00-543b-11ea-8351-f4d86860893a.gif)\n\n[![Washing your code. A book on clean code for frontend developers](https://sapegin.me/images/washing-code-github.jpg)](https://sapegin.me/book/)\n\n## Usage\n\n- **[Getting Started](https://react-styleguidist.js.org/docs/getting-started): install and run Styleguidist**\n- [Documenting components](https://react-styleguidist.js.org/docs/documenting): how to write documentation\n- [Locating components](https://react-styleguidist.js.org/docs/components): point Styleguidist to your React components\n- [Configuring webpack](https://react-styleguidist.js.org/docs/webpack): tell Styleguidist how to load your code\n- [Cookbook](https://react-styleguidist.js.org/docs/cookbook): how to solve common tasks with Styleguidist\n\n## Advanced documentation\n\n- [Configuration](https://react-styleguidist.js.org/docs/configuration)\n- [CLI commands and options](https://react-styleguidist.js.org/docs/cli)\n- [Node.js API](https://react-styleguidist.js.org/docs/api)\n\n## Examples\n\n- [Basic style guide](https://react-styleguidist.js.org/examples/basic/), [source](./examples/basic)\n- Style guide with sections, [source](./examples/sections)\n- Style guide with customized styles, [source](./examples/customised)\n- Style guide with custom express endpoints, [source](./examples/express)\n- Create React App integration, [source](./examples/cra)\n\n## Showcase\n\nReal projects using React Styleguidist:\n\n- [Rumble Charts](https://rumble-charts.github.io/rumble-charts/)\n- [better-react-spinkit](http://better-react-spinkit.benjamintatum.com/)\n- [Semantic UI Components for React](https://hallister.github.io/semantic-react/)\n- [Dialog Components](https://dialogs.github.io/dialog-web-components/)\n- [Bulma Components](https://bokuweb.github.io/re-bulma/)\n- [Yammer Components](https://microsoft.github.io/YamUI/)\n- [More projects…](https://github.com/styleguidist/react-styleguidist/issues/127)\n\n## Integration with other tools\n\n- Create React App — supported out of the box, see the [Getting Started](https://react-styleguidist.js.org/docs/getting-started) guide\n- Vue, see [Vue Styleguidist](https://github.com/vue-styleguidist/vue-styleguidist)\n\n## Third-party tools\n\n- [snapguidist](https://github.com/styleguidist/snapguidist): snapshot testing for React Styleguidist\n- [react-styleguidist-visual](https://github.com/unindented/react-styleguidist-visual): automated visual testing for React Styleguidist, using Puppeteer and pixelmatch\n- [styleguidist-scrapper](https://github.com/livechat/styleguidist-scrapper): scrapper script for documentation generated by React Styleguidist\n\n## Resources\n\n- [The Dream of Styleguide Driven Development](https://www.youtube.com/watch?v=JjXnmhNW8Cs) talk by [Sara Vieira](https://github.com/saravieira)\n- [Building React Components Library](https://skillsmatter.com/skillscasts/8140-building-react-components-library) talk by [Robert Haritonov](https://github.com/operatino)\n- [Say Cheese: Snapshots and Visual Testing](https://developers.livechatinc.com/blog/snapshots-visual-testing/)\n- [Interview with Artem Sapegin](https://survivejs.com/blog/styleguidist-interview/) about React Styleguidist.\n\n## Change log\n\nThe change log can be found on the [Releases page](https://github.com/styleguidist/react-styleguidist/releases).\n\n## Contributing\n\nEveryone is welcome to contribute. Please take a moment to read the [contributing guidelines](.github/Contributing.md) and the [developer guide](https://react-styleguidist.js.org/docs/development).\n\n## Sponsoring\n\n[Become a sponsor](https://opencollective.com/styleguidist#sponsor) and get your logo on our Readme on GitHub with a link to your site.\n\n<!-- prettier-ignore -->\n<a href=\"https://opencollective.com/styleguidist/sponsor/0/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/1/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/2/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/3/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/4/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/5/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/6/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/7/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/8/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/9/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/9/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/10/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/10/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/11/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/11/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/12/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/12/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/13/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/13/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/14/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/14/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/15/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/15/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/16/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/16/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/17/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/17/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/18/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/18/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/19/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/19/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/20/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/20/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/21/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/21/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/22/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/22/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/23/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/23/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/24/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/24/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/25/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/25/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/26/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/26/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/27/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/27/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/28/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/28/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/sponsor/29/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/sponsor/29/avatar.svg\"></a>\n\n[Become a backer](https://opencollective.com/styleguidist#backer) get your image on our Readme on GitHub with a link to your site.\n\n<!-- prettier-ignore -->\n<a href=\"https://opencollective.com/styleguidist/backer/0/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/1/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/2/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/3/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/4/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/5/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/6/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/7/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/8/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/9/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/9/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/10/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/10/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/11/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/11/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/12/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/12/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/13/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/13/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/14/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/14/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/15/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/15/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/16/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/16/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/17/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/17/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/18/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/18/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/19/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/19/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/20/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/20/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/21/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/21/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/22/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/22/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/23/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/23/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/24/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/24/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/25/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/25/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/26/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/26/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/27/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/27/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/28/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/28/avatar.svg\"></a>\n<a href=\"https://opencollective.com/styleguidist/backer/29/website\" target=\"_blank\"><img src=\"https://opencollective.com/styleguidist/backer/29/avatar.svg\"></a>\n\n<a href=\"https://www.buymeacoffee.com/sapegin\" target=\"_blank\"><img src=\"https://cdn.buymeacoffee.com/buttons/lato-orange.png\" alt=\"Buy Me A Coffee\" style=\"height: 51px !important;width: 217px !important;\" ></a>\n\n## Authors and license\n\n[Artem Sapegin](http://sapegin.me) and [contributors](https://github.com/styleguidist/react-styleguidist/graphs/contributors).\n\nLogo by [Sara Vieira](https://github.com/SaraVieira) and [Andrey Okonetchnikov](https://github.com/okonet).\n\nMIT License, see the included [License.md](License.md) file.\n"
  },
  {
    "path": "babel.config.js",
    "content": "module.exports = {\n\tpresets: [\n\t\t[\n\t\t\t'@babel/env',\n\t\t\t{\n\t\t\t\tloose: true,\n\t\t\t\tmodules: false,\n\t\t\t\tuseBuiltIns: 'usage',\n\t\t\t\tcorejs: 3,\n\t\t\t},\n\t\t],\n\t\t'@babel/typescript',\n\t\t'@babel/react',\n\t],\n\tplugins: ['@babel/plugin-proposal-class-properties'],\n\toverrides: [\n\t\t{\n\t\t\tinclude: ['src/bin', 'src/loaders', 'src/scripts', 'src/share', 'src/typings'],\n\t\t\texclude: ['src/loaders/utils/client'],\n\t\t\tpresets: [\n\t\t\t\t[\n\t\t\t\t\t'@babel/env',\n\t\t\t\t\t{\n\t\t\t\t\t\tloose: true,\n\t\t\t\t\t\tmodules: 'commonjs',\n\t\t\t\t\t\tuseBuiltIns: 'usage',\n\t\t\t\t\t\tcorejs: 3,\n\t\t\t\t\t\ttargets: {\n\t\t\t\t\t\t\tnode: '10',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t],\n\t\t},\n\t],\n\tenv: {\n\t\ttest: {\n\t\t\tpresets: [\n\t\t\t\t[\n\t\t\t\t\t'@babel/env',\n\t\t\t\t\t{\n\t\t\t\t\t\tloose: true,\n\t\t\t\t\t\tmodules: 'commonjs',\n\t\t\t\t\t\tuseBuiltIns: 'usage',\n\t\t\t\t\t\tcorejs: 3,\n\t\t\t\t\t\ttargets: {\n\t\t\t\t\t\t\tnode: 'current',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t'@babel/react',\n\t\t\t\t'@babel/flow',\n\t\t\t],\n\t\t\tplugins: ['@babel/plugin-proposal-class-properties'],\n\t\t},\n\t},\n};\n"
  },
  {
    "path": "cypress.json",
    "content": "{\n  \"baseUrl\": \"http://localhost:8082\",\n  \"fixturesFolder\": \"test/cypress/fixtures\",\n  \"integrationFolder\": \"test/cypress/integration\",\n  \"pluginsFile\": \"test/cypress/plugins/index.js\",\n  \"screenshotsFolder\": \"test/cypress/screenshots\",\n  \"videosFolder\": \"test/cypress/videos\",\n  \"supportFile\": \"test/cypress/support/index.js\",\n  \"video\": false,\n  \"chromeWebSecurity\": false\n}\n"
  },
  {
    "path": "dangerfile.ts",
    "content": "import { danger, warn } from 'danger';\n\nconst packageChanged = danger.git.modified_files.includes('package.json');\nconst lockfileChanged = danger.git.modified_files.includes('package-lock.json');\n\nif (packageChanged && !lockfileChanged) {\n\twarn(`Changes were made to \\`package.json\\`, but not to \\`package-lock.json\\`.\n\nIf you’ve changed any dependencies (added, removed or updated any packages), please run \\`npm install\\` and commit changes in package-lock.json file. Make sure you’re using npm 5+.`);\n}\n\nif (!packageChanged && lockfileChanged) {\n\twarn(`Changes were made to \\`package-lock.json\\`, but not to \\`package.json\\`.\n\nPlease remove \\`package-lock.json\\` changes from your pull request. Try to run \\`git checkout master -- package-lock.json\\` and commit changes.`);\n}\n"
  },
  {
    "path": "docs/API.md",
    "content": "<!-- Node.js API #api -->\n\n# Node.js API\n\n## Initialization\n\nFirst, you need to initialize the API for your style guide config.\n\nUsing a JavaScript object:\n\n```javascript\nimport styleguidist from 'react-styleguidist'\nconst styleguide = styleguidist({\n  logger: {\n    warn: console.warn,\n    info: console.log,\n    debug: console.log\n  },\n  components: './lib/components/**/*.js',\n  webpackConfig: {\n    module: {\n      rules: [\n        {\n          test: /\\.jsx?$/,\n          exclude: /node_modules/,\n          loader: 'babel-loader'\n        },\n        {\n          test: /\\.css$/,\n          use: [\n            'style-loader',\n            {\n              loader: 'css-loader',\n              options: {\n                modules: true\n              }\n            }\n          ]\n        }\n      ]\n    }\n  }\n})\n```\n\n> **Info:** Any output is disabled by default, you may need to define your own [logger](Configuration.md#logger).\n\nUsing a config file:\n\n```javascript\nimport styleguidist from 'react-styleguidist'\nconst styleguide = styleguidist(require('../styleguide.config.js'))\n```\n\nOr auto searching a config file:\n\n```javascript\nimport styleguidist from 'react-styleguidist'\nconst styleguide = styleguidist()\n```\n\nSee all available [config options](Configuration.md).\n\n## Methods\n\n### `build(callback)`\n\n#### Arguments\n\n1.  `callback(err, config, stats)` (_Function_): A callback to be invoked when style guide is built:\n\n    1.  `err` (_Object_): error details.\n    2.  `config` (_Object_): normalized style guide config.\n    3.  `stats` (_Object_): webpack build stats.\n\n#### Returns\n\n(_Compiler_): webpack `Compiler` instance.\n\n#### Example\n\n```javascript\nimport styleguidist from 'react-styleguidist'\nstyleguidist(require('../styleguide.config.js')).build(\n  (err, config) => {\n    if (err) {\n      console.log(err)\n    } else {\n      console.log('Style guide published to', config.styleguideDir)\n    }\n  }\n)\n```\n\n### `server(callback)`\n\n#### Arguments\n\n1.  `callback(err, config)` (_Function_): A callback to be invoked when style guide is built:\n\n    1.  `err` (_Object_): error details.\n    2.  `config` (_Object_): normalized style guide config.\n\n#### Returns\n\n(_Object_): Object containing a webpack `Compiler` instance and the React Styleguidist server\n\n#### Example\n\n```javascript\nimport styleguidist from 'react-styleguidist'\nstyleguidist(require('../styleguide.config.js')).server(\n  (err, config) => {\n    if (err) {\n      console.log(err)\n    } else {\n      const url = `http://${config.serverHost}:${config.serverPort}`\n      console.log(`Listening at ${url}`)\n    }\n  }\n)\n```\n\n### `makeWebpackConfig([env])`\n\n#### Arguments\n\n1.  \\[`env`=`'production'`\\] (_String_): `production` or `development`.\n\n#### Returns\n\n(_Object_): webpack config.\n\n#### Example\n\n```javascript\n// webpack.config.js\nmodule.exports = [\n  {\n    // User webpack config\n  },\n  // note that this is requiring rsg in commonjs mode\n  // it does not need to access .default\n  require('react-styleguidist').makeWebpackConfig()\n]\n```\n"
  },
  {
    "path": "docs/CLI.md",
    "content": "<!-- CLI commands #cli -->\n\n# CLI commands and options\n\n## Commands\n\n- `styleguidist server`: Run dev server.\n- `styleguidist build`: Generate a static HTML style guide.\n\n## Options\n\n| Option            | Description                                   |\n| ----------------- | --------------------------------------------- |\n| `--config <file>` | Specify path to a config file                 |\n| `--port <port>`   | Specify port to run the development server on |\n| `--open`          | Open Styleguidist in the default browser      |\n| `--verbose`       | Print debug information                       |\n\n## Usage\n\nAdd these commands into your `package.json`’s `scripts` section:\n\n```json\n{\n  \"scripts\": {\n    \"styleguide\": \"styleguidist server\",\n    \"styleguide:build\": \"styleguidist build\"\n  }\n}\n```\n\nOr run them directly from your terminal:\n\n```bash\nnpx styleguidist server\nnpx styleguidist build\n```\n\n> **Tip:** [npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) is a part of npm and will run locally-installed `styleguidist` package.\n"
  },
  {
    "path": "docs/Components.md",
    "content": "<!-- Locating components #components -->\n\n# Locating your components and organizing your style guide\n\n## Finding components\n\nBy default Styleguidist will search components using this [glob pattern](https://github.com/isaacs/node-glob#glob-primer): `src/components/**/*.{js,jsx,ts,tsx}`.\n\nIt will pick up files like:\n\n- `src/components/Button.js`,\n- `src/components/Button/Button.js`,\n- `src/components/Button/index.js`.\n\nBut will ignore tests:\n\n- `__tests__` folder,\n- files containing `.test.js` or `.spec.js` (or same for `.jsx`, `.ts` and `.tsx`).\n\nIf it doesn’t work for you, create a `styleguide.config.js` file in your project’s root folder and configure the patterns to fit your project structure.\n\nFor example, if your component files look like `components/Button/Button.js`, but you reexport them in `components/Button/index.js` (like `export { default } from './Button'`) to simplify imports (`components/Button` instead of `components/Button/Button`), you need to skip `index.js`:\n\n```javascript\nmodule.exports = {\n  components: 'src/components/**/[A-Z]*.js'\n}\n```\n\n> **Info:** All paths are relative to the config folder.\n\n> **Tip:** Use [ignore](Configuration.md#ignore) option to exclude some files from the style guide.\n\n> **Tip:** Use [getComponentPathLine](Configuration.md#getcomponentpathline) option to change the path you see below a component name.\n\n## Loading and exposing components\n\nStyleguidist _loads_ your components and _exposes_ them globally for your examples to consume.\n\n### Identifier\n\nIt will try to use the `displayName` of your component as the identifier. If it cannot understand a `displayName` (for example if it is dynamically generated), it will fall back to something it can understand.\n\nIn each of the following cases, the global identifier will be `Component`.\n\n| Path | Code | Styleguidist understands |\n| --- | --- | --- |\n| /whatever.js | `export default function Component() { ... }` | displayName |\n| /whatever.js | `export default function SomeName() { ... }`<br>`SomeName.displayName = 'Component';` | displayName |\n| /whatever.js | `export default function Component() { ... }`<br>`Component.displayName = dynamicNamer();` | displayName at declaration |\n| /component.js | `const name = 'SomeName';`<br>`const componentMap = {`<br>`[name]: function() { ... }`<br>`};`<br>`export default componentMap[name];` | Filename |\n| /component/index.js | `const name = 'SomeName';`<br>`const componentMap = {`<br>`[name]: function() { ... }`<br>`};`<br>`export default componentMap[name];` | Folder name |\n\n### Default vs named exports\n\nStylegudist will use an ECMAScript module’s `default` export or CommonJS `module.exports` if they are defined.\n\n```javascript\n// /component.js\nexport default function Component() { ... }\n// will be exposed globally as Component\n\n// /component.js\nfunction Component() { ... }\nmodule.exports = Component;\n// will be exposed globally as Component\n```\n\nIf you use only named exports, Styleguidist will expose named exports from modules as follows...\n\nIf there is only one named export, it will expose that.\n\n```javascript\n// /component.js\nexport function Component() { ... }\n// will be exposed globally as Component\n```\n\nIf there are several named exports, it will expose the named export which has the same name as the understood identifier.\n\n```javascript\n// /component.js\nexport function someUtil() { ... }\n// will not be exposed\n\nexport function Component() { ... }\n// will be exposed globally as Component\n```\n\n> **Caution:** If you export several React components as named exports from a single module, Styleguidist is likely to behave unreliably. If it cannot understand which named export to expose, you may not be able to access that export.\n\n## Sections\n\nGroup components into sections or add extra Markdown documents to your style guide.\n\nEach section consists of (all fields are optional):\n\n- `name` — section title.\n- `content` — location of a Markdown file containing the overview content.\n- `components` — a glob pattern string, an array of component paths or glob pattern strings, or a function returning a list of components or glob pattern strings. The same rules apply as for the root `components` option.\n- `sections` — array of subsections (can be nested).\n- `description` — A small description of this section.\n- `sectionDepth` — Number of subsections with single pages, only available with [pagePerSection](Configuration.md#pagepersection) is enabled.\n- `exampleMode` — Initial state of the code example tab, uses [exampleMode](Configuration.md#examplemode).\n- `usageMode` — Initial state of the props and methods tab, uses [usageMode](Configuration.md#usagemode).\n- `ignore` — string/array of globs that should not be included in the section.\n- `href` - an URL to navigate to instead of navigating to the section content\n- `external` - if set, the link will open in a new window\n- `expand` - Determines if the section should be expanded by default even when `tocMode` is set to `collapse` in general settings\n\nConfiguring a style guide with textual documentation section and a list of components would look like:\n\n```javascript\n// styleguide.config.js\n\nmodule.exports = {\n  sections: [\n    {\n      name: 'Introduction',\n      content: 'docs/introduction.md'\n    },\n    {\n      name: 'Documentation',\n      sections: [\n        {\n          name: 'Installation',\n          content: 'docs/installation.md',\n          description: 'The description for the installation section'\n        },\n        {\n          name: 'Configuration',\n          content: 'docs/configuration.md'\n        },\n        {\n          name: 'Live Demo',\n          external: true,\n          href: 'http://example.com'\n        }\n      ]\n    },\n    {\n      name: 'UI Components',\n      content: 'docs/ui.md',\n      components: 'lib/components/ui/*.js',\n      exampleMode: 'expand', // 'hide' | 'collapse' | 'expand'\n      usageMode: 'expand' // 'hide' | 'collapse' | 'expand'\n    }\n  ]\n}\n```\n\n## Limitations\n\nIn some cases Styleguidist may not understand your components, [see possible solutions](Thirdparties.md).\n"
  },
  {
    "path": "docs/Configuration.md",
    "content": "# Configuration\n\nBy default, Styleguidist will look for `styleguide.config.js` file in your project’s root folder. You can change the location of the config file using `--config` [CLI](CLI.md) option.\n\n## `assetsDir`\n\nType: `String` or `Array`, optional\n\nYour application static assets folder will be accessible as `/` in the style guide dev server.\n\n## `compilerConfig`\n\nType: `Object`, default:\n\n```javascript\n{\n  // Don't include an Object.assign ponyfill, we have our own\n  objectAssign: 'Object.assign',\n  // Transpile only features needed for IE11\n  target: { ie: 11 },\n  transforms: {\n    // Don't throw on ESM imports, we transpile them ourselves\n    modules: false,\n    // Enable tagged template literals for styled-components\n    dangerousTaggedTemplateString: true,\n    // to make async/await work by default (no transformation)\n    asyncAwait: false,\n  },\n}\n```\n\nStyleguidist uses [Bublé](https://buble.surge.sh/guide/) to run ES6 code on the frontend. This config object will be added as the second argument for `buble.transform`.\n\n## `components`\n\nType: `String`, `Function` or `Array`, default: `src/components/**/*.{js,jsx,ts,tsx}`\n\n- when `String`: a [glob pattern](https://github.com/isaacs/node-glob#glob-primer) that matches all your component modules.\n- when `Function`: a function that returns an array of module paths.\n- when `Array`: an array of module paths.\n\nAll paths are relative to config folder.\n\nSee examples in the [Components section](Components.md).\n\n## `context`\n\nType: `Object`, optional\n\nModules that will be available for examples. You can use it for utility functions like Lodash or for data fixtures.\n\n```javascript\nmodule.exports = {\n  context: {\n    map: 'lodash/map',\n    users: path.resolve(__dirname, 'fixtures/users')\n  }\n}\n```\n\nThen you can use them in any example:\n\n```jsx\n<Message>{map(users, 'name').join(', ')}</Message>\n```\n\n## `contextDependencies`\n\nType: `String[]`, optional\n\nArray of absolute paths that allow you to specify absolute paths of directories to watch for additions or removals of components.\n\nBy default Styleguidist uses common parent directory of your components.\n\n```javascript\nmodule.exports = {\n  contextDependencies: [path.resolve(__dirname, 'lib/components')]\n}\n```\n\n## `configureServer`\n\nType: `Function`, optional\n\nFunction that allows you to add endpoints to the underlying Express server:\n\n```javascript\nmodule.exports = {\n  configureServer(app) {\n    // `app` is the instance of the express server running Styleguidist\n    app.get('/custom-endpoint', (req, res) => {\n      res.status(200).send({ response: 'Server invoked' })\n    })\n  }\n}\n```\n\nYour components will be able to invoke the URL `http://localhost:6060/custom-endpoint` from their examples.\n\n## `dangerouslyUpdateWebpackConfig`\n\nType: `Function`, optional\n\n> **Danger:** You may break Styleguidist by using this option, try to use [webpackConfig](#webpackconfig) option instead.\n\nAllows you to modify webpack config without any restrictions.\n\n```javascript\nmodule.exports = {\n  dangerouslyUpdateWebpackConfig(webpackConfig, env) {\n    // WARNING: inspect Styleguidist Webpack config before modifying it, otherwise you may break Styleguidist\n    console.log(webpackConfig)\n    webpackConfig.externals = {\n      jquery: 'jQuery'\n    }\n    return webpackConfig\n  }\n}\n```\n\n## `defaultExample`\n\nType: `Boolean` or `String`, default: `false`\n\nFor components that do not have an example, a default one can be used. When set to `true`, the [DefaultExample.md](https://raw.githubusercontent.com/styleguidist/react-styleguidist/master/templates/DefaultExample.md) is used, or you can provide the path to your own example Markdown file.\n\nWhen writing your own default example file, `__COMPONENT__` will be replaced by the actual component name at compile time.\n\n## `exampleMode`\n\nType: `String`, default: `collapse`\n\nDefines the initial state of the example code tab:\n\n- `collapse`: collapses the tab by default.\n- `hide`: hide the tab and it can´t be toggled in the UI.\n- `expand`: expand the tab by default.\n\n## `getComponentPathLine`\n\nType: `Function`, default: component filename\n\nFunction that returns a component path line (displayed under the component name).\n\nFor example, instead of `components/Button/Button.js` you can print `import Button from 'components/Button';`:\n\n```javascript\nconst path = require('path')\nmodule.exports = {\n  getComponentPathLine(componentPath) {\n    const name = path.basename(componentPath, '.js')\n    const dir = path.dirname(componentPath)\n    return `import ${name} from '${dir}';`\n  }\n}\n```\n\n## `getExampleFilename`\n\nType: `Function`, default: finds `Readme.md` or `ComponentName.md` in the component folder\n\nFunction that returns examples file path for a given component path.\n\nFor example, instead of `Readme.md` you can use `ComponentName.examples.md`:\n\n```javascript\nmodule.exports = {\n  getExampleFilename(componentPath) {\n    return componentPath.replace(/\\.jsx?$/, '.examples.md')\n  }\n}\n```\n\n## `handlers`\n\nType: `Function`, optional, default: [[react-docgen-displayname-handler](https://github.com/nerdlabs/react-docgen-displayname-handler)]\n\nFunction that returns functions used to process the discovered components and generate documentation objects. Default behaviors include discovering component documentation blocks, prop types, and defaults. If setting this property, it is best to build from the default [react-docgen](https://github.com/reactjs/react-docgen) handler list, such as in the example below. See the [react-docgen handler documentation](https://github.com/reactjs/react-docgen#handlers) for more information about handlers.\n\n> **Note:** `react-docgen-displayname-handler` should be included.\n\n```javascript\nmodule.exports = {\n  handlers: componentPath =>\n    require('react-docgen').defaultHandlers.concat(\n      (documentation, path) => {\n        // Calculate a display name for components based upon the declared class name.\n        if (\n          path.value.type === 'ClassDeclaration' &&\n          path.value.id.type === 'Identifier'\n        ) {\n          documentation.set('displayName', path.value.id.name)\n\n          // Calculate the key required to find the component in the module exports\n          if (\n            path.parentPath.value.type === 'ExportNamedDeclaration'\n          ) {\n            documentation.set('path', path.value.id.name)\n          }\n        }\n\n        // The component is the default export\n        if (\n          path.parentPath.value.type === 'ExportDefaultDeclaration'\n        ) {\n          documentation.set('path', 'default')\n        }\n      },\n\n      require('react-docgen-displayname-handler').createDisplayNameHandler(\n        componentPath\n      )\n    )\n}\n```\n\n## `ignore`\n\nType: `String[]`, default: `['**/__tests__/**', '**/*.test.{js,jsx,ts,tsx}', '**/*.spec.{js,jsx,ts,tsx}', '**/*.d.ts']`\n\nArray of [glob pattern](https://github.com/isaacs/node-glob#glob-primer) that should not be included in the style guide.\n\n> **Caution:** You should pass glob patterns, for example, use `**/components/Button.js` instead of `components/Button.js`.\n\n## `logger`\n\nType: `Object`, by default will use `console.*` in CLI or nothing in Node.js API\n\nCustom logger functions:\n\n```javascript\nmodule.exports = {\n  logger: {\n    // One of: info, debug, warn\n    // Suppress messages\n    info: () => {},\n    // Override display function\n    warn: message => console.warn(`NOOOOOO: ${message}`)\n  }\n}\n```\n\n## `minimize`\n\nType: `Boolean`, default: `true`\n\nIf `false`, the production build will not be minimized.\n\n## `moduleAliases`\n\nType: `object`, optional\n\nDefine aliases for modules, that you can import in your examples, to make example code more realistic and copypastable:\n\n```javascript\nconst path = require('path')\nmodule.exports = {\n  moduleAliases: {\n    'rsg-example': path.resolve(__dirname, 'src')\n  }\n}\n```\n\n````jsx\n// ```jsx inside Markdown\nimport React from 'react'\nimport Button from 'rsg-example/components/Button'\nimport Placeholder from 'rsg-example/components/Placeholder'\n````\n\nCheck out the [webpack resolve.alias documentation](https://webpack.js.org/configuration/resolve/#resolve-alias) for available syntax.\n\n## `mountPointId`\n\nType: `string`, default: `rsg-root`\n\nThe ID of a DOM element where Styleguidist mounts.\n\n## `pagePerSection`\n\nType: `Boolean`, default: `false`\n\nRender one section or component per page.\n\nIf `true`, each section will be a single page.\n\nThe value may depend on a current environment:\n\n```javascript\nmodule.exports = {\n  pagePerSection: process.env.NODE_ENV !== 'production'\n}\n```\n\nTo isolate section’s children as single pages (subroutes), add `sectionDepth` into each section with the number of subroutes (depth) to render as single pages.\n\nFor example:\n\n```javascript\nmodule.exports = {\n  pagePerSection: true,\n  sections: [\n    {\n      name: 'Documentation',\n      sections: [\n        {\n          name: 'Files',\n          sections: [\n            {\n              name: 'First File'\n            },\n            {\n              name: 'Second File'\n            }\n          ]\n        }\n      ],\n      // Will show \"Documentation\" and \"Files\" as single pages, filtering its children\n      sectionDepth: 2\n    },\n    {\n      name: 'Components',\n      sections: [\n        {\n          name: 'Buttons',\n          sections: [\n            {\n              name: 'WrapperButton'\n            }\n          ]\n        }\n      ],\n      // Will show \"Components\" as single page, filtering its children\n      sectionDepth: 1\n    },\n    {\n      name: 'Examples',\n      sections: [\n        {\n          name: 'Case 1',\n          sections: [\n            {\n              name: 'Buttons'\n            }\n          ]\n        }\n      ],\n      // There is no subroutes, \"Examples\" will show all its children on a page\n      sectionDepth: 0\n    }\n  ]\n}\n```\n\n## `printBuildInstructions`\n\nType: `Function`, optional\n\nFunction that allows you to override the printing of build messages to console.log.\n\n```javascript\nmodule.exports = {\n  printBuildInstructions(config) {\n    console.log(\n      `Style guide published to ${config.styleguideDir}. Something else interesting.`\n    )\n  }\n}\n```\n\n## `printServerInstructions`\n\nType: `Function`, optional\n\nFunction that allows you to override the printing of local dev server messages to console.log.\n\n```javascript\nmodule.exports = {\n  serverHost: 'your-domain',\n  printServerInstructions(config, { isHttps }) {\n    console.log(`Local style guide: http://${config.serverHost}`)\n  }\n}\n```\n\n## `previewDelay`\n\nType: `Number`, default: 500\n\nDebounce time in milliseconds used before rendering the changes from the editor. While typing code the preview will not be updated.\n\n## `propsParser`\n\nType: `Function`, optional\n\nFunction that allows you to override the mechanism used to parse props from a source file. The default mechanism is using [react-docgen](https://github.com/reactjs/react-docgen) to parse props.\n\n```javascript\nmodule.exports = {\n  propsParser(filePath, source, resolver, handlers) {\n    return require('react-docgen').parse(source, resolver, handlers)\n  }\n}\n```\n\n## `require`\n\nType: `String[]`, optional\n\nModules that are required for your style guide. Useful for third-party styles or polyfills.\n\n```javascript\nmodule.exports = {\n  require: [\n    'babel-polyfill',\n    path.join(__dirname, 'styleguide/styles.css')\n  ]\n}\n```\n\n> **Note:** This will add a separate webpack entry for each array item.\n\nDon’t forget to add webpack loaders for each file you add here. For example, to require a CSS file you’ll need:\n\n```javascript\nmodule.exports = {\n  webpackConfig: {\n    module: {\n      rules: [\n        {\n          test: /\\.css$/,\n          use: ['style-loader', 'css-loader']\n        }\n      ]\n    }\n  }\n}\n```\n\nSee [Configuring webpack](Webpack.md) for mode details.\n\n## `resolver`\n\nType: `Function`, optional\n\nFunction that allows you to override the mechanism used to identify classes/components to analyze. Default behavior is to find all exported components in each file. You can configure it to find all components or use a custom detection method. See the [react-docgen resolver documentation](https://github.com/reactjs/react-docgen#resolver) for more information about resolvers.\n\n```javascript\nmodule.exports = {\n  resolver: require('react-docgen').resolver\n    .findAllComponentDefinitions\n}\n```\n\n## `ribbon`\n\nType: `Object`, optional\n\nShow “Fork Me” ribbon in the top right corner.\n\n```javascript\nmodule.exports = {\n  ribbon: {\n    // Link to open on the ribbon click (required)\n    url: 'http://example.com/',\n    // Text to show on the ribbon (optional)\n    text: 'Fork me on GitHub'\n  }\n}\n```\n\nUse the [theme](#theme) config option to change ribbon style.\n\n## `sections`\n\nType: `Array`, optional\n\nAllows components to be grouped into sections with a title and overview content. Sections can also be content only, with no associated components (for example, a textual introduction). Sections can be nested.\n\nSee examples of [sections configuration](Components.md#sections).\n\n## `serverHost`\n\nType: `String`, default: `0.0.0.0`\n\nDev server hostname.\n\n## `serverPort`\n\nType: `Number`, default: `process.env.NODE_PORT` or `6060`\n\nDev server port. Can also be set via command line `--port=6060`.\n\n## `showSidebar`\n\nType: `Boolean`, default: `true`\n\nToggle sidebar visibility. The sidebar will be hidden when opening components or examples in isolation mode even if this value is set to `true`. When set to `false`, the sidebar will always be hidden.\n\n## `skipComponentsWithoutExample`\n\nType: `Boolean`, default: `false`\n\nIgnore components that don’t have an example file (as determined by [getExampleFilename](#getexamplefilename)). These components won’t be accessible from other examples unless you [manually `require` them](Cookbook.md#how-to-hide-some-components-in-style-guide-but-make-them-available-in-examples).\n\n## `sortProps`\n\nType: `Function`, optional\n\nFunction that sorts component props. By default props are sorted such that required props come first, optional props come second. Props in both groups are sorted by their property names.\n\nTo disable sorting, use the identity function:\n\n```javascript\nmodule.exports = {\n  sortProps: props => props\n}\n```\n\n## `styleguideComponents`\n\nType: `Object`, optional\n\nOverride React components used to render the style guide:\n\n```javascript\nmodule.exports = {\n  styleguideComponents: {\n    Wrapper: path.join(__dirname, 'styleguide/components/Wrapper'),\n    StyleGuideRenderer: path.join(\n      __dirname,\n      'styleguide/components/StyleGuide'\n    )\n  }\n}\n```\n\nSee an example of [customized style guide](https://github.com/styleguidist/react-styleguidist/tree/master/examples/customised).\n\nTo wrap, rather than replace a component, make sure to import the default implementation using the full path to `react-styleguidist`. See an example of [wrapping a Styleguidist component](https://github.com/styleguidist/react-styleguidist/blob/master/examples/customised/styleguide/components/SectionsRenderer.js).\n\n**Note**: these components are not guaranteed to be safe from breaking changes in React Styleguidist updates.\n\n## `styleguideDir`\n\nType: `String`, default: `styleguide`\n\nFolder for static HTML style guide generated with `styleguidist build` command.\n\n## `styles`\n\nType: `Object`, `String` or `Function`, optional\n\nCustomize styles of any Styleguidist’s component using an object, a function returning said object or a file path to a file exporting said styles.\n\nSee examples in the [cookbook](Cookbook.md#how-to-change-styles-of-a-style-guide).\n\n> **Tip:** Using a function allows access to theme variables like in the example below. See available [theme variables](https://github.com/styleguidist/react-styleguidist/blob/master/src/client/styles/theme.ts). The returned object folows the same format as when configured as a litteral.\n\n```javascript\nmodule.exports = {\n  styles: function (theme) {\n    return {\n      Logo: {\n        logo: {\n          // we can now change the color used in the logo item to use the theme's `link` color\n          color: theme.color.link\n        }\n      }\n    }\n  }\n}\n```\n\n**Note:** If using a file path, it has to be absolute or relative to the config file.\n\n## `template`\n\nType: `Object` or `Function`, optional.\n\nChange HTML for the style guide app.\n\nAn object with options to add a favicon, meta tags, inline JavaScript or CSS, etc. See [@vxna/mini-html-webpack-template docs](https://www.npmjs.com/package/@vxna/mini-html-webpack-template).\n\n```javascript\nmodule.exports = {\n  template: {\n    favicon: 'https://assets-cdn.github.com/favicon.ico'\n  }\n}\n```\n\nA function that returns an HTML string, see [mini-html-webpack-plugin docs](https://github.com/styleguidist/mini-html-webpack-plugin#custom-templates).\n\n## `theme`\n\nType: `Object` or `String`, optional\n\nCustomize style guide UI fonts, colors, etc. using a theme object or the path to a file exporting such object.\n\nThe path is relative to the config file or absolute.\n\nSee examples in the [cookbook](Cookbook.md#how-to-change-styles-of-a-style-guide).\n\n> **Info:** See available [theme variables](https://github.com/styleguidist/react-styleguidist/blob/master/src/client/styles/theme.ts).\n\n> **Info:** Styles use [JSS](https://github.com/cssinjs/jss/blob/master/docs/jss-syntax.md) with these plugins: [jss-plugin-isolate](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-isolate), [jss-plugin-nested](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-nested), [jss-plugin-camel-case](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-camel-case), [jss-plugin-default-unit](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-default-unit), [jss-plugin-compose](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-compose) and [jss-plugin-global](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-global).\n\n> **Tip:** Use [React Developer Tools](https://github.com/facebook/react) to find component and style names. For example a component `<LogoRenderer><h1 className=\"rsg--logo-53\">` corresponds to an example above.\n\n## `title`\n\nType: `String`, default: `<app name from package.json> Style Guide`\n\nStyle guide title.\n\n## `tocMode`\n\nType: `String` default: `expand`\n\nDefines if the table of contents sections will behave like an accordion:\n\n- `collapse`: All sections are collapsed by default\n- `expand`: Sections cannot be collapsed in the Table Of Contents\n\nCollapse the sections created in the sidebar to reduce the height of the sidebar. This can be useful in large codebases with lots of components to avoid having to scroll too far.\n\n## `updateDocs`\n\nType: `Function`, optional\n\nFunction that modifies props, methods, and metadata after parsing a source file. For example, load a component version from a JSON file:\n\n```javascript\nmodule.exports = {\n  updateDocs(docs, file) {\n    if (docs.doclets.version) {\n      const versionFilePath = path.resolve(\n        path.dirname(file),\n        docs.doclets.version\n      )\n      const version = require(versionFilePath).version\n\n      docs.doclets.version = version\n      docs.tags.version[0].description = version\n    }\n\n    return docs\n  }\n}\n```\n\nWith this component JSDoc comment block:\n\n```javascript\n/**\n * Component is described here.\n *\n * @version ./package.json\n */\nexport default class Button extends React.Component {\n  // ...\n}\nexport default\n```\n\n## `updateExample`\n\nType: `Function`, optional\n\nFunction that modifies code example (Markdown fenced code block). For example, you can use it to load examples from files:\n\n```javascript\nmodule.exports = {\n  updateExample(props, exampleFilePath) {\n    const { settings, lang } = props\n    if (typeof settings.file === 'string') {\n      const filepath = path.resolve(\n        path.dirname(exampleFilePath),\n        settings.file\n      )\n      const { file, ...restSettings } = settings\n      return {\n        content: fs.readFileSync(filepath, 'utf8'),\n        settings: restSettings,\n        lang\n      }\n    }\n    return props\n  }\n}\n```\n\nUse it like this in your Markdown files:\n\n    ```js { \"file\": \"./some/file.js\" }\n    ```\n\nYou can also use this function to dynamically update some of your fenced code blocks that you do not want to be interpreted as React components by using the [static modifier](Documenting.md#usage-examples-and-readme-files).\n\n```javascript\nmodule.exports = {\n  updateExample(props) {\n    const { settings, lang } = props\n    if (lang === 'javascript' || lang === 'js' || lang === 'jsx') {\n      settings.static = true\n    }\n    return props\n  }\n}\n```\n\n## `usageMode`\n\nType: `String`, default: `collapse`\n\nDefines the initial state of the props and methods tab:\n\n- `collapse`: collapses the tab by default.\n- `hide`: hide the tab and it can´t be toggled in the UI.\n- `expand`: expand the tab by default.\n\n## `verbose`\n\nType: `Boolean`, default: `false`\n\nPrint debug information. Same as `--verbose` command line switch.\n\n## `version`\n\nType: `String`, optional\n\nStyle guide version, displayed under the title in the sidebar.\n\n## `webpackConfig`\n\nType: `Object` or `Function`, optional\n\nCustom webpack config options: loaders, extensions, plugins, etc. required for your project.\n\nCan be an object:\n\n```javascript\nmodule.exports = {\n  webpackConfig: {\n    module: {\n      resolve: {\n        extensions: ['.es6']\n      },\n      rules: [\n        {\n          test: /\\.scss$/,\n          loaders: [\n            'style-loader',\n            'css-loader',\n            'sass-loader?precision=10'\n          ]\n        }\n      ]\n    }\n  }\n}\n```\n\nOr a function:\n\n```javascript\nmodule.exports = {\n  webpackConfig(env) {\n    if (env === 'development') {\n      return {\n        // custom options\n      }\n    }\n    return {}\n  }\n}\n```\n\n> **Caution:** This option disables config load from `webpack.config.js`, load your config [manually](Webpack.md#reusing-your-projects-webpack-config).\n\n> **Danger:** `entry`, `externals`, `output`, `watch`, and `stats` options will be ignored. For production builds, `devtool` will also be ignored.\n\n> **Danger:** `CommonsChunkPlugins`, `HtmlWebpackPlugin`, `MiniHtmlWebpackPlugin`, `UglifyJsPlugin`, `TerserPlugin`, `HotModuleReplacementPlugin` plugins will be ignored because Styleguidist already includes them or they may break Styleguidist.\n\n> **Tip:** Run style guide in verbose mode to see the actual webpack config used by Styleguidist: `npx styleguidist server --verbose`.\n\nSee [Configuring webpack](Webpack.md) for examples.\n"
  },
  {
    "path": "docs/Cookbook.md",
    "content": "# Cookbook\n\n## How to use `ref`s in examples?\n\nUse `ref` prop as a function and assign a reference to a local variable:\n\n```jsx\nconst [value, setValue] = React.useState('')\nlet textarea\n;<div>\n  <Button onClick={() => textarea.insertAtCursor('Pizza')}>\n    Insert\n  </Button>\n  <Textarea\n    value={value}\n    onChange={e => setValue(e.target.value)}\n    ref={ref => (textarea = ref)}\n  />\n</div>\n```\n\n## How to exclude some components from style guide?\n\nStyleguidist will ignore tests (`__tests__` folder and filenames containing `.test.js` or `.spec.js`) by default.\n\nUse [ignore](Configuration.md#ignore) option to customize this behavior:\n\n```javascript\nmodule.exports = {\n  ignore: ['**/*.spec.js', '**/components/Button.js']\n}\n```\n\n> **Caution:** You should pass glob patterns, for example, use `**/components/Button.js` instead of `components/Button.js`.\n\n## How to hide some components in style guide but make them available in examples?\n\nEnable [skipComponentsWithoutExample](Configuration.md#skipcomponentswithoutexample) option and do not add an example file (`Readme.md` by default) to components you want to ignore.\n\nImport these components in your examples:\n\n````jsx\n// ```jsx inside Markdown\nimport Button from '../common/Button'\n;<Button>Push Me Tender</Button>\n````\n\nOr, to make these components available for all examples:\n\n```jsx\n// styleguide.config.js\nmodule.exports = {\n  require: [path.resolve(__dirname, 'styleguide/setup.js')]\n}\n\n// styleguide/setup.js\nimport Button from './src/components/common/Button'\nglobal.Button = Button\n```\n\nThe `Button` component will be available in every example without a need to `import` it.\n\n## How to render React components that aren’t part of the style guide?\n\nImport these components in your examples:\n\n````jsx\n// ```jsx or ```jsx noeditor inside Markdown\nimport ColorPalette from './components/ColorPalette'\n;<ColorPalette />\n````\n\n## How to dynamically load other components in an example?\n\nAlthough examples don’t have direct access to webpack’s `require.context` feature, you _can_ use it in a separate helper file which you require in your example code. If you wanted to create an example to load and show all your icon components, you could do this:\n\n```js\n// load-icons.js\nconst iconsContext = require.context('./icons/', true, /js$/)\nconst icons = iconsContext.keys().reduce((icons, file) => {\n  const Icon = iconsContext(file).default\n  const label = file.slice(2, -3) // strip './' and '.js'\n  icons[label] = Icon\n  return icons\n}, {})\n\nexport default icons\n```\n\n````jsx\n// ```jsx or ```jsx noeditor inside Markdown\nimport icons from './load-icons'\nconst iconElements = Object.keys(icons).map(iconName => {\n  const Icon = icons[iconName]\n  return (\n    <span key={iconName}>\n      {iconName}: {<Icon />}\n    </span>\n  )\n})\n<div>{iconElements}</div>\n````\n\n## How to display the source code of any file?\n\nFirst, code examples can receive [props and settings](Documenting.md#usage-examples-and-readme-files):\n\n    ```js { \"file\": \"../mySourceCode.js\" }\n    ```\n\nThe above example adds a setting called `file` with the **relative path** to the file we want to display as value.\n\nSecond, use the [updateExample](Configuration#updateexample) config option, to detect the setting and change the content of a fenced code block:\n\n```javascript\nmodule.exports = {\n  updateExample(props, exampleFilePath) {\n    // props.settings are passed by any fenced code block, in this case\n    const { settings, lang } = props\n    // \"../mySourceCode.js\"\n    if (typeof settings.file === 'string') {\n      // \"absolute path to mySourceCode.js\"\n      const filepath = path.resolve(exampleFilePath, settings.file)\n      // displays the block as static code\n      settings.static = true\n      // no longer needed\n      delete settings.file\n      return {\n        content: fs.readFileSync(filepath, 'utf8'),\n        settings,\n        lang\n      }\n    }\n    return props\n  }\n}\n```\n\n## How to set global styles for user components?\n\nUsing the [jss-global](https://github.com/cssinjs/jss-global) API you can set global styles in your config:\n\n```javascript\nmodule.exports = {\n  components: 'src/components/**/[A-Z]*.js',\n  styles: {\n    StyleGuide: {\n      '@global body': {\n        fontFamily: 'Helvetica'\n      }\n    }\n  }\n}\n```\n\nAbove, we have set `font-family: 'Helvetica';` on the body.\n\n> **Tip:** This does not set styles on the style guide UI, for that read [How to change styles of a style guide](#how-to-change-styles-of-a-style-guide).\n\n## How to add custom JavaScript and CSS or polyfills?\n\nIn your style guide config:\n\n```javascript\nconst path = require('path')\nmodule.exports = {\n  require: [\n    'babel-polyfill',\n    path.join(__dirname, 'path/to/script.js'),\n    path.join(__dirname, 'path/to/styles.css')\n  ]\n}\n```\n\n## How to use React Styleguidist with Preact?\n\nYou need to alias `react` and `react-dom` to `preact-compat`:\n\n```javascript\nmodule.exports = {\n  webpackConfig: {\n    resolve: {\n      alias: {\n        react: 'preact-compat',\n        'react-dom': 'preact-compat'\n      }\n    }\n  }\n}\n```\n\nSee the [Preact example style guide](https://github.com/styleguidist/react-styleguidist/tree/master/examples/preact).\n\n## How to change styles of a style guide?\n\nThere are two config options to change your style guide UI: [theme](Configuration.md#theme) and [styles](Configuration.md#styles).\n\nUse [theme](Configuration.md#theme) to change fonts, colors, etc.\n\nUse [styles](Configuration.md#styles) to tweak the style of any particular Styleguidist component.\n\nAs an example:\n\n```javascript\nmodule.exports = {\n  theme: {\n    color: {\n      link: 'firebrick',\n      linkHover: 'salmon'\n    },\n    fontFamily: {\n      base: '\"Comic Sans MS\", \"Comic Sans\", cursive'\n    }\n  },\n  styles: {\n    Logo: {\n      // We're changing the LogoRenderer component\n      logo: {\n        // We're changing the rsg--logo-XX class name inside the component\n        animation: '$blink ease-in-out 300ms infinite'\n      },\n      '@keyframes blink': {\n        to: { opacity: 0 }\n      }\n    }\n  }\n}\n```\n\n> **Info:** See available [theme variables](https://github.com/styleguidist/react-styleguidist/blob/master/src/client/styles/theme.ts).\n\n> **Info:** Styles use [JSS](https://github.com/cssinjs/jss/blob/master/docs/jss-syntax.md) with these plugins: [jss-isolate](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-isolate), [jss-nested](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-nested), [jss-camel-case](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-camel-case), [jss-default-unit](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-default-unit), [jss-compose](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-compose) and [jss-global](https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-global).\n\n> **Tip:** Use [React Developer Tools](https://github.com/facebook/react) to find component and style names. For example a component `<LogoRenderer><h1 className=\"rsg--logo-53\">` corresponds to an example above.\n\n> **Tip:** Use a function instead of an object for [styles](Configuration.md#styles) to access all theme variables in your custom styles.\n\nYou can store all styles in a separate file to allow hot module replacement (HMR). Same goes for theme variables.\n\nThe same example above would then translate as:\n\nIn `styleguide.config,js`, objects are replaced with file paths\n\n```javascript\nmodule.exports = {\n  // ...\n  styles: './styleguide/styles.js',\n  theme: './styleguide/themes.js'\n}\n```\n\nthen in `./styleguide/theme.js`\n\n```javascript\nmodule.exports = {\n  color: {\n    link: 'firebrick',\n    linkHover: 'salmon'\n  },\n  fontFamily: {\n    base: '\"Comic Sans MS\", \"Comic Sans\", cursive'\n  }\n}\n```\n\nand in `./styleguide/styles.js`\n\n```javascript\nmodule.exports = {\n  Logo: {\n    // We're changing the LogoRenderer component\n    logo: {\n      // We're changing the rsg--logo-XX class name inside the component\n      animation: '$blink ease-in-out 300ms infinite'\n    },\n    '@keyframes blink': {\n      to: { opacity: 0 }\n    }\n  }\n}\n```\n\nEach modification of `theme.js` or `styles.js` will trigger a hot module replacement, updating the styleguide in the browser.\n\nCheck out the [themed example](https://github.com/styleguidist/react-styleguidist/tree/master/examples/themed) on the github repo to learn more and try it out.\n\n```javascript\nmodule.exports = {\n  styles: function (theme) {\n    return {\n      Logo: {\n        logo: {\n          // we can now change the color used in the logo item to use the theme's `link` color\n          color: theme.color.link\n        }\n      }\n    }\n  }\n}\n```\n\n## How to use CSS animations in your style guide?\n\nAs seen in the `@keyframes` animation examples above, the animation property in CSS rules do not directly use the name of their keyframe animations because of internal keyframe scoping.\n\nTo use a CSS animation, you have to define its keyframe at the root of the renderer object. The use of `@keyframes` in styling above are good examples of this.\n\n## How to change the layout of a style guide?\n\nYou can replace any Styleguidist React component. But in most of the cases you’ll want to replace `*Renderer` components — all HTML is rendered by these components. For example `ReactComponentRenderer`, `ComponentsListRenderer`, `PropsRenderer`, etc. — [check the source](https://github.com/styleguidist/react-styleguidist/tree/master/src/client/rsg-components) to see what components are available.\n\nThere’s also a special wrapper component — `Wrapper` — that wraps every example component. By default, it renders `children` as is but you can use it to provide custom logic.\n\nFor example, you can replace the `Wrapper` component to wrap any example in the [React Intl’s](https://github.com/yahoo/react-intl) provider component. You can’t wrap the whole style guide because every example is compiled separately in a browser.\n\n```javascript\n// styleguide.config.js\nconst path = require('path')\nmodule.exports = {\n  styleguideComponents: {\n    Wrapper: path.join(__dirname, 'src/styleguide/Wrapper')\n  }\n}\n```\n\n```jsx\n// src/styleguide/Wrapper.js\nimport React, { Component } from 'react'\nimport { IntlProvider } from 'react-intl'\nexport default class Wrapper extends Component {\n  render() {\n    return (\n      <IntlProvider locale=\"en\">{this.props.children}</IntlProvider>\n    )\n  }\n}\n```\n\nYou can replace the `StyleGuideRenderer` component like this:\n\n```javascript\n// styleguide.config.js\nconst path = require('path')\nmodule.exports = {\n  styleguideComponents: {\n    StyleGuideRenderer: path.join(\n      __dirname,\n      'src/styleguide/StyleGuideRenderer'\n    )\n  }\n}\n```\n\n```jsx\n// src/styleguide/StyleGuideRenderer.js\nimport React from 'react'\nconst StyleGuideRenderer = ({\n  title,\n  version,\n  homepageUrl,\n  components,\n  toc,\n  hasSidebar\n}) => (\n  <div className=\"root\">\n    <h1>{title}</h1>\n    {version && <h2>{version}</h2>}\n    <main className=\"wrapper\">\n      <div className=\"content\">\n        {components}\n        <footer className=\"footer\">\n          <Markdown\n            text={`Created with [React Styleguidist](${homepageUrl})`}\n          />\n        </footer>\n      </div>\n      {hasSidebar && <div className=\"sidebar\">{toc}</div>}\n    </main>\n  </div>\n)\n```\n\nWe have [an example style guide](https://github.com/styleguidist/react-styleguidist/tree/master/examples/customised) with custom components.\n\n## How to change syntax highlighting colors?\n\nStyleguidist uses [Prism](https://prismjs.com/) for code highlighting in static examples and inside the editor. You can change the colors using the [theme](Configuration.md#theme) config option:\n\n```javascript\n// styleguide.config.js\nmodule.exports = {\n  theme: {\n    color: {\n      codeComment: '#6d6d6d',\n      codePunctuation: '#999',\n      codeProperty: '#905',\n      codeDeleted: '#905',\n      codeString: '#690',\n      codeInserted: '#690',\n      codeOperator: '#9a6e3a',\n      codeKeyword: '#1673b1',\n      codeFunction: '#DD4A68',\n      codeVariable: '#e90'\n    }\n  }\n}\n```\n\n## How to change style guide dev server logs output?\n\nYou can modify webpack dev server logs format changing `stats` option of webpack config:\n\n```javascript\nmodule.exports = {\n  webpackConfig(env) {\n    if (env === 'development') {\n      return {\n        stats: {\n          chunks: false,\n          chunkModules: false,\n          chunkOrigins: false\n        }\n      }\n    }\n    return {}\n  }\n}\n```\n\n## How to debug my components and examples?\n\n1. Open your browser’s developer tools\n2. Write `debugger;` statement wherever you want: in a component source, a Markdown example or even in an editor in a browser.\n\n![](https://d3vv6lp55qjaqc.cloudfront.net/items/3i3E3j2h3t1315141k0o/debugging.png)\n\n## How to debug the exceptions thrown from my components?\n\n1. Put `debugger;` statement at the beginning of your code.\n2. Press the ![Debugger](https://d3vv6lp55qjaqc.cloudfront.net/items/2h2q3N123N3G3R252o41/debugger.png) button in your browser’s developer tools.\n3. Press the ![Continue](https://d3vv6lp55qjaqc.cloudfront.net/items/3b3c1P3g3O1h3q111I2l/continue.png) button and the debugger will stop execution at the next exception.\n\n## How to use the production or development build of React?\n\nIn some cases, you might need to use the development build of React instead of the default [production one](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build). For example, this might be needed if you use React Native and make references to a React Native component’s PropTypes in your code. As React removes all PropTypes in its production build, your code will fail. By default, Styleguidist uses the development build for the dev server and the production one for static builds.\n\n```js\nimport React from 'react'\nimport { TextInput } from 'react-native'\n\nconst CustomInput = ({ value }) => <TextInput value={value} />\n\nCustomInput.propTypes = {\n  // Will fail in a static build\n  value: TextInput.value.isRequired\n}\n```\n\nIf you use code like the example above, you might see a `Cannot read property 'isRequired' of undefined` error. To avoid it, you need to tell Styleguidist to use React’s development build. To do this, set the `NODE_ENV` variable to `development` in your npm script.\n\n```json\n{\n  \"scripts\": {\n    \"build\": \"cross-env NODE_ENV=development react-styleguidist build\"\n  }\n}\n```\n\n**Note:** The script above uses [cross-env](https://github.com/kentcdodds/cross-env) to make sure the environment variable is properly set on all platforms. Run `npm i -D cross-env` to add it.\n\n## How to use Vagrant with Styleguidist?\n\nFirst, read [Vagrant guide](https://webpack.js.org/guides/development-vagrant/) from the webpack documentation. Then enable polling in your webpack config:\n\n```js\ndevServer: {\n  watchOptions: {\n    poll: true\n  }\n}\n```\n\n## How to add a favicon?\n\nTwo options:\n\n1. Put a `favicon.ico` file into the root folder of your site.\n\n2. Use [template](Configuration.md#template) option:\n\n```javascript\nmodule.exports = {\n  template: {\n    favicon: 'https://assets-cdn.github.com/favicon.ico'\n  }\n}\n```\n\n## How to add external JavaScript and CSS files?\n\nUse [template](Configuration.md#template) option:\n\n```javascript\nmodule.exports = {\n  template: {\n    head: {\n      scripts: [\n        {\n          src: 'assets/js/babelHelpers.min.js'\n        }\n      ],\n      links: [\n        {\n          rel: 'stylesheet',\n          href:\n            'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css'\n        }\n      ]\n    }\n  }\n}\n```\n\nIn comparison to [require](Configuration.md#require) option, these scripts and links are run in the browser, not during webpack build process. It can be useful for side effect-causing scripts in which your components, or in this case Babel output, need to function properly.\n\n## How to add fonts from Google Fonts?\n\nUse [template](Configuration.md#template) and [theme](Configuration.md#theme) options:\n\n```javascript\nmodule.exports = {\n  template: {\n    head: {\n      links: [\n        {\n          rel: 'stylesheet',\n          href: 'https://fonts.googleapis.com/css?family=Roboto'\n        }\n      ]\n    }\n  },\n  theme: {\n    fontFamily: {\n      base: '\"Roboto\", sans-serif'\n    }\n  }\n}\n```\n\n## How to reuse project’s webpack config?\n\nSee in [configuring webpack](Webpack.md#reusing-your-projects-webpack-config).\n\n## How to use React Styleguidist with Redux, Relay or Styled Components?\n\nSee [working with third-party libraries](Thirdparties.md).\n\n## How to use React-axe to test accessibility of components?\n\n1. Install [react-axe](https://github.com/dequelabs/react-axe).\n\n2. Load React-axe with the style guide and run checks for each example:\n\n```jsx\n// styleguide.config.js\nmodule.exports = {\n  require: [path.resolve(__dirname, 'styleguide/setup.js')]\n}\n\n// styleguide/setup.js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nvar context = {\n  include: [['[data-preview]']]\n}\nif (process.env.NODE_ENV !== 'production') {\n  var axe = require('react-axe')\n  axe(React, ReactDOM, 1000, undefined, context)\n}\n```\n\n3. [Start your style guide server](https://react-styleguidist.js.org/docs/getting-started#3-start-your-style-guide) and open your browser’s developer tools console.\n\nIf you are using Jest for testing you can also use [jest-axe](https://github.com/nickcolley/jest-axe).\n\n## How to change the names of components displayed in Styleguidist UI?\n\nYou might want to change your components’ names to be displayed differently, for example, for stylistic purposes or to give them more descriptive names in your style guide.\n\nThis can be done by adding [@visibleName](Documenting.md#defining-custom-component-names) tag to your component documentation.\n\nIn case you want to change components’ names in bulk, for example, based on their current name, you can use [updateDocs](Configuration.md#updatedocs) config option:\n\n```javascript\nmodule.exports = {\n  updateDocs(docs) {\n    if (docs && docs.displayName) {\n      docs.visibleName = docs.displayName.toLowerCase()\n    }\n    return docs\n  }\n}\n```\n\n## How to re-use the types in Styleguidist?\n\nFrom version 10, Styleguidist is written using TypeScript language.\n\nIt allows the maintainers to catch type mismatch before execution and gives them a better developer experience.\n\nIt also allows you to write customized style guide components using TypeScript TSX instead of JavaScript JSX.\n\n**NOTE:** Since all files in `src/client/rsg-components` are aliased to `rsg-components` using webpack, you will have to add this alias to your `tsconfig.json` file:\n\n```json\n{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"paths\": {\n      // remap rsg-components/anything to its version in react-styleguidist\n      \"rsg-components/*\": [\n        \"node_modules/react-styleguidist/lib/client/rsg-components/*\"\n      ]\n    }\n  },\n  \"include\": [\"src\"],\n  \"exclude\": [\"node_modules\"]\n}\n```\n\nThis way when you write the following component, TypeScript will resolve typings for client components and help you type them properly.\n\n```ts\nimport Styled from 'rsg-components/Styled'\nimport Heading from 'rsg-components/Heading'\n\nexport default function SectionsRenderer({ children }) {\n  return (\n    <div>\n      {children.length > 0 && (\n        <div>\n          <Heading level={1}>Example Components</Heading>\n          <p>These are the greatest components</p>\n        </div>\n      )}\n      <DefaultSectionsRenderer>{children}</DefaultSectionsRenderer>\n    </div>\n  )\n}\n```\n\n## What’s the difference between Styleguidist and Storybook?\n\nBoth tools are good and mature, they have many similarities but also some distinctions that may make you choose one or the other. For me, the biggest distinction is how you describe component variations.\n\nWith [Storybook](https://storybook.js.org/) you write _stories_ in JavaScript files:\n\n```js\nimport React from 'react'\nimport { storiesOf } from '@storybook/react'\nimport { action } from '@storybook/addon-actions'\nimport Button from '../components/Button'\n\nstoriesOf('Button', module)\n  .add('default', () => (\n    <Button onClick={action('clicked')}>Push Me</Button>\n  ))\n  .add('large size', () => <Button size=\"large\">Push Me</Button>)\n```\n\n<video controls muted playsinline alt=\"Storybook demo video\"><source src=\"https://storybook.js.org/videos/storybook-hero-video-optimized.mp4\" type=\"video/mp4\" /></video>\n\nAnd with Styleguidist you write _examples_ in Markdown files:\n\n    React button component example:\n\n    ```js\n    <Button onClick={() => console.log('clicked')>Push Me</Button>\n    ```\n\n    Large size:\n\n    ```js\n    <Button size=\"large\">Push Me</Button>\n    ```\n\n![Styleguidist screenshot](https://camo.githubusercontent.com/7af8e5fc43288807978f28530656275008c5afbf/68747470733a2f2f64337676366c703535716a6171632e636c6f756466726f6e742e6e65742f6974656d732f32373142333732783130325330633035326933462f72656163742d7374796c6567756964697374372e676966)\n\nAnother important distinction is that Storybook shows only one variation of one component at a time but Styleguidist can show all variations of all components, all variations of a single component or one variation. It’s easier to create a style guide with Styleguidist but Storybook has more tools to develop components (though we’re working on that too).\n\n| Feature | Storybook | Styleguidist |\n| --- | --- | --- |\n| Component examples | JavaScript | Markdown |\n| Props docs | Yes | Yes |\n| Public methods docs | No | Yes |\n| Style guide¹ | No | Yes |\n| Customizable design | No | Yes |\n| Extra documentation² | No | Yes |\n| Plugins | Many | [In development](https://github.com/styleguidist/react-styleguidist/issues/354) |\n| React | Yes | Yes |\n| Preact | Yes | Yes |\n| React Native | Yes | [react-native-web](https://github.com/styleguidist/react-styleguidist/issues/675) |\n| Vue | Yes | [Fork](https://github.com/vue-styleguidist/vue-styleguidist) |\n\n¹ All components on a single page.<br> ² Include non-component documentation.\n\n## Are there any other projects like this?\n\n### Active\n\n- [Catalog](https://github.com/interactivethings/catalog), create living style guides using Markdown or React.\n- [Cosmos](https://github.com/react-cosmos/react-cosmos), a tool for designing encapsulated React components.\n- [Docz](https://www.docz.site/), a tool for documenting your components with zero configuration and live preview.\n- [React Storybook](https://storybooks.js.org/), isolate your React UI Component development from the main app.\n\n### Inactive\n\n- [Atellier](https://github.com/scup/atellier), a React components emulator. Last release 2016.\n- [Carte Blanche](https://github.com/carteb/carte-blanche), an isolated development space with integrated fuzz testing for your components. Last release 2016.\n- [React BlueKit](http://bluekit.blueberry.io/), render React components with editable source and live preview. Last release 2017.\n- [React Cards](https://github.com/steos/reactcards), devcards for React. Last release 2017.\n- [React Styleguide Generator](https://github.com/pocotan001/react-styleguide-generator), a React style guide generator. Last release 2017.\n- [React-demo](https://github.com/rpominov/react-demo), a component for creating demos of other components with props editor. Last release 2017.\n- [SourceJS](https://github.com/sourcejs/Source), a platform to unify all your frontend documentation. It has a [Styleguidist plugin](https://github.com/sourcejs/sourcejs-react-styleguidist). On hold.\n"
  },
  {
    "path": "docs/Development.md",
    "content": "<!-- Developer guide #development -->\n\n# Developer guide\n\n_For basics see [How to contribute](https://github.com/styleguidist/react-styleguidist/blob/master/.github/Contributing.md)._\n\nStyleguidist isn’t an ordinary single-page app and some design decisions may look confusing to an outsider. In this guide, we’ll explain these decisions to un-confuse potential contributors.\n\nThe main thing is that we’re running two apps at the same time: user’s components and Styleguidist UI. They share a webpack configuration and have styles in the same scope (there’s only one scope in CSS). And we can control only one of these two apps: Styleguidist UI. That puts us under some restrictions:\n\n- Our styles should not affect user component styles.\n- User styles (especially global like Bootstrap) should not affect Styleguidist UI.\n- `body` styles (like `font-family`) should affect user components as the user expects but not Styleguidist UI.\n\n## How it works\n\nStyleguidist uses [react-docgen](https://github.com/reactjs/react-docgen) to parse _source_ files (not transpiled). react-docgen finds exported React components and generates documentation based on PropTypes or Flow annotations.\n\nStyleguidist uses Markdown for documentation: each JavaScript code block is rendered as an interactive playground with [react-simple-code-editor](https://github.com/satya164/react-simple-code-editor). To do that we extract all these code blocks using [Remark](http://remark.js.org/).\n\nWebpack loaders (see below) generate JavaScript modules with all user components, their documentation and examples and pass that to a React app which renders a style guide.\n\n## Webpack loaders and webpack configuration\n\nWe use webpack loaders to hot reload the style guide on changes in user components, styles and Markdown documentation. We have three loaders ([loaders](https://github.com/styleguidist/react-styleguidist/tree/master/src/loaders) folder):\n\n- `styleguide-loader`: loads components and sections;\n- `props-loaders`: loads props documentation using react-docgen;\n- `examples-loader`: loads examples from Markdown files;\n\nStyleguidist tries to load and reuse the user’s webpack config (`webpack.config.js` in project root folder). It works most of the time but has some restrictions: Styleguidist [ignores](https://github.com/styleguidist/react-styleguidist/blob/master/src/scripts/utils/mergeWebpackConfig.js) some fields and plugins because they are already included (like `webpack.HotModuleReplacementPlugin`), don’t make sense for a style guide (like `output`) or may break Styleguidist (like `entry`).\n\nWe’re trying to keep Styleguidist’s [webpack config](https://github.com/styleguidist/react-styleguidist/blob/master/src/scripts/make-webpack-config.ts) minimal to reduce clashes with the user’s configuration.\n\n## React components\n\nMost of StyleGuidist UI components consist of two parts: `Foo/Foo.js` that contains all logic and `Foo/FooRenderer.js` that contains all markup and styles. This allows users to customize rendering by overriding `*Renderer` component using webpack aliases (or [styleguideComponents](Configuration.md#styleguidecomponents) config option):\n\n```js\n// styleguide.config.js\nconst path = require('path')\nmodule.exports = {\n  webpackConfig: {\n    resolve: {\n      alias: {\n        'rsg-components/Wrapper': path.join(\n          __dirname,\n          'lib/styleguide/Wrapper'\n        )\n      }\n    }\n  }\n}\n```\n\nAll Styleguidist components should be imported like this: `import Foo from 'rsg-components/Foo'` to make aliases work.\n\nEach component folder usually has several files:\n\n- `Foo/Foo.js` (optional for basic components);\n- `Foo/FooRenderer.js`;\n- `Foo/Foo.spec.js` — tests;\n- `Foo/index.js` — reexport of `Foo.js` or `FooRenderer.js`.\n\n## Styles\n\nFor styles we use [JSS](http://cssinjs.org/), it allows users to customize their style guide and allows us to ensure style isolation (thanks to [jss-isolate](http://cssinjs.org/jss-isolate/)). No user styles should affect Styleguidist UI and no Styleguidist styles should affect user components.\n\nUse [clsx](https://github.com/lukeed/clsx) to merge several class names or for conditional class names, import it as `cx` (`import cx from 'clsx'`).\n\nWe use `Styled` higher-order component to allow theming (see [theme](Configuration.md#theme) and [style](Configuration.md#style) style guide config options). Use it like this:\n\n```jsx\nimport React from 'react'\nimport Styled from 'rsg-components/Styled'\n\nexport const styles = ({ fontFamily, fontSize, color }) => ({\n  button: {\n    fontSize: fontSize.base,\n    fontFamily: fontFamily.base,\n    color: color.light,\n    '&:hover, &:active': {\n      isolate: false,\n      color: color.lightest\n    }\n  }\n})\n\nfunction ExamplePlaceholderRenderer({ classes }) {\n  return (\n    <button className={classes.button}>I am a styled button</button>\n  )\n}\n\nexport default Styled(styles)(ExamplePlaceholderRenderer)\n```\n\nCheck available theme variables in [src/client/styles/theme.js](https://github.com/styleguidist/react-styleguidist/blob/master/src/client/styles/theme.js).\n\nBecause of isolation and theming you need to explicitly declare `fontFamily`, `fontSize` and `color`. Add `isolate: false` to your hover styles, otherwise you’ll have to repeat base non-hover styles.\n\n## Testing\n\nWe’re using [Jest with React Test Renderer](https://reactjs.org/docs/test-renderer.html) for testing. Put your component tests into `Component.spec.js` file in the same folder and all other tests into `__tests__/filename.spec.js`.\n\nTo test particular class names use `classes` function (available in the global namespace in tests):\n\n```js\nimport { TabButtonRenderer, styles } from './TabButtonRenderer'\n\nconst props = {\n  classes: classes(styles)\n}\n\nit('should render active styles', () => {\n  const renderer = createRenderer()\n  renderer.render(\n    <TabButtonRenderer {...props} active>\n      pizza\n    </TabButtonRenderer>\n  )\n  expect(actual.toJson()).toMatchSnapshot()\n})\n```\n"
  },
  {
    "path": "docs/Documenting.md",
    "content": "<!-- Documenting components #documenting -->\n\n# Documenting components\n\nStyleguidist generates documentation for your components based on the comments in your source code, propTypes declarations, and Readme files.\n\n> **Tip:** [See examples](https://github.com/styleguidist/react-styleguidist/tree/master/examples/basic/src/components) of documented components in our demo style guide.\n\n## Code comments and propTypes\n\nStyleguidist will display your components’ JSDoc comment blocks. Also, it will pick up props from propTypes declarations and display them in a table.\n\n```javascript\nimport React from 'react'\nimport PropTypes from 'prop-types'\n\n/**\n * General component description in JSDoc format. Markdown is *supported*.\n */\nexport default class Button extends React.Component {\n  static propTypes = {\n    /** Description of prop \"foo\". */\n    foo: PropTypes.number,\n    /** Description of prop \"baz\". */\n    baz: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n  }\n  static defaultProps = {\n    foo: 42\n  }\n\n  render() {\n    /* ... */\n  }\n}\n```\n\n> **Info:** [Flow](https://flowtype.org/) and [TypeScript](https://www.typescriptlang.org) type annotations are supported.\n\n> **Tip:** You can change its behavior using [propsParser](Configuration.md#propsparser) and [resolver](Configuration.md#resolver) options.\n\n> **Info:** Component’s `PropTypes` and documentation comments are parsed by the [react-docgen](https://github.com/reactjs/react-docgen) library. They can be modified using the [updateDocs](Configuration.md#updatedocs) function.\n\n## Usage examples and Readme files\n\nStyleguidist will look for any `Readme.md` or `ComponentName.md` files in the component’s folder and display them. Any code block with a language tag of `js`, `jsx`, or `javascript` will be rendered as a React component with an interactive playground. For backwards compatibility, code blocks without a language tag are also rendered in this way. It is recommended to always use the proper language tag for new documentation.\n\n    React component example:\n\n    ```js\n    <Button size=\"large\">Push Me</Button>\n    ```\n\n    You can add a custom props to an example wrapper:\n\n    ```js { \"props\": { \"className\": \"checks\" } }\n    <Button>I’m transparent!</Button>\n    ```\n\n    Or add padding between examples in a block by passing the `padded` modifier:\n\n    ```jsx padded\n    <Button>Push Me</Button>\n    <Button>Click Me</Button>\n    <Button>Tap Me</Button>\n    ```\n\n    Or disable an editor by passing a `noeditor` modifier:\n\n    ```jsx noeditor\n    <Button>Push Me</Button>\n    ```\n\n    To render an example as highlighted source code add a `static` modifier:\n\n    ```jsx static\n    import React from 'react';\n    ```\n\n    Examples with all other languages are rendered only as highlighted source code, not an actual component:\n\n    ```html\n    <Button size=\"large\">Push Me</Button>\n    ```\n\n    Any [Markdown](http://daringfireball.net/projects/markdown/) is **allowed** _here_.\n\n> **Tip:** You can configure examples file name with the [getExampleFilename](Configuration.md#getexamplefilename) option.\n\n> **Tip:** If you need to display some JavaScript code in your documentation that you don’t want to be rendered as an interactive playground you can use the `static` modifier with a language tag (e.g. `js static`).\n\n## External examples using doclet tags\n\nAdditional example files can be associated with components using `@example` doclet syntax.\n\nThe following component will also have an example loaded from the `extra.examples.md` file:\n\n```javascript\n/**\n * Component is described here.\n *\n * @example ./extra.examples.md\n */\nexport default class Button extends React.Component {\n  // ...\n}\n```\n\n> **Note:** You’ll need a regular example file (like `Readme.md`) too when [skipComponentsWithoutExample](Configuration.md#skipcomponentswithoutexample) is `true`.\n\n## Public methods\n\nBy default, any methods your components have are considered to be private and are not published. Mark your public methods with JSDoc [`@public`](http://usejsdoc.org/tags-public.html) tag to get them published in the docs:\n\n```javascript\n/**\n * Insert text at cursor position.\n *\n * @param {string} text\n * @public\n */\ninsertAtCursor(text) {\n  // ...\n}\n```\n\n## Ignoring props\n\nBy default, all props your components have are considered to be public and are published. In some rare cases, you might want to remove a prop from the documentation while keeping it in the code. To do so, mark the prop with JSDoc [`@ignore`](http://usejsdoc.org/tags-ignore.html) tag to remove it from the docs:\n\n```javascript\nMyComponent.propTypes = {\n  /**\n   * A prop that should not be visible in the documentation.\n   *\n   * @ignore\n   */\n  hiddenProp: React.PropTypes.string\n}\n```\n\n## Defining custom component names\n\nUse `@visibleName` JSDoc tag to define component names that are used in the Styleguidist UI:\n\n```javascript\n/**\n * The only true button.\n *\n * @visibleName The Best Button Ever 🐙\n */\nclass Button extends React.Component {\n```\n\nThe component will be displayed with a custom “The Best Button Ever 🐙” name and this will not change the name of the component used in the code of your app or Styleguidist examples.\n\n## Using JSDoc tags\n\nYou can use the following [JSDoc](http://usejsdoc.org/) tags when documenting components, props and methods:\n\n- [@deprecated](http://usejsdoc.org/tags-deprecated.html)\n- [@see, @link](http://usejsdoc.org/tags-see.html)\n- [@author](http://usejsdoc.org/tags-author.html)\n- [@since](http://usejsdoc.org/tags-since.html)\n- [@version](http://usejsdoc.org/tags-version.html)\n\nWhen documenting props you can also use:\n\n- [@param, @arg, @argument](http://usejsdoc.org/tags-param.html)\n\nAll tags can render Markdown.\n\n```javascript\n/**\n * The only true button.\n *\n * @version 1.0.1\n * @author [Artem Sapegin](https://github.com/sapegin)\n * @author [Andy Krings-Stern](https://github.com/ankri)\n */\nclass Button extends React.Component {\n  static propTypes = {\n    /**\n     * Button label.\n     */\n    children: PropTypes.string.isRequired,\n    /**\n     * The color for the button\n     *\n     * @see See [Wikipedia](https://en.wikipedia.org/wiki/Web_colors#HTML_color_names) for a list of color names\n     * @see See [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) for a list of color names\n     */\n    color: PropTypes.string,\n    /**\n     * The size of the Button\n     *\n     * @since Version 1.0.1\n     */\n    size: PropTypes.oneOf(['small', 'normal', 'large']),\n    /**\n     * The width of the button\n     *\n     * @deprecated Do not use! Use `size` instead!\n     */\n    width: PropTypes.number,\n    /**\n     * Gets called when the user clicks on the button\n     *\n     * @param {SyntheticEvent} event The react `SyntheticEvent`\n     * @param {Object} allProps All props of this Button\n     */\n    onClick: PropTypes.func\n  }\n}\n```\n\n## Writing code examples\n\nCode examples in Markdown use ES6+JSX syntax. You can use the current component without explicitly importing it:\n\n````jsx\n// ```jsx inside Button/Readme.md or Button.md\n<Button>Push Me</Button>\n````\n\n> **Info:** Styleguidist uses [Bublé](https://buble.surge.sh/guide/) to run ES6 code on the frontend, it supports [most of the ES6 features](https://buble.surge.sh/guide/#unsupported-features).\n\nTo use other components, you need to explicitly `import` them:\n\n````jsx\n// ```jsx inside Panel/Readme.md or Panel.md\nimport Button from '../Button'\n;<Panel>\n  <p>\n    Using the Button component in the example of the Panel component:\n  </p>\n  <Button>Push Me</Button>\n</Panel>\n````\n\nYou can also `import` other modules, like mock data:\n\n````jsx\n// ```jsx inside Markdown\nimport mockData from './mocks'\n;<Message content={mockData.hello} />\n````\n\nOr you can explicitly import all your example dependencies, to make examples easier to copy into your app code:\n\n````jsx\n// ```jsx inside Markdown\nimport React from 'react'\nimport Button from 'rsg-example/components/Button'\nimport Placeholder from 'rsg-example/components/Placeholder'\n````\n\n> **Info:** `rsg-example` module is an alias defined by the [moduleAliases](Configuration.md#modulealiases) config option.\n\n> **Caution:** You can only use `import` by editing your Markdown files, not by editing the example code in the browser.\n\nEach example acts as a function component and you can use the `useState` Hook to handle its state.\n\n````jsx\n// ```jsx inside Markdown\nconst [isOpen, setIsOpen] = React.useState(false)\n;<div>\n  <button onClick={() => setIsOpen(true)}>Open</button>\n  <Modal isOpen={isOpen}>\n    <h1>Hallo!</h1>\n    <button onClick={() => setIsOpen(false)}>Close</button>\n  </Modal>\n</div>\n````\n\nIf a component uses React Context, you need a context provider in the example or in a custom `Wrapper` component. See [ThemeButton example](https://github.com/styleguidist/react-styleguidist/tree/master/examples/sections/src/components/ThemeButton).\n\n> **Tip:** If you need a more complex demo it’s often a good idea to define it in a separate JavaScript file and `import` it in Markdown.\n\n## Limitations\n\nIn some cases Styleguidist may not understand your components, [see possible solutions](Thirdparties.md).\n"
  },
  {
    "path": "docs/GettingStarted.md",
    "content": "<!-- Getting started #getting-started -->\n\n# Getting started with React Styleguidist\n\n## 1. Install Styleguidist\n\nInstall webpack if you don’t have it already and aren’t using Create React App:\n\n```bash\nnpm install --save-dev webpack\n```\n\nInstall Styleguidist:\n\n```bash\nnpm install --save-dev react-styleguidist\n```\n\n## 2. Configure your style guide\n\n**If you’re using [Create React App](https://github.com/facebook/create-react-app) you can skip this step.**\n\n- [Point Styleguidist to your React components](Components.md)\n- [Tell Styleguidist how to load your app’s code](Webpack.md)\n\n## 3. Start your style guide\n\n- Run **`npx styleguidist server`** to start a style guide dev server.\n- Run **`npx styleguidist build`** to build a production HTML version.\n\n> **Tip:** We recommend [adding these commands to your `package.json`](CLI.md#usage).\n\n## 4. Start documenting your components\n\nSee how to [document your components](Documenting.md).\n\n## Something isn’t working?\n\n- [Solutions for common problems and questions](Cookbook.md)\n- [Configuring Styleguidist with third-party tools](Thirdparties.md)\n"
  },
  {
    "path": "docs/Maintenance.md",
    "content": "<!-- Maintainer guide #maintenance -->\n\n# Maintainer guide\n\n_See also [Developer guide](Development.md)._\n\n## We need you!\n\nHelp us develop and maintain Styleguidist:\n\n- Answer questions in [GitHub issues](https://github.com/styleguidist/react-styleguidist/issues) and [Stack Overflow](https://stackoverflow.com/questions/tagged/react-styleguidist).\n- Review [pull requests](https://github.com/styleguidist/react-styleguidist/pulls).\n- Fix bugs and add new features.\n- Write articles and talk about Styleguidist on conferences and meetups (we’re always happy to review your texts and slides).\n\n## Commit message conventions\n\nWe use a simplified [Angular commit message conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit). This makes automated releases with [semantic-release](https://github.com/semantic-release/semantic-release) possible.\n\n\\*\\*The main differences with the Angular convention is that all messages are capitalized. Commit messages are written for humans to read, so we should use text convention for humans, not for machines.\n\nHovewer, we commit messages should follow a ceratain structure, so they semantic-release could generate nice human-readalbe changelogs.\n\n**The commit message** consists of a `header`, a `body`, and a `footer`:\n\n```\n<header>\n<BLANK LINE>\n<body>\n<BLANK LINE>\n<footer>\n```\n\nThe `header` is mandatory and must conform to the commit message header format described below.\n\nThe `body` optional but higly recommended for most commits, except very simple ones.\n\nThe `footer` is optional.\n\n**The commit message header** looks like this:\n\n```\n<type>: <Short summary>\n  │       │\n  │       └─⫸ Summary in present tense. Capitalized. No period at the end.\n  │\n  └─⫸ Commit type: chore|docs|feat|fix|refactor|test\n```\n\nThe `<type>` and `<Short summary>` fields are mandatory.\n\n### Type\n\nMust be one of the following:\n\n- `chore` — configuration change, dependencies upgrade, and so on.\n- `docs` — changes to documentation only.\n- `feat` — a new feature.\n- `fix` — a bug fix.\n- `refactor` — a code change that neither fixes a bug nor adds a feature.\n- `test` — adding missing tests or correcting existing tests.\n\n### Short summary\n\nUse the summary field to provide a short description of the change.\n\n- use the imperative, present tense: “change” not “changed” nor “changes”;\n- always capitalize the first letter;\n- no dot (.) at the end.\n\n### Commit message body\n\nAs in the summary, use the imperative, present tense: “fix” not “fixed” nor “fixes”, but put a dot (.) at the end of each sentence.\n\nExplain the motivation for the change: why you are making it. You could include a comparison of the previous behavior with the new behavior to illustrate the impact of the change.\n\n### Commit message footer\n\nThe footer could contain information about breaking changes, and is also the place to reference GitHub issues, and other pull requests that this commit closes or is related to.\n\n```\nBREAKING CHANGE: <breaking change summary>\n<BLANK LINE>\n<breaking change description + migration instructions>\n<BLANK LINE>\n<BLANK LINE>\nFixes #<issue number>\n```\n\nBreaking change section should start with the phrase `BREAKING CHANGE:` (with a `:` and a space at the end, you must use ALL CAPS — _sorry but life is full of pain_) followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.\n\nIf the commit doesn’t completely fix the issue, then use (`Refs #1234`) instead of (`Fixes #1234`).\n\n### Commit messsage example\n\n````\nFix: Fix missing FlowType enum values in prop description\n\nIn ef4c109b, the file `PropsRenderer.js` (located at\n`src/client/rsg-components/Props/PropsRenderer.js`) was removed. In\n`PropsRenderer.js`, the `renderExtra` method checked whether `getType`\nfor the argument to `renderExtra` was present:\n\n```es6\nfunction renderExtra(prop) {\n  const type = getType(prop);\n  if (!type) {\n    return null;\n  }\n  ...\n}\n```\n\nHowever, in ef4c109b, this method was replaced with `renderExtra.tsx`\nand the condition was changed to:\n\n```typescript\nexport default function renderExtra(prop: PropDescriptorWithFlow): React.ReactNode {\n  const type = getType(prop);\n  if (!prop.type || !type) {\n    return null;\n  }\n```\n\nUnfortunately, this extra condition has resulted in this method always returning `null` for a Flow typed prop as `prop.type` is always `null` as `prop.type` is never set.\n\nThis commit reverts the condition to what it was before the migration to TypeScript.\n\nFixes #1234\n\n````\n\n## Pull requests\n\nMaintainers merge pull requests by squashing all commits and editing the commit message if necessary using the GitHub user interface.\n\nUse an appropriate commit type. Be especially careful with breaking changes. See _Commit message conventions_ above for details.\n\n## Releases\n\nWe’re doing automated releases with semantic-release. We’re using [milestones](https://github.com/styleguidist/react-styleguidist/milestones) to group approved pull requests that should be released together (most useful for major releases).\n\n### Patch releases\n\nAny commit of a `fix` type merged into the master branch, is published as a _patch_ release as soon as CI passes.\n\n![](https://d3vv6lp55qjaqc.cloudfront.net/items/1T3v1z0c3f1I1E3l0B3s/patch-commit.png)\n\n### Minor releases\n\nAny commit of a `feat` type merged into the master branch, is published as a _minor_ release as soon as CI passes.\n\n### Major releases\n\nAny commit of a `feat` type with a breaking change section merged into the master branch, is published as a _major_ release as soon as CI passes.\n\n1. Merge all pull requests from a milestone. If a milestone has more than one pull request, they should be merged and released together:\n   1. Create a new branch.\n   2. Merge all pull requests into this new branch (you can change the target branch on the pull request page and merge it using the GitHub user interface).\n   3. Resolve possible merge conflicts.\n2. Wait until semantic-release publishes the release.\n3. Edit the release notes on GitHub (see _Changelogs_ below).\n4. Tweet the release!\n\n## Changelogs\n\n### What is a good changelog\n\n- Changelogs are written for users, not developers.\n- Changelog should show new features with code examples or GIFs.\n- Changelog should make all breaking changes clear.\n- Changelog should explain how to migrate to a new version if there are breaking changes.\n- Commit log **is not** a changelog but can be a base for it.\n\nHere’s a [good example of a changelog](https://github.com/styleguidist/react-styleguidist/releases/tag/v7.1.0). Check out [Keep a Changelog](https://keepachangelog.com/) for more details on good changelogs.\n\n### What should be in a changelog\n\n- Information about pull request authors:<br> `(#1040 by @rafaesc)`\n- Open Collective link at the very top:<br> `👋 **[Support Styleguidist](https://opencollective.com/styleguidist) on Open Collective** 👋`\n\n"
  },
  {
    "path": "docs/Readme.md",
    "content": "# React Styleguidist Documentation\n\n- **[Getting Started](https://react-styleguidist.js.org/docs/getting-started): install and run Styleguidist**\n- [Documenting components](https://react-styleguidist.js.org/docs/documenting): how to write documentation\n- [Locating components](https://react-styleguidist.js.org/docs/components): point Styleguidist to your React components\n- [Configuring webpack](https://react-styleguidist.js.org/docs/webpack): tell Styleguidist how to load your code\n- [Cookbook](https://react-styleguidist.js.org/docs/cookbook): how to solve common tasks with Styleguidist\n\n---\n\n- [Configuration](https://react-styleguidist.js.org/docs/configuration)\n- [CLI commands and options](https://react-styleguidist.js.org/docs/cli)\n- [Node.js API](https://react-styleguidist.js.org/docs/api)\n"
  },
  {
    "path": "docs/Thirdparties.md",
    "content": "<!-- Working with third-parties #thirdparties -->\n\n# Working with third-party libraries\n\n## How Styleguidist works\n\nStyleguidist _loads_ your components (see [Loading and exposing components](Components.md#loading-and-exposing-components) for more) but it uses [react-docgen](https://github.com/reactjs/react-docgen) to _generate documentation_ which may require changes in your code to work properly.\n\nReact-docgen reads your components as static text files and looks for patterns like class or function declarations that look like React components. It does not run any JavaScript code, so, if your component is dynamically generated, is wrapped in a higher-order component, or is split into several files, then react-docgen may not understand it.\n\nIt supports components defined via `React.createClass`, ES6 classes and function components, with optional Flow and TypeScript type annotations.\n\nIn many cases you may trick Styleguidist and react-docgen by exporting both components: an enhanced component as the default export and a base component as a named export:\n\n```javascript\nimport React from 'react'\nimport CSSModules from 'react-css-modules'\nimport styles from './Button.css'\n\n// Base component will be used by react-docgen to generate documentation\nexport function Button({ color, size, children }) {\n  /* ... */\n}\n\n// Enhanced component will be used when you write <Button /> in your example files\nexport default CSSModules(Button, styles)\n```\n\nEach example is rendered in an independent React root. You can control React Context by defining a custom Wrapper component like this:\n\n```javascript\n// styleguide.config.js\nconst path = require('path')\nmodule.exports = {\n  styleguideComponents: {\n    Wrapper: path.join(__dirname, 'src/styleguide/Wrapper')\n  }\n}\n```\n\nPlease see our [examples](https://github.com/styleguidist/react-styleguidist/tree/master/examples) and refer to [react-docgen](https://github.com/reactjs/react-docgen) documentation for more information about what types of syntax are supported.\n\nWhile Styleguidist supports TypeScript out of the box, thanks to `react-docgen`, this support is limited. Consider this example:\n\n```javascript\nimport Button from 'antd/es/button'\n\nexport default Button\n```\n\nHere we’re reexporting a third-party component from `node_modules`. Styleguidist won’t be able to render prop types of this component, unless we’re using `react-docgen-typescript`:\n\n1. Install [react-docgen-typescript](https://github.com/styleguidist/react-docgen-typescript).\n2. Create a `styleguide.config.js`, see [configuration](Configuration.md) reference.\n3. Update your `styleguide.config.js`:\n\n   ```javascript\n   module.exports = {\n     propsParser: require('react-docgen-typescript').withCustomConfig(\n       './tsconfig.json'\n     ).parse\n   }\n   ```\n\n## Using Styleguidist with other libraries\n\n### Redux\n\nTo use Redux store with one component, import it from your Markdown example:\n\n````jsx\n// ```jsx inside Markdown\nimport { Provider } from 'react-redux'\nimport configureStore from '../utils/configureStore'\nconst initialState = {\n  app: {\n    name: 'Pizza Delivery'\n  }\n}\nconst store = configureStore({ initialState })\n;<Provider store={store}>\n  <App greeting=\"Choose your pizza!\" />\n</Provider>\n````\n\nTo use Redux store in every component, redefine the `Wrapper` component:\n\n```javascript\n// styleguide.config.js\nconst path = require('path')\nmodule.exports = {\n  styleguideComponents: {\n    Wrapper: path.join(__dirname, 'src/styleguide/Wrapper')\n  }\n}\n```\n\n```jsx\n// src/styleguide/Wrapper.js\nimport React, { Component } from 'react'\nimport { Provider } from 'react-redux'\nimport configureStore from '../utils/configureStore'\nconst initialState = {\n  app: {\n    name: 'Pizza Delivery'\n  }\n}\nconst store = configureStore({ initialState })\nexport default class Wrapper extends Component {\n  render() {\n    return <Provider store={store}>{this.props.children}</Provider>\n  }\n}\n```\n\n### Relay\n\n**First, mock out Relay.** You’ll need the content from [this Gist](https://gist.github.com/mikberg/07b4006e22aacf31ffe6) for your mocked-out Relay replacement.\n\n```js\n// styleguide.config.js\nconst path = require('path')\nconst merge = require('webpack-merge')\nmodule.exports = {\n  webpackConfig: merge(require('./webpack.config'), {\n    resolve: {\n      alias: {\n        'react-relay': path.join(\n          __dirname,\n          'src/styleguide/FakeRelay'\n        ),\n        'real-react-relay': require.resolve('react-relay')\n      }\n    }\n  })\n}\n```\n\n```js\n// src/styleguide/FakeRelay.js\nimport Relay from 'real-react-relay'\n// Copy contents from https://gist.github.com/mikberg/07b4006e22aacf31ffe6\n```\n\n**Second, provide sample data to your React components** to send actual results from your GraphQL backend:\n\n```js\n// styleguide.config.js\nmodule.exports = {\n  context: {\n    sample: path.join(__dirname, 'src/styleguide/sample_data')\n  }\n}\n```\n\n```js\n// src/styleguide/sample_data.js\nmodule.exports = {\n  object: {\n    // Something similar to your GraphQL results\n  }\n}\n```\n\n````jsx\n// ```jsx inside Markdown\n<MyComponent object={sample.object} />\n````\n\n_Based on @mikberg’s [blog post](https://medium.com/@mikaelberg/writing-simple-unit-tests-with-relay-707f19e90129)._\n\n### Styled-components\n\nTo show PropTypes documentation for [styled-components](https://www.styled-components.com/), you need to add the `@component` JSDoc annotation to the component export:\n\n```jsx\nimport React from 'react'\nimport PropTypes from 'prop-types'\nimport styled from 'styled-components'\n\nconst SalmonButton = styled.button`\n  background-color: salmon;\n  border: 1px solid indianred;\n  color: snow;\n`\n\nButton.propTypes = {\n  children: PropTypes.node\n}\n\n/** @component */\nexport default SalmonButton\n```\n\n> **Caution:** Object notation isn’t supported yet, use string literals instead:\n\n```diff\n- const Button = styled.button({\n-  color: 'tomato'\n- })\n+ const Button = styled.button`\n+  color: tomato;\n+ `\n```\n\n> **Caution:** Other use case for calling the `styled` factory as a function, like styled-system, aren’t supported too:\n\n```diff\n- const Input = styled.input(\n-  css({\n- \t\tboxSizing: 'border-box',\n-     // ...\n- \t})\n- );\n```\n\n#### Adding styled-components `ThemeProvider`\n\nIf your styled-components require a theme to render properly, add a `ThemeProvider` to your style guide.\n\nFirst, create a `Provider` component:\n\n```jsx\n// src/Provider.js\nimport React from 'react'\nimport { ThemeProvider } from 'styled-components'\nimport theme from './theme'\n\nexport default function Provider({ children }) {\n  return <ThemeProvider theme={theme}>{children}</ThemeProvider>\n}\n```\n\nNext, add `Provider` to your `styleguide.config.js`:\n\n```javascript\n// styleguide.config.js\nconst path = require('path')\nmodule.exports = {\n  styleguideComponents: {\n    Wrapper: path.join(__dirname, 'src/Provider.js')\n  }\n}\n```\n\nThis will automatically apply your theme to your styled-components. When you open the style guide by running `npx styleguidist server`, you should see your components render as expected.\n\n### Emotion\n\nThe usage is similar to [styled-components](#styled-components).\n\n### Theme UI\n\nThe usage is similar to [Adding styled-components `ThemeProvider`](#adding-styled-components-themeprovider).\n\n### Fela\n\nCheck out the [official example](https://github.com/rofrischmann/fela/tree/master/examples/example-with-styleguidist).\n\n### CSS Modules with react-css-modules\n\nYou need to export two components: (1) unstyled React component as named export and (2) enhanced component as a default export:\n\n```javascript\nimport React from 'react'\nimport CSSModules from 'react-css-modules'\nimport styles from './Button.css'\n\nexport function Button({ color, size, children }) {\n  /* ... */\n}\n\nexport default CSSModules(Button, styles)\n```\n\nThis approach will also work with [react-css-themr](https://github.com/javivelasco/react-css-themr) and other similar libraries.\n\n### Styletron\n\nTo use Styletron store with one component, require it from your example:\n\n````jsx\n// ```jsx inside Markdown\nimport Styletron from 'styletron-client'\nimport { StyletronProvider } from 'styletron-react'\n;<StyletronProvider styletron={new Styletron()}>\n  <App greeting=\"Choose your pizza!\" />\n</StyletronProvider>\n````\n\nTo use Styletron in every component redefine the Wrapper component:\n\n```javascript\n// styleguide.config.js\nconst path = require('path')\nmodule.exports = {\n  styleguideComponents: {\n    Wrapper: path.join(__dirname, 'src/styleguide/Wrapper')\n  }\n}\n```\n\n```jsx\n// src/styleguide/Wrapper.js\nimport React, { Component } from 'react'\nimport Styletron from 'styletron-client'\nimport { StyletronProvider } from 'styletron-react'\nexport default class Wrapper extends Component {\n  render() {\n    return (\n      <StyletronProvider styletron={new Styletron()}>\n        {this.props.children}\n      </StyletronProvider>\n    )\n  }\n}\n```\n"
  },
  {
    "path": "docs/Webpack.md",
    "content": "<!-- Configuring webpack #webpack -->\n\n# Configuring webpack\n\nStyleguidist uses [webpack](https://webpack.js.org/) under the hood and it needs to know how to load your project’s files.\n\n_Webpack is required to run Styleguidist but your project doesn’t have to use it._\n\n> **Note:** See [cookbook](Cookbook.md) for more examples.\n\n## Reusing your project’s webpack config\n\nBy default, Styleguidist will try to find `webpack.config.js` in your project’s root directory and use it.\n\nIf your webpack config is located somewhere else, you need to load it manually:\n\n```javascript\nmodule.exports = {\n  webpackConfig: require('./configs/webpack.js')\n}\n```\n\nOr, merge it with other options:\n\n```javascript\nmodule.exports = {\n  webpackConfig: Object.assign({}, require('./configs/webpack.js'), {\n    /* Custom config options */\n  })\n}\n```\n\n> **Caution:** `entry`, `externals`, `output`, `watch`, and `stats` options will be ignored. For production builds, `devtool` will also be ignored.\n\n> **Caution:** `CommonsChunkPlugins`, `HtmlWebpackPlugin`, `MiniHtmlWebpackPlugin`, `UglifyJsPlugin`, `TerserPlugin`, `HotModuleReplacementPlugin` plugins will be ignored because Styleguidist already includes them or they may break Styleguidist.\n\n> **Tip:** If your loaders don’t work with Styleguidist try to make `include` and `exclude` absolute paths.\n\n> **Note:** Babelified webpack configs (like `webpack.config.babel.js`) are not supported. We recommend to convert your config to native Node — Node 6 supports [many ES6 features](http://node.green/).\n\n> **Tip:** Use [webpack-merge](https://github.com/survivejs/webpack-merge) for easier config merging.\n\n## Custom webpack config\n\nAdd a `webpackConfig` section to your `styleguide.config.js`:\n\n```javascript\nmodule.exports = {\n  webpackConfig: {\n    module: {\n      rules: [\n        // Babel loader will use your project’s babel.config.js\n        {\n          test: /\\.jsx?$/,\n          exclude: /node_modules/,\n          loader: 'babel-loader'\n        },\n        // Other loaders that are needed for your components\n        {\n          test: /\\.css$/,\n          use: ['style-loader', 'css-loader']\n        }\n      ]\n    }\n  }\n}\n```\n\n> **Caution:** This option disables config load from `webpack.config.js`, see above how to load your config manually.\n\n> **Caution:** `entry`, `externals`, `output`, `watch`, and `stats` options will be ignored. For production builds, `devtool` will also be ignored.\n\n> **Caution:** `CommonsChunkPlugins`, `HtmlWebpackPlugin`, `MiniHtmlWebpackPlugin`, `UglifyJsPlugin`, `TerserPlugin`, `HotModuleReplacementPlugin` plugins will be ignored because Styleguidist already includes them or they may break Styleguidist.\n\n## Create React App\n\n[Create React App](https://github.com/facebook/create-react-app) is supported out of the box, you don’t even need to create a style guide config if your components could be found using a default pattern: all files with `.js` or `.jsx` extensions inside `src/components` or `src/Components` folders.\n\n## Next.js\n\nThe [Next.js](https://nextjs.org/) framework abstracts away webpack for you, but it still uses webpack under the hood.\n\nAfter configuring your webpack loaders in `styleguide.config.js` you will need to also configure Babel. First install all the required Babel dependencies:\n\n```bash\nnpm install --save-dev babel-loader @babel/core @babel/preset-react\n```\n\nNext, you'll want to configure Babel to use the appropriate presets, here is an example `.babelrc` file:\n\n```json\n{\n  \"presets\": [\"@babel/preset-react\"]\n}\n```\n\nThat's it, notice that we don't need to install webpack as it's already included by Next.js.\n\n## Non-webpack projects\n\nTo use features, not supported by browsers, like JSX, you’ll need to compile your code with Babel or another tool.\n\nLet’s configure Styleguidist with Babel.\n\n> **Info:** Babel is not required for Styleguidist or React, but likely you’ll want to use it to run your code.\n\nFirst, install the Babel webpack loader:\n\n```bash\nnpm install --save-dev babel-loader\n```\n\n> **Caution:** If your project doesn’t use webpack you still need to add webpack loaders for your files, otherwise Styleguidist won’t be able to load your code.\n\nThen, add a `webpackConfig` section to your `styleguide.config.js`\n\n```js\nmodule.exports = {\n  webpackConfig: {\n    module: {\n      rules: [\n        {\n          test: /\\.jsx?$/,\n          exclude: /node_modules/,\n          loader: 'babel-loader'\n        }\n      ]\n    }\n  }\n}\n```\n\nor create a webpack config, `webpack.config.js`:\n\n```js\nmodule: {\n  rules: [\n    {\n      test: /\\.jsx?$/,\n      exclude: /node_modules/,\n      loader: 'babel-loader'\n    }\n  ]\n}\n```\n\nIf you don’t have Babel in your project, you need to install it with two presets — [env](https://babeljs.io/docs/en/babel-preset-env) and [react](https://babeljs.io/docs/en/babel-preset-react):\n\n```bash\nnpm install --save-dev @babel/core @babel/preset-env @babel/preset-react\n```\n\nAnd create a config file in your project’s root folder, `babel.config.js`:\n\n```js\nmodule.exports = {\n  presets: [\n    [\n      '@babel/env',\n      {\n        modules: false,\n        useBuiltIns: 'usage'\n      }\n    ],\n    '@babel/react'\n  ]\n}\n```\n\nWe also recommend to add a [browserslist](https://github.com/browserslist/browserslist) config to your `package.json` file like this:\n\n```diff\n+  \"browserslist\": [\n+    \">1%\",\n+    \"last 1 version\",\n+    \"Firefox ESR\",\n+    \"not dead\"\n+  ]\n```\n\nThis will tell Babel (and some other tools) which browsers you support, so it won’t apply unnecessary transformations, making code smaller and faster.\n\n## When nothing else works\n\nIn very rare cases, like using legacy or third-party libraries, you may need to change webpack options that Styleguidist doesn’t allow you to change via `webpackConfig` options. In this case, you can use [dangerouslyUpdateWebpackConfig](Configuration.md#dangerouslyupdatewebpackconfig) option.\n\n> **Danger:** You may break Styleguidist using this option, use it at your own risk.\n"
  },
  {
    "path": "examples/.eslintrc",
    "content": "{\n\t\"parser\": \"babel-eslint\",\n\t\"extends\": \"tamia/react\",\n\t\"rules\": {\n\t\t\"valid-jsdoc\": 0,\n\t\t\"react/prefer-stateless-function\": 0\n\t},\n\t\"overrides\": [\n\t\t{\n\t\t\t\"files\": [\"*.ts\", \"*.tsx\"],\n\t\t\t\"parser\": \"@typescript-eslint/parser\",\n\t\t\t\"plugins\": [\"@typescript-eslint\"],\n\t\t\t\"extends\": [\n\t\t\t\t\"tamia/typescript-react\"\n\t\t\t]\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "examples/basic/Readme.md",
    "content": "# React Styleguidist basic example style guide\n\nSee [deployed version](https://react-styleguidist.js.org/examples/basic/).\n\n![](https://d3vv6lp55qjaqc.cloudfront.net/items/0U313M3L0p120g2Y1y3J/Image%202016-04-12%20at%207.25.03%20PM.png)\n\nHow to start locally:\n\n```\ngit clone https://github.com/styleguidist/react-styleguidist.git\ncd react-styleguidist/examples/basic\nnpm install\nnpx styleguidist server\n```\n\nThen open [http://localhost:6060](http://localhost:6060) in your browser.\n"
  },
  {
    "path": "examples/basic/babel.config.js",
    "content": "module.exports = {\n\tpresets: [\n\t\t[\n\t\t\t'@babel/env',\n\t\t\t{\n\t\t\t\tmodules: false,\n\t\t\t\tuseBuiltIns: 'usage',\n\t\t\t\tcorejs: 3,\n\t\t\t},\n\t\t],\n\t\t'@babel/react',\n\t],\n\tplugins: ['@babel/plugin-proposal-class-properties'],\n};\n"
  },
  {
    "path": "examples/basic/package.json",
    "content": "{\n  \"name\": \"react-styleguidist-example-basic\",\n  \"description\": \"React styleguidist basic example\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"homepage\": \"https://github.com/styleguidist/react-styleguidist\",\n  \"author\": {\n    \"name\": \"Artem Sapegin\",\n    \"url\": \"http://sapegin.me/\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/styleguidist/react-styleguidist.git\"\n  },\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=10\"\n  },\n  \"scripts\": {\n    \"styleguide\": \"styleguidist server\",\n    \"styleguide:build\": \"styleguidist build\"\n  },\n  \"dependencies\": {\n    \"dog-names\": \"^2.0.0\",\n    \"lodash\": \"^4.17.19\",\n    \"prop-types\": \"^15.7.2\",\n    \"react\": \"^17.0.2\",\n    \"react-dom\": \"^17.0.2\",\n    \"react-styleguidist\": \"^12.0.1\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.9.0\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.8.3\",\n    \"@babel/preset-env\": \"^7.9.0\",\n    \"@babel/preset-react\": \"^7.18.6\",\n    \"babel-loader\": \"^8.1.0\",\n    \"css-loader\": \"^6.7.1\",\n    \"file-loader\": \"^6.2.0\",\n    \"style-loader\": \"^3.3.1\",\n    \"url-loader\": \"^4.1.1\",\n    \"webpack\": \"^5.72.0\"\n  }\n}\n"
  },
  {
    "path": "examples/basic/src/components/Button/Button.css",
    "content": ".button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n\n.button[disabled] {\n\topacity: 0.35;\n\tcursor: default;\n}\n\n.checks {\n\tbackground-image: linear-gradient(45deg, #f5f5f5 25%, transparent 25%),\n\t\tlinear-gradient(-45deg, #f5f5f5 25%, transparent 25%),\n\t\tlinear-gradient(45deg, transparent 75%, #f5f5f5 75%),\n\t\tlinear-gradient(-45deg, transparent 75%, #f5f5f5 75%);\n\tbackground-size: 16px 16px;\n\tbackground-position: 0 0, 0 8px, 8px -8px, -8px 0px;\n}\n"
  },
  {
    "path": "examples/basic/src/components/Button/Button.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './Button.css';\n\n/**\n * The only true button.\n */\nexport default function Button({ color, size, onClick, disabled, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: Button.sizes[size],\n\t};\n\n\treturn (\n\t\t<button className=\"button\" style={styles} onClick={onClick} disabled={disabled}>\n\t\t\t{children}\n\t\t</button>\n\t);\n}\nButton.propTypes = {\n\t/** Button label */\n\tchildren: PropTypes.node.isRequired,\n\t/** The color for the button */\n\tcolor: PropTypes.string,\n\t/** The size of the button */\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n\t/** Disable button */\n\tdisabled: PropTypes.bool,\n\t/** Gets called when the user clicks on the button */\n\tonClick: PropTypes.func,\n};\nButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n\tonClick: (event) => {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log('You have clicked me!', event.target);\n\t},\n};\nButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n"
  },
  {
    "path": "examples/basic/src/components/Button/Readme.md",
    "content": "Basic button:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nBig pink button:\n\n```jsx\n<Button size=\"large\" color=\"deeppink\">\n  Click Me\n</Button>\n```\n\nAnd you _can_ **use** `any` [Markdown](http://daringfireball.net/projects/markdown/) here.\n\nFenced code blocks with `js`, `jsx` or `javascript` languages are rendered as a interactive playgrounds:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nAdd padding between examples in a block by passing a `padded` modifier (` ```jsx padded `):\n\n```jsx padded\n<Button>Push Me</Button>\n<Button>Click Me</Button>\n<Button>Tap Me</Button>\n```\n\nYou can add a custom props to an example wrapper (` ```js { \"props\": { \"className\": \"checks\" } } `):\n\n```js { \"props\": { \"className\": \"checks\" } }\n<Button>I’m transparent!</Button>\n```\n\nOr disable an editor by passing a `noeditor` modifier (` ```js noeditor `):\n\n```jsx noeditor\n<Button>Push Me</Button>\n```\n\nTo render an example as highlighted source code add a `static` modifier: (` ```js static `):\n\n```js static\nimport React from 'react'\n```\n\nFenced blocks with other languages are rendered as highlighted code:\n\n```html\n<h1>Hello world</h1>\n```\n\nCurrent component (like `Button` in this example) is always accessible by its name in the example code. If you want to use other components, you need to explicitly import them:\n\n```jsx\nimport Placeholder from '../Placeholder'\n;<Button>\n  <Placeholder />\n</Button>\n```\n\nOr you can explicitly import everything, to make examples easier to copy into your app code:\n\n```jsx\nimport React from 'react'\nimport Button from 'rsg-example/components/Button'\nimport Placeholder from 'rsg-example/components/Placeholder'\n;<Button>\n  <Placeholder />\n</Button>\n```\n\n_Note: `rsg-example` module is an alias defined by the [moduleAliases](https://react-styleguidist.js.org/docs/configuration#modulealiases) config option._\n\nEach example's state can be accessed by React hook `useState`:\n\n```jsx\nconst [isOpen, setisOpen] = React.useState(false)\n;<div>\n  <Button\n    size=\"small\"\n    onClick={() => setisOpen(true)}\n    disabled={isOpen}\n  >\n    Show Me\n  </Button>\n  {isOpen && (\n    <Button size=\"small\" onClick={() => setisOpen(false)}>\n      Hide Me\n    </Button>\n  )}\n</div>\n```\n\nYou can change the default state:\n\n```jsx\nconst [count, setCount] = React.useState(42)\n;<Button onClick={() => setCount(count + 1)}>{count}</Button>\n```\n"
  },
  {
    "path": "examples/basic/src/components/Button/index.js",
    "content": "export { default } from './Button';\n"
  },
  {
    "path": "examples/basic/src/components/CounterButton/CounterButton.js",
    "content": "import React, { Component } from 'react';\n\n/**\n * Button that counts how many times it was pressed and exposes a `@public` method to reset itself.\n */\nexport default class CounterButton extends Component {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.state = {\n\t\t\tvalue: 0,\n\t\t};\n\t}\n\n\t/**\n\t * Sets the counter to a particular value.\n\t *\n\t * @public\n\t * @version 1.0.5\n\t * @param {Number} [newValue=0] New value for the counter\n\t * @returns {string} Test\n\t */\n\tset(newValue = 0) {\n\t\tthis.setState({\n\t\t\tvalue: parseInt(newValue, 10),\n\t\t});\n\t}\n\n\t/**\n\t * Increments the counter. This method is not marked @public and is not visible in the style guide.\n\t */\n\thandleIncrement = () => {\n\t\tthis.setState({\n\t\t\tvalue: this.state.value + 1,\n\t\t});\n\t};\n\n\trender() {\n\t\treturn (\n\t\t\t<button className=\"button\" onClick={this.handleIncrement}>\n\t\t\t\t{this.state.value}\n\t\t\t</button>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/basic/src/components/CounterButton/Readme.md",
    "content": "```js\nimport Button from '../Button'\nlet ref\n;<div>\n  <CounterButton ref={r => (ref = r)} />\n  <Button size=\"small\" onClick={() => ref.set(0)}>\n    Reset\n  </Button>\n</div>\n```\n"
  },
  {
    "path": "examples/basic/src/components/CounterButton/index.js",
    "content": "export { default } from './CounterButton';\n"
  },
  {
    "path": "examples/basic/src/components/Label/Label.md",
    "content": "Basic Label:\n\n    <Label>Hi there !!!</Label>\n\nPink background label:\n\n    <Label background=\"deeppink\" color=\"white\">Click Me</Label>\n"
  },
  {
    "path": "examples/basic/src/components/Label/index.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\n/**\n * The only true label.\n */\nexport default function Label({ color, background, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tbackground,\n\t\tpadding: '.5em 1em',\n\t\tborderRadius: '0.3em',\n\t\tfontFamily: 'arial',\n\t};\n\n\t// eslint-disable-next-line jsx-a11y/label-has-for\n\treturn <label style={styles}>{children}</label>;\n}\nLabel.propTypes = {\n\t/**\n\t * Label text.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\tcolor: PropTypes.string,\n\tbackground: PropTypes.string,\n};\nLabel.defaultProps = {\n\tcolor: '#333',\n\tbackground: 'white',\n};\n"
  },
  {
    "path": "examples/basic/src/components/Placeholder/Placeholder.css",
    "content": ".placeholder {\n\tbackground: #ccc;\n}\n"
  },
  {
    "path": "examples/basic/src/components/Placeholder/Placeholder.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport './Placeholder.css';\n\n/**\n * Image placeholders.\n */\nexport default class Placeholder extends Component {\n\tstatic propTypes = {\n\t\ttype: PropTypes.oneOf([\n\t\t\t'animal',\n\t\t\t'bacon',\n\t\t\t'beard',\n\t\t\t'bear',\n\t\t\t'cat',\n\t\t\t'food',\n\t\t\t'city',\n\t\t\t'nature',\n\t\t\t'people',\n\t\t]),\n\t\twidth: PropTypes.number,\n\t\theight: PropTypes.number,\n\t\talt: PropTypes.string,\n\t};\n\n\tstatic defaultProps = {\n\t\ttype: 'animal',\n\t\twidth: 150,\n\t\theight: 150,\n\t\talt: 'Photo of an animal',\n\t};\n\n\tgetImageUrl() {\n\t\tconst { type, width, height } = this.props;\n\t\tconst types = {\n\t\t\tanimal: `http://placeimg.com/${width}/${height}/animals`,\n\t\t\tbacon: `http://baconmockup.com/${width}/${height}`,\n\t\t\tbear: `http://www.placebear.com/${width}/${height}`,\n\t\t\tbeard: `http://placebeard.it/${width}/${height}`,\n\t\t\tcat: `http://lorempixel.com/${width}/${height}/cats`,\n\t\t\tcity: `http://lorempixel.com/${width}/${height}/city`,\n\t\t\tfood: `http://lorempixel.com/${width}/${height}/food`,\n\t\t\tnature: `http://lorempixel.com/${width}/${height}/nature`,\n\t\t\tpeople: `http://lorempixel.com/${width}/${height}/people`,\n\t\t};\n\t\treturn types[type];\n\t}\n\n\trender() {\n\t\tconst { width, height, alt } = this.props;\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"placeholder\"\n\t\t\t\tsrc={this.getImageUrl()}\n\t\t\t\twidth={width}\n\t\t\t\theight={height}\n\t\t\t\talt={alt}\n\t\t\t/>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/basic/src/components/Placeholder/Readme.md",
    "content": "```jsx\n<Placeholder type=\"beard\" />\n```\n"
  },
  {
    "path": "examples/basic/src/components/Placeholder/index.js",
    "content": "export { default } from './Placeholder';\n"
  },
  {
    "path": "examples/basic/src/components/PushButton/PushButton.css",
    "content": ".push-button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/basic/src/components/PushButton/PushButton.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './PushButton.css';\n\n/**\n * An example-less button with custom display name.\n * @visibleName Push Button 🎉\n */\nexport default function PushButton({ color, size, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: PushButton.sizes[size],\n\t};\n\n\treturn (\n\t\t<button className=\"push-button\" style={styles}>\n\t\t\t{children}\n\t\t</button>\n\t);\n}\nPushButton.propTypes = {\n\t/**\n\t * PushButton label.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\tcolor: PropTypes.string,\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n};\nPushButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n};\nPushButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n"
  },
  {
    "path": "examples/basic/src/components/PushButton/index.js",
    "content": "export { default } from './PushButton';\n"
  },
  {
    "path": "examples/basic/src/components/RandomButton/RandomButton.css",
    "content": ".random-button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\tfont-size: 16px;\n\tfont-weight: bold;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/basic/src/components/RandomButton/RandomButton.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport sample from 'lodash/sample';\n\nimport './RandomButton.css';\n\n/**\n * Button that changes label on every click.\n */\n// eslint-disable-next-line import/prefer-default-export\nexport class RandomButton extends Component {\n\tstatic propTypes = {\n\t\t/**\n\t\t * List of possible labels.\n\t\t */\n\t\tvariants: PropTypes.array.isRequired,\n\t};\n\n\tconstructor(props) {\n\t\tsuper();\n\t\tthis.state = {\n\t\t\tlabel: sample(props.variants),\n\t\t};\n\t}\n\n\thandleClick = () => {\n\t\tthis.setState({\n\t\t\tlabel: sample(this.props.variants),\n\t\t});\n\t};\n\n\trender() {\n\t\treturn (\n\t\t\t<button className=\"random-button\" onClick={this.handleClick}>\n\t\t\t\t{this.state.label}\n\t\t\t</button>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/basic/src/components/RandomButton/Readme.md",
    "content": "You can `import` external files in your examples:\n\n```jsx\nimport { all } from 'dog-names'\nimport { RandomButton } from '../RandomButton'\n;<RandomButton variants={all} />\n```\n"
  },
  {
    "path": "examples/basic/src/components/RandomButton/index.js",
    "content": "// eslint-disable-next-line import/prefer-default-export\nexport { RandomButton } from './RandomButton';\n"
  },
  {
    "path": "examples/basic/src/components/WrappedButton/Readme.md",
    "content": "Enhanced/Decorated components work as well:\n\n```jsx\n<WrappedButton>I'm a wrapped button</WrappedButton>\n```\n"
  },
  {
    "path": "examples/basic/src/components/WrappedButton/WrappedButton.css",
    "content": ".wrapped-button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/basic/src/components/WrappedButton/WrappedButton.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\n/**\n * A button wrapped by a Decorator/Enhancer\n *\n * @version 1.0.1\n * @author [Jeremy Gayed](https://github.com/tizmagik)\n * @deprecated Use the [only true button](#button) instead\n */\nconst WrappedButton = ({ color, size, children }) => {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: WrappedButton.sizes[size],\n\t};\n\n\treturn (\n\t\t<button className=\"wrapped-button\" style={styles}>\n\t\t\t{children}\n\t\t</button>\n\t);\n};\nWrappedButton.propTypes = {\n\t/**\n\t * Button label.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\t/**\n\t * The color for the button\n\t *\n\t * @see Check [Wikipedia](https://en.wikipedia.org/wiki/Web_colors#HTML_color_names) for a list of color names\n\t */\n\tcolor: PropTypes.string,\n\t/**\n\t * The size of the Button\n\t *\n\t * @since Version 1.0.1\n\t */\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n\t/**\n\t * The width of the button\n\t *\n\t * @deprecated Do not use! Use size instead!\n\t */\n\twidth: PropTypes.number,\n\t/**\n\t * Gets called when the user clicks on the button\n\t *\n\t * @param { SyntheticEvent } event The react `SyntheticEvent`\n\t * @return { SyntheticEvent } The `onClick` `SyntheticEvent`\n\t */\n\tonClick: PropTypes.func,\n\t/**\n\t * A prop that should not be visible in the doc.\n\t * @ignore\n\t */\n\tignoredProp: PropTypes.bool,\n};\nWrappedButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n};\nWrappedButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n\nconst Decorator = (Composed) =>\n\tclass MyHOC extends Component {\n\t\trender() {\n\t\t\treturn <Composed {...this.props} />;\n\t\t}\n\t};\n\nexport default Decorator(WrappedButton);\n"
  },
  {
    "path": "examples/basic/src/components/WrappedButton/index.js",
    "content": "export { default } from './WrappedButton';\n"
  },
  {
    "path": "examples/basic/styleguide.config.js",
    "content": "const path = require('path');\nconst { version } = require('./package');\n\nmodule.exports = {\n\tcomponents: 'src/components/**/[A-Z]*.js',\n\tdefaultExample: true,\n\tmoduleAliases: {\n\t\t'rsg-example': path.resolve(__dirname, 'src'),\n\t},\n\tribbon: {\n\t\turl: 'https://github.com/styleguidist/react-styleguidist',\n\t},\n\tversion,\n\twebpackConfig: {\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\t\texclude: /node_modules/,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.css$/,\n\t\t\t\t\tuse: ['style-loader', 'css-loader'],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n};\n"
  },
  {
    "path": "examples/cra/Readme.md",
    "content": "# React Styleguidist Create React App example style guide\n\n![](https://d3vv6lp55qjaqc.cloudfront.net/items/0U313M3L0p120g2Y1y3J/Image%202016-04-12%20at%207.25.03%20PM.png)\n\nHow to start locally:\n\n```\ngit clone https://github.com/styleguidist/react-styleguidist.git\ncd react-styleguidist/examples/cra\nnpm install\nnpx styleguidist server\n```\n\nThen open [http://localhost:6060](http://localhost:6060) in your browser.\n"
  },
  {
    "path": "examples/cra/package.json",
    "content": "{\n  \"name\": \"react-styleguidist-example-cra\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"homepage\": \"https://github.com/styleguidist/react-styleguidist\",\n  \"author\": {\n    \"name\": \"Artem Sapegin\",\n    \"url\": \"http://sapegin.me/\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/styleguidist/react-styleguidist.git\"\n  },\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=10\"\n  },\n  \"devDependencies\": {\n    \"react-scripts\": \"^3.2.0\",\n    \"react-styleguidist\": \"^9.1.16\"\n  },\n  \"dependencies\": {\n    \"dog-names\": \"^2.0.0\",\n    \"lodash\": \"^4.17.15\",\n    \"prop-types\": \"^15.7.2\",\n    \"react\": \"^16.10.2\",\n    \"react-dom\": \"^16.10.2\"\n  },\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\",\n    \"styleguide\": \"styleguidist server\",\n    \"styleguide:build\": \"styleguidist build\"\n  }\n}\n"
  },
  {
    "path": "examples/cra/public/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <link rel=\"shortcut icon\" href=\"%PUBLIC_URL%/favicon.ico\">\n    <!--\n      Notice the use of %PUBLIC_URL% in the tag above.\n      It will be replaced with the URL of the `public` folder during the build.\n      Only files inside the `public` folder can be referenced from the HTML.\n\n      Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n      work correctly both with client-side routing and a non-root public URL.\n      Learn how to configure a non-root public URL by running `npm run build`.\n    -->\n    <title>React App</title>\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <!--\n      This HTML file is a template.\n      If you open it directly in the browser, you will see an empty page.\n\n      You can add webfonts, meta tags, or analytics to this file.\n      The build step will place the bundled scripts into the <body> tag.\n\n      To begin the development, run `npm start`.\n      To create a production bundle, use `npm run build`.\n    -->\n  </body>\n</html>\n"
  },
  {
    "path": "examples/cra/src/App.css",
    "content": ".App {\n\ttext-align: center;\n}\n\n.App-logo {\n\tanimation: App-logo-spin infinite 20s linear;\n\theight: 80px;\n}\n\n.App-header {\n\tbackground-color: #222;\n\theight: 150px;\n\tpadding: 20px;\n\tcolor: white;\n}\n\n.App-intro {\n\tfont-size: large;\n}\n\n@keyframes App-logo-spin {\n\tfrom {\n\t\ttransform: rotate(0deg);\n\t}\n\tto {\n\t\ttransform: rotate(360deg);\n\t}\n}\n"
  },
  {
    "path": "examples/cra/src/App.js",
    "content": "/* eslint-disable */\n\nimport React, { Component } from 'react';\nimport logo from './logo.svg';\nimport './App.css';\n\nclass App extends Component {\n\trender() {\n\t\treturn (\n\t\t\t<div className=\"App\">\n\t\t\t\t<div className=\"App-header\">\n\t\t\t\t\t<img src={logo} className=\"App-logo\" alt=\"React logo\" />\n\t\t\t\t\t<h2>Welcome to React</h2>\n\t\t\t\t</div>\n\t\t\t\t<p className=\"App-intro\">\n\t\t\t\t\tTo get started, edit <code>src/App.js</code> and save to reload.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n}\n\nexport default App;\n"
  },
  {
    "path": "examples/cra/src/App.test.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\n\nit('renders without crashing', () => {\n\tconst div = document.createElement('div');\n\tReactDOM.render(<App />, div);\n});\n"
  },
  {
    "path": "examples/cra/src/components/Button.css",
    "content": ".button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/cra/src/components/Button.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './Button.css';\n\n/**\n * The only true button.\n */\nexport default function Button({ color, size, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: Button.sizes[size],\n\t};\n\n\treturn (\n\t\t<button className=\"button\" style={styles}>\n\t\t\t{children}\n\t\t</button>\n\t);\n}\nButton.propTypes = {\n\t/**\n\t * Button label.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\tcolor: PropTypes.string,\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n};\nButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n};\nButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n"
  },
  {
    "path": "examples/cra/src/components/Button.md",
    "content": "Basic button:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nBig pink button:\n\n```jsx\n<Button size=\"large\" color=\"deeppink\">\n  Click Me\n</Button>\n```\n\nAnd you _can_ **use** `any` [Markdown](http://daringfireball.net/projects/markdown/) here.\n\nFenced code blocks with `js`, `jsx` or `javascript` languages are rendered as an interactive playgrounds:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nYou can disable an editor by passing a `noeditor` modifier (` ```js noeditor `):\n\n```jsx noeditor\n<Button>Push Me</Button>\n```\n\nTo render an example as highlighted source code add a `static` modifier (` ```js static `):\n\n```js static\nimport React from 'react'\n```\n\nFenced blocks with other languages are rendered as highlighted code:\n\n```html\n<h1>Hello world</h1>\n```\n"
  },
  {
    "path": "examples/cra/src/components/Placeholder.css",
    "content": ".placeholder {\n\tbackground: #ccc;\n}\n"
  },
  {
    "path": "examples/cra/src/components/Placeholder.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport './Placeholder.css';\n\n/**\n * Image placeholders.\n */\nexport default class Placeholder extends Component {\n\tstatic propTypes = {\n\t\ttype: PropTypes.oneOf([\n\t\t\t'animal',\n\t\t\t'bacon',\n\t\t\t'beard',\n\t\t\t'bear',\n\t\t\t'cat',\n\t\t\t'food',\n\t\t\t'city',\n\t\t\t'nature',\n\t\t\t'people',\n\t\t]),\n\t\twidth: PropTypes.number,\n\t\theight: PropTypes.number,\n\t\talt: PropTypes.string,\n\t};\n\n\tstatic defaultProps = {\n\t\ttype: 'animal',\n\t\twidth: 150,\n\t\theight: 150,\n\t\talt: 'Photo of an animal',\n\t};\n\n\tgetImageUrl() {\n\t\tconst { type, width, height } = this.props;\n\t\tconst types = {\n\t\t\tanimal: `http://placeimg.com/${width}/${height}/animals`,\n\t\t\tbacon: `http://baconmockup.com/${width}/${height}`,\n\t\t\tbear: `http://www.placebear.com/${width}/${height}`,\n\t\t\tbeard: `http://placebeard.it/${width}/${height}`,\n\t\t\tcat: `http://lorempixel.com/${width}/${height}/cats`,\n\t\t\tcity: `http://lorempixel.com/${width}/${height}/city`,\n\t\t\tfood: `http://lorempixel.com/${width}/${height}/food`,\n\t\t\tnature: `http://lorempixel.com/${width}/${height}/nature`,\n\t\t\tpeople: `http://lorempixel.com/${width}/${height}/people`,\n\t\t};\n\t\treturn types[type];\n\t}\n\n\trender() {\n\t\tconst { width, height, alt } = this.props;\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"placeholder\"\n\t\t\t\tsrc={this.getImageUrl()}\n\t\t\t\twidth={width}\n\t\t\t\theight={height}\n\t\t\t\talt={alt}\n\t\t\t/>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/cra/src/components/Placeholder.md",
    "content": "```jsx\n<Placeholder type=\"beard\" />\n```\n"
  },
  {
    "path": "examples/cra/src/components/RandomButton.css",
    "content": ".random-button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\tfont-size: 16px;\n\tfont-weight: bold;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/cra/src/components/RandomButton.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport sample from 'lodash/sample';\n\nimport './RandomButton.css';\n\n/**\n * Button that changes label on every click.\n */\nexport default class RandomButton extends Component {\n\tstatic propTypes = {\n\t\t/**\n\t\t * List of possible labels.\n\t\t */\n\t\tvariants: PropTypes.array.isRequired,\n\t};\n\n\tconstructor(props) {\n\t\tsuper();\n\t\tthis.state = {\n\t\t\tlabel: sample(props.variants),\n\t\t};\n\t}\n\n\thandleClick = () => {\n\t\tthis.setState({\n\t\t\tlabel: sample(this.props.variants),\n\t\t});\n\t};\n\n\trender() {\n\t\treturn (\n\t\t\t<button className=\"random-button\" onClick={this.handleClick}>\n\t\t\t\t{this.state.label}\n\t\t\t</button>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/cra/src/components/RandomButton.md",
    "content": "You can `import` external files in your examples:\n\n```jsx\nimport { all } from 'dog-names'\n;<RandomButton variants={all} />\n```\n"
  },
  {
    "path": "examples/cra/src/index.css",
    "content": "body {\n\tmargin: 0;\n\tpadding: 0;\n\tfont-family: sans-serif;\n}\n"
  },
  {
    "path": "examples/cra/src/index.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\nimport './index.css';\n\nReactDOM.render(<App />, document.getElementById('root'));\n"
  },
  {
    "path": "examples/cra/styleguide.config.js",
    "content": "// Empty config file to trick Styleguidist not to use the config file from ../..\n// You don't need an empty config in your project.\n"
  },
  {
    "path": "examples/customised/Readme.md",
    "content": "# React Styleguidist customized example style guide\n\n![](https://d3vv6lp55qjaqc.cloudfront.net/items/0h0d3k2f172v3t3a2d1U/customised.png)\n\nHow to start locally:\n\n```\ngit clone https://github.com/styleguidist/react-styleguidist.git\ncd react-styleguidist/examples/customised\nnpm install\nnpx styleguidist server\n```\n\nThen open [http://localhost:6060](http://localhost:6060) in your browser.\n"
  },
  {
    "path": "examples/customised/babel.config.js",
    "content": "module.exports = {\n\tpresets: [\n\t\t[\n\t\t\t'@babel/env',\n\t\t\t{\n\t\t\t\tdebug: true,\n\t\t\t\tmodules: false,\n\t\t\t\tuseBuiltIns: 'usage',\n\t\t\t\tcorejs: 3,\n\t\t\t},\n\t\t],\n\t\t'@babel/react',\n\t],\n\tplugins: ['@babel/plugin-proposal-class-properties'],\n};\n"
  },
  {
    "path": "examples/customised/package.json",
    "content": "{\n  \"name\": \"react-styleguidist-example-customised\",\n  \"description\": \"React styleguidist customised example\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"homepage\": \"https://github.com/styleguidist/react-styleguidist\",\n  \"author\": {\n    \"name\": \"Artem Sapegin\",\n    \"url\": \"http://sapegin.me/\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/styleguidist/react-styleguidist.git\"\n  },\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=10\"\n  },\n  \"dependencies\": {\n    \"dog-names\": \"^2.0.0\",\n    \"lodash\": \"^4.17.19\",\n    \"prop-types\": \"^15.7.2\",\n    \"react\": \"^16.10.2\",\n    \"react-dom\": \"^16.10.2\"\n  },\n  \"scripts\": {\n    \"styleguide\": \"styleguidist server\",\n    \"styleguide:build\": \"styleguidist build\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.6.4\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.5.5\",\n    \"@babel/preset-env\": \"^7.6.3\",\n    \"@babel/preset-react\": \"^7.6.3\",\n    \"babel-loader\": \"^8.0.6\",\n    \"css-loader\": \"^3.2.0\",\n    \"react-styleguidist\": \"^9.1.16\",\n    \"style-loader\": \"^1.0.0\",\n    \"url-loader\": \"^2.2.0\",\n    \"webpack\": \"^4.41.1\"\n  }\n}\n"
  },
  {
    "path": "examples/customised/src/components/Button/Button.css",
    "content": ".root {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/customised/src/components/Button/Button.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport s from './Button.css';\n\n/**\n * The only true button.\n */\nexport default function Button({ color, size, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: Button.sizes[size],\n\t};\n\n\treturn (\n\t\t<button className={s.root} style={styles}>\n\t\t\t{children}\n\t\t</button>\n\t);\n}\nButton.propTypes = {\n\t/**\n\t * Button label.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\tcolor: PropTypes.string,\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n};\nButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n};\nButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n"
  },
  {
    "path": "examples/customised/src/components/Button/Button.json",
    "content": "{\n  \"tags\": [ \"atom\", \"interactive\" ]\n}\n"
  },
  {
    "path": "examples/customised/src/components/Button/Readme.md",
    "content": "Basic button:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nBig pink button:\n\n```jsx\n<Button size=\"large\" color=\"deeppink\">\n  Click Me\n</Button>\n```\n\nAnd you _can_ **use** `any` [Markdown](http://daringfireball.net/projects/markdown/) here.\n\nFenced code blocks with `js`, `jsx` or `javascript` languages are rendered as an interactive playgrounds:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nYou can disable an editor by passing a `noeditor` modifier (` ```js noeditor `):\n\n```jsx noeditor\n<Button>Push Me</Button>\n```\n\nTo render an example as highlighted source code add a `static` modifier (` ```js static `):\n\n```js static\nimport React from 'react'\n```\n\nFenced blocks with other languages are rendered as highlighted code:\n\n```html\n<h1>Hello world</h1>\n```\n"
  },
  {
    "path": "examples/customised/src/components/Button/index.js",
    "content": "export { default } from './Button';\n"
  },
  {
    "path": "examples/customised/src/components/Placeholder/Placeholder.css",
    "content": ".root {\n\tbackground: #ccc;\n}\n"
  },
  {
    "path": "examples/customised/src/components/Placeholder/Placeholder.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport s from './Placeholder.css';\n\n/**\n * Image placeholders.\n */\nexport default class Placeholder extends Component {\n\tstatic propTypes = {\n\t\ttype: PropTypes.oneOf([\n\t\t\t'animal',\n\t\t\t'bacon',\n\t\t\t'beard',\n\t\t\t'bear',\n\t\t\t'cat',\n\t\t\t'food',\n\t\t\t'city',\n\t\t\t'nature',\n\t\t\t'people',\n\t\t]),\n\t\twidth: PropTypes.number,\n\t\theight: PropTypes.number,\n\t\talt: PropTypes.string,\n\t};\n\n\tstatic defaultProps = {\n\t\ttype: 'animal',\n\t\twidth: 150,\n\t\theight: 150,\n\t\talt: 'Photo of an animal',\n\t};\n\n\tgetImageUrl() {\n\t\tconst { type, width, height } = this.props;\n\t\tconst types = {\n\t\t\tanimal: `http://placeimg.com/${width}/${height}/animals`,\n\t\t\tbacon: `http://baconmockup.com/${width}/${height}`,\n\t\t\tbear: `http://www.placebear.com/${width}/${height}`,\n\t\t\tbeard: `http://placebeard.it/${width}/${height}`,\n\t\t\tcat: `http://lorempixel.com/${width}/${height}/cats`,\n\t\t\tcity: `http://lorempixel.com/${width}/${height}/city`,\n\t\t\tfood: `http://lorempixel.com/${width}/${height}/food`,\n\t\t\tnature: `http://lorempixel.com/${width}/${height}/nature`,\n\t\t\tpeople: `http://lorempixel.com/${width}/${height}/people`,\n\t\t};\n\t\treturn types[type];\n\t}\n\n\trender() {\n\t\tconst { width, height, alt } = this.props;\n\t\treturn (\n\t\t\t<img className={s.root} src={this.getImageUrl()} width={width} height={height} alt={alt} />\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/customised/src/components/Placeholder/Placeholder.json",
    "content": "{\n  \"tags\": [ \"image\" ]\n}\n"
  },
  {
    "path": "examples/customised/src/components/Placeholder/Readme.md",
    "content": "```jsx\n<Placeholder type=\"beard\" />\n```\n"
  },
  {
    "path": "examples/customised/src/components/Placeholder/index.js",
    "content": "export { default } from './Placeholder';\n"
  },
  {
    "path": "examples/customised/src/components/RandomButton/RandomButton.css",
    "content": ".root {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\tfont-size: 16px;\n\tfont-weight: bold;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/customised/src/components/RandomButton/RandomButton.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport sample from 'lodash/sample';\n\nimport s from './RandomButton.css';\n\n/**\n * Button that changes label on every click.\n */\nexport default class RandomButton extends Component {\n\tstatic propTypes = {\n\t\t/**\n\t\t * List of possible labels.\n\t\t */\n\t\tvariants: PropTypes.array.isRequired,\n\t};\n\n\tconstructor(props) {\n\t\tsuper();\n\t\tthis.state = {\n\t\t\tlabel: sample(props.variants),\n\t\t};\n\t}\n\n\thandleClick = () => {\n\t\tthis.setState({\n\t\t\tlabel: sample(this.props.variants),\n\t\t});\n\t};\n\n\trender() {\n\t\treturn (\n\t\t\t<button className={s.root} onClick={this.handleClick}>\n\t\t\t\t{this.state.label}\n\t\t\t</button>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/customised/src/components/RandomButton/RandomButton.json",
    "content": "{\n  \"tags\": [ \"atom\", \"interactive\", \"random\" ]\n}\n"
  },
  {
    "path": "examples/customised/src/components/RandomButton/Readme.md",
    "content": "You can `import` external files in your examples:\n\n```jsx\nimport { all } from 'dog-names'\n;<RandomButton variants={all} />\n```\n"
  },
  {
    "path": "examples/customised/src/components/RandomButton/index.js",
    "content": "export { default } from './RandomButton';\n"
  },
  {
    "path": "examples/customised/styleguide/components/Logo.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled from 'rsg-components/Styled';\nimport logo from './logo.svg';\n\nconst styles = ({ fontFamily, color }) => ({\n\tlogo: {\n\t\tdisplay: 'flex',\n\t\talignItems: 'center',\n\t\tmargin: 0,\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: 18,\n\t\tfontWeight: 'normal',\n\t\tcolor: color.baseBackground,\n\t},\n\timage: {\n\t\twidth: '2.5em',\n\t\tmarginLeft: '-0.5em',\n\t},\n});\n\nexport function LogoRenderer({ classes, children }) {\n\treturn (\n\t\t<h1 className={classes.logo}>\n\t\t\t<img className={classes.image} src={logo} alt=\"React logo\" />\n\t\t\t{children}\n\t\t</h1>\n\t);\n}\n\nLogoRenderer.propTypes = {\n\tclasses: PropTypes.object.isRequired,\n\tchildren: PropTypes.node,\n};\n\nexport default Styled(styles)(LogoRenderer);\n"
  },
  {
    "path": "examples/customised/styleguide/components/SectionsRenderer.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled from 'rsg-components/Styled';\nimport Heading from 'rsg-components/Heading';\n// Import default implementation from react-styleguidist using the full path\nimport DefaultSectionsRenderer from 'react-styleguidist/lib/client/rsg-components/Sections/SectionsRenderer';\n\nconst styles = ({ fontFamily, space }) => ({\n\theadingSpacer: {\n\t\tmarginBottom: space[2],\n\t},\n\tdescriptionText: {\n\t\tmarginTop: space[0],\n\t\tfontFamily: fontFamily.base,\n\t},\n});\n\nexport function SectionsRenderer({ classes, children }) {\n\treturn (\n\t\t<div>\n\t\t\t{children.length > 0 && (\n\t\t\t\t<div className={classes.headingSpacer}>\n\t\t\t\t\t<Heading level={1}>Example Components</Heading>\n\t\t\t\t\t<p className={classes.descriptionText}>These are the greatest components</p>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<DefaultSectionsRenderer>{children}</DefaultSectionsRenderer>\n\t\t</div>\n\t);\n}\n\nSectionsRenderer.propTypes = {\n\tclasses: PropTypes.object.isRequired,\n\tchildren: PropTypes.node,\n};\n\nexport default Styled(styles)(SectionsRenderer);\n"
  },
  {
    "path": "examples/customised/styleguide/components/StyleGuide.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Logo from 'rsg-components/Logo';\nimport Markdown from 'rsg-components/Markdown';\nimport Styled from 'rsg-components/Styled';\n\nconst xsmall = '@media (max-width: 600px)';\n\nconst styles = ({ font, base, light, link, baseBackground, mq }) => ({\n\troot: {\n\t\tcolor: base,\n\t\tbackgroundColor: baseBackground,\n\t},\n\theader: {\n\t\tcolor: '#fff',\n\t\tbackgroundColor: link,\n\t},\n\tbar: {\n\t\tdisplay: 'flex',\n\t\talignItems: 'center',\n\t\t[xsmall]: {\n\t\t\tflexDirection: 'column',\n\t\t\talignItems: 'center',\n\t\t},\n\t},\n\tnav: {\n\t\tmarginLeft: 'auto',\n\t\tmarginRight: '-0.5em',\n\t\t[xsmall]: {\n\t\t\tmargin: [[10, 0, 0]],\n\t\t},\n\t},\n\theaderLink: {\n\t\t'&, &:link, &:visited': {\n\t\t\tmarginLeft: '0.5em',\n\t\t\tmarginRight: '0.5em',\n\t\t\tfontFamily: font,\n\t\t\tcolor: '#efefef',\n\t\t},\n\t\t'&:hover, &:active': {\n\t\t\tcolor: '#fff',\n\t\t\tcursor: 'pointer',\n\t\t},\n\t},\n\tcontent: {\n\t\tmaxWidth: 1000,\n\t\tpadding: [[15, 30]],\n\t\tmargin: [[0, 'auto']],\n\t\t[mq.small]: {\n\t\t\tpadding: 15,\n\t\t},\n\t\tdisplay: 'block',\n\t},\n\tcomponents: {\n\t\toverflow: 'auto', // To prevent the pane from growing out of the screen\n\t},\n\tfooter: {\n\t\tdisplay: 'block',\n\t\tcolor: light,\n\t\tfontFamily: font,\n\t\tfontSize: 12,\n\t},\n});\n\nexport function StyleGuideRenderer({ classes, title, homepageUrl, children }) {\n\treturn (\n\t\t<div className={classes.root}>\n\t\t\t<header className={classes.header}>\n\t\t\t\t<div className={classes.content}>\n\t\t\t\t\t<div className={classes.bar}>\n\t\t\t\t\t\t<Logo>{title}</Logo>\n\t\t\t\t\t\t<nav className={classes.nav}>\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\tclassName={classes.headerLink}\n\t\t\t\t\t\t\t\thref=\"https://github.com/styleguidist/react-styleguidist/tree/master/docs\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tDocs\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\tclassName={classes.headerLink}\n\t\t\t\t\t\t\t\thref=\"https://github.com/styleguidist/react-styleguidist\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tGitHub\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t<a className={classes.headerLink} href=\"https://gitter.im/styleguidist/styleguidist\">\n\t\t\t\t\t\t\t\tGitter\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</nav>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</header>\n\t\t\t<main className={classes.content}>\n\t\t\t\t{children}\n\t\t\t\t<footer className={classes.footer}>\n\t\t\t\t\t<Markdown text={`Created with [React Styleguidist](${homepageUrl}) ❤️`} />\n\t\t\t\t</footer>\n\t\t\t</main>\n\t\t</div>\n\t);\n}\n\nStyleGuideRenderer.propTypes = {\n\tclasses: PropTypes.object.isRequired,\n\ttitle: PropTypes.string.isRequired,\n\thomepageUrl: PropTypes.string.isRequired,\n\tchildren: PropTypes.node.isRequired,\n};\n\nexport default Styled(styles)(StyleGuideRenderer);\n"
  },
  {
    "path": "examples/customised/styleguide.config.js",
    "content": "const path = require('path');\n\nmodule.exports = {\n\ttitle: 'Style guide example',\n\tcomponents: './src/components/**/[A-Z]*.js',\n\tshowSidebar: false,\n\ttheme: {\n\t\tbaseBackground: '#fdfdfc',\n\t\tlink: '#274e75',\n\t\tlinkHover: '#90a7bf',\n\t\tborder: '#e0d2de',\n\t\tfont: ['Helvetica', 'sans-serif'],\n\t},\n\tstyles: function styles(theme) {\n\t\treturn {\n\t\t\tPlayground: {\n\t\t\t\tpreview: {\n\t\t\t\t\tpaddingLeft: 0,\n\t\t\t\t\tpaddingRight: 0,\n\t\t\t\t\tborderWidth: [[0, 0, 1, 0]],\n\t\t\t\t\tborderRadius: 0,\n\t\t\t\t},\n\t\t\t},\n\t\t\tCode: {\n\t\t\t\tcode: {\n\t\t\t\t\t// make inline code example appear the same color as links\n\t\t\t\t\tcolor: theme.color.link,\n\t\t\t\t\tfontSize: 14,\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t},\n\tgetComponentPathLine(componentPath) {\n\t\tconst name = path.basename(componentPath, '.js');\n\t\treturn `import { ${name} } from 'my-awesome-library';`;\n\t},\n\n\t// Example of overriding the CLI message in local development.\n\t// Uncomment/edit the following `serverHost` entry to see in output\n\t// serverHost: 'your-domain',\n\tprintServerInstructions(config) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(`View your styleguide at: http://${config.serverHost}:${config.serverPort}`);\n\t},\n\n\t// Override Styleguidist components\n\tstyleguideComponents: {\n\t\tLogoRenderer: path.join(__dirname, 'styleguide/components/Logo'),\n\t\tStyleGuideRenderer: path.join(__dirname, 'styleguide/components/StyleGuide'),\n\t\tSectionsRenderer: path.join(__dirname, 'styleguide/components/SectionsRenderer'),\n\t},\n\twebpackConfig: {\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\t\texclude: /node_modules/,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.css$/,\n\t\t\t\t\tuse: [\n\t\t\t\t\t\t'style-loader',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tloader: 'css-loader',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tmodules: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.svg$/,\n\t\t\t\t\tloader: 'url-loader',\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\tresolve: {\n\t\t\talias: {\n\t\t\t\t// Make sure the example uses the local version of react-styleguidist\n\t\t\t\t// This is only for the examples in this repo, you won't need it for your own project\n\t\t\t\t'react-styleguidist': path.join(__dirname, '../../'),\n\t\t\t},\n\t\t},\n\t},\n};\n"
  },
  {
    "path": "examples/express/Readme.md",
    "content": "# React Styleguidist custom express endpoint example\n\n![](https://d3vv6lp55qjaqc.cloudfront.net/items/353m2x0d1a1A3I1K3J2P/Image%202016-04-12%20at%208.10.14%20PM.png)\n\nHow to start locally:\n\n```\ngit clone https://github.com/styleguidist/react-styleguidist.git\ncd react-styleguidist/examples/express\nnpm install\nnpx styleguidist server\n```\n\nThen open [http://localhost:6060](http://localhost:6060) in your browser.\n"
  },
  {
    "path": "examples/express/babel.config.js",
    "content": "module.exports = {\n\tpresets: [\n\t\t[\n\t\t\t'@babel/env',\n\t\t\t{\n\t\t\t\tdebug: true,\n\t\t\t\tmodules: false,\n\t\t\t\tuseBuiltIns: 'usage',\n\t\t\t\tcorejs: 3,\n\t\t\t},\n\t\t],\n\t\t'@babel/react',\n\t],\n\tplugins: ['@babel/plugin-proposal-class-properties'],\n};\n"
  },
  {
    "path": "examples/express/package.json",
    "content": "{\n  \"name\": \"react-styleguidist-example-express\",\n  \"description\": \"React styleguidist express example\",\n  \"version\": \"1.0.0\",\n  \"homepage\": \"https://github.com/styleguidist/react-styleguidist\",\n  \"author\": {\n    \"name\": \"Artem Sapegin\",\n    \"url\": \"http://sapegin.me/\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/styleguidist/react-styleguidist.git\"\n  },\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=10\"\n  },\n  \"dependencies\": {\n    \"lodash\": \"^4.17.19\",\n    \"prop-types\": \"^15.7.2\",\n    \"react\": \"^16.10.2\",\n    \"react-dom\": \"^16.10.2\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.6.4\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.5.5\",\n    \"@babel/preset-env\": \"^7.6.3\",\n    \"@babel/preset-react\": \"^7.6.3\",\n    \"babel-loader\": \"^8.0.6\",\n    \"css-loader\": \"^3.2.0\",\n    \"file-loader\": \"^4.2.0\",\n    \"react-styleguidist\": \"^9.1.16\",\n    \"style-loader\": \"^1.0.0\",\n    \"url-loader\": \"^2.2.0\",\n    \"webpack\": \"^4.41.1\"\n  },\n  \"scripts\": {\n    \"styleguide\": \"styleguidist server\",\n    \"styleguide:build\": \"styleguidist build\"\n  }\n}\n"
  },
  {
    "path": "examples/express/src/components/CustomEndpoint/CustomEndpoint.js",
    "content": "import React, { Component } from 'react';\n\n/* eslint-disable compat/compat */\n\nexport default class CustomEndpoint extends Component {\n\tstate = { response: 'No Server Response' };\n\n\thandleInvokeEndpoint = () => {\n\t\tfetch('http://localhost:6060/custom', { method: 'GET' })\n\t\t\t.then((responseObj) => responseObj.json())\n\t\t\t.then(({ response } = {}) => this.setState({ response, error: null }))\n\t\t\t.catch(() =>\n\t\t\t\tthis.setState({\n\t\t\t\t\tresponse: null,\n\t\t\t\t\terror: 'Ouch, something went wrong!',\n\t\t\t\t})\n\t\t\t);\n\t};\n\n\trender() {\n\t\treturn (\n\t\t\t<div>\n\t\t\t\t<div>{this.state.response}</div>\n\t\t\t\t{this.state.error ? <div>{this.state.error}</div> : null}\n\t\t\t\t<button onClick={this.handleInvokeEndpoint}>Invoke server</button>\n\t\t\t</div>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/express/src/components/CustomEndpoint/Readme.md",
    "content": "Custom Endpoint Example\n\nThe example component invokes an endpoint added to the running styleguide server.\n\n```js\n<CustomEndpoint />\n```\n"
  },
  {
    "path": "examples/express/src/components/CustomEndpoint/index.js",
    "content": "export { default } from './CustomEndpoint';\n"
  },
  {
    "path": "examples/express/styleguide.config.js",
    "content": "module.exports = {\n\ttitle: 'Style guide example',\n\tcomponents: './src/components/**/[A-Z]*.js',\n\twebpackConfig: {\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\t\texclude: /node_modules/,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.css$/,\n\t\t\t\t\tuse: [\n\t\t\t\t\t\t'style-loader',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tloader: 'css-loader',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tmodules: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\tconfigureServer(app) {\n\t\tapp.get('/custom', (req, res) => {\n\t\t\tres.status(200).send({ response: 'Server invoked' });\n\t\t});\n\t},\n};\n"
  },
  {
    "path": "examples/preact/Readme.md",
    "content": "# React Styleguidist Preact example style guide\n\n![](https://d3vv6lp55qjaqc.cloudfront.net/items/0U313M3L0p120g2Y1y3J/Image%202016-04-12%20at%207.25.03%20PM.png)\n\nHow to start locally:\n\n```\ngit clone https://github.com/styleguidist/react-styleguidist.git\ncd react-styleguidist/examples/preact\nnpm install\nnpx styleguidist server\n```\n\nThen open [http://localhost:6060](http://localhost:6060) in your browser.\n"
  },
  {
    "path": "examples/preact/babel.config.js",
    "content": "module.exports = {\n\tpresets: [\n\t\t[\n\t\t\t'@babel/env',\n\t\t\t{\n\t\t\t\tdebug: true,\n\t\t\t\tmodules: false,\n\t\t\t\tuseBuiltIns: 'usage',\n\t\t\t\tcorejs: 3,\n\t\t\t},\n\t\t],\n\t\t'@babel/react',\n\t],\n\tplugins: ['@babel/plugin-proposal-class-properties'],\n};\n"
  },
  {
    "path": "examples/preact/package.json",
    "content": "{\n  \"name\": \"react-styleguidist-example-preact\",\n  \"description\": \"React styleguidist Preact example\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"homepage\": \"https://github.com/styleguidist/react-styleguidist\",\n  \"author\": {\n    \"name\": \"Artem Sapegin\",\n    \"url\": \"http://sapegin.me/\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/styleguidist/react-styleguidist.git\"\n  },\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=10\"\n  },\n  \"dependencies\": {\n    \"dog-names\": \"^2.0.0\",\n    \"lodash\": \"^4.17.19\",\n    \"preact\": \"^8.5.2\",\n    \"preact-compat\": \"^3.19.0\",\n    \"prop-types\": \"^15.7.2\",\n    \"react\": \"^16.10.2\",\n    \"react-dom\": \"^16.10.2\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.6.4\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.5.5\",\n    \"@babel/preset-env\": \"^7.6.3\",\n    \"@babel/preset-react\": \"^7.6.3\",\n    \"babel-loader\": \"^8.0.6\",\n    \"css-loader\": \"^3.2.0\",\n    \"file-loader\": \"^4.2.0\",\n    \"react-styleguidist\": \"^9.1.16\",\n    \"style-loader\": \"^1.0.0\",\n    \"url-loader\": \"^2.2.0\",\n    \"webpack\": \"^4.41.1\"\n  },\n  \"scripts\": {\n    \"styleguide\": \"styleguidist server\",\n    \"styleguide:build\": \"styleguidist build\"\n  }\n}\n"
  },
  {
    "path": "examples/preact/src/components/Button/Button.css",
    "content": ".button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/preact/src/components/Button/Button.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './Button.css';\n\n/**\n * The only true button.\n */\nexport default function Button({ color, size, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: Button.sizes[size],\n\t};\n\n\treturn (\n\t\t<button className=\"button\" style={styles}>\n\t\t\t{children}\n\t\t</button>\n\t);\n}\nButton.propTypes = {\n\t/**\n\t * Button label.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\tcolor: PropTypes.string,\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n};\nButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n};\nButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n"
  },
  {
    "path": "examples/preact/src/components/Button/Readme.md",
    "content": "Basic button:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nBig pink button:\n\n```jsx\n<Button size=\"large\" color=\"deeppink\">\n  Click Me\n</Button>\n```\n\nAnd you _can_ **use** `any` [Markdown](http://daringfireball.net/projects/markdown/) here.\n\nFenced code blocks with `js`, `jsx` or `javascript` languages are rendered as an interactive playgrounds:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nYou can disable an editor by passing a `noeditor` modifier (` ```js noeditor `):\n\n```jsx noeditor\n<Button>Push Me</Button>\n```\n\nTo render an example as highlighted source code add a `static` modifier (` ```js static `):\n\n```js static\nimport React from 'react'\n```\n\nFenced blocks with other languages are rendered as highlighted code:\n\n```html\n<h1>Hello world</h1>\n```\n"
  },
  {
    "path": "examples/preact/src/components/Button/index.js",
    "content": "export { default } from './Button';\n"
  },
  {
    "path": "examples/preact/src/components/CounterButton/CounterButton.js",
    "content": "import React, { Component } from 'react';\n\n/**\n * Button that counts how many times it was pressed and exposes a `@public` method to reset itself.\n */\nexport default class CounterButton extends Component {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.state = {\n\t\t\tvalue: 0,\n\t\t};\n\t}\n\n\t/**\n\t * Sets the counter to a particular value.\n\t *\n\t * @public\n\t * @param {Number} newValue - New value for the counter.\n\t */\n\tset(newValue) {\n\t\tthis.setState({\n\t\t\tvalue: parseInt(newValue, 10),\n\t\t});\n\t}\n\n\t/**\n\t * Increments the counter. This method is not marked @public and is not visible in the style guide.\n\t */\n\thandleIncrement = () => {\n\t\tthis.setState({\n\t\t\tvalue: this.state.value + 1,\n\t\t});\n\t};\n\n\trender() {\n\t\treturn (\n\t\t\t<button className=\"button\" onClick={this.handleIncrement}>\n\t\t\t\t{this.state.value}\n\t\t\t</button>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/preact/src/components/CounterButton/Readme.md",
    "content": "```jsx\n<CounterButton />\n```\n"
  },
  {
    "path": "examples/preact/src/components/CounterButton/index.js",
    "content": "export { default } from './CounterButton';\n"
  },
  {
    "path": "examples/preact/src/components/Placeholder/Placeholder.css",
    "content": ".placeholder {\n\tbackground: #ccc;\n}\n"
  },
  {
    "path": "examples/preact/src/components/Placeholder/Placeholder.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport './Placeholder.css';\n\n/**\n * Image placeholders.\n */\nexport default class Placeholder extends Component {\n\tstatic propTypes = {\n\t\ttype: PropTypes.oneOf([\n\t\t\t'animal',\n\t\t\t'bacon',\n\t\t\t'beard',\n\t\t\t'bear',\n\t\t\t'cat',\n\t\t\t'food',\n\t\t\t'city',\n\t\t\t'nature',\n\t\t\t'people',\n\t\t]),\n\t\twidth: PropTypes.number,\n\t\theight: PropTypes.number,\n\t\talt: PropTypes.string,\n\t};\n\n\tstatic defaultProps = {\n\t\ttype: 'animal',\n\t\twidth: 150,\n\t\theight: 150,\n\t\talt: 'Photo of an animal',\n\t};\n\n\tgetImageUrl() {\n\t\tconst { type, width, height } = this.props;\n\t\tconst types = {\n\t\t\tanimal: `http://placeimg.com/${width}/${height}/animals`,\n\t\t\tbacon: `http://baconmockup.com/${width}/${height}`,\n\t\t\tbear: `http://www.placebear.com/${width}/${height}`,\n\t\t\tbeard: `http://placebeard.it/${width}/${height}`,\n\t\t\tcat: `http://lorempixel.com/${width}/${height}/cats`,\n\t\t\tcity: `http://lorempixel.com/${width}/${height}/city`,\n\t\t\tfood: `http://lorempixel.com/${width}/${height}/food`,\n\t\t\tnature: `http://lorempixel.com/${width}/${height}/nature`,\n\t\t\tpeople: `http://lorempixel.com/${width}/${height}/people`,\n\t\t};\n\t\treturn types[type];\n\t}\n\n\trender() {\n\t\tconst { width, height, alt } = this.props;\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"placeholder\"\n\t\t\t\tsrc={this.getImageUrl()}\n\t\t\t\twidth={width}\n\t\t\t\theight={height}\n\t\t\t\talt={alt}\n\t\t\t/>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/preact/src/components/Placeholder/Readme.md",
    "content": "```jsx\n<Placeholder type=\"beard\" />\n```\n"
  },
  {
    "path": "examples/preact/src/components/Placeholder/index.js",
    "content": "export { default } from './Placeholder';\n"
  },
  {
    "path": "examples/preact/src/components/PushButton/PushButton.css",
    "content": ".push-button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/preact/src/components/PushButton/PushButton.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './PushButton.css';\n\n/**\n * An example-less button.\n */\nexport default function PushButton({ color, size, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: PushButton.sizes[size],\n\t};\n\n\treturn (\n\t\t<button className=\"push-button\" style={styles}>\n\t\t\t{children}\n\t\t</button>\n\t);\n}\nPushButton.propTypes = {\n\t/**\n\t * PushButton label.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\tcolor: PropTypes.string,\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n};\nPushButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n};\nPushButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n"
  },
  {
    "path": "examples/preact/src/components/PushButton/index.js",
    "content": "export { default } from './PushButton';\n"
  },
  {
    "path": "examples/preact/src/components/RandomButton/RandomButton.css",
    "content": ".random-button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\tfont-size: 16px;\n\tfont-weight: bold;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/preact/src/components/RandomButton/RandomButton.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport sample from 'lodash/sample';\n\nimport './RandomButton.css';\n\n/**\n * Button that changes label on every click.\n */\nexport default class RandomButton extends Component {\n\tstatic propTypes = {\n\t\t/**\n\t\t * List of possible labels.\n\t\t */\n\t\tvariants: PropTypes.array.isRequired,\n\t};\n\n\tconstructor(props) {\n\t\tsuper();\n\t\tthis.state = {\n\t\t\tlabel: sample(props.variants),\n\t\t};\n\t}\n\n\thandleClick = () => {\n\t\tthis.setState({\n\t\t\tlabel: sample(this.props.variants),\n\t\t});\n\t};\n\n\trender() {\n\t\treturn (\n\t\t\t<button className=\"random-button\" onClick={this.handleClick}>\n\t\t\t\t{this.state.label}\n\t\t\t</button>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/preact/src/components/RandomButton/Readme.md",
    "content": "You can `import` external files in your examples:\n\n```jsx\nimport { all } from 'dog-names'\n;<RandomButton variants={all} />\n```\n"
  },
  {
    "path": "examples/preact/src/components/RandomButton/index.js",
    "content": "export { default } from './RandomButton';\n"
  },
  {
    "path": "examples/preact/src/components/WrappedButton/Readme.md",
    "content": "Enhanced/Decorated components work as well:\n\n```jsx\n<WrappedButton>I'm a wrapped button</WrappedButton>\n```\n"
  },
  {
    "path": "examples/preact/src/components/WrappedButton/WrappedButton.css",
    "content": ".wrapped-button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/preact/src/components/WrappedButton/WrappedButton.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\n/**\n * A button wrapped by a Decorator/Enhancer\n */\nconst WrappedButton = ({ color, size, children }) => {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: WrappedButton.sizes[size],\n\t};\n\n\treturn (\n\t\t<button className=\"wrapped-button\" style={styles}>\n\t\t\t{children}\n\t\t</button>\n\t);\n};\nWrappedButton.propTypes = {\n\t/**\n\t * Button label.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\tcolor: PropTypes.string,\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n};\nWrappedButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n};\nWrappedButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n\nconst Decorator = (Composed) =>\n\tclass MyHOC extends Component {\n\t\trender() {\n\t\t\treturn <Composed {...this.props} />;\n\t\t}\n\t};\n\nexport default Decorator(WrappedButton);\n"
  },
  {
    "path": "examples/preact/src/components/WrappedButton/index.js",
    "content": "export { default } from './WrappedButton';\n"
  },
  {
    "path": "examples/preact/styleguide.config.js",
    "content": "module.exports = {\n\tcomponents: 'src/components/**/[A-Z]*.js',\n\tdefaultExample: true,\n\twebpackConfig: {\n\t\tresolve: {\n\t\t\talias: {\n\t\t\t\treact: 'preact-compat',\n\t\t\t\t'react-dom': 'preact-compat',\n\t\t\t},\n\t\t},\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\t\texclude: /node_modules/,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.css$/,\n\t\t\t\t\tuse: [\n\t\t\t\t\t\t'style-loader',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tloader: 'css-loader',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tmodules: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n};\n"
  },
  {
    "path": "examples/react-native/.editorconfig",
    "content": "# EditorConfig is awesome: http://EditorConfig.org\n\n# top-most EditorConfig file\nroot = true\n\n# Unix-style newlines with a newline ending every file\n[*]\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 2\n\n[*.gradle]\nindent_size = 4\n\n[BUCK]\nindent_size = 4"
  },
  {
    "path": "examples/react-native/.gitignore",
    "content": "node_modules/**/*\n.expo/*\nnpm-debug.*\n*.jks\n*.p12\n*.key\n*.mobileprovision\n"
  },
  {
    "path": "examples/react-native/.watchmanconfig",
    "content": "{}\n"
  },
  {
    "path": "examples/react-native/App.js",
    "content": "import Root from './src/Root';\n\nexport default Root;\n"
  },
  {
    "path": "examples/react-native/README.md",
    "content": "# React Styleguidist react-native example style guide\n\n![](https://media.giphy.com/media/3ohs4v5loJ50dKw9FK/giphy.gif)\n\nHow to start locally:\n\n```\ngit clone https://github.com/styleguidist/react-styleguidist.git\ncd react-styleguidist/examples/react-native\nnpm install\n```\n\nRun Styleguidist\n\n```\nnpx styleguidist server\n```\n\n(Optional) Run the react-native app via simulator (or [Expo](https://expo.io/learn))\n\n```\nnpm run start\n```\n\nThen open [http://localhost:6060](http://localhost:6060) in your browser.\n\n## Add Styleguidist to an existing react-native project\n\nA collection of dev-dependencies related to webpack are required to get `react-native` and `react-styleguidist` running on a browser. `module:metro-react-native-babel-preset` reflects the bundle server that normally serves to react-native apps to the simulators and/or devices.\n\n```\nnpm install --save-dev @babel/core @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread @babel/polyfill @babel/preset-env babel-loader babel-plugin-react-native-web file-loader metro-react-native-babel-preset react-art react-dom react-native-web react-styleguidist webpack\n```\n\nAdd and configure `styleguide.config.js` to the root of your `react-native` project.\n\n## Common Caveats\n\n[react-native-web](https://github.com/necolas/react-native-web) does not support everything, components requiring DeviceInfo is a common breaking point for example. Configuring components or selections in your `styleguide.config.js` to only select ui components is recommended. A good rule of thumb is to expect an approximate visual representation with code examples and props documentation.\n\n[react-native-vector-icons](https://oblador.github.io/react-native-vector-icons/) (or any other dependency using external assets) can be solved by adding a custom template to `styleguide.config.js`\n\n# Generated by Expo\n\nThis project was bootstrapped with [Expo](https://expo.io/).\n\nThe most recent version of this guide is available [here](https://expo.io/learn).\n"
  },
  {
    "path": "examples/react-native/app.json",
    "content": "{\n  \"expo\": {\n    \"name\": \"react-styleguidist-example-react-native\",\n    \"slug\": \"react-styleguidist-example-react-native\",\n    \"privacy\": \"public\",\n    \"sdkVersion\": \"32.0.0\",\n    \"platforms\": [\n      \"ios\",\n      \"android\"\n    ],\n    \"version\": \"1.0.0\",\n    \"orientation\": \"portrait\",\n    \"icon\": \"./assets/icon.png\",\n    \"splash\": {\n      \"image\": \"./assets/splash.png\",\n      \"resizeMode\": \"contain\",\n      \"backgroundColor\": \"#ffffff\"\n    },\n    \"updates\": {\n      \"fallbackToCacheTimeout\": 0\n    },\n    \"assetBundlePatterns\": [\n      \"**/*\"\n    ],\n    \"ios\": {\n      \"supportsTablet\": true\n    }\n  }\n}"
  },
  {
    "path": "examples/react-native/babel.config.js",
    "content": "module.exports = function (api) {\n\tapi.cache(true);\n\treturn {\n\t\tpresets: ['babel-preset-expo'],\n\t};\n};\n"
  },
  {
    "path": "examples/react-native/package.json",
    "content": "{\n  \"main\": \"node_modules/expo/AppEntry.js\",\n  \"scripts\": {\n    \"start\": \"expo start\",\n    \"android\": \"expo start --android\",\n    \"ios\": \"expo start --ios\",\n    \"eject\": \"expo eject\",\n    \"styleguide\": \"styleguidist server\",\n    \"styleguide:build\": \"styleguidist build\"\n  },\n  \"dependencies\": {\n    \"expo\": \"^35.0.0\",\n    \"prop-types\": \"^15.7.2\",\n    \"react\": \"16.10.2\",\n    \"react-native\": \"https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.6.4\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.5.5\",\n    \"@babel/plugin-proposal-object-rest-spread\": \"^7.6.2\",\n    \"@babel/polyfill\": \"^7.6.0\",\n    \"@babel/preset-env\": \"^7.6.3\",\n    \"babel-loader\": \"^8.0.6\",\n    \"babel-plugin-react-native-web\": \"^0.11.7\",\n    \"babel-preset-expo\": \"^7.0.0\",\n    \"metro-react-native-babel-preset\": \"^0.56.0\",\n    \"react-art\": \"^16.10.2\",\n    \"react-dom\": \"^16.10.2\",\n    \"react-native-web\": \"^0.11.7\",\n    \"react-styleguidist\": \"^9.1.16\",\n    \"webpack\": \"^4.41.1\"\n  },\n  \"private\": true\n}\n"
  },
  {
    "path": "examples/react-native/src/Root.js",
    "content": "import React, { Component } from 'react';\n// eslint-disable-next-line import/extensions\nimport { StyleSheet, Text, ScrollView } from 'react-native';\nimport SimpleCard from './SimpleCard';\n\nconst styles = StyleSheet.create({\n\tcontainer: {\n\t\tflex: 1,\n\t\tflexDirection: 'column',\n\t\tjustifyContent: 'center',\n\t\talignItems: 'stretch',\n\t\tmargin: 12,\n\t\tmarginTop: 30,\n\t},\n});\n\nexport default class Root extends Component {\n\trender() {\n\t\treturn (\n\t\t\t<ScrollView contentContainerStyle={styles.container}>\n\t\t\t\t<SimpleCard title=\"Welcome\">\n\t\t\t\t\t<Text>Open up App.js to start working on your app!</Text>\n\t\t\t\t\t<Text>Changes you make will automatically reload.</Text>\n\t\t\t\t\t<Text>Shake your phone to open the developer menu.</Text>\n\t\t\t\t</SimpleCard>\n\t\t\t\t<SimpleCard title=\"Card 2\" color=\"#26572c\">\n\t\t\t\t\t<Text>This is a second card.</Text>\n\t\t\t\t</SimpleCard>\n\t\t\t\t<SimpleCard title=\"Card 3\">\n\t\t\t\t\t<Text>This is a third card.</Text>\n\t\t\t\t</SimpleCard>\n\t\t\t</ScrollView>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/react-native/src/Root.md",
    "content": "```\n<Root />\n```\n"
  },
  {
    "path": "examples/react-native/src/SimpleCard.js",
    "content": "import React, { PureComponent } from 'react';\n// eslint-disable-next-line import/extensions\nimport { StyleSheet, Text, View } from 'react-native';\nimport PropTypes from 'prop-types';\n\nconst styles = StyleSheet.create({\n\tcontainer: {\n\t\tbackgroundColor: '#fff',\n\t\tborderWidth: 1,\n\t\tmarginBottom: 12,\n\t},\n\ttitleView: {\n\t\tpadding: 12,\n\t},\n\ttitleText: {\n\t\tfontWeight: '600',\n\t\tfontSize: 18,\n\t},\n\tcontentContainer: {\n\t\tpadding: 12,\n\t},\n});\n\nexport default class SimpleCard extends PureComponent {\n\tstatic propTypes = {\n\t\t/** Contents of the card */\n\t\tchildren: PropTypes.node.isRequired,\n\t\t/** Title of the card */\n\t\ttitle: PropTypes.string.isRequired,\n\t\t/** The color for the card */\n\t\tcolor: PropTypes.string,\n\t\t/** The color for title text */\n\t\ttitleTextColor: PropTypes.string,\n\t};\n\n\tstatic defaultProps = {\n\t\tcolor: '#333',\n\t\ttitleTextColor: '#fff',\n\t};\n\n\trender() {\n\t\tconst { children, color, title, titleTextColor } = this.props;\n\t\treturn (\n\t\t\t<View style={[styles.container, { borderColor: color }]}>\n\t\t\t\t<View style={[styles.titleView, { backgroundColor: color }]}>\n\t\t\t\t\t<Text style={[styles.titleText, { color: titleTextColor }]}>{title}</Text>\n\t\t\t\t</View>\n\t\t\t\t<View style={styles.contentContainer}>{children}</View>\n\t\t\t</View>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/react-native/src/SimpleCard.md",
    "content": "Basic use example:\n\n```jsx\nconst Text = require('react-native').Text\n;<SimpleCard title=\"Basic Card\">\n  <Text>Basic example 1</Text>\n</SimpleCard>\n```\n\nBasic use example with color:\n\n```jsx\nconst Text = require('react-native').Text\n;<SimpleCard color=\"#ffd289\" title=\"Basic Card\">\n  <Text>Basic example 2</Text>\n</SimpleCard>\n```\n\nBasic use example with title color and color property:\n\n```jsx\nconst Text = require('react-native').Text\n;<SimpleCard color=\"#ffefd5\" titleTextColor=\"#000\" title=\"Basic Card\">\n  <Text>Basic example 3</Text>\n</SimpleCard>\n```\n"
  },
  {
    "path": "examples/react-native/styleguide.config.js",
    "content": "const webpack = require('webpack');\n\nmodule.exports = {\n\trequire: ['@babel/polyfill'],\n\tcomponents: 'src/**/[A-Z]*.js',\n\twebpackConfig: {\n\t\tresolve: {\n\t\t\t// auto resolves any react-native import as react-native-web\n\t\t\talias: { 'react-native': 'react-native-web' },\n\t\t\textensions: ['.web.js', '.js'],\n\t\t},\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.js$/,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t\texclude: [/node_modules/],\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tplugins: [\n\t\t\t\t\t\t\t'@babel/proposal-class-properties',\n\t\t\t\t\t\t\t'@babel/proposal-object-rest-spread',\n\t\t\t\t\t\t\t'react-native-web',\n\t\t\t\t\t\t],\n\t\t\t\t\t\tpresets: ['@babel/preset-env', 'module:metro-react-native-babel-preset'],\n\t\t\t\t\t\tbabelrc: false,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.(jpe?g|png|gif)$/i,\n\t\t\t\t\tuse: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tloader: 'file-loader',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\thash: 'sha512',\n\t\t\t\t\t\t\t\tdigest: 'hex',\n\t\t\t\t\t\t\t\tname: '[hash].[ext]',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.ttf$/,\n\t\t\t\t\tloader: 'file-loader',\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t// Most react native projects will need some extra plugin configuration.\n\t\tplugins: [\n\t\t\t// Add __DEV__ flag to browser example.\n\t\t\tnew webpack.DefinePlugin({\n\t\t\t\t__DEV__: process.env,\n\t\t\t}),\n\t\t],\n\t},\n};\n"
  },
  {
    "path": "examples/sections/Readme.md",
    "content": "# React Styleguidist example style guide with sections\n\n![](https://d3vv6lp55qjaqc.cloudfront.net/items/3B12372E3v2e3q2U323O/Image%202016-04-20%20at%209.15.24%20AM.png)\n\nHow to start locally:\n\n```\ngit clone https://github.com/styleguidist/react-styleguidist.git\ncd react-styleguidist/examples/sections\nnpm install\nnpx styleguidist server\n```\n\nThen open [http://localhost:6060](http://localhost:6060) in your browser.\n"
  },
  {
    "path": "examples/sections/babel.config.js",
    "content": "module.exports = {\n\tpresets: [\n\t\t[\n\t\t\t'@babel/env',\n\t\t\t{\n\t\t\t\tmodules: false,\n\t\t\t\tuseBuiltIns: 'usage',\n\t\t\t\tcorejs: 3,\n\t\t\t},\n\t\t],\n\t\t'@babel/react',\n\t],\n\tplugins: ['@babel/plugin-proposal-class-properties'],\n};\n"
  },
  {
    "path": "examples/sections/docs/Components.md",
    "content": "Tempor qui ad ad sint nulla sint magna aliquip qui ex. Non commodo mollit et exercitation nostrud esse. Minim aliqua cillum est amet dolore ipsum qui tempor eu ea.\n\nUt veniam sit pariatur deserunt non officia. Esse commodo proident quis culpa esse enim occaecat occaecat laborum nostrud non non sunt. Labore incididunt reprehenderit sunt elit reprehenderit nulla nulla Lorem aliquip incididunt. Qui cillum consectetur Lorem anim amet ex magna deserunt sunt.\n\nList of components:\n\n- [Buttons](#/Components?id=section-buttons)\n- [Fields](#/Components?id=section-fields)\n- [Others](#/Components?id=section-others)\n"
  },
  {
    "path": "examples/sections/docs/Documentation.md",
    "content": "Excepteur ullamco ut ea laborum in duis fugiat in dolor minim non. Minim amet velit duis fugiat nisi excepteur occaecat elit exercitation eiusmod est aute nulla. Et deserunt labore consectetur elit nostrud consequat commodo occaecat consectetur mollit sunt. Eiusmod laboris incididunt consectetur nisi nulla cupidatat. Velit consequat voluptate eiusmod aliqua esse culpa tempor quis tempor dolor dolor irure.\n\nProident laboris esse do culpa ullamco proident deserunt minim nostrud et ut deserunt. Pariatur cillum et nulla labore proident nisi eu veniam. Nulla aute non incididunt laboris dolor magna laborum eu incididunt est.\n\nUt culpa non sint eiusmod ut duis. Cillum consequat labore cupidatat eiusmod aute aute. Minim irure labore ea cillum id consectetur incididunt ex tempor deserunt labore. Officia deserunt consequat cupidatat nulla quis aute. Enim laborum aliquip aliquip sit exercitation sint eiusmod do do. Irure esse aliqua veniam do laborum cillum dolor nulla laborum consequat velit amet. Mollit ullamco incididunt Lorem dolor ut qui sunt proident.\n"
  },
  {
    "path": "examples/sections/docs/Files.md",
    "content": "Qui adipisicing officia voluptate cillum duis magna eu esse. Officia velit do tempor veniam exercitation ullamco irure. Reprehenderit laborum aliquip ipsum dolore ullamco. Consequat irure commodo culpa id nostrud. Aute et officia esse cillum amet commodo consequat nulla amet aute sint elit proident. Incididunt sunt tempor in ullamco ea eiusmod quis mollit occaecat ea. Sint minim eu mollit occaecat cupidatat velit sunt aliqua reprehenderit do minim anim magna dolore.\n\nAute fugiat nulla eu cillum dolore proident eu nisi sint minim veniam. Sunt velit aliqua ullamco quis qui sint aliqua incididunt irure dolor sint nulla commodo qui. Eu nisi pariatur Lorem dolore id aute occaecat adipisicing. Consectetur cupidatat magna magna aute anim eu non officia Lorem esse. Pariatur exercitation id velit anim id laborum dolore laboris esse est in anim dolor. Aute ea in et laboris culpa voluptate laboris ipsum nisi.\n\nList of files:\n\n- [First File](#/Documentation/Files/First%20File)\n- [Second File](#/Documentation/Files/Second%20File)\n- [WrappedButton](#/Documentation/Files/WrappedButton)\n"
  },
  {
    "path": "examples/sections/docs/One.md",
    "content": "# Heading 1\n\n## Heading 2\n\n### Heading 3\n\n#### Heading 4\n\n##### Heading 5\n\n###### Heading 6\n\nThere was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, “Oh dear! Oh dear! I shall be late!” (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural); but when the Rabbit actually _took a watch out of its waistcoat-pocket_, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.\n\n> In another moment down went Alice after it, never once considering how in the world she was to get out again.\n\nText attributes: _italic_, **bold**, `monospace`.\n\nBullet list:\n\n- coffee\n- croissant\n\nNumbered list:\n\n1.  coffee\n2.  croissant\n\nNested list:\n\n- coffee\n- food\n  1.  croissant\n  1.  pizza\n- dog\n\nList with checkboxes:\n\n- [x] Coffee\n- [x] Croissant\n- [ ] Pizza\n\nTable:\n\n| Foo | Bar |\n| --- | --- |\n| 1   | 2   |\n\nA [link](http://example.com).\n\n---\n\n![React](http://morning.photos/photos/thumb/2014-09-27-3218-thumb.jpg)\n\n```js static\nfunction eatFood(food) {\n  if (!food.length) {\n    return ['No food']\n  }\n\n  return food.map(dish => `No ${dish.toLowerCase()}`)\n}\n\nconst food = ['Pizza', 'Buger', 'Coffee']\nconsole.log(eatFood(food))\n```\n\nSome more text here.\n\n## Details\n\n<details>\n <summary>Solution</summary>\n\nSome hidden text.\n\n</details>\n"
  },
  {
    "path": "examples/sections/docs/Two.md",
    "content": "That big pink button again:\n\n```jsx\nimport Button from '../src/components/Button'\n;<Button size=\"large\" color=\"deeppink\">\n  Click Me\n</Button>\n```\n"
  },
  {
    "path": "examples/sections/package.json",
    "content": "{\n  \"name\": \"react-styleguidist-example-sections\",\n  \"description\": \"React styleguidist sections example\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"homepage\": \"https://github.com/styleguidist/react-styleguidist\",\n  \"author\": {\n    \"name\": \"Artem Sapegin\",\n    \"url\": \"http://sapegin.me/\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/styleguidist/react-styleguidist.git\"\n  },\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=10\"\n  },\n  \"dependencies\": {\n    \"add\": \"^2.0.6\",\n    \"core-js\": \"^3.2.1\",\n    \"dog-names\": \"^2.0.0\",\n    \"lodash\": \"^4.17.19\",\n    \"prop-types\": \"^15.7.2\",\n    \"react\": \"^16.10.2\",\n    \"react-dom\": \"^16.10.2\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.6.4\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.5.5\",\n    \"@babel/preset-env\": \"^7.6.3\",\n    \"@babel/preset-react\": \"^7.6.3\",\n    \"babel-loader\": \"^8.0.6\",\n    \"css-loader\": \"^3.2.0\",\n    \"file-loader\": \"^4.2.0\",\n    \"react-styleguidist\": \"^9.1.16\",\n    \"style-loader\": \"^1.0.0\",\n    \"url-loader\": \"^2.2.0\",\n    \"webpack\": \"^4.41.1\"\n  },\n  \"scripts\": {\n    \"styleguide\": \"styleguidist server\",\n    \"styleguide:build\": \"styleguidist build\"\n  }\n}\n"
  },
  {
    "path": "examples/sections/src/ThemeContext.js",
    "content": "import React from 'react';\n\n/**\n * Context that stores selected application theme: 'light' | 'dark'\n */\nexport default React.createContext('light');\n"
  },
  {
    "path": "examples/sections/src/components/Button/Button.css",
    "content": ".button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/sections/src/components/Button/Button.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './Button.css';\n\n/**\n * The only true button.\n */\nexport default function Button({ color, size, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: Button.sizes[size],\n\t};\n\n\treturn (\n\t\t<button className=\"button\" style={styles}>\n\t\t\t{children}\n\t\t</button>\n\t);\n}\nButton.propTypes = {\n\t/**\n\t * Button label.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\tcolor: PropTypes.string,\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n};\nButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n};\nButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n"
  },
  {
    "path": "examples/sections/src/components/Button/Readme.md",
    "content": "Basic button:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nBig pink button:\n\n```jsx\n<Button size=\"large\" color=\"deeppink\">\n  Click Me\n</Button>\n```\n\nAnd you _can_ **use** `any` [Markdown](http://daringfireball.net/projects/markdown/) here.\n\nFenced code blocks with `js`, `jsx` or `javascript` languages are rendered as an interactive playgrounds:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nYou can disable an editor by passing a `noeditor` modifier (` ```js noeditor `):\n\n```jsx noeditor\n<Button>Push Me</Button>\n```\n\nTo render an example as highlighted source code add a `static` modifier (` ```js static `):\n\n```js static\nimport React from 'react'\n```\n\nFenced blocks with other languages are rendered as highlighted code:\n\n```html\n<h1>Hello world</h1>\n```\n"
  },
  {
    "path": "examples/sections/src/components/Button/index.js",
    "content": "export { default } from './Button';\n"
  },
  {
    "path": "examples/sections/src/components/Label/Label.js",
    "content": "import React from 'react';\n\n/**\n * Simple text label.\n */\nexport default function Label() {\n\treturn <span>Hello React!</span>;\n}\n"
  },
  {
    "path": "examples/sections/src/components/Label/Readme.md",
    "content": "Should use the `fantasy` font inherited from `body`:\n\n```jsx\n<Label />\n```\n"
  },
  {
    "path": "examples/sections/src/components/Label/index.js",
    "content": "export { default } from './Label';\n"
  },
  {
    "path": "examples/sections/src/components/MyLabel/Label.js",
    "content": "import React from 'react';\n\n/**\n * Simple text label.\n */\nexport default function Label() {\n\treturn <span>I am a duplicate Label component!</span>;\n}\n"
  },
  {
    "path": "examples/sections/src/components/MyLabel/Readme.md",
    "content": "Should use the `fantasy` font inherited from `body`:\n\n```jsx\n<Label />\n```\n"
  },
  {
    "path": "examples/sections/src/components/MyLabel/index.js",
    "content": "export { default } from './Label';\n"
  },
  {
    "path": "examples/sections/src/components/Placeholder/Example.md",
    "content": "Extra example file linked via `@example` doclet:\n\n```jsx\nimport Placeholder from '../Placeholder'\n;<Placeholder type=\"bear\" />\n```\n"
  },
  {
    "path": "examples/sections/src/components/Placeholder/Placeholder.css",
    "content": ".placeholder {\n\tbackground: #ccc;\n}\n"
  },
  {
    "path": "examples/sections/src/components/Placeholder/Placeholder.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport './Placeholder.css';\n\n/**\n * Image placeholders.\n *\n * @example ./Example.md\n */\nexport default class Placeholder extends Component {\n\tstatic propTypes = {\n\t\ttype: PropTypes.oneOf([\n\t\t\t'animal',\n\t\t\t'bacon',\n\t\t\t'beard',\n\t\t\t'bear',\n\t\t\t'cat',\n\t\t\t'food',\n\t\t\t'city',\n\t\t\t'nature',\n\t\t\t'people',\n\t\t]),\n\t\twidth: PropTypes.number,\n\t\theight: PropTypes.number,\n\t\talt: PropTypes.string,\n\t};\n\n\tstatic defaultProps = {\n\t\ttype: 'animal',\n\t\twidth: 150,\n\t\theight: 150,\n\t\talt: 'Photo of an animal',\n\t};\n\n\tgetImageUrl() {\n\t\tconst { type, width, height } = this.props;\n\t\tconst types = {\n\t\t\tanimal: `http://placeimg.com/${width}/${height}/animals`,\n\t\t\tbacon: `http://baconmockup.com/${width}/${height}`,\n\t\t\tbear: `http://www.placebear.com/${width}/${height}`,\n\t\t\tbeard: `http://placebeard.it/${width}/${height}`,\n\t\t\tcat: `http://lorempixel.com/${width}/${height}/cats`,\n\t\t\tcity: `http://lorempixel.com/${width}/${height}/city`,\n\t\t\tfood: `http://lorempixel.com/${width}/${height}/food`,\n\t\t\tnature: `http://lorempixel.com/${width}/${height}/nature`,\n\t\t\tpeople: `http://lorempixel.com/${width}/${height}/people`,\n\t\t};\n\t\treturn types[type];\n\t}\n\n\trender() {\n\t\tconst { width, height, alt } = this.props;\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"placeholder\"\n\t\t\t\tsrc={this.getImageUrl()}\n\t\t\t\twidth={width}\n\t\t\t\theight={height}\n\t\t\t\talt={alt}\n\t\t\t/>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/sections/src/components/Placeholder/_Readme.md",
    "content": "```jsx\n<Placeholder type=\"beard\" />\n```\n"
  },
  {
    "path": "examples/sections/src/components/Placeholder/index.js",
    "content": "export { default } from './Placeholder';\n"
  },
  {
    "path": "examples/sections/src/components/RandomButton/RandomButton.css",
    "content": ".random-button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\tfont-size: 16px;\n\tfont-weight: bold;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/sections/src/components/RandomButton/RandomButton.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport sample from 'lodash/sample';\n\nimport './RandomButton.css';\n\n/**\n * Button that changes label on every click.\n */\nexport default class RandomButton extends Component {\n\tstatic propTypes = {\n\t\t/**\n\t\t * List of possible labels.\n\t\t */\n\t\tvariants: PropTypes.array.isRequired,\n\t};\n\n\tconstructor(props) {\n\t\tsuper();\n\t\tthis.state = {\n\t\t\tlabel: sample(props.variants),\n\t\t};\n\t}\n\n\thandleClick = () => {\n\t\tthis.setState({\n\t\t\tlabel: sample(this.props.variants),\n\t\t});\n\t};\n\n\trender() {\n\t\treturn (\n\t\t\t<button className=\"random-button\" onClick={this.handleClick}>\n\t\t\t\t{this.state.label}\n\t\t\t</button>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/sections/src/components/RandomButton/index.js",
    "content": "export { default } from './RandomButton';\n"
  },
  {
    "path": "examples/sections/src/components/ThemeButton/Readme.md",
    "content": "An example of using React Context with a component:\n\n```jsx\nimport ThemeContext from '../../ThemeContext.js'\n\nconst [theme, setTheme] = React.useState('light')\nconst toggleTheme = () =>\n  setTheme(theme === 'light' ? 'dark' : 'light')\n;<>\n  <div\n    style={{\n      backgroundColor: '#ccc',\n      margin: '-16px -16px 16px -16px',\n      padding: '16px'\n    }}\n  >\n    <button onClick={toggleTheme}>Theme: {theme}</button>\n  </div>\n  <div>\n    <ThemeContext.Provider value={theme}>\n      <ThemeButton>Themable button</ThemeButton>\n    </ThemeContext.Provider>\n  </div>\n</>\n```\n"
  },
  {
    "path": "examples/sections/src/components/ThemeButton/ThemeButton.css",
    "content": ".ThemeButton {\n\tpadding: 0.5em 1.5em;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\tfont-size: 16px;\n\tfont-weight: bold;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n\n.ThemeButton--light {\n\tcolor: #111133;\n\tbackground-color: #eeeeff;\n}\n\n.ThemeButton--dark {\n\tcolor: #eeeeff;\n\tbackground-color: #111133;\n}\n"
  },
  {
    "path": "examples/sections/src/components/ThemeButton/ThemeButton.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport ThemeContext from '../../ThemeContext';\nimport './ThemeButton.css';\n\n/**\n * Button that is themed by a context value\n */\nexport default class ThemeButton extends Component {\n\trender() {\n\t\tconst className =\n\t\t\tthis.context === 'light' ? 'ThemeButton ThemeButton--light' : 'ThemeButton ThemeButton--dark';\n\t\treturn <button className={className}>{this.props.children}</button>;\n\t}\n}\n\n/** ThemeContext {string} */\nThemeButton.contextType = ThemeContext;\nThemeButton.propTypes = {\n\t/**\n\t * ThemeButton label\n\t */\n\tchildren: PropTypes.string.isRequired,\n};\n"
  },
  {
    "path": "examples/sections/src/components/ThemeButton/index.js",
    "content": "export { default } from './ThemeButton';\n"
  },
  {
    "path": "examples/sections/src/components/WrappedButton/Readme.md",
    "content": "react-docgen is not able to parse prop types of enhanced components that are imported from other files. Styleguidist will add them to your style guide anyway.\n\n```jsx\n<WrappedButton>I'm a wrapped button</WrappedButton>\n```\n"
  },
  {
    "path": "examples/sections/src/components/WrappedButton/WrappedButton.js",
    "content": "import React from 'react';\nimport Button from '../Button';\n\nconst dummyWrapper = (WrappedComponent) => (props) => <WrappedComponent {...props} />;\n\n/**\n * A button wrapped by a Decorator/Enhancer\n */\nconst WrappedButton = dummyWrapper(Button);\n\nexport default WrappedButton;\n"
  },
  {
    "path": "examples/sections/src/components/WrappedButton/index.js",
    "content": "export { default } from './WrappedButton';\n"
  },
  {
    "path": "examples/sections/src/styles.css",
    "content": "/* Styles that should be inherited from body */\nbody {\n\tfont-family: fantasy;\n}\n\n/* All HTML tags except div and span to test styles isolation */\na,\nabbr,\naddress,\narea,\narticle,\naside,\naudio,\nb,\nbase,\nbdi,\nbdo,\nblockquote,\nbody,\nbr,\nbutton,\ncanvas,\ncaption,\ncite,\ncode,\ncol,\ncolgroup,\ndata,\ndatalist,\ndd,\ndel,\ndetails,\ndfn,\ndialog,\ndl,\ndt,\nem,\nembed,\nfieldset,\nfigcaption,\nfigure,\nfooter,\nform,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhead,\nheader,\nhr,\ni,\niframe,\nimg,\ninput,\nins,\nkbd,\nkeygen,\nlabel,\nlegend,\nli,\nlink,\nmain,\nmap,\nmark,\nmath,\nmenu,\nmenuitem,\nmeta,\nmeter,\nnav,\nnoscript,\nobject,\nol,\noptgroup,\noption,\noutput,\np,\nparam,\npicture,\npre,\nprogress,\nq,\nrb,\nrp,\nrt,\nrtc,\nruby,\ns,\nsamp,\nscript,\nsection,\nselect,\nsmall,\nsource,\nstrong,\nstyle,\nsub,\nsummary,\nsup,\nsvg,\ntable,\ntbody,\ntd,\ntemplate,\ntextarea,\ntfoot,\nth,\nthead,\ntime,\ntitle,\ntr,\ntrack,\nu,\nul,\nvar,\nvideo,\nwbr {\n\tborder: 2px dotted #f0f;\n\tcolor: #f0f;\n}\n\n::placeholder {\n\tcolor: #f0f;\n\tfont-family: fantasy;\n}\n"
  },
  {
    "path": "examples/sections/styleguide/CNAME",
    "content": "react-styleguidist.js.org\n"
  },
  {
    "path": "examples/sections/styleguide.config.js",
    "content": "const path = require('path');\n\nmodule.exports = {\n\ttitle: 'React Style Guide Example',\n\tpagePerSection: true,\n\t// tocMode: 'collapse',\n\tsections: [\n\t\t{\n\t\t\tname: 'Documentation',\n\t\t\tcontent: 'docs/Documentation.md',\n\t\t\tsections: [\n\t\t\t\t{\n\t\t\t\t\tname: 'Files',\n\t\t\t\t\tcontent: 'docs/Files.md',\n\t\t\t\t\tcomponents: () => ['./src/components/WrappedButton/WrappedButton.js'],\n\t\t\t\t\tsections: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'First File',\n\t\t\t\t\t\t\tcontent: 'docs/One.md',\n\t\t\t\t\t\t\tdescription: 'This is the first section description',\n\t\t\t\t\t\t\tcomponents: () => ['./src/components/Label/Label.js'],\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Second File',\n\t\t\t\t\t\t\tcontent: 'docs/Two.md',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Online documentation',\n\t\t\t\t\thref: 'https://github.com/styleguidist/react-styleguidist',\n\t\t\t\t\texternal: true,\n\t\t\t\t},\n\t\t\t],\n\t\t\tsectionDepth: 2,\n\t\t},\n\t\t{\n\t\t\tname: 'Components',\n\t\t\tcontent: 'docs/Components.md',\n\t\t\tsections: [\n\t\t\t\t{\n\t\t\t\t\tname: 'Buttons',\n\t\t\t\t\tcomponents: () => [\n\t\t\t\t\t\t'./src/components/Button/Button.js',\n\t\t\t\t\t\t'./src/components/ThemeButton/ThemeButton.js',\n\t\t\t\t\t],\n\t\t\t\t\texampleMode: 'expand', // 'hide' | 'collapse' | 'expand'\n\t\t\t\t\tusageMode: 'hide', // 'hide' | 'collapse' | 'expand'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Fields',\n\t\t\t\t\tcomponents: () => ['./src/components/Placeholder/Placeholder.js'],\n\t\t\t\t\texampleMode: 'expand', // 'hide' | 'collapse' | 'expand'\n\t\t\t\t\tusageMode: 'expand', // 'hide' | 'collapse' | 'expand'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Labels',\n\t\t\t\t\tcomponents: () => ['./src/components/MyLabel/Label.js'],\n\t\t\t\t\texampleMode: 'expand', // 'hide' | 'collapse' | 'expand'\n\t\t\t\t\tusageMode: 'expand', // 'hide' | 'collapse' | 'expand'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Others',\n\t\t\t\t\tcomponents: () => ['./src/components/RandomButton/RandomButton.js'],\n\t\t\t\t\texampleMode: 'collapse', // 'hide' | 'collapse' | 'expand'\n\t\t\t\t\tusageMode: 'collapse', // 'hide' | 'collapse' | 'expand'\n\t\t\t\t},\n\t\t\t],\n\t\t\tsectionDepth: 0,\n\t\t},\n\t],\n\trequire: [path.join(__dirname, 'src/styles.css')],\n\twebpackConfig: (env) => ({\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\t\texclude: /node_modules/,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.css$/,\n\t\t\t\t\tuse: ['style-loader', 'css-loader'],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t// How to analyze what's in the bundle:\n\t\t// 1. Comment `hints: 'error'` line below\n\t\t// 2. Uncomment a line with `stats.json` in src/scripts/build.js\n\t\t// 3. npm run build:sections\n\t\t// 4. npx webpack-bundle-analyzer stats.json\n\t\tperformance:\n\t\t\tenv === 'development'\n\t\t\t\t? false\n\t\t\t\t: {\n\t\t\t\t\t\tmaxAssetSize: 1200000, // bytes\n\t\t\t\t\t\tmaxEntrypointSize: 1200000, // bytes\n\t\t\t\t\t\thints: 'error',\n\t\t\t\t  },\n\t}),\n};\n"
  },
  {
    "path": "examples/styled-components/Readme.md",
    "content": "# Example of React Styleguidist using styled-components (and Emotion) with TypeScript\n\nHow to start locally:\n\n```\ngit clone https://github.com/styleguidist/react-styleguidist.git\ncd react-styleguidist/examples/styled-components\nnpm install\nnpx styleguidist server\n```\n\nThen open [http://localhost:6060](http://localhost:6060) in your browser.\n"
  },
  {
    "path": "examples/styled-components/babel.config.js",
    "content": "module.exports = {\n\tpresets: [\n\t\t[\n\t\t\t'@babel/env',\n\t\t\t{\n\t\t\t\tmodules: false,\n\t\t\t\tuseBuiltIns: 'usage',\n\t\t\t\tcorejs: 3,\n\t\t\t},\n\t\t],\n\t\t['@babel/preset-react'],\n\t\t['@babel/preset-typescript'],\n\t],\n\tplugins: ['@babel/plugin-proposal-class-properties'],\n};\n"
  },
  {
    "path": "examples/styled-components/package.json",
    "content": "{\n  \"name\": \"react-styleguidist-example-styled-components\",\n  \"description\": \"React styleguidist styled-components example\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"homepage\": \"https://github.com/styleguidist/react-styleguidist\",\n  \"author\": {\n    \"name\": \"Artem Sapegin\",\n    \"url\": \"http://sapegin.me/\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/styleguidist/react-styleguidist.git\"\n  },\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=10\"\n  },\n  \"scripts\": {\n    \"styleguide\": \"styleguidist server\",\n    \"styleguide:dev\": \"node ../../lib/bin/styleguidist server --config ./styleguide.config.js\",\n    \"styleguide:build\": \"styleguidist build\"\n  },\n  \"dependencies\": {\n    \"@emotion/core\": \"^10.0.10\",\n    \"@emotion/styled\": \"^10.0.12\",\n    \"babel-loader\": \"^8.0.5\",\n    \"babel-plugin-styled-components\": \"^1.7.1\",\n    \"core-js\": \"^3.0.1\",\n    \"polished\": \"^3.2.0\",\n    \"prop-types\": \"^15.7.2\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\",\n    \"react-styleguidist\": \"9.0.8\",\n    \"styled-components\": \"^4.2.0\",\n    \"styled-system\": \"^4.1.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.4.3\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.4.0\",\n    \"@babel/preset-env\": \"^7.4.3\",\n    \"@babel/preset-react\": \"^7.0.0\",\n    \"@babel/preset-typescript\": \"^7.3.3\",\n    \"@types/jest\": \"^24.0.9\",\n    \"@types/react\": \"^16.8.14\",\n    \"@types/react-dom\": \"^16.8.2\",\n    \"@types/styled-components\": \"^4.1.14\",\n    \"@types/styled-system\": \"^4.1.0\",\n    \"typescript\": \"^3.4.4\",\n    \"webpack\": \"^4.30.0\"\n  }\n}\n"
  },
  {
    "path": "examples/styled-components/src/StyleGuideWrapper.tsx",
    "content": "import React, { ReactNode } from 'react';\nimport ThemeProvider from './ThemeProvider';\nimport GlobalStyle from './styles';\n\ninterface Props {\n    children?: ReactNode\n}\n\nconst StyleGuideWrapper = function({ children }: Props) {\n    return (\n        <ThemeProvider>\n            <>\n                <GlobalStyle />\n                {children}\n            </>\n        </ThemeProvider>\n    )\n};\n\nexport default StyleGuideWrapper;\n"
  },
  {
    "path": "examples/styled-components/src/ThemeProvider.tsx",
    "content": "import React, { ReactNode } from 'react';\nimport { ThemeProvider } from 'styled-components';\nimport theme, { inverted } from './theme';\n\ninterface Props {\n    children: any\n}\n\nexport default ({ children }: Props) => (\n\t<ThemeProvider theme={theme}>{children}</ThemeProvider>\n);\n\nexport const Inverted = ({ children }: Props) => (\n\t<ThemeProvider theme={inverted}>{children}</ThemeProvider>\n);\n"
  },
  {
    "path": "examples/styled-components/src/components/Box/Box.js",
    "content": "import styled from 'styled-components';\nimport PropTypes from 'prop-types';\n\nconst Box = styled.div``;\n\nBox.propTypes = {\n\tbig: PropTypes.bool,\n};\n\n/* @component */\nexport default Box;\n"
  },
  {
    "path": "examples/styled-components/src/components/Button/Button.md",
    "content": "### React Styleguidist styled-components TypeScript\n\nSecondary and primary buttons:\n\n```jsx harmony\n<Button>Push me</Button> <Button variant=\"primary\">Push me</Button>\n```\n\nDisabled buttons:\n\n```jsx harmony\n<Button disabled>Can’t touch this</Button> <Button variant=\"primary\" disabled>Can’t touch this</Button>\n```\n\nFull width button:\n\n```js\n<Button fullWidth>Click me</Button> <Button variant=\"primary\" fullWidth as=\"a\" href=\"/\">Click me</Button>\n```\n\nButton as a link:\n\n```js\n<Button as=\"a\" href=\"/\">Click me</Button> <Button as=\"a\" href=\"/\" variant=\"primary\">Click me</Button>\n```\n"
  },
  {
    "path": "examples/styled-components/src/components/Button/Button.tsx",
    "content": "import React, { ReactNode } from 'react'\nimport styled from 'styled-components';\nimport { themeGet } from 'styled-system';\n\ninterface ButtonProps {\n\t/** Button label */\n\tchildren: ReactNode,\n\t/** Button variation */\n\tvariant: 'primary' | 'secondary',\n\tfullWidth: Boolean,\n}\n\nconst getColor = (variant: string) => ({ primary: 'bg', secondary: 'primary' }[variant]);\nconst getBgColor = (variant: string) => ({ primary: 'primary' }[variant]);\n\n/**\n * A button.\n */\nconst Button = styled.button<ButtonProps>`\n\tdisplay: ${props => props.fullWidth && 'block'};\n\twidth: ${props => props.fullWidth && '100%'};\n\theight: 2.5rem;\n\tpadding: ${themeGet('space.3')} ${themeGet('space.4')};\n\ttext-align: center;\n\tborder: 1px solid ${themeGet('colors.primary')};\n\tborder-radius: ${themeGet('radii.base')};\n\tfont-family: ${themeGet('fonts.base')};\n\tfont-size: ${themeGet('fontSizes.base')};\n\tcolor: ${props => props.theme.colors[getColor(props.variant)]};\n\tbackground-color: ${props =>\n\t\tprops.theme.colors[getBgColor(props.variant)] || 'transparent'};\n\ttext-decoration: none;\n\tuser-select: none;\n\tbox-sizing: border-box;\n\t/* We can't use :enabled here because it doesn't work with <a> */\n\t&:hover:not(:disabled),\n\t&:active:not(:disabled) {\n\t\tborder-color: ${themeGet('colors.hover')};\n\t\tbackground-color: ${themeGet('colors.hover')};\n\t\tcursor: pointer;\n\t}\n\t&:focus {\n\t\toutline: 0;\n\t\tbox-shadow: 0 0 0 2px ${themeGet('colors.focus')};\n\t}\n\t&:disabled {\n\t\topacity: 0.6;\n\t\tfilter: saturate(60%);\n\t}\n\t&::-moz-focus-inner {\n\t\tborder: 0;\n\t}\n`;\n\n/** @component */\nexport default Button;\n"
  },
  {
    "path": "examples/styled-components/src/components/Button/index.ts",
    "content": "export { default } from './Button'\n"
  },
  {
    "path": "examples/styled-components/src/components/Flex/Flex.tsx",
    "content": "import styled from \"@emotion/styled\";\n\ninterface FlexProps {\n    bool: boolean\n}\n\nconst Flex = styled('div')<FlexProps>`\n\tdisplay: flex;\n`;\n\n/** @component */\nexport default Flex;\n"
  },
  {
    "path": "examples/styled-components/src/components/Heading/Heading.md",
    "content": "```jsx\n<Heading value=\"test\" />\n```\n"
  },
  {
    "path": "examples/styled-components/src/components/Heading/Heading.tsx",
    "content": "import React from 'react';\n\ninterface HeadingProps {\n    /** A value to render */\n    value: string,\n    /** Size of the heading */\n    size?: 'sm' | 'md' | 'lg'\n}\n\nconst Heading = ({ value, size = 'md' }: HeadingProps) => {\n    return (\n        <h1>Heading for {value} of {size}</h1>\n    );\n}\n\nexport default Heading\n"
  },
  {
    "path": "examples/styled-components/src/components/Heading/index.ts",
    "content": "export { default } from './Heading'\n"
  },
  {
    "path": "examples/styled-components/src/styles.ts",
    "content": "import { createGlobalStyle } from 'styled-components';\n\nconst GlobalStyle = createGlobalStyle`\n\tbody {\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t}\n\thtml {\n\t\tbox-sizing: border-box;\n\t}\n\t*,\n\t*:before,\n\t*:after {\n \t\tbox-sizing: inherit;\n\t}\n`;\n\nexport default GlobalStyle;\n"
  },
  {
    "path": "examples/styled-components/src/theme.ts",
    "content": "import { transparentize, modularScale } from 'polished';\n\nconst scale = (value: number) => modularScale(value, '1rem', 'majorThird');\n\nconst fontSizes = {\n\txxxl: scale(5),\n\txxl: scale(4),\n\txl: scale(3),\n\tl: scale(1),\n\tm: scale(0),\n\ts: scale(-0.5),\n\txs: scale(-0.75),\n};\n\nconst theme = {\n\tfonts: {\n\t\tbase: 'Helvetica Neue, Helvetica, Arial, sans-serif',\n\t\theading: 'Helvetica Neue, Helvetica, Arial, sans-serif',\n\t},\n\tfontSizes: {\n\t\tbase: fontSizes.m,\n\t\t...fontSizes,\n\t},\n\tfontWeights: {\n\t\tnormal: 400,\n\t\tbold: 700,\n\t},\n\theadingFontWeights: {\n\t\txxxl: 400,\n\t\txxl: 400,\n\t\txl: 400,\n\t\tl: 400,\n\t\tm: 700,\n\t},\n\tlineHeights: {\n\t\tbase: 1.5,\n\t\theading: 1.1,\n\t},\n\tcolors: {\n\t\tbg: '#fff',\n\t\tbase: '#333',\n\t\tprimary: '#8667a8',\n\t\tsecondary: '#767676',\n\t\tlight: '#ccc',\n\t\tlighter: '#efefef',\n\t\thover: '#ed9dc5',\n\t\tfocus: transparentize(0.4, '#ed9dc5'),\n\t\terror: '#d0453e',\n\t\trating: '#f8c124',\n\t},\n\tborders: {\n\t\tnone: 'none',\n\t\tthin: '1px solid',\n\t},\n\tradii: {\n\t\tbase: '0.15em',\n\t},\n\tspace: [\n\t\t0,\n\t\t'0.125rem', // 2px\n\t\t'0.25rem', // 4px\n\t\t'0.5rem', // 8px\n\t\t'1rem', // 16px\n\t\t'2rem', // 32px\n\t\t'4rem', // 64px\n\t\t'8rem', // 128px\n\t\t'16rem', // 256px\n\t\t'32rem', // 512px\n\t],\n};\n\nexport default theme;\n\nexport const inverted = {\n\t...theme,\n\tcolors: {\n\t\t...theme.colors,\n\t\tbg: theme.colors.base,\n\t\tbase: theme.colors.bg,\n\t\tprimary: theme.colors.bg,\n\t\tfocus: transparentize(0.1, theme.colors.hover),\n\t\tsecondary: '#ccc',\n\t},\n};\n"
  },
  {
    "path": "examples/styled-components/styleguide.config.js",
    "content": "const path = require('path');\nconst { version } = require('./package');\n\nmodule.exports = {\n\tcomponents: 'src/components/**/*.{js,tsx}',\n\tstyleguideComponents: {\n\t\tWrapper: path.join(__dirname, 'src/StyleGuideWrapper'),\n\t},\n\tdefaultExample: true,\n\tmoduleAliases: {\n\t\t'rsg-example': path.resolve(__dirname, 'src'),\n\t},\n\tusageMode: 'expand',\n\tversion,\n\twebpackConfig: {\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.(js|ts)x?$/,\n\t\t\t\t\texclude: /node_modules/,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t},\n\t\t\t],\n\t\t\tnoParse: /\\.(css|scss)/,\n\t\t},\n\t\tresolve: {\n\t\t\textensions: ['.js', 'jsx', '.ts', '.tsx', '.json'],\n\t\t},\n\t},\n};\n"
  },
  {
    "path": "examples/styled-components/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"jsx\": \"react\",\n    \"target\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"allowJs\": true,\n    \"checkJs\": false,\n    \"noEmit\": true,\n    \"pretty\": true,\n    \"strict\": true,\n    \"isolatedModules\": false,\n    \"skipLibCheck\": true,\n    \"esModuleInterop\": true,\n    \"module\": \"commonjs\",\n    \"lib\": [\n      \"dom\",\n      \"es6\",\n      \"es7\",\n      \"dom.iterable\",\n      \"scripthost\"\n    ],\n    \"types\": [\n    \"./node_modules/@types/\"\n    ]\n  },\n  \"include\": [\n    \"src\"\n  ],\n  \"exclude\": [\n    \"node_modules\"\n  ]\n}\n"
  },
  {
    "path": "examples/themed/Readme.md",
    "content": "# React Styleguidist themed example style guide\n\nHow to start locally:\n\n```\ngit clone https://github.com/styleguidist/react-styleguidist.git\ncd react-styleguidist/examples/themed\nnpm install\nnpx styleguidist server\n```\n\nThen open [http://localhost:6060](http://localhost:6060) in your browser.\n"
  },
  {
    "path": "examples/themed/babel.config.js",
    "content": "module.exports = {\n\tpresets: [\n\t\t[\n\t\t\t'@babel/env',\n\t\t\t{\n\t\t\t\tmodules: false,\n\t\t\t\tuseBuiltIns: 'usage',\n\t\t\t\tcorejs: 3,\n\t\t\t},\n\t\t],\n\t\t'@babel/react',\n\t],\n\tplugins: ['@babel/plugin-proposal-class-properties'],\n};\n"
  },
  {
    "path": "examples/themed/package.json",
    "content": "{\n  \"name\": \"react-styleguidist-example-themed\",\n  \"description\": \"React styleguidist themed example\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"homepage\": \"https://github.com/styleguidist/react-styleguidist\",\n  \"author\": {\n    \"name\": \"Artem Sapegin\",\n    \"url\": \"http://sapegin.me/\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/styleguidist/react-styleguidist.git\"\n  },\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=10\"\n  },\n  \"scripts\": {\n    \"styleguide\": \"styleguidist server\",\n    \"styleguide:build\": \"styleguidist build\"\n  },\n  \"dependencies\": {\n    \"dog-names\": \"^2.0.0\",\n    \"lodash\": \"^4.17.15\",\n    \"prop-types\": \"^15.7.2\",\n    \"react\": \"^16.11.0\",\n    \"react-dom\": \"^16.11.0\",\n    \"react-styleguidist\": \"^10.3.2\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.5.5\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.5.5\",\n    \"@babel/preset-env\": \"^7.5.5\",\n    \"@babel/preset-react\": \"^7.0.0\",\n    \"babel-loader\": \"^8.0.6\",\n    \"css-loader\": \"^3.2.0\",\n    \"file-loader\": \"^4.2.0\",\n    \"style-loader\": \"^1.0.0\",\n    \"url-loader\": \"^2.1.0\",\n    \"webpack\": \"^4.39.1\"\n  }\n}\n"
  },
  {
    "path": "examples/themed/src/Components/Button/Button.css",
    "content": ".button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n\n.button[disabled] {\n\topacity: 0.35;\n\tcursor: default;\n}\n\n.checks {\n\tbackground-image: linear-gradient(45deg, #f5f5f5 25%, transparent 25%),\n\t\tlinear-gradient(-45deg, #f5f5f5 25%, transparent 25%),\n\t\tlinear-gradient(45deg, transparent 75%, #f5f5f5 75%),\n\t\tlinear-gradient(-45deg, transparent 75%, #f5f5f5 75%);\n\tbackground-size: 16px 16px;\n\tbackground-position: 0 0, 0 8px, 8px -8px, -8px 0px;\n}\n"
  },
  {
    "path": "examples/themed/src/Components/Button/Button.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './Button.css';\n\n/**\n * The only true button.\n */\nexport default function Button({ color, size, onClick, disabled, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: Button.sizes[size],\n\t};\n\n\treturn (\n\t\t<button className=\"button\" style={styles} onClick={onClick} disabled={disabled}>\n\t\t\t{children}\n\t\t</button>\n\t);\n}\nButton.propTypes = {\n\t/** Button label */\n\tchildren: PropTypes.node.isRequired,\n\t/** The color for the button */\n\tcolor: PropTypes.string,\n\t/** The size of the button */\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n\t/** Disable button */\n\tdisabled: PropTypes.bool,\n\t/** Gets called when the user clicks on the button */\n\tonClick: PropTypes.func,\n};\nButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n\tonClick: (event) => {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log('You have clicked me!', event.target);\n\t},\n};\nButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n"
  },
  {
    "path": "examples/themed/src/Components/Button/Readme.md",
    "content": "Basic button:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nBig pink button:\n\n```jsx\n<Button size=\"large\" color=\"deeppink\">\n  Click Me\n</Button>\n```\n\nAnd you _can_ **use** `any` [Markdown](http://daringfireball.net/projects/markdown/) here.\n\nFenced code blocks with `js`, `jsx` or `javascript` languages are rendered as a interactive playgrounds:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nAdd padding between examples in a block by passing a `padded` modifier (` ```jsx padded `):\n\n```jsx padded\n<Button>Push Me</Button>\n<Button>Click Me</Button>\n<Button>Tap Me</Button>\n```\n\nYou can add a custom props to an example wrapper (` ```js { \"props\": { \"className\": \"checks\" } } `):\n\n```js { \"props\": { \"className\": \"checks\" } }\n<Button>I’m transparent!</Button>\n```\n\nOr disable an editor by passing a `noeditor` modifier (` ```js noeditor `):\n\n```jsx noeditor\n<Button>Push Me</Button>\n```\n\nTo render an example as highlighted source code add a `static` modifier: (` ```js static `):\n\n```js static\nimport React from 'react'\n```\n\nFenced blocks with other languages are rendered as highlighted code:\n\n```html\n<h1>Hello world</h1>\n```\n"
  },
  {
    "path": "examples/themed/src/Components/Button/index.js",
    "content": "export { default } from './Button';\n"
  },
  {
    "path": "examples/themed/src/Components/CounterButton/CounterButton.js",
    "content": "import React, { Component } from 'react';\n\n/**\n * Button that counts how many times it was pressed and exposes a `@public` method to reset itself.\n */\nexport default class CounterButton extends Component {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.state = {\n\t\t\tvalue: 0,\n\t\t};\n\t}\n\n\t/**\n\t * Sets the counter to a particular value.\n\t *\n\t * @public\n\t * @version 1.0.5\n\t * @param {Number} [newValue=0] New value for the counter\n\t * @returns {string} Test\n\t */\n\tset(newValue = 0) {\n\t\tthis.setState({\n\t\t\tvalue: parseInt(newValue, 10),\n\t\t});\n\t}\n\n\t/**\n\t * Increments the counter. This method is not marked @public and is not visible in the style guide.\n\t */\n\thandleIncrement = () => {\n\t\tthis.setState({\n\t\t\tvalue: this.state.value + 1,\n\t\t});\n\t};\n\n\trender() {\n\t\treturn (\n\t\t\t<button className=\"button\" onClick={this.handleIncrement}>\n\t\t\t\t{this.state.value}\n\t\t\t</button>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/themed/src/Components/CounterButton/Readme.md",
    "content": "```js\nimport Button from '../Button'\nlet ref\n;<div>\n  <CounterButton ref={r => (ref = r)} />\n  <Button size=\"small\" onClick={() => ref.set(0)}>\n    Reset\n  </Button>\n</div>\n```\n"
  },
  {
    "path": "examples/themed/src/Components/CounterButton/index.js",
    "content": "export { default } from './CounterButton';\n"
  },
  {
    "path": "examples/themed/styleguide.config.js",
    "content": "const path = require('path');\nconst { version } = require('./package');\n\nmodule.exports = {\n\tcomponents: 'src/components/**/[A-Z]*.js',\n\tdefaultExample: true,\n\tmoduleAliases: {\n\t\t'rsg-example': path.resolve(__dirname, 'src'),\n\t},\n\tribbon: {\n\t\turl: 'https://github.com/styleguidist/react-styleguidist',\n\t},\n\ttheme: 'styleguide.theme.js',\n\tstyles: 'styleguide.styles.js',\n\tversion,\n\twebpackConfig: {\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\t\texclude: /node_modules/,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.css$/,\n\t\t\t\t\tuse: ['style-loader', 'css-loader'],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n};\n"
  },
  {
    "path": "examples/themed/styleguide.styles.js",
    "content": "export default {\n\tPlayground: {\n\t\tpreview: {\n\t\t\tpaddingLeft: 0,\n\t\t\tpaddingRight: 0,\n\t\t\tborderWidth: [[0, 110, 1, 0]],\n\t\t\tborderRadius: 0,\n\t\t\tborderColor: 'pink',\n\t\t},\n\t},\n};\n"
  },
  {
    "path": "examples/themed/styleguide.theme.js",
    "content": "export default {\n\tcolor: {\n\t\tlink: '#F50',\n\t},\n};\n"
  },
  {
    "path": "examples/webpack/Readme.md",
    "content": "# React Styleguidist webpack example style guide\n\n![](https://d3vv6lp55qjaqc.cloudfront.net/items/0U313M3L0p120g2Y1y3J/Image%202016-04-12%20at%207.25.03%20PM.png)\n\nHow to start locally:\n\n```\ngit clone https://github.com/styleguidist/react-styleguidist.git\ncd react-styleguidist/examples/webpack\nnpm install\nnpx styleguidist server\n```\n\nThen open [http://localhost:6060](http://localhost:6060) in your browser.\n"
  },
  {
    "path": "examples/webpack/babel.config.js",
    "content": "module.exports = {\n\tpresets: [\n\t\t[\n\t\t\t'@babel/preset-env',\n\t\t\t{\n\t\t\t\tmodules: false,\n\t\t\t\tuseBuiltIns: 'usage',\n\t\t\t\tcorejs: 3,\n\t\t\t},\n\t\t],\n\t\t'@babel/react',\n\t],\n\tplugins: ['@babel/plugin-proposal-class-properties'],\n};\n"
  },
  {
    "path": "examples/webpack/package.json",
    "content": "{\n  \"name\": \"react-styleguidist-example-webpack\",\n  \"description\": \"React styleguidist basic example\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"homepage\": \"https://github.com/styleguidist/react-styleguidist\",\n  \"author\": {\n    \"name\": \"Artem Sapegin\",\n    \"url\": \"http://sapegin.me/\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/styleguidist/react-styleguidist.git\"\n  },\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=14\"\n  },\n  \"dependencies\": {\n    \"css-loader\": \"^5.0.0\",\n    \"dog-names\": \"^1.0.2\",\n    \"file-loader\": \"^6.2.0\",\n    \"lodash\": \"^4.17.19\",\n    \"prop-types\": \"^15.6.1\",\n    \"react\": \"^17.0.1\",\n    \"react-dom\": \"^17.0.1\",\n    \"react-styleguidist\": \"file:../../\",\n    \"style-loader\": \"^2.0.0\",\n    \"webpack\": \"^5.3.2\"\n  },\n  \"scripts\": {\n    \"build\": \"webpack\",\n    \"styleguide\": \"styleguidist server\",\n    \"styleguide:build\": \"styleguidist build\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.12.3\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.12.1\",\n    \"@babel/preset-env\": \"^7.12.1\",\n    \"@babel/preset-react\": \"^7.12.1\",\n    \"babel-loader\": \"^8.1.0\",\n    \"core-js\": \"^3.6.5\"\n  }\n}\n"
  },
  {
    "path": "examples/webpack/src/App.css",
    "content": ".App {\n\ttext-align: center;\n}\n\n.App-logo {\n\tanimation: App-logo-spin infinite 20s linear;\n\theight: 80px;\n}\n\n.App-header {\n\tbackground-color: #222;\n\theight: 150px;\n\tpadding: 20px;\n\tcolor: white;\n}\n\n.App-intro {\n\tfont-size: large;\n}\n\n@keyframes App-logo-spin {\n\tfrom {\n\t\ttransform: rotate(0deg);\n\t}\n\tto {\n\t\ttransform: rotate(360deg);\n\t}\n}\n"
  },
  {
    "path": "examples/webpack/src/App.js",
    "content": "/* eslint-disable */\n\nimport React, { Component } from 'react';\nimport logo from './logo.svg';\nimport './App.css';\n\nclass App extends Component {\n\trender() {\n\t\treturn (\n\t\t\t<div className=\"App\">\n\t\t\t\t<div className=\"App-header\">\n\t\t\t\t\t<img src={logo} className=\"App-logo\" alt=\"logo\" />\n\t\t\t\t\t<h2>Welcome to React</h2>\n\t\t\t\t</div>\n\t\t\t\t<p className=\"App-intro\">\n\t\t\t\t\tTo get started, edit <code>src/App.js</code> and save to reload.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n}\n\nexport default App;\n"
  },
  {
    "path": "examples/webpack/src/App.test.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\n\nit('renders without crashing', () => {\n\tconst div = document.createElement('div');\n\tReactDOM.render(<App />, div);\n});\n"
  },
  {
    "path": "examples/webpack/src/components/Button.css",
    "content": ".button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/webpack/src/components/Button.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './Button.css';\n\n/**\n * The only true button.\n */\nexport default function Button({ color, size, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: Button.sizes[size],\n\t};\n\n\treturn (\n\t\t<button className=\"button\" style={styles}>\n\t\t\t{children}\n\t\t</button>\n\t);\n}\nButton.propTypes = {\n\t/**\n\t * Button label.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\tcolor: PropTypes.string,\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n};\nButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n};\nButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n"
  },
  {
    "path": "examples/webpack/src/components/Button.md",
    "content": "Basic button:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nBig pink button:\n\n```jsx\n<Button size=\"large\" color=\"deeppink\">\n  Click Me\n</Button>\n```\n\nAnd you _can_ **use** `any` [Markdown](http://daringfireball.net/projects/markdown/) here.\n\nFenced code blocks with `js`, `jsx` or `javascript` languages are rendered as an interactive playgrounds:\n\n```jsx\n<Button>Push Me</Button>\n```\n\nYou can disable an editor by passing a `noeditor` modifier (` ```js noeditor `):\n\n```jsx noeditor\n<Button>Push Me</Button>\n```\n\nTo render an example as highlighted source code add a `static` modifier (` ```js static `):\n\n```js static\nimport React from 'react'\n```\n\nFenced blocks with other languages are rendered as highlighted code:\n\n```html\n<h1>Hello world</h1>\n```\n"
  },
  {
    "path": "examples/webpack/src/components/Placeholder.css",
    "content": ".placeholder {\n\tbackground: #ccc;\n}\n"
  },
  {
    "path": "examples/webpack/src/components/Placeholder.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport './Placeholder.css';\n\n/**\n * Image placeholders.\n */\nexport default class Placeholder extends Component {\n\tstatic propTypes = {\n\t\ttype: PropTypes.oneOf([\n\t\t\t'animal',\n\t\t\t'bacon',\n\t\t\t'beard',\n\t\t\t'bear',\n\t\t\t'cat',\n\t\t\t'food',\n\t\t\t'city',\n\t\t\t'nature',\n\t\t\t'people',\n\t\t]),\n\t\twidth: PropTypes.number,\n\t\theight: PropTypes.number,\n\t\talt: PropTypes.string,\n\t};\n\n\tstatic defaultProps = {\n\t\ttype: 'animal',\n\t\twidth: 150,\n\t\theight: 150,\n\t\talt: 'Photo of an animal',\n\t};\n\n\tgetImageUrl() {\n\t\tconst { type, width, height } = this.props;\n\t\tconst types = {\n\t\t\tanimal: `http://placeimg.com/${width}/${height}/animals`,\n\t\t\tbacon: `http://baconmockup.com/${width}/${height}`,\n\t\t\tbear: `http://www.placebear.com/${width}/${height}`,\n\t\t\tbeard: `http://placebeard.it/${width}/${height}`,\n\t\t\tcat: `http://lorempixel.com/${width}/${height}/cats`,\n\t\t\tcity: `http://lorempixel.com/${width}/${height}/city`,\n\t\t\tfood: `http://lorempixel.com/${width}/${height}/food`,\n\t\t\tnature: `http://lorempixel.com/${width}/${height}/nature`,\n\t\t\tpeople: `http://lorempixel.com/${width}/${height}/people`,\n\t\t};\n\t\treturn types[type];\n\t}\n\n\trender() {\n\t\tconst { width, height, alt } = this.props;\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"placeholder\"\n\t\t\t\tsrc={this.getImageUrl()}\n\t\t\t\twidth={width}\n\t\t\t\theight={height}\n\t\t\t\talt={alt}\n\t\t\t/>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/webpack/src/components/Placeholder.md",
    "content": "```jsx\n<Placeholder type=\"beard\" />\n```\n"
  },
  {
    "path": "examples/webpack/src/components/RandomButton.css",
    "content": ".random-button {\n\tpadding: 0.5em 1.5em;\n\tcolor: #666;\n\tbackground-color: #fff;\n\tborder: 1px solid currentColor;\n\tborder-radius: 0.3em;\n\tfont-size: 16px;\n\tfont-weight: bold;\n\ttext-align: center;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n"
  },
  {
    "path": "examples/webpack/src/components/RandomButton.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport sample from 'lodash/sample';\n\nimport './RandomButton.css';\n\n/**\n * Button that changes label on every click.\n */\nexport default class RandomButton extends Component {\n\tstatic propTypes = {\n\t\t/**\n\t\t * List of possible labels.\n\t\t */\n\t\tvariants: PropTypes.array.isRequired,\n\t};\n\n\tconstructor(props) {\n\t\tsuper();\n\t\tthis.state = {\n\t\t\tlabel: sample(props.variants),\n\t\t};\n\t}\n\n\thandleClick = () => {\n\t\tthis.setState({\n\t\t\tlabel: sample(this.props.variants),\n\t\t});\n\t};\n\n\trender() {\n\t\treturn (\n\t\t\t<button className=\"random-button\" onClick={this.handleClick}>\n\t\t\t\t{this.state.label}\n\t\t\t</button>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "examples/webpack/src/components/RandomButton.md",
    "content": "You can `import` external files in your examples:\n\n```jsx\nimport { all } from 'dog-names'\n;<RandomButton variants={all} />\n```\n"
  },
  {
    "path": "examples/webpack/src/index.css",
    "content": "body {\n\tmargin: 0;\n\tpadding: 0;\n\tfont-family: sans-serif;\n}\n"
  },
  {
    "path": "examples/webpack/src/index.js",
    "content": "import 'core-js';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\nimport './index.css';\n\nReactDOM.render(<App />, document.getElementById('root'));\n"
  },
  {
    "path": "examples/webpack/styleguide.config.js",
    "content": "module.exports = {\n\ttitle: 'React Style Guide Example',\n\tcomponents: 'src/components/**/*.js',\n};\n"
  },
  {
    "path": "examples/webpack/webpack.config.js",
    "content": "const path = require('path');\n\nmodule.exports = {\n\tentry: './src/index.js',\n\toutput: {\n\t\tfilename: 'bundle.js',\n\t\tpath: path.resolve(__dirname, 'build'),\n\t},\n\tmodule: {\n\t\trules: [\n\t\t\t{\n\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\texclude: /node_modules/,\n\t\t\t\tloader: 'babel-loader',\n\t\t\t},\n\t\t\t{\n\t\t\t\ttest: /\\.css$/,\n\t\t\t\tuse: [\n\t\t\t\t\t'style-loader',\n\t\t\t\t\t{\n\t\t\t\t\t\tloader: 'css-loader',\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\timportLoaders: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\ttest: /\\.svg$/,\n\t\t\t\tloader: 'file-loader',\n\t\t\t\toptions: {\n\t\t\t\t\tname: 'static/media/[name].[hash:8].[ext]',\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t},\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-styleguidist\",\n  \"description\": \"React components style guide generator\",\n  \"version\": \"11.0.0-beta2\",\n  \"homepage\": \"https://github.com/styleguidist/react-styleguidist\",\n  \"author\": {\n    \"name\": \"Artem Sapegin\",\n    \"url\": \"http://sapegin.me/\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/styleguidist/react-styleguidist.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/styleguidist/react-styleguidist/issues\"\n  },\n  \"license\": \"MIT\",\n  \"main\": \"lib/scripts/index.js\",\n  \"module\": \"lib/scripts/index.esm.js\",\n  \"bin\": {\n    \"styleguidist\": \"lib/bin/styleguidist.js\"\n  },\n  \"files\": [\n    \"lib\",\n    \"templates\"\n  ],\n  \"engines\": {\n    \"node\": \">=14\"\n  },\n  \"dependencies\": {\n    \"@tippyjs/react\": \"4.1.0\",\n    \"@types/react-test-renderer\": \"^18.0.0\",\n    \"@vxna/mini-html-webpack-template\": \"^2.0.0\",\n    \"acorn\": \"^6.4.1\",\n    \"acorn-jsx\": \"^5.1.0\",\n    \"assert\": \"1.5.0\",\n    \"ast-types\": \"~0.14.2\",\n    \"buble\": \"0.20.0\",\n    \"clean-webpack-plugin\": \"^4.0.0\",\n    \"clipboard-copy\": \"^3.1.0\",\n    \"clsx\": \"^1.0.4\",\n    \"common-dir\": \"^3.0.0\",\n    \"copy-webpack-plugin\": \"^11.0.0\",\n    \"core-js\": \"^3.6.4\",\n    \"doctrine\": \"^3.0.0\",\n    \"es6-object-assign\": \"~1.1.0\",\n    \"es6-promise\": \"^4.2.8\",\n    \"escape-string-regexp\": \"^1.0.5\",\n    \"escodegen\": \"^1.12.0\",\n    \"estree-walker\": \"~0.9.0\",\n    \"fastest-levenshtein\": \"^1.0.9\",\n    \"findup\": \"^0.1.5\",\n    \"function.name-polyfill\": \"^1.0.6\",\n    \"github-slugger\": \"^1.2.1\",\n    \"glob\": \"^7.1.5\",\n    \"glogg\": \"^1.0.2\",\n    \"hash-sum\": \"^2.0.0\",\n    \"is-plain-obj\": \"^1.1.0\",\n    \"javascript-stringify\": \"^2.0.0\",\n    \"jss\": \"^10.9.0\",\n    \"jss-plugin-camel-case\": \"^10.9.0\",\n    \"jss-plugin-compose\": \"^10.9.0\",\n    \"jss-plugin-default-unit\": \"^10.9.0\",\n    \"jss-plugin-global\": \"^10.9.0\",\n    \"jss-plugin-isolate\": \"^10.9.0\",\n    \"jss-plugin-nested\": \"^10.9.0\",\n    \"kleur\": \"^3.0.3\",\n    \"listify\": \"^1.0.0\",\n    \"lodash\": \"^4.17.15\",\n    \"lowercase-keys\": \"^2.0.0\",\n    \"markdown-to-jsx\": \"^6.11.4\",\n    \"mini-html-webpack-plugin\": \"^3.1.3\",\n    \"mri\": \"^1.1.4\",\n    \"ora\": \"^4.0.2\",\n    \"prismjs\": \"^1.17.1\",\n    \"prop-types\": \"^15.8.1\",\n    \"q-i\": \"^2.0.1\",\n    \"qss\": \"^2.0.3\",\n    \"react-dev-utils\": \"^12.0.0\",\n    \"react-docgen\": \"^5.0.0\",\n    \"react-docgen-annotation-resolver\": \"^2.0.0\",\n    \"react-docgen-displayname-handler\": \"^3.0.0\",\n    \"react-group\": \"^3.0.2\",\n    \"react-icons\": \"^3.8.0\",\n    \"react-simple-code-editor\": \"^0.13.1\",\n    \"recast\": \"~0.18.5\",\n    \"remark\": \"^13.0.0\",\n    \"strip-html-comments\": \"^1.0.0\",\n    \"terser-webpack-plugin\": \"^5.3.3\",\n    \"to-ast\": \"^1.0.0\",\n    \"type-detect\": \"^4.0.8\",\n    \"unist-util-visit\": \"^2.0.0\",\n    \"webpack-dev-server\": \"^4.15.0\",\n    \"webpack-merge\": \"^4.2.2\"\n  },\n  \"peerDependencies\": {\n    \"react\": \">=18.0\",\n    \"react-dom\": \">=18.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.8.4\",\n    \"@babel/core\": \"^7.9.0\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.8.3\",\n    \"@babel/preset-env\": \"^7.9.0\",\n    \"@babel/preset-flow\": \"^7.9.0\",\n    \"@babel/preset-react\": \"^7.18.6\",\n    \"@babel/preset-typescript\": \"^7.18.6\",\n    \"@testing-library/jest-dom\": \"^5.11.4\",\n    \"@testing-library/react\": \"^13.4.0\",\n    \"@types/buble\": \"^0.19.2\",\n    \"@types/copy-webpack-plugin\": \"^5.0.2\",\n    \"@types/doctrine\": \"0.0.3\",\n    \"@types/escodegen\": \"0.0.6\",\n    \"@types/estree\": \"^0.0.39\",\n    \"@types/hash-sum\": \"^1.0.0\",\n    \"@types/jest\": \"^26.0.14\",\n    \"@types/keymirror\": \"^0.1.1\",\n    \"@types/lodash\": \"^4.14.144\",\n    \"@types/markdown-to-jsx\": \"^6.9.0\",\n    \"@types/node\": \"^12.12.3\",\n    \"@types/prismjs\": \"^1.16.0\",\n    \"@types/react\": \"^18.0.28\",\n    \"@types/react-dom\": \"^18.0.10\",\n    \"@types/terser-webpack-plugin\": \"^2.2.3\",\n    \"@types/type-detect\": \"^4.0.1\",\n    \"@types/webpack\": \"^5.28.0\",\n    \"@types/webpack-dev-server\": \"^3.11.1\",\n    \"@types/webpack-env\": \"^1.14.1\",\n    \"@typescript-eslint/eslint-plugin\": \"^4.4.1\",\n    \"@typescript-eslint/parser\": \"^4.4.1\",\n    \"babel-core\": \"^7.0.0-bridge.0\",\n    \"babel-eslint\": \"^10.1.0\",\n    \"babel-jest\": \"^26.6.0\",\n    \"babel-loader\": \"^8.1.0\",\n    \"css-loader\": \"^6.7.1\",\n    \"danger\": \"^10.5.3\",\n    \"deabsdeep\": \"^1.0.6\",\n    \"deepfreeze\": \"^2.0.0\",\n    \"dog-names\": \"^2.0.0\",\n    \"eslint\": \"^7.11.0\",\n    \"eslint-config-tamia\": \"^7.2.6\",\n    \"eslint-import-resolver-typescript\": \"^2.3.0\",\n    \"eslint-plugin-compat\": \"^3.8.0\",\n    \"eslint-plugin-import\": \"^2.22.1\",\n    \"eslint-plugin-jsx-a11y\": \"^6.3.1\",\n    \"eslint-plugin-react\": \"^7.21.4\",\n    \"file-loader\": \"^6.2.0\",\n    \"fs-extra\": \"^9.0.0\",\n    \"husky\": \"^4.3.0\",\n    \"jest\": \"^26.6.0\",\n    \"keymirror\": \"^0.1.1\",\n    \"lint-staged\": \"^10.5.1\",\n    \"memfs\": \"~2.15.5\",\n    \"prettier\": \"2.1.2\",\n    \"raf\": \"^3.4.1\",\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\",\n    \"react-test-renderer\": \"^18.2.0\",\n    \"strip-shebang\": \"^1.0.2\",\n    \"style-loader\": \"^3.3.1\",\n    \"typescript\": \"^4.7.4\",\n    \"url-loader\": \"^4.1.1\",\n    \"webpack\": \"^5.72.0\",\n    \"webpack-cli\": \"^4.9.2\"\n  },\n  \"scripts\": {\n    \"pretest\": \"npm run lint && npm run typecheck\",\n    \"typecheck\": \"tsc -p . --noEmit\",\n    \"test\": \"npm run test:jest\",\n    \"posttest\": \"npm run format\",\n    \"test:jest\": \"jest\",\n    \"test:watch\": \"jest --watch\",\n    \"test:coverage\": \"jest --coverage\",\n    \"start\": \"node lib/bin/styleguidist.js server --config examples/basic/styleguide.config.js\",\n    \"start:customised\": \"node lib/bin/styleguidist.js server --config examples/customised/styleguide.config.js\",\n    \"start:sections\": \"node lib/bin/styleguidist.js server --config examples/sections/styleguide.config.js\",\n    \"start:ui\": \"node lib/bin/styleguidist.js server\",\n    \"lint\": \"eslint . --cache --fix --ext .js,.ts,.tsx\",\n    \"compile\": \"babel --delete-dir-on-start --ignore **/__mocks__/*,**/__tests__/*,**/*.spec.ts,**/*.spec.tsx,**/*.spec.js,**/*.d.ts --extensions .js,.ts,.tsx -d lib/ src/\",\n    \"compile:types\": \"tsc -p ./tsconfig.types.json --emitDeclarationOnly\",\n    \"compile:watch\": \"npm run compile -- --watch\",\n    \"prepublishOnly\": \"npm run compile && npm run compile:types\",\n    \"build:basic\": \"node lib/bin/styleguidist.js build --config examples/basic/styleguide.config.js\",\n    \"build:customised\": \"node lib/bin/styleguidist.js build --config examples/customised/styleguide.config.js\",\n    \"build:sections\": \"node lib/bin/styleguidist.js build --config examples/sections/styleguide.config.js\",\n    \"test:browser:pre\": \"npm i --no-save puppeteer\",\n    \"test:browser:basic\": \"node test/browser.js examples/basic/styleguide/index.html\",\n    \"test:browser:customised\": \"node test/browser.js examples/customised/styleguide/index.html\",\n    \"test:browser:sections\": \"node test/browser.js examples/sections/styleguide/index.html\",\n    \"format\": \"prettier --loglevel warn --write \\\"**/*.{js,md}\\\"\",\n    \"test:cypress:pre\": \"npm i --no-save cypress@6.5.0 wait-on\",\n    \"test:cypress:open\": \"cypress open\",\n    \"test:cypress:run\": \"cypress run\",\n    \"test:cypress:startServer\": \"node test/run.server.js\",\n    \"test:cypress:startServer:post\": \"wait-on http://localhost:8082\"\n  },\n  \"jest\": {\n    \"testURL\": \"http://localhost/\",\n    \"setupFiles\": [\n      \"./test/raf-polyfill.js\",\n      \"./test/jestsetup.js\"\n    ],\n    \"setupFilesAfterEnv\": [\n      \"@testing-library/jest-dom/extend-expect\"\n    ],\n    \"modulePaths\": [\n      \"./src/client\"\n    ],\n    \"testPathIgnorePatterns\": [\n      \"<rootDir>/lib/\",\n      \"<rootDir>/examples/\",\n      \"<rootDir>/test/\"\n    ],\n    \"coveragePathIgnorePatterns\": [\n      \"<rootDir>/src/scripts/server.js\",\n      \"<rootDir>/src/scripts/build.js\"\n    ],\n    \"snapshotSerializers\": [\n      \"./test/deabsdeepSerializer\"\n    ]\n  },\n  \"keywords\": [\n    \"react\",\n    \"jsx\",\n    \"styleguide\",\n    \"style guide\",\n    \"documentation\",\n    \"docs\",\n    \"generator\",\n    \"component\",\n    \"components\"\n  ],\n  \"browserslist\": [\n    \"last 2 Chrome versions\",\n    \"last 2 Opera versions\",\n    \"last 2 Firefox versions\",\n    \"last 2 Edge versions\",\n    \"last 1 Safari version\",\n    \"IE >= 11\"\n  ],\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"lint-staged\"\n    }\n  },\n  \"lint-staged\": {\n    \"*.{js,ts,tsx}\": [\n      \"eslint --fix\",\n      \"git add\"\n    ],\n    \"*.{js,ts,tsx,md,css,json}\": [\n      \"prettier --write\",\n      \"git add\"\n    ]\n  },\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/styleguidist\"\n  }\n}\n"
  },
  {
    "path": "site/.eslintrc.json",
    "content": "{\n\t\"extends\": \"tamia\",\n\t\"parserOptions\": {\n\t\t\"sourceType\": \"script\"\n\t},\n\t\"rules\": {\n\t\t\"no-console\": 0\n\t}\n}\n"
  },
  {
    "path": "site/.gitignore",
    "content": "# Dependencies\n/node_modules\n\n# Production\n/build\n\n# Generated files\n.docusaurus\n.cache-loader\ndocs\n\n# Misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n"
  },
  {
    "path": "site/CNAME",
    "content": "react-styleguidist.js.org\n"
  },
  {
    "path": "site/Readme.md",
    "content": "# [React Styleguidist site](https://react-styleguidist.js.org)\n\n[![Netlify Status](https://api.netlify.com/api/v1/badges/2c45b383-a004-4878-a6c6-79ea2668b865/deploy-status)](https://app.netlify.com/sites/styleguidist/deploys)\n\nThis site is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static site generator.\n\n### Installation\n\n```\nnpm install\nnpm run sync\n```\n\n### Local Development\n\n```\nnpm start\n```\n\nThis command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server.\n\n### Build\n\n```\nnpm run build\n```\n\nThis command generates static content into the `build` directory and can be served using any static contents hosting service.\n"
  },
  {
    "path": "site/docusaurus.config.js",
    "content": "module.exports = {\n\ttitle: 'React Styleguidist',\n\ttagline: 'Isolated React component development environment with a living style guide',\n\turl: 'https://react-styleguidist.js.org/',\n\tbaseUrl: '/',\n\tfavicon: 'img/favicon.ico',\n\torganizationName: 'styleguidist',\n\tprojectName: 'react-styleguidist',\n\tstylesheets: ['https://fonts.googleapis.com/css?family=Bree+Serif|Open+Sans:400,400i,700'],\n\tthemeConfig: {\n\t\tcolorMode: {\n\t\t\tdisableSwitch: true,\n\t\t},\n\t\tprism: {\n\t\t\t// eslint-disable-next-line import/no-extraneous-dependencies\n\t\t\ttheme: require('prism-react-renderer/themes/nightOwlLight'),\n\t\t},\n\t\tnavbar: {\n\t\t\thideOnScroll: false,\n\t\t\ttitle: 'React Styleguidist',\n\t\t\titems: [\n\t\t\t\t{\n\t\t\t\t\tto: 'docs/getting-started',\n\t\t\t\t\tactiveBasePath: 'docs',\n\t\t\t\t\tlabel: 'Docs',\n\t\t\t\t\tposition: 'right',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tto: 'learn',\n\t\t\t\t\tactiveBasePath: 'learn',\n\t\t\t\t\tlabel: 'Learn',\n\t\t\t\t\tposition: 'right',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\thref: 'https://github.com/styleguidist/react-styleguidist',\n\t\t\t\t\tlabel: 'GitHub',\n\t\t\t\t\tposition: 'right',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\thref: 'https://twitter.com/styleguidist',\n\t\t\t\t\tlabel: 'Twitter',\n\t\t\t\t\tposition: 'right',\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\tfooter: {\n\t\t\tlinks: [\n\t\t\t\t{\n\t\t\t\t\ttitle: 'Misc',\n\t\t\t\t\titems: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: 'Changelog',\n\t\t\t\t\t\t\thref: 'https://github.com/styleguidist/react-styleguidist/releases',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: 'Code of conduct',\n\t\t\t\t\t\t\thref:\n\t\t\t\t\t\t\t\t'https://github.com/styleguidist/react-styleguidist/blob/master/.github/Code_of_Conduct.md',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttitle: 'Social',\n\t\t\t\t\titems: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: 'GitHub',\n\t\t\t\t\t\t\thref: 'https://github.com/styleguidist/react-styleguidist',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: 'Twitter',\n\t\t\t\t\t\t\thref: 'https://twitter.com/styleguidist',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttitle: 'Sponsor',\n\t\t\t\t\titems: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: 'Open Collective',\n\t\t\t\t\t\t\thref: 'https://opencollective.com/styleguidist',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: 'Buy me a coffee',\n\t\t\t\t\t\t\thref: 'https://www.buymeacoffee.com/sapegin',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t\tcopyright: `Made with coffee in Berlin by <a href=\"https://sapegin.me/\" target=\"_blank\" rel=\"noopener noreferrer\">Artem Sapegin</a> and <a href=\"https://github.com/styleguidist/react-styleguidist/graphs/contributors\" target=\"_blank\" rel=\"noopener noreferrer\">amazing contributors</a>. Logo: <a href=\"https://okonet.ru/\" target=\"_blank\" rel=\"noopener noreferrer\">Andrey Okonetchnikov</a> and <a href=\"https://iamsaravieira.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Sara Vieira</a>. Hosting: <a href=\"https://www.netlify.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Netlify</a>`,\n\t\t},\n\t\talgolia: {\n\t\t\tapiKey: '0bd0dc976499f3a333c9d26416b4fee1',\n\t\t\tindexName: 'react_styleguidist',\n\t\t\talgoliaOptions: {},\n\t\t},\n\t},\n\tplugins: [require.resolve('./src/plugins/goatcounter-plugin.js')],\n\tpresets: [\n\t\t[\n\t\t\t'@docusaurus/preset-classic',\n\t\t\t{\n\t\t\t\tdebug: false,\n\t\t\t\tdocs: {\n\t\t\t\t\tincludeCurrentVersion: true,\n\t\t\t\t\tsidebarPath: require.resolve('./sidebars.js'),\n\t\t\t\t\tremarkPlugins: require('./remark'),\n\t\t\t\t},\n\t\t\t\ttheme: {\n\t\t\t\t\tcustomCss: require.resolve('./src/css/custom.css'),\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t],\n};\n"
  },
  {
    "path": "site/package.json",
    "content": "{\n  \"name\": \"styleguidist-site\",\n  \"version\": \"0.0.1\",\n  \"private\": true,\n  \"scripts\": {\n    \"start\": \"docusaurus start\",\n    \"build\": \"docusaurus build\",\n    \"swizzle\": \"docusaurus swizzle\",\n    \"sync\": \"node scripts/sync.js\",\n    \"deploy\": \"bash scripts/deploy.sh\"\n  },\n  \"dependencies\": {\n    \"@charlietango/use-script\": \"^2.1.1\",\n    \"@docusaurus/core\": \"2.0.0-alpha.64\",\n    \"@docusaurus/preset-classic\": \"2.0.0-alpha.64\",\n    \"clsx\": \"^1.1.1\",\n    \"fs-extra\": \"^9.0.1\",\n    \"glob\": \"^7.1.6\",\n    \"lodash\": \"^4.17.20\",\n    \"react\": \"^16.13.1\",\n    \"react-dom\": \"^16.13.1\",\n    \"unist-util-visit\": \"^2.0.3\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.2%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  }\n}\n"
  },
  {
    "path": "site/remark.js",
    "content": "const visit = require('unist-util-visit');\nconst { kebabCase } = require('lodash');\n\nconst IGNORES = [\n\t'https://raw.githubusercontent.com/styleguidist/react-styleguidist/master/templates/DefaultExample.md',\n\t'https://github.com/styleguidist/react-styleguidist/blob/master/.github/Contributing.md',\n];\nconst REPLACEMENTS = {\n\t'https://github.com/styleguidist/react-styleguidist': 'https://react-styleguidist.js.org/',\n};\n\nconst getDocUrl = (url) => url.replace(/(\\w+)(?:\\.md)/, (_, $1) => `/docs/${kebabCase($1)}`);\n\n/*\n * Fix links:\n * GettingStarted.md -> /docs/getting-started\n */\nfunction link() {\n\treturn (ast) =>\n\t\tvisit(ast, 'link', (node) => {\n\t\t\tif (IGNORES.includes(node.url)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (REPLACEMENTS[node.url]) {\n\t\t\t\tnode.url = REPLACEMENTS[node.url];\n\t\t\t} else if (node.url.endsWith('.md') || node.url.includes('.md#')) {\n\t\t\t\tnode.url = getDocUrl(node.url);\n\t\t\t}\n\t\t});\n}\n\nmodule.exports = [link];\n"
  },
  {
    "path": "site/scripts/deploy.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\n# Deploy to Netlify\n\nEXAMPLE_DIR=\"../examples/basic\"\nSTATIC_DIR=\"static\"\n\necho \"Node $(node -v)\"\necho \"npm $(npm -v)\"\n\n# Build a basic example\necho\necho \"Building the basic example...\"\ncd \"$EXAMPLE_DIR\"\nnpm install\nnpm run styleguide:build\ncd -\n\n# Copy to the public folder\necho\necho \"Copying the basic example...\"\nmkdir -p \"$STATIC_DIR/examples/basic\"\ncp -R $EXAMPLE_DIR/styleguide/* \"$STATIC_DIR/examples/basic\"\n\n# Build the site\necho\necho \"Building the site...\"\nnpm run sync\nnpm run build\n"
  },
  {
    "path": "site/scripts/sync.js",
    "content": "// Get docs from the docs folder and each preset and task\n\nconst { readFileSync, writeFileSync, emptyDirSync } = require('fs-extra');\nconst glob = require('glob');\nconst { kebabCase } = require('lodash');\n\nconst DEST_DIR = 'docs';\n\nconst read = (file) => readFileSync(file, 'utf8');\n\nconst write = (file, contents) => writeFileSync(`${DEST_DIR}/${file}.md`, contents);\n\nconst getTitle = (contents) => contents.match(/^#\\s*(.*?)$/m) || [];\n\nconst getSidebarTitle = (contents) => contents.match(/^<!--\\s*(.*?)(?:\\s*#([\\w-]+))?\\s*-->/) || [];\n\nconst stripTitle = (contents) => contents.replace(/^#.*?$/m, '');\n\nconst markdownToDocusaurus = (contents) =>\n\tcontents.replace(\n\t\t/^>\\s*\\*\\*(\\w+):\\*\\*\\s*(.*?)$/gm,\n\t\t(_, $1, $2) => `:::${$1.toLowerCase()}\\n${$2}\\n:::`\n\t);\n\nconst htmlToXml = (contents) => contents.replace(/<br>/g, '<br />');\n\nconst getEditUrl = (relativePath) =>\n\t`https://github.com/styleguidist/react-styleguidist/edit/master/${relativePath.replace(\n\t\t'../docs',\n\t\t'docs'\n\t)}`;\n\nconst template = ({ id, title, sidebarLabel, editUrl, contents }) => `---\nid: ${id}\ntitle: ${title}\nsidebar_label: ${sidebarLabel}\ncustom_edit_url: ${getEditUrl(editUrl)}\n---\n\n${stripTitle(htmlToXml(markdownToDocusaurus(contents)))}`;\n\nemptyDirSync(DEST_DIR);\n\nconsole.log('Syncing docs...');\n\nconst docs = glob.sync('../docs/*.md');\ndocs.forEach((filepath) => {\n\tconsole.log(`👉 ${filepath}`);\n\tconst contents = read(filepath);\n\tconst [, title] = getTitle(contents);\n\tconst [, sidebarLabel = title, customId] = getSidebarTitle(contents);\n\tconst id = customId || kebabCase(sidebarLabel);\n\twrite(\n\t\tid,\n\t\ttemplate({\n\t\t\tid,\n\t\t\ttitle,\n\t\t\tsidebarLabel,\n\t\t\teditUrl: filepath,\n\t\t\tcontents,\n\t\t})\n\t);\n});\n"
  },
  {
    "path": "site/sidebars.js",
    "content": "module.exports = {\n\tsomeSidebar: {\n\t\tEssentials: [\n\t\t\t'getting-started',\n\t\t\t'documenting',\n\t\t\t'components',\n\t\t\t'thirdparties',\n\t\t\t'webpack',\n\t\t\t'cookbook',\n\t\t],\n\t\tAdvanced: ['configuration', 'cli', 'api', 'development', 'maintenance'],\n\t},\n};\n"
  },
  {
    "path": "site/src/.eslintrc.json",
    "content": "{\n\t\"root\": true,\n\t\"extends\": \"tamia/react\"\n}\n"
  },
  {
    "path": "site/src/components/Box.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport styles from './Box.module.css';\n\nexport const Box = ({ children, textAlign, className, as: Component = 'div', ...rest }) => (\n\t<Component\n\t\tclassName={clsx(styles.box, textAlign && styles[`box--textAlign-${textAlign}`], className)}\n\t\t{...rest}\n\t>\n\t\t{children}\n\t</Component>\n);\n\nBox.propTypes = {\n\tchildren: PropTypes.node,\n\ttextAlign: PropTypes.oneOf(['center']),\n\tclassName: PropTypes.string,\n\tas: PropTypes.string,\n};\n"
  },
  {
    "path": "site/src/components/Box.module.css",
    "content": ".box--textAlign-center {\n\ttext-align: center;\n}\n"
  },
  {
    "path": "site/src/components/Column.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport styles from './Column.module.css';\n\nexport const Row = ({ children, className, as: Component = 'div', ...rest }) => (\n\t<Component className={clsx('row', className)} {...rest}>\n\t\t{children}\n\t</Component>\n);\n\nRow.propTypes = {\n\tchildren: PropTypes.node.isRequired,\n\tclassName: PropTypes.string,\n\tas: PropTypes.string,\n};\n\nexport const Column = ({ children, size, order, className, as: Component = 'div', ...rest }) => (\n\t<Component\n\t\tclassName={clsx('col', `col--${size}`, order && styles[`col--order-${order}`], className)}\n\t\t{...rest}\n\t>\n\t\t{children}\n\t</Component>\n);\n\nColumn.propTypes = {\n\tchildren: PropTypes.node.isRequired,\n\tsize: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]).isRequired,\n\torder: PropTypes.oneOf([2]),\n\tclassName: PropTypes.string,\n\tas: PropTypes.string,\n};\n"
  },
  {
    "path": "site/src/components/Column.module.css",
    "content": "@media (min-width: 997px) {\n\t.col--order-2 {\n\t\torder: 2;\n\t}\n}\n"
  },
  {
    "path": "site/src/components/ImageLink.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport styles from './ImageLink.module.css';\n\nexport const ImageLink = ({ children, className, ...rest }) => (\n\t<a className={clsx(styles.link, className)} target=\"_blank\" rel=\"noopener noreferrer\" {...rest}>\n\t\t{children}\n\t</a>\n);\n\nImageLink.propTypes = {\n\thref: PropTypes.string.isRequired,\n\tclassName: PropTypes.string,\n\tchildren: PropTypes.node.isRequired,\n};\n"
  },
  {
    "path": "site/src/components/ImageLink.module.css",
    "content": ".link {\n\tdisplay: inline-block;\n}\n.link:focus {\n\toutline: 0;\n}\n\n.link img {\n\tvertical-align: middle;\n\toutline: 1px solid var(--ifm-color-gray-200);\n}\n.link:hover img,\n.link:active img,\n.link:focus img {\n\toutline: 2px solid var(--ifm-color-primary-lightest);\n}\n"
  },
  {
    "path": "site/src/components/List.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport { Stack } from './Stack';\nimport styles from './List.module.css';\n\nexport const List = ({ children, className, ...rest }) => (\n\t<Stack as=\"ul\" gap=\"s\" className={clsx(styles.list, className)} {...rest}>\n\t\t{children}\n\t</Stack>\n);\n\nList.propTypes = {\n\tchildren: PropTypes.node,\n\tclassName: PropTypes.string,\n};\n"
  },
  {
    "path": "site/src/components/List.module.css",
    "content": ".list {\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n"
  },
  {
    "path": "site/src/components/Stack.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport styles from './Stack.module.css';\n\nexport const Stack = ({ children, gap, className, as: Component = 'div', ...rest }) => (\n\t<Component className={clsx(styles.stack, styles[`stack--${gap}`], className)} {...rest}>\n\t\t{children}\n\t</Component>\n);\n\nStack.propTypes = {\n\tchildren: PropTypes.node.isRequired,\n\tgap: PropTypes.oneOf(['xxs', 'xs', 's', 'm', 'l', 'xl']).isRequired,\n\tclassName: PropTypes.string,\n\tas: PropTypes.string,\n};\n"
  },
  {
    "path": "site/src/components/Stack.module.css",
    "content": ".stack.stack > * {\n\tmargin-bottom: 0;\n}\n.stack--xxs.stack--xxs > * + * {\n\tmargin-top: 0.125rem; /* 2px */\n}\n.stack--xs.stack--xs > * + * {\n\tmargin-top: 0.25rem; /* 4px */\n}\n.stack--s.stack--s > * + * {\n\tmargin-top: 0.5rem; /* 8px */\n}\n.stack--m.stack--m > * + * {\n\tmargin-top: 1rem; /* 16px */\n}\n.stack--l.stack--l > * + * {\n\tmargin-top: 2rem; /* 32px */\n}\n.stack--xl.stack--xl > * + * {\n\tmargin-top: 4rem; /* 32px */\n}\n"
  },
  {
    "path": "site/src/components/VideoImage.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport styles from './VideoImage.module.css';\n\nexport const VideoImage = ({ className, ...rest }) => (\n\t<div className={clsx(styles.container, className)}>\n\t\t<img {...rest} />\n\t</div>\n);\n\nVideoImage.propTypes = {\n\tsrc: PropTypes.string.isRequired,\n\talt: PropTypes.string.isRequired,\n\tclassName: PropTypes.string,\n};\n"
  },
  {
    "path": "site/src/components/VideoImage.module.css",
    "content": ".container {\n\tposition: relative;\n}\n\n.container::after {\n\tcontent: '';\n\tposition: absolute;\n\tleft: calc(50% - 2rem);\n\ttop: calc(50% - 4rem);\n\twidth: 0;\n\theight: 0;\n\tborder-style: solid;\n\tborder-width: 4rem 0 4rem 6.95rem;\n\tborder-color: transparent transparent transparent var(--ifm-color-primary-lightest);\n\tfilter: drop-shadow(0 0 0.75rem var(--ifm-color-gray-400));\n}\n"
  },
  {
    "path": "site/src/components/VisuallyHidden.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport styles from './VisuallyHidden.module.css';\n\nexport const VisuallyHidden = ({ children, as: Component = 'span', ...rest }) => (\n\t<Component className={styles.visuallyHidden} {...rest}>\n\t\t{children}\n\t</Component>\n);\n\nVisuallyHidden.propTypes = {\n\tchildren: PropTypes.node.isRequired,\n\tas: PropTypes.string,\n};\n"
  },
  {
    "path": "site/src/components/VisuallyHidden.module.css",
    "content": ".visuallyHidden {\n\tborder: 0;\n\tclip: rect(0 0 0 0);\n\theight: 1px;\n\tmargin: -1px;\n\toverflow: hidden;\n\tpadding: 0;\n\tposition: absolute;\n\twidth: 1px;\n\twhite-space: nowrap;\n\tword-wrap: normal;\n}\n"
  },
  {
    "path": "site/src/css/custom.css",
    "content": "/**\n * Any CSS included here will be global. The classic template\n * bundles Infima by default. Infima is a CSS framework designed to\n * work well for content-centric websites.\n */\n\n/* You can override the default Infima variables here. */\n:root {\n\t--color-base: #252525;\n\t--ifm-color-gray-0: var(--ifm-color-white);\n\t--ifm-color-gray-100: #f5f5f5;\n\t--ifm-color-gray-200: #ebebeb;\n\t--ifm-color-gray-300: #dadada;\n\t--ifm-color-gray-400: #cccccc;\n\t--ifm-color-gray-500: #bebebe;\n\t--ifm-color-gray-600: #8d8d8d;\n\t--ifm-color-gray-700: #606060;\n\t--ifm-color-gray-800: #444444;\n\t--ifm-color-gray-900: #1c1c1c;\n\t--ifm-color-gray-1000: var(--ifm-color-black);\n\t--ifm-color-primary: #0094a9;\n\t--ifm-color-primary-dark: #008598;\n\t--ifm-color-primary-darker: #007e90;\n\t--ifm-color-primary-darkest: #006876;\n\t--ifm-color-primary-light: #00a3ba;\n\t--ifm-color-primary-lighter: #00aac2;\n\t--ifm-color-primary-lightest: #00c0dc;\n\t--ifm-font-color-base: var(--color-base);\n\t--ifm-heading-color: var(--color-base);\n\t--ifm-button-color: var(--color-base);\n\t--ifm-hero-text-color: var(--color-base);\n\t--ifm-link-hover-color: var(--ifm-color-primary-lightest);\n\t--ifm-font-family-base: 'Open Sans', Helvetica, sans-serif;\n\t--ifm-heading-font-weight: normal;\n\t--ifm-button-color: var(--ifm-color-primary);\n\t--ifm-button-background-color: var(--ifm-color-white);\n\t--ifm-button-border-color: var(--ifm-color-primary);\n\t--ifm-button-border-radius: 3px;\n\t--ifm-button-font-weight: normal;\n\t--ifm-button-padding-vertical: 0.5rem;\n\t--ifm-link-decoration: underline;\n\t--ifm-navbar-background-color: var(--ifm-color-primary);\n\t--ifm-navbar-link-color: var(--ifm-color-white);\n\t--ifm-navbar-link-hover-color: var(--ifm-color-gray-300);\n\t--ifm-navbar-search-input-background-color: var(--ifm-color-gray-100);\n\t--ifm-menu-color-background-hover: rgba(0, 0, 0, 0.15);\n\t--ifm-footer-background-color: var(--ifm-color-primary-darkest);\n\t--ifm-footer-color: var(--ifm-color-gray-300);\n\t--ifm-footer-title-color: var(--ifm-color-gray-300);\n\t--ifm-footer-link-color: var(--ifm-color-white);\n\t--ifm-footer-link-hover-color: var(--ifm-color-gray-300);\n\t--ifm-h1-font-size: 2.4rem;\n\t--ifm-h2-font-size: 1.8rem;\n\t--ifm-h3-font-size: 1.4rem;\n\t--ifm-h4-font-size: 1.2rem;\n}\n\n.DocSearch-Button.DocSearch-Button {\n\t--docsearch-muted-color: var(--ifm-color-gray-600);\n\t--docsearch-key-gradient: transparent;\n\t--docsearch-key-shadow: 0 0 0 1px var(--docsearch-muted-color);\n\t--docsearch-searchbox-shadow: 0 0 0 2px var(--ifm-navbar-background-color),\n\t\t0 0 0 4px var(--ifm-button-background-color);\n\n\tborder-radius: var(--ifm-button-border-radius);\n}\n.DocSearch-Button-Key.DocSearch-Button-Key {\n\tpadding: 0;\n}\n\na:focus {\n\toutline: solid 2px;\n\toutline-offset: 2px;\n}\n\nvideo {\n\tmax-width: 100%;\n}\n\n.button:hover,\n.button:active,\n.button:focus {\n\tcolor: var(--ifm-link-hover-color);\n\tborder-color: var(--ifm-link-hover-color);\n}\n.button:focus {\n\tbox-shadow: 0 0 0 2px var(--ifm-button-background-color), 0 0 0 4px var(--ifm-link-hover-color);\n}\n\n.docusaurus-highlight-code-line {\n\tbackground-color: rgb(72, 77, 91);\n\tdisplay: block;\n\tmargin: 0 calc(-1 * var(--ifm-pre-padding));\n\tpadding: 0 var(--ifm-pre-padding);\n}\n\n/* Colors from https://getbootstrap.com/docs/4.5/components/alerts/ */\n.alert--secondary {\n\t--ifm-alert-color: #383d41;\n\t--ifm-alert-background-color: #e2e3e5;\n\t--ifm-alert-border-color: #d6d8db;\n}\n.alert--info {\n\t--ifm-alert-color: #0c5460;\n\t--ifm-alert-background-color: #d1ecf1;\n\t--ifm-alert-border-color: #bee5eb;\n}\n.alert--success {\n\t--ifm-alert-color: #155724;\n\t--ifm-alert-background-color: #d4edda;\n\t--ifm-alert-border-color: #c3e6cb;\n}\n.alert--warning {\n\t--ifm-alert-color: #856404;\n\t--ifm-alert-background-color: #fff3cd;\n\t--ifm-alert-border-color: #ffeeba;\n}\n.alert--danger {\n\t--ifm-alert-color: #721c24;\n\t--ifm-alert-background-color: #f8d7da;\n\t--ifm-alert-border-color: #f5c6cb;\n}\n.alert {\n\t--ifm-heading-color: var(--ifm-alert-color);\n\t--ra-admonition-icon-color: var(--ifm-alert-color);\n}\n.alert h5 {\n\tfont-weight: bold;\n}\n.alert code {\n\tpadding: 0;\n\tcolor: inherit;\n\tbackground-color: transparent;\n}\n\n/* Fix missing empty lines in code examples */\n.token-line {\n\tmin-height: 1.25rem;\n}\n\n@media (max-width: 996px) {\n\t.row .col.col.col + .col.col.col {\n\t\tmargin-top: 1rem;\n\t\torder: initial;\n\t}\n}\n\n.navbar__brand {\n\ttext-decoration: none;\n}\n.navbar__brand:hover {\n\tcolor: var(--ifm-navbar-link-hover-color);\n}\n.navbar__toggle {\n\tcolor: var(--ifm-navbar-link-color);\n}\n.navbar__toggle:hover {\n\tcolor: var(--ifm-navbar-link-hover-color);\n}\n.navbar__toggle:focus {\n\toutline: 1px dotted;\n}\n\n.menu__link {\n\ttext-decoration: none;\n}\n.navbar-sidebar .menu__link {\n\t--ifm-menu-color: var(--ifm-color-white);\n}\n\n.footer a:link,\n.footer a:visited {\n\tcolor: var(--ifm-footer-link-color);\n}\n.footer a:hover,\n.footer a:active,\n.footer a:focus {\n\tcolor: var(--ifm-footer-link-hover-color);\n}\n"
  },
  {
    "path": "site/src/pages/index.js",
    "content": "import React from 'react';\nimport clsx from 'clsx';\nimport Layout from '@theme/Layout';\nimport PropTypes from 'prop-types';\nimport Link from '@docusaurus/Link';\nimport useDocusaurusContext from '@docusaurus/useDocusaurusContext';\nimport useBaseUrl from '@docusaurus/useBaseUrl';\nimport { VisuallyHidden } from '../components/VisuallyHidden';\nimport { Row, Column } from '../components/Column';\nimport { Stack } from '../components/Stack';\nimport { ImageLink } from '../components/ImageLink';\nimport styles from './index.module.css';\n\nconst features = [\n\t{\n\t\ttitle: 'Development environment',\n\t\tsubtitle:\n\t\t\t'Focus on one component at a time, see all its variants and work faster with hot reload',\n\t\tparagraphs: [\n\t\t\t'Supports JavaScript, TypeScript and Flow',\n\t\t\t'Works with Create React App out of the box',\n\t\t],\n\t\tfigure: (\n\t\t\t<ImageLink href=\"https://react-styleguidist.js.org/examples/basic/\">\n\t\t\t\t<img src=\"/img/workbench.jpg\" alt=\"React Styleguidist example style guide\" />\n\t\t\t</ImageLink>\n\t\t),\n\t},\n\t{\n\t\ttitle: 'Style guide',\n\t\tsubtitle: 'Share components with your team, including designers and developers',\n\t\tparagraphs: [\n\t\t\t'All components in one place',\n\t\t\t'Autogenerated usage documentation',\n\t\t\t'Editable live examples',\n\t\t],\n\t\tfigure: (\n\t\t\t<Row>\n\t\t\t\t<Column size={6}>\n\t\t\t\t\t<ImageLink href=\"https://cdds.netlify.app/styleguide/\">\n\t\t\t\t\t\t<img src=\"/img/styleguide1.jpg\" alt=\"Component-driven.io style guide\" />\n\t\t\t\t\t</ImageLink>\n\t\t\t\t</Column>\n\t\t\t\t<Column size={6}>\n\t\t\t\t\t<ImageLink href=\"https://tamiadev.github.io/tamia/\">\n\t\t\t\t\t\t<img src=\"/img/styleguide2.jpg\" alt=\"React Styleguidist example style guide\" />\n\t\t\t\t\t</ImageLink>\n\t\t\t\t</Column>\n\t\t\t</Row>\n\t\t),\n\t},\n\t{\n\t\ttitle: 'Interactive playground',\n\t\tsubtitle: 'See how components react to different props and data right in the browser',\n\t\tparagraphs: ['Find the right combination of props and copy the code'],\n\t\tfigure: (\n\t\t\t<ImageLink href=\"https://react-kawaii.now.sh/\" className={styles.featureFigureKawaii}>\n\t\t\t\t<img src=\"/img/playground1.png\" alt=\"React Kawaii docs\" />\n\t\t\t</ImageLink>\n\t\t),\n\t},\n];\n\nconst examples = [\n\t{\n\t\ttitle: 'Example style guide',\n\t\thref: 'https://react-styleguidist.js.org/examples/basic/',\n\t\timage: '/img/example1.png',\n\t},\n\t{\n\t\ttitle: 'Dialog components',\n\t\thref: 'https://dialogs.github.io/dialog-web-components/',\n\t\timage: '/img/example2.png',\n\t},\n\t{\n\t\ttitle: 'Everydayhero Constructicon',\n\t\thref: 'https://everydayhero.github.io/constructicon/',\n\t\timage: '/img/example3.png',\n\t},\n\t{\n\t\ttitle: 'Re-bulma',\n\t\thref: 'https://bokuweb.github.io/re-bulma/',\n\t\timage: '/img/example4.png',\n\t},\n];\n\nfunction Feature({ title, subtitle, paragraphs, figure, flipped }) {\n\treturn (\n\t\t<Row className={styles.feature}>\n\t\t\t<Column size={4} order={flipped ? 2 : undefined}>\n\t\t\t\t<Stack gap=\"m\">\n\t\t\t\t\t<h3>{title}</h3>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<b>{subtitle}</b>\n\t\t\t\t\t</p>\n\t\t\t\t\t<Stack gap=\"s\">\n\t\t\t\t\t\t{paragraphs.map((para) => (\n\t\t\t\t\t\t\t<p key={para}>{para}</p>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Stack>\n\t\t\t\t</Stack>\n\t\t\t</Column>\n\t\t\t<Column size={8}>\n\t\t\t\t<div className={styles.featureFigure}>{figure}</div>\n\t\t\t</Column>\n\t\t</Row>\n\t);\n}\n\nFeature.propTypes = {\n\ttitle: PropTypes.node.isRequired,\n\tsubtitle: PropTypes.node.isRequired,\n\tparagraphs: PropTypes.arrayOf(PropTypes.node).isRequired,\n\tfigure: PropTypes.node.isRequired,\n\tflipped: PropTypes.bool.isRequired,\n};\n\nfunction Resource({ href, title, cover }) {\n\treturn (\n\t\t<Link to={href} className=\"col col--6\">\n\t\t\t<img src={useBaseUrl(cover)} alt={title} />\n\t\t</Link>\n\t);\n}\n\nResource.propTypes = {\n\thref: PropTypes.string.isRequired,\n\ttitle: PropTypes.string.isRequired,\n\tcover: PropTypes.string.isRequired,\n};\n\nfunction Home() {\n\tconst context = useDocusaurusContext();\n\tconst { siteConfig = {} } = context;\n\treturn (\n\t\t<Layout title={`${siteConfig.title}: ${siteConfig.tagline}`} description={siteConfig.tagline}>\n\t\t\t<header className={clsx('hero', styles.heroBanner)}>\n\t\t\t\t<Stack gap=\"l\" className=\"container\">\n\t\t\t\t\t<Stack gap=\"m\" className=\"container\">\n\t\t\t\t\t\t<img src={useBaseUrl('img/logo.svg')} alt=\"\" width={300} />\n\t\t\t\t\t\t<h1 className=\"hero__title\">{siteConfig.title}</h1>\n\t\t\t\t\t\t<p className=\"hero__subtitle\">{siteConfig.tagline}</p>\n\t\t\t\t\t</Stack>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<Link className=\"button button--lg\" to=\"/docs/getting-started\">\n\t\t\t\t\t\t\tGet Started\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t</div>\n\t\t\t\t</Stack>\n\t\t\t</header>\n\t\t\t<main className={styles.main}>\n\t\t\t\t<div className=\"container\">\n\t\t\t\t\t<section className={styles.section}>\n\t\t\t\t\t\t<VisuallyHidden as=\"h2\">React Styleguidist features</VisuallyHidden>\n\t\t\t\t\t\t<Stack gap=\"xl\">\n\t\t\t\t\t\t\t{features.map((feature, index) => (\n\t\t\t\t\t\t\t\t<Feature key={feature.title} flipped={index % 2} {...feature} />\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t</section>\n\t\t\t\t\t<section className={styles.section}>\n\t\t\t\t\t\t<h2>See it in action</h2>\n\t\t\t\t\t\t<Row>\n\t\t\t\t\t\t\t{examples.map((example) => (\n\t\t\t\t\t\t\t\t<Column key={example.href} size={3}>\n\t\t\t\t\t\t\t\t\t<ImageLink href={example.href}>\n\t\t\t\t\t\t\t\t\t\t<Stack gap=\"xs\">\n\t\t\t\t\t\t\t\t\t\t\t<img src={example.image} alt=\"\" />\n\t\t\t\t\t\t\t\t\t\t\t<div>{example.title}</div>\n\t\t\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t\t\t</ImageLink>\n\t\t\t\t\t\t\t\t</Column>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</Row>\n\t\t\t\t\t</section>\n\t\t\t\t</div>\n\t\t\t</main>\n\t\t</Layout>\n\t);\n}\n\nexport default Home;\n"
  },
  {
    "path": "site/src/pages/index.module.css",
    "content": ".heroBanner {\n\t--ifm-heading-line-height: 1;\n\t--ifm-heading-font-weight: normal;\n\tpadding: 1rem;\n\ttext-align: center;\n}\n\n.heroBanner :global(.hero__title) {\n\tfont-size: 2.8rem;\n\tfont-family: 'Bree Serif', Georgia, serif;\n}\n\n.heroBanner :global(.hero__subtitle) {\n\tfont-size: 1.4rem;\n\tfont-family: 'Bree Serif', Georgia, serif;\n\tline-height: 1.3;\n}\n\n@media screen and (min-width: 768px) {\n\t.heroBanner :global(.hero__title) {\n\t\tfont-size: 4.2rem;\n\t}\n\n\t.heroBanner :global(.hero__subtitle) {\n\t\tfont-size: 1.8rem;\n\t}\n}\n\n@media screen and (min-width: 966px) {\n\t.heroBanner {\n\t\tpadding: 2rem 0;\n\t}\n}\n\n.main {\n\tpadding: 3rem 0;\n}\n\n.section + .section {\n\tmargin-top: 2rem;\n}\n\n.feature {\n\t--ifm-h3-font-size: 1.8rem;\n\t--ifm-heading-font-weight: normal;\n}\n\n.featureFigureKawaii {\n\tposition: relative;\n}\n\n.featureFigureKawaii::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tbackground-image: url(/img/playground2.png);\n\tbackground-size: 100%;\n\topacity: 0;\n\ttransition: opacity 0.2s ease-in-out;\n}\n\n.featureFigureKawaii:hover::after,\n.featureFigureKawaii:active::after,\n.featureFigureKawaii:focus::after {\n\topacity: 1;\n}\n"
  },
  {
    "path": "site/src/pages/learn.js",
    "content": "import React from 'react';\nimport Layout from '@theme/Layout';\nimport Link from '@docusaurus/Link';\nimport { Row, Column } from '../components/Column';\nimport { Stack } from '../components/Stack';\nimport { List } from '../components/List';\nimport { ImageLink } from '../components/ImageLink';\nimport { VideoImage } from '../components/VideoImage';\nimport styles from './learn.module.css';\n\nconst sections = [\n\t{\n\t\ttitle: 'Video courses',\n\t\titems: [\n\t\t\t{\n\t\t\t\ttitle: 'React Styleguidist essentials',\n\t\t\t\thref: 'https://egghead.io/playlists/react-styleguidist-essentials-627f',\n\t\t\t\timage: '/img/rsgcourse.png',\n\t\t\t\ttype: 'video',\n\t\t\t},\n\t\t\t{\n\t\t\t\ttitle: 'Component-driven development in React',\n\t\t\t\thref: 'https://egghead.io/playlists/component-driven-development-in-react-e0bf',\n\t\t\t\timage: '/img/cddcourse.png',\n\t\t\t\ttype: 'video',\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\ttitle: 'Workshops',\n\t\tdescription: (\n\t\t\t<Stack gap=\"m\">\n\t\t\t\t<p>\n\t\t\t\t\tLearn how to create resilient component libraries using React Styleguidist from its\n\t\t\t\t\tmaintainers at{' '}\n\t\t\t\t\t<Link\n\t\t\t\t\t\thref=\"https://component-driven.dev/offerings\"\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t>\n\t\t\t\t\t\tComponent-driven\n\t\t\t\t\t</Link>\n\t\t\t\t\t.\n\t\t\t\t</p>\n\t\t\t\t<Link\n\t\t\t\t\thref=\"https://component-driven.dev/offerings\"\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\tclassName={styles.componentDrivenHero}\n\t\t\t\t>\n\t\t\t\t\t<img src=\"/img/component-driven-inverted.svg\" alt=\"Component-driven\" />\n\t\t\t\t</Link>\n\t\t\t</Stack>\n\t\t),\n\t},\n\t{\n\t\ttitle: 'Articles',\n\t\tlinks: [\n\t\t\t{\n\t\t\t\ttitle: 'Front-End Documentation, Style Guides and the Rise of MDX',\n\t\t\t\thref: 'https://css-tricks.com/front-end-documentation-style-guides-and-the-rise-of-mdx/',\n\t\t\t},\n\t\t\t{\n\t\t\t\ttitle: 'How to Visualise Your Components with React Styleguidist',\n\t\t\t\thref: 'https://medium.com/simply/3-react-styleguidist-c7f67830f40a',\n\t\t\t},\n\t\t\t{\n\t\t\t\ttitle: 'React Components Living Style Guides Overview',\n\t\t\t\thref: 'https://www.nearform.com/blog/react-components-living-style-guides-overview/',\n\t\t\t},\n\t\t\t{\n\t\t\t\ttitle: 'Storybook vs Styleguidist: A comparison of the top UI component explorers',\n\t\t\t\thref: 'https://blog.hichroma.com/storybook-vs-styleguidist-2bd93d6dcc06',\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\ttitle: 'Talks',\n\t\tlinks: [\n\t\t\t{\n\t\t\t\ttitle: 'Using React Styleguidist The Wrong Way by Bogdan Kolbik',\n\t\t\t\thref: 'https://youtu.be/2J0WtYfPc-A',\n\t\t\t},\n\t\t\t{\n\t\t\t\ttitle: 'Scalable Design Systems with TypeScript by Tejas Kumar',\n\t\t\t\thref: 'https://youtu.be/ZsBW4S8hYMU',\n\t\t\t},\n\t\t\t{\n\t\t\t\ttitle: 'The Dream of Styleguide Driven Development by Sara Vieira',\n\t\t\t\thref: 'https://youtu.be/JjXnmhNW8Cs',\n\t\t\t},\n\t\t],\n\t},\n];\n\nconst EditIcon = () => (\n\t<svg\n\t\tfill=\"currentColor\"\n\t\theight=\"1.2em\"\n\t\twidth=\"1.2em\"\n\t\tpreserveAspectRatio=\"xMidYMid meet\"\n\t\tviewBox=\"0 0 40 40\"\n\t\tstyle={{\n\t\t\tmarginRight: '0.3em',\n\t\t\tverticalAlign: 'sub',\n\t\t}}\n\t>\n\t\t<g>\n\t\t\t<path d=\"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z\" />\n\t\t</g>\n\t</svg>\n);\n\nfunction Learn() {\n\treturn (\n\t\t<Layout\n\t\t\ttitle=\"Learn React Styleguidist\"\n\t\t\tdescription=\"Video courses, workshops, talks, articles and other learning resources about React Styleguidist\"\n\t\t>\n\t\t\t<Stack gap=\"l\" className=\"container padding-vert--lg\">\n\t\t\t\t<Stack gap=\"m\" as=\"header\">\n\t\t\t\t\t<h1>Learn React Styleguidist</h1>\n\t\t\t\t\t<p>\n\t\t\t\t\t\tLearn how to use React Styleguidist efficiently from its creators and the community.\n\t\t\t\t\t</p>\n\t\t\t\t</Stack>\n\t\t\t\t{sections.map((section) => (\n\t\t\t\t\t<Stack key={section.title} gap=\"m\" as=\"section\">\n\t\t\t\t\t\t<h2>{section.title}</h2>\n\t\t\t\t\t\t{section.description}\n\t\t\t\t\t\t{section.links && (\n\t\t\t\t\t\t\t<List>\n\t\t\t\t\t\t\t\t{section.links.map((link) => (\n\t\t\t\t\t\t\t\t\t<li key={link.href}>\n\t\t\t\t\t\t\t\t\t\t<Link href={link.href} target=\"_blank\" rel=\"noopener noreferrer\">\n\t\t\t\t\t\t\t\t\t\t\t{link.title}\n\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</List>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{section.items && (\n\t\t\t\t\t\t\t<Row>\n\t\t\t\t\t\t\t\t{section.items.map((item) => (\n\t\t\t\t\t\t\t\t\t<Column key={item.href} size={6}>\n\t\t\t\t\t\t\t\t\t\t<ImageLink href={item.href}>\n\t\t\t\t\t\t\t\t\t\t\t<Stack gap=\"xs\">\n\t\t\t\t\t\t\t\t\t\t\t\t{item.type === 'video' && <VideoImage src={item.image} alt=\"\" />}\n\t\t\t\t\t\t\t\t\t\t\t\t<div>{item.title}</div>\n\t\t\t\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t\t\t\t</ImageLink>\n\t\t\t\t\t\t\t\t\t</Column>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</Row>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Stack>\n\t\t\t\t))}\n\t\t\t\t<p>\n\t\t\t\t\t<Link\n\t\t\t\t\t\thref=\"https://github.com/styleguidist/react-styleguidist/edit/master/site/src/pages/learn.js\"\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<EditIcon />\n\t\t\t\t\t\tEdit this page\n\t\t\t\t\t</Link>\n\t\t\t\t</p>\n\t\t\t</Stack>\n\t\t</Layout>\n\t);\n}\n\nexport default Learn;\n"
  },
  {
    "path": "site/src/pages/learn.module.css",
    "content": ".componentDrivenHero {\n\t--shade-color: hsla(228, 37%, 31%, 0.8);\n\n\tdisplay: block;\n\tpadding: 2rem 1rem;\n\ttext-align: center;\n\tbackground-image: linear-gradient(var(--shade-color), var(--shade-color)), url(/img/workshop.jpg);\n\tbackground-position: 50% 50%;\n\tbackground-size: cover;\n}\n"
  },
  {
    "path": "site/src/plugins/goatcounter-plugin.js",
    "content": "module.exports = function () {\n\treturn {\n\t\tname: 'goatcounter-plugin',\n\t\tinjectHtmlTags() {\n\t\t\treturn {\n\t\t\t\theadTags: [\n\t\t\t\t\t`<script>\nif ('history' in window) {\n\tfunction trackView() {\n\t\tif ('goatcounter' in window) {\n\t\t\twindow.goatcounter.count({\n\t\t\t\tpath: location.pathname + location.search,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Monkey patch browser pushState\n\tconst pushState = history.pushState;\n\thistory.pushState = function() {\n\t\tconst returnValue = pushState.apply(history, arguments);\n\t\ttrackView();\n \t\treturn returnValue;\n\t}\n}\n\t\t\t\t\t</script>`,\n\t\t\t\t\t{\n\t\t\t\t\t\ttagName: 'script',\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t'data-goatcounter': 'https://react-styleguidist.goatcounter.com/count',\n\t\t\t\t\t\t\tasync: true,\n\t\t\t\t\t\t\tsrc: '//gc.zgo.at/count.js',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t};\n};\n"
  },
  {
    "path": "site/src/theme/DocSidebar/index.js",
    "content": "import React, { useEffect, useRef } from 'react';\nimport PropTypes from 'prop-types';\nimport useScript from '@charlietango/use-script';\nimport DocSidebarBase from '@theme-original/DocSidebar';\nimport styles from './styles.module.css';\n\nconst SCRIPT_URL = 'https://media.ethicalads.io/media/client/ethicalads.min.js';\nconst PUBLISHER_ID = 'react-styleguidist';\n\nfunction Extra({ path }) {\n\t// Load the EthicalAds script\n\tuseScript(SCRIPT_URL);\n\n\tconst adElement = useRef(null);\n\n\t// Update the ad on navigation\n\tuseEffect(() => {\n\t\tif (window.ethicalads) {\n\t\t\tadElement.current?.classList.add(styles.hidden);\n\t\t\tadElement.current?.classList.remove('loaded');\n\t\t\twindow.ethicalads.load_placements();\n\t\t\tsetTimeout(() => {\n\t\t\t\tadElement.current?.classList.remove(styles.hidden);\n\t\t\t}, 500);\n\t\t}\n\t}, [path]);\n\n\treturn (\n\t\t<div className={styles.extra}>\n\t\t\t<div\n\t\t\t\tref={adElement}\n\t\t\t\tdata-ea-publisher={PUBLISHER_ID}\n\t\t\t\tdata-ea-type=\"image\"\n\t\t\t\tdata-ea-keywords=\"frontend|react\"\n\t\t\t\tclassName=\"bordered\"\n\t\t\t></div>\n\t\t</div>\n\t);\n}\n\nExtra.propTypes = {\n\tpath: PropTypes.string.isRequired,\n};\n\nfunction DocSidebar({ showExtra, ...props }) {\n\treturn (\n\t\t<div className={styles.sidebar}>\n\t\t\t{showExtra && <Extra path={props.path} />}\n\t\t\t<DocSidebarBase {...props} />\n\t\t</div>\n\t);\n}\n\nDocSidebar.propTypes = {\n\tshowExtra: PropTypes.bool,\n\tpath: PropTypes.string.isRequired,\n};\n\nDocSidebar.defaultProps = {\n\tshowExtra: true,\n};\n\nexport default DocSidebar;\n"
  },
  {
    "path": "site/src/theme/DocSidebar/styles.module.css",
    "content": "/* Styles below are mostly copy of the default theme styles. We need to move\n   the sidebar container styles to our own container that contains both:\n   the original sidebar (with styles on the root element removed) and EthicalAds\n   container */\n\n.extra {\n\tdisplay: flex;\n\tjustify-content: center;\n\tmin-height: 12.5rem;\n\tbackground-color: var(--ifm-color-white);\n\ttransition: opacity 0.2s ease-in-out;\n}\n\n.hidden {\n\topacity: 0;\n}\n\n/* HACK: Horizontal EthicalAds layout */\n@media (max-width: 996px) {\n\t[class*='docSidebarContainer'] {\n\t\twidth: auto !important;\n\t}\n\n\t.extra [data-ea-publisher]:global(.loaded) :global(.ea-content) {\n\t\tmax-width: 100%;\n\t}\n\t.extra [data-ea-publisher]:global(.loaded) :global(.ea-content) > :global(.ea-text) {\n\t\tmargin-top: 0;\n\t\ttext-align: left;\n\t\toverflow: hidden;\n\t}\n\t.extra [data-ea-publisher]:global(.loaded) :global(.ea-callout) {\n\t\tmax-width: 100%;\n\t\ttext-align: right;\n\t}\n}\n\n@media (min-width: 997px) {\n\t.extra {\n\t\tmin-height: 24rem;\n\t\tpadding-top: var(--ifm-navbar-height);\n\t}\n\n\t.sidebar {\n\t\theight: 100vh;\n\t\toverflow-y: auto;\n\t\tposition: sticky;\n\t\ttop: 0;\n\t}\n\n\t/* HACK: Remove styles from the theme sidebar container */\n\t.sidebar > *:first-child + * {\n\t\theight: initial;\n\t\toverflow: initial;\n\t\tposition: initial;\n\t\ttop: initial;\n\t\tpadding-top: initial;\n\t}\n\n\t.sidebar::-webkit-scrollbar {\n\t\twidth: 7px;\n\t}\n\n\t.sidebar::-webkit-scrollbar-track {\n\t\tbackground: #f1f1f1;\n\t\tborder-radius: 10px;\n\t}\n\n\t.sidebar::-webkit-scrollbar-thumb {\n\t\tbackground: #888;\n\t\tborder-radius: 10px;\n\t}\n\n\t.sidebar::-webkit-scrollbar-thumb:hover {\n\t\tbackground: #555;\n\t}\n}\n"
  },
  {
    "path": "src/bin/.eslintrc",
    "content": "{\n\t\"extends\": \"tamia\",\n\t\"parserOptions\": {\n\t\t\"sourceType\": \"script\"\n\t}\n}\n"
  },
  {
    "path": "src/bin/__tests__/styleguidist.spec.js",
    "content": "const fs = require('fs');\nconst vm = require('vm');\nconst path = require('path');\nconst stripShebang = require('strip-shebang');\n\nconst BIN_PATH = path.resolve(__dirname, '../styleguidist.js');\n\n// Very simple test to be sure we’re not using any syntax that is not supported in versions of Node we support\nit('should not throw when parsing a script', () => {\n\tconst code = stripShebang(fs.readFileSync(BIN_PATH, 'utf8'));\n\n\texpect(() => new vm.Script(code)).not.toThrow();\n});\n"
  },
  {
    "path": "src/bin/styleguidist.js",
    "content": "#!/usr/bin/env node\n/* eslint-disable no-console */\nconst mri = require('mri');\nconst kleur = require('kleur');\nconst ora = require('ora');\nconst stringify = require('q-i').stringify;\nconst formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');\nconst webpackDevServerUtils = require('react-dev-utils/WebpackDevServerUtils');\nconst openBrowser = require('react-dev-utils/openBrowser');\nconst logger = require('glogg')('rsg');\nconst getConfig = require('../scripts/config').default;\nconst setupLogger = require('../scripts/logger').default;\nconst consts = require('../scripts/consts');\nconst StyleguidistError = require('../scripts/utils/error').default;\n\nconst argv = mri(process.argv.slice(2));\nconst command = argv._[0];\n\n// Do not show nasty stack traces for Styleguidist errors\nprocess.on('uncaughtException', (err) => {\n\tif (err.code === 'EADDRINUSE') {\n\t\tprintErrorWithLink(\n\t\t\t`Another server is running at port ${config.serverPort} already. Please stop it or change the default port to continue.`,\n\t\t\t'You can change the port using the `serverPort` option in your style guide config:',\n\t\t\tconsts.DOCS_CONFIG\n\t\t);\n\t} else if (err instanceof StyleguidistError) {\n\t\tconsole.error(kleur.bold().red(err.message));\n\t\tlogger.debug(err.stack);\n\t} else {\n\t\tconsole.error(err.toString());\n\t\tconsole.error(err.stack);\n\t}\n\tprocess.exit(1);\n});\n\n// Make sure user has webpack installed\nrequire('../scripts/utils/ensureWebpack');\n\n// Set environment before loading style guide config because user’s webpack config may use it\nconst env = command === 'build' ? 'production' : 'development';\nprocess.env.NODE_ENV = process.env.NODE_ENV || env;\n\n// Load style guide config\nlet config;\ntry {\n\tconfig = getConfig(argv.config, updateConfig);\n} catch (err) {\n\tif (err instanceof StyleguidistError) {\n\t\tconst link = consts.DOCS_CONFIG + (err.extra ? `#${err.extra.toLowerCase()}` : '');\n\t\tprintErrorWithLink(err.message, `Learn how to configure your style guide:`, link);\n\t\tprocess.exit(1);\n\t} else {\n\t\tthrow err;\n\t}\n}\n\nverboseLog('Styleguidist config:', config);\n\nswitch (command) {\n\tcase 'build':\n\t\tcommandBuild();\n\t\tbreak;\n\tcase 'server':\n\t\tcommandServer();\n\t\tbreak;\n\tdefault:\n\t\tcommandHelp();\n}\n\n/**\n * @param {object} prevConfig\n * @return {object}\n */\nfunction updateConfig(prevConfig) {\n\t// Set verbose mode from config option or command line switch\n\tconst verbose = prevConfig.verbose || argv.verbose;\n\n\t// Set serverPort from from command line or config option\n\tconst serverPort = parseInt(argv.port) || prevConfig.serverPort;\n\n\t// Setup logger *before* config validation (because validations may use logger to print warnings)\n\tsetupLogger(prevConfig.logger, verbose);\n\n\treturn {\n\t\t...prevConfig,\n\t\tverbose,\n\t\tserverPort,\n\t};\n}\n\nfunction commandBuild() {\n\tconsole.log('Building style guide...');\n\n\tconst build = require('../scripts/build').default;\n\tconst compiler = build(config, (err) => {\n\t\tif (err) {\n\t\t\tconsole.error(err);\n\t\t\tprocess.exit(1);\n\t\t} else if (config.printBuildInstructions) {\n\t\t\tconfig.printBuildInstructions(config);\n\t\t} else {\n\t\t\tprintBuildInstructions(config);\n\t\t}\n\t});\n\n\tverboseLog('Webpack config:', compiler.options);\n\n\t// Custom error reporting\n\tcompiler.hooks.done.tap('rsgCustomErrorBuild', function (stats) {\n\t\tconst messages = formatWebpackMessages(stats.toJson({}, true));\n\t\tconst hasErrors = printAllErrorsAndWarnings(messages, stats.compilation);\n\t\tif (hasErrors) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n}\n\nfunction commandServer() {\n\tlet spinner;\n\n\tconst server = require('../scripts/server').default;\n\tconst compiler = server(config, (err) => {\n\t\tif (err) {\n\t\t\tconsole.error(err);\n\t\t} else {\n\t\t\tconst isHttps = compiler.options.devServer && compiler.options.devServer.https;\n\t\t\tconst urls = webpackDevServerUtils.prepareUrls(\n\t\t\t\tisHttps ? 'https' : 'http',\n\t\t\t\tconfig.serverHost,\n\t\t\t\tconfig.serverPort\n\t\t\t);\n\n\t\t\tif (config.printServerInstructions) {\n\t\t\t\tconfig.printServerInstructions(config, { isHttps });\n\t\t\t} else {\n\t\t\t\tprintServerInstructions(urls);\n\t\t\t}\n\n\t\t\tif (argv.open) {\n\t\t\t\topenBrowser(urls.localUrlForBrowser);\n\t\t\t}\n\t\t}\n\t}).compiler;\n\n\tverboseLog('Webpack config:', compiler.options);\n\n\t// Show message when webpack is recompiling the bundle\n\tcompiler.hooks.invalid.tap('rsgInvalidServer', function () {\n\t\tconsole.log();\n\t\tspinner = ora('Compiling...').start();\n\t});\n\n\t// Custom error reporting\n\tcompiler.hooks.done.tap('rsgCustomErrorServer', function (stats) {\n\t\tif (spinner) {\n\t\t\tspinner.stop();\n\t\t}\n\n\t\tconst messages = formatWebpackMessages(stats.toJson({}, true));\n\n\t\tif (!messages.errors.length && !messages.warnings.length) {\n\t\t\tprintStatus('Compiled successfully!', 'success');\n\t\t}\n\n\t\tprintAllErrorsAndWarnings(messages, stats.compilation);\n\t});\n}\n\nfunction commandHelp() {\n\tconsole.log(\n\t\t[\n\t\t\tkleur.underline('Usage'),\n\t\t\t'',\n\t\t\t'    ' +\n\t\t\t\tkleur.bold('styleguidist') +\n\t\t\t\t' ' +\n\t\t\t\tkleur.cyan('<command>') +\n\t\t\t\t' ' +\n\t\t\t\tkleur.yellow('[<options>]'),\n\t\t\t'',\n\t\t\tkleur.underline('Commands'),\n\t\t\t'',\n\t\t\t'    ' + kleur.cyan('build') + '           Build style guide',\n\t\t\t'    ' + kleur.cyan('server') + '          Run development server',\n\t\t\t'    ' + kleur.cyan('help') + '            Display React Styleguidist help',\n\t\t\t'',\n\t\t\tkleur.underline('Options'),\n\t\t\t'',\n\t\t\t'    ' + kleur.yellow('--config') + '        Config file path',\n\t\t\t'    ' + kleur.yellow('--port') + '          Port to run development server on',\n\t\t\t'    ' + kleur.yellow('--open') + '          Open Styleguidist in the default browser',\n\t\t\t'    ' + kleur.yellow('--verbose') + '       Print debug information',\n\t\t].join('\\n')\n\t);\n}\n\n/**\n * @param {object} urls\n */\nfunction printServerInstructions(urls) {\n\tconsole.log(`You can now view your style guide in the browser:`);\n\tconsole.log();\n\tconsole.log(`  ${kleur.bold('Local:')}            ${urls.localUrlForTerminal}`);\n\tif (urls.lanUrlForTerminal) {\n\t\tconsole.log(`  ${kleur.bold('On your network:')}  ${urls.lanUrlForTerminal}`);\n\t}\n\tconsole.log();\n}\n\n/**\n * @param {object} config\n */\nfunction printBuildInstructions({ styleguideDir }) {\n\tconsole.log('Style guide published to:\\n' + kleur.underline(styleguideDir));\n}\n\n/**\n * @param {string} message\n * @param {string} linkTitle\n * @param {string} linkUrl\n */\nfunction printErrorWithLink(message, linkTitle, linkUrl) {\n\tconsole.error(`${kleur.bold().red(message)}\\n\\n${linkTitle}\\n${kleur.underline(linkUrl)}\\n`);\n}\n\n/**\n * @param {string} header\n * @param {object} errors\n * @param {object} originalErrors\n * @param {'success'|'error'|'warning'} type\n */\nfunction printErrors(header, errors, originalErrors, type) {\n\tprintStatus(header, type);\n\tconsole.error();\n\tconst messages = argv.verbose ? originalErrors : errors;\n\tmessages.forEach((message) => {\n\t\tconsole.error(message.message || message);\n\t});\n}\n\n/**\n * @param {string} text\n * @param {'success'|'error'|'warning'} type\n */\nfunction printStatus(text, type) {\n\tif (type === 'success') {\n\t\tconsole.log(kleur.inverse().bold().green(' DONE ') + ' ' + text);\n\t} else if (type === 'error') {\n\t\tconsole.error(kleur.inverse().bold().red(' FAIL ') + ' ' + kleur.red(text));\n\t} else {\n\t\tconsole.error(kleur.inverse().bold().yellow(' WARN ') + ' ' + kleur.yellow(text));\n\t}\n}\n\n/**\n * @param {object} messages\n * @param {object} compilation\n * @return {boolean}\n */\nfunction printAllErrorsAndWarnings(messages, compilation) {\n\t// If errors exist, only show errors\n\tif (messages.errors.length) {\n\t\tprintAllErrors(messages.errors, compilation.errors);\n\t\treturn true;\n\t}\n\n\t// Show warnings if no errors were found\n\tif (messages.warnings.length) {\n\t\tprintAllWarnings(messages.warnings, compilation.warnings);\n\t}\n\n\treturn false;\n}\n\n/**\n * @param {object} errors\n * @param {object} originalErrors\n */\nfunction printAllErrors(errors, originalErrors) {\n\tprintStyleguidistError(errors);\n\tprintNoLoaderError(errors);\n\tprintErrors('Failed to compile', errors, originalErrors, 'error');\n}\n\n/**\n * @param {object} warnings\n * @param {object} originalWarnings\n */\nfunction printAllWarnings(warnings, originalWarnings) {\n\tprintErrors('Compiled with warnings', warnings, originalWarnings, 'warning');\n}\n\n/**\n * @param {object} errors\n */\nfunction printStyleguidistError(errors) {\n\tconst styleguidistError = errors.find((message) =>\n\t\tmessage.includes('Module build failed: Error: Styleguidist:')\n\t);\n\tif (!styleguidistError) {\n\t\treturn;\n\t}\n\n\tconst m = styleguidistError.match(/Styleguidist: (.*?)\\n/);\n\tprintErrorWithLink(m[1], 'Learn how to configure your style guide:', consts.DOCS_CONFIG);\n\tprocess.exit(1);\n}\n\n/**\n * @param {object} errors\n */\nfunction printNoLoaderError(errors) {\n\tif (argv.verbose) {\n\t\treturn;\n\t}\n\n\tconst noLoaderError = errors.find((message) =>\n\t\tmessage.includes('You may need an appropriate loader')\n\t);\n\tif (!noLoaderError) {\n\t\treturn;\n\t}\n\n\tprintErrorWithLink(\n\t\tnoLoaderError,\n\t\t'Learn how to add webpack loaders to your style guide:',\n\t\tconsts.DOCS_WEBPACK\n\t);\n\tprocess.exit(1);\n}\n\n/**\n * @param {string} header\n * @param {object} object\n */\nfunction verboseLog(header, object) {\n\tlogger.debug(kleur.bold(header) + '\\n\\n' + stringify(object));\n}\n"
  },
  {
    "path": "src/client/consts.ts",
    "content": "export const DisplayModes = Object.freeze({\n\t// Show all sections and components (default)\n\tall: 'all',\n\t// Show one section\n\tsection: 'section',\n\t// Show one component\n\tcomponent: 'component',\n\t// Show one example inside component or section\n\texample: 'example',\n\t// Show error 404\n\tnotFound: 'notFound',\n});\n\nexport const ExampleModes = Object.freeze({\n\thide: 'hide',\n\tcollapse: 'collapse',\n\texpand: 'expand',\n});\n\nexport const UsageModes = Object.freeze({\n\thide: 'hide',\n\tcollapse: 'collapse',\n\texpand: 'expand',\n});\n"
  },
  {
    "path": "src/client/index.ts",
    "content": "/* eslint-disable import/first */\nimport './polyfills';\nimport './styles';\nimport { createRoot, Root } from 'react-dom/client';\nimport renderStyleguide from './utils/renderStyleguide';\nimport { getParameterByName, hasInHash, getHash } from './utils/handleHash';\n\n// Examples code revision to rerender only code examples (not the whole page) when code changes\nlet codeRevision = 0;\n\n// Scrolls to origin when current window location hash points to an isolated view.\nconst scrollToOrigin = () => {\n\tconst hash = window.location.hash;\n\tlet idHashParam;\n\n\tif (hasInHash(hash, '#/') || hasInHash(hash, '#!/')) {\n\t\t// Extracts the id param of hash\n\t\tidHashParam = getParameterByName(hash, 'id');\n\t} else {\n\t\tidHashParam = getHash(hash, '#');\n\t}\n\n\tif (hash) {\n\t\tif (idHashParam) {\n\t\t\tconst idElement = document.getElementById(idHashParam);\n\n\t\t\tif (idElement) {\n\t\t\t\tidElement.scrollIntoView(true);\n\t\t\t}\n\t\t} else {\n\t\t\twindow.scrollTo(0, 0);\n\t\t}\n\t}\n};\n\nlet reactRoot: Root | null = null;\n\nconst render = () => {\n\t// eslint-disable-next-line @typescript-eslint/no-var-requires\n\tconst styleguide = require('!!../loaders/styleguide-loader!./index.js');\n\n\tif (!reactRoot) {\n\t\tconst rootNode = document.getElementById(styleguide.config.mountPointId);\n\t\tif (rootNode) {\n\t\t\treactRoot = createRoot(rootNode);\n\t\t}\n\t}\n\n\tif (reactRoot) {\n\t\treactRoot.render(renderStyleguide(styleguide, codeRevision));\n\t}\n};\n\nwindow.addEventListener('hashchange', render);\nwindow.addEventListener('hashchange', scrollToOrigin);\n\n/* istanbul ignore if */\nif (module.hot) {\n\tmodule.hot.accept('!!../loaders/styleguide-loader!./index.js', () => {\n\t\tcodeRevision += 1;\n\t\trender();\n\t});\n}\n\nrender();\n"
  },
  {
    "path": "src/client/polyfills.ts",
    "content": "// Function.name for IE11\nimport 'function.name-polyfill';\n\n// Object.assign() for IE11\nimport 'es6-object-assign/auto';\n\n// Promise to support webpack 2 require.ensure() in IE11\nimport 'es6-promise/auto';\n"
  },
  {
    "path": "src/client/rsg-components/Argument/Argument.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { ArgumentRenderer, styles } from './ArgumentRenderer';\n\nconst name = 'Foo';\nconst type = { type: 'NameExpression', name: 'Array' };\nconst description = 'Converts foo to bar';\nconst props = {\n\tclasses: classes(styles),\n\tname: 'argname',\n};\n\nit('should render argument', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<ArgumentRenderer {...props} name={name} type={type} description={description} />\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should render argument without type', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<ArgumentRenderer {...props} name={name} description={description} />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should render optional argument', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<ArgumentRenderer\n\t\t\t{...props}\n\t\t\ttype={{ type: 'OptionalType', expression: { type: 'NameExpression', name: 'Array' } }}\n\t\t\tdescription={description}\n\t\t/>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should render default value of argument', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<ArgumentRenderer\n\t\t\t{...props}\n\t\t\ttype={{ type: 'NameExpression', name: 'String' }}\n\t\t\tdefault=\"bar\"\n\t\t\tdescription={description}\n\t\t/>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should render default value of optional argument', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<ArgumentRenderer\n\t\t\t{...props}\n\t\t\ttype={{ type: 'OptionalType', expression: { type: 'NameExpression', name: 'Boolean' } }}\n\t\t\tdefault=\"true\"\n\t\t\tdescription={description}\n\t\t/>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should render argument without description', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<ArgumentRenderer {...props} name={name} type={type} />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should render return value', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<ArgumentRenderer {...props} type={type} description={description} returns />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should render with block styles', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<ArgumentRenderer {...props} block />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Argument/ArgumentRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport Markdown from 'rsg-components/Markdown';\nimport Name from 'rsg-components/Name';\nimport Type from 'rsg-components/Type';\nimport Group from 'react-group';\nimport doctrine from 'doctrine';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ space }: Rsg.Theme) => ({\n\tblock: {\n\t\tmarginBottom: space[2],\n\t},\n});\n\nexport interface ArgumentProps {\n\tname?: string;\n\ttype?: any;\n\tdefault?: string;\n\tdescription?: string;\n\treturns?: boolean;\n\tblock?: boolean;\n}\n\ntype ArgumentPropsWithClasses = ArgumentProps & JssInjectedProps;\n\nexport const ArgumentRenderer: React.FunctionComponent<ArgumentPropsWithClasses> = ({\n\tclasses,\n\tname,\n\ttype,\n\tdescription,\n\treturns,\n\tblock,\n\t...props\n}) => {\n\tconst isOptional = type && type.type === 'OptionalType';\n\tconst defaultValue = props.default;\n\tif (isOptional) {\n\t\ttype = type.expression;\n\t}\n\tconst typeName = type ? doctrine.type.stringify(type) : '';\n\tconst content = (\n\t\t<Group>\n\t\t\t{returns && 'Returns'}\n\t\t\t{name && (\n\t\t\t\t<span>\n\t\t\t\t\t<Name>{name}</Name>\n\t\t\t\t\t{type && ':'}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t{type && (\n\t\t\t\t<Type>\n\t\t\t\t\t{typeName}\n\t\t\t\t\t{isOptional && '?'}\n\t\t\t\t\t{!!defaultValue && `=${defaultValue}`}\n\t\t\t\t</Type>\n\t\t\t)}\n\t\t\t{type && description && `—`}\n\t\t\t{description && <Markdown text={`${description}`} inline />}\n\t\t</Group>\n\t);\n\n\tif (block) {\n\t\treturn <div className={classes.block}>{content}</div>;\n\t}\n\n\treturn content;\n};\n\nArgumentRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tname: PropTypes.string,\n\ttype: PropTypes.object,\n\tdefault: PropTypes.string,\n\tdescription: PropTypes.string,\n\treturns: PropTypes.bool,\n\tblock: PropTypes.bool,\n};\n\nexport default Styled<ArgumentPropsWithClasses>(styles)(ArgumentRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Argument/__snapshots__/Argument.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should render argument 1`] = `\n<Group\n  separator=\" \"\n>\n  <span>\n    <Styled(Name)>\n      Foo\n    </Styled(Name)>\n    :\n  </span>\n  <Styled(Type)>\n    Array\n  </Styled(Type)>\n  —\n  <Markdown\n    inline={true}\n    text=\"Converts foo to bar\"\n  />\n</Group>\n`;\n\nexports[`should render argument without description 1`] = `\n<Group\n  separator=\" \"\n>\n  <span>\n    <Styled(Name)>\n      Foo\n    </Styled(Name)>\n    :\n  </span>\n  <Styled(Type)>\n    Array\n  </Styled(Type)>\n</Group>\n`;\n\nexports[`should render argument without type 1`] = `\n<Group\n  separator=\" \"\n>\n  <span>\n    <Styled(Name)>\n      Foo\n    </Styled(Name)>\n  </span>\n  <Markdown\n    inline={true}\n    text=\"Converts foo to bar\"\n  />\n</Group>\n`;\n\nexports[`should render default value of argument 1`] = `\n<Group\n  separator=\" \"\n>\n  <span>\n    <Styled(Name)>\n      argname\n    </Styled(Name)>\n    :\n  </span>\n  <Styled(Type)>\n    String\n    =bar\n  </Styled(Type)>\n  —\n  <Markdown\n    inline={true}\n    text=\"Converts foo to bar\"\n  />\n</Group>\n`;\n\nexports[`should render default value of optional argument 1`] = `\n<Group\n  separator=\" \"\n>\n  <span>\n    <Styled(Name)>\n      argname\n    </Styled(Name)>\n    :\n  </span>\n  <Styled(Type)>\n    Boolean\n    ?\n    =true\n  </Styled(Type)>\n  —\n  <Markdown\n    inline={true}\n    text=\"Converts foo to bar\"\n  />\n</Group>\n`;\n\nexports[`should render optional argument 1`] = `\n<Group\n  separator=\" \"\n>\n  <span>\n    <Styled(Name)>\n      argname\n    </Styled(Name)>\n    :\n  </span>\n  <Styled(Type)>\n    Array\n    ?\n  </Styled(Type)>\n  —\n  <Markdown\n    inline={true}\n    text=\"Converts foo to bar\"\n  />\n</Group>\n`;\n\nexports[`should render return value 1`] = `\n<Group\n  separator=\" \"\n>\n  Returns\n  <span>\n    <Styled(Name)>\n      argname\n    </Styled(Name)>\n    :\n  </span>\n  <Styled(Type)>\n    Array\n  </Styled(Type)>\n  —\n  <Markdown\n    inline={true}\n    text=\"Converts foo to bar\"\n  />\n</Group>\n`;\n\nexports[`should render with block styles 1`] = `\n<div\n  className=\"block\"\n>\n  <Group\n    separator=\" \"\n  >\n    <span>\n      <Styled(Name)>\n        argname\n      </Styled(Name)>\n    </span>\n  </Group>\n</div>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Argument/index.ts",
    "content": "export { default } from 'rsg-components/Argument/ArgumentRenderer';\nexport * from 'rsg-components/Argument/ArgumentRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Arguments/Arguments.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { ArgumentsRenderer, styles } from './ArgumentsRenderer';\n\nconst props = {\n\tclasses: classes(styles),\n};\n\nconst args = [\n\t{\n\t\tname: 'Foo',\n\t\tdescription: 'Converts foo to bar',\n\t\ttype: { name: 'Array' },\n\t},\n\t{\n\t\tname: 'Foo',\n\t},\n];\n\nit('renderer should render arguments', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<ArgumentsRenderer {...props} args={args} />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('renderer should render heading', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<ArgumentsRenderer {...props} args={[args[1]]} heading />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('renderer should render nothing for empty array', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<ArgumentsRenderer {...props} args={[]} />);\n\n\texpect(renderer.getRenderOutput()).toBe(null);\n});\n"
  },
  {
    "path": "src/client/rsg-components/Arguments/ArgumentsRenderer.tsx",
    "content": "import React from 'react';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport Argument, { ArgumentProps } from 'rsg-components/Argument';\nimport Heading from 'rsg-components/Heading';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ space }: Rsg.Theme) => ({\n\troot: {\n\t\tmarginBottom: space[2],\n\t\tfontSize: 'inherit',\n\t},\n\theadingWrapper: {\n\t\tmarginBottom: space[0],\n\t},\n});\n\ninterface ArgumentsProps extends JssInjectedProps {\n\theading?: boolean;\n\targs: ArgumentProps[];\n}\n\nexport const ArgumentsRenderer: React.FunctionComponent<ArgumentsProps> = ({\n\tclasses,\n\targs,\n\theading,\n}) => {\n\tif (args.length === 0) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div className={classes.root}>\n\t\t\t{heading && (\n\t\t\t\t<div className={classes.headingWrapper}>\n\t\t\t\t\t<Heading level={5}>Arguments</Heading>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{args.map((arg) => (\n\t\t\t\t<Argument key={arg.name} {...arg} />\n\t\t\t))}\n\t\t</div>\n\t);\n};\n\nexport default Styled<ArgumentsProps>(styles)(ArgumentsRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Arguments/__snapshots__/Arguments.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render arguments 1`] = `\n<div\n  className=\"root\"\n>\n  <Styled(Argument)\n    description=\"Converts foo to bar\"\n    name=\"Foo\"\n    type={\n      Object {\n        \"name\": \"Array\",\n      }\n    }\n  />\n  <Styled(Argument)\n    name=\"Foo\"\n  />\n</div>\n`;\n\nexports[`renderer should render heading 1`] = `\n<div\n  className=\"root\"\n>\n  <div\n    className=\"headingWrapper\"\n  >\n    <Styled(Heading)\n      level={5}\n    >\n      Arguments\n    </Styled(Heading)>\n  </div>\n  <Styled(Argument)\n    name=\"Foo\"\n  />\n</div>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Arguments/index.ts",
    "content": "export { default } from 'rsg-components/Arguments/ArgumentsRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Code/Code.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { CodeRenderer } from './CodeRenderer';\n\ndescribe('Code blocks', () => {\n\tit('should render code', () => {\n\t\tconst code = '<button>OK</button>';\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(<CodeRenderer classes={{}}>{code}</CodeRenderer>);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Code/CodeRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ fontFamily }: Rsg.Theme) => ({\n\tcode: {\n\t\tfontFamily: fontFamily.monospace,\n\t\tfontSize: 'inherit',\n\t\tcolor: 'inherit',\n\t\tbackground: 'transparent',\n\t\twhiteSpace: 'inherit',\n\t},\n});\n\ninterface CodeProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n}\n\nexport const CodeRenderer: React.FunctionComponent<CodeProps> = ({ classes, children }) => {\n\treturn <code className={classes.code}>{children}</code>;\n};\nCodeRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any.isRequired,\n};\n\nexport default Styled<CodeProps>(styles)(CodeRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Code/__snapshots__/Code.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Code blocks should render code 1`] = `\n<code>\n  &lt;button&gt;OK&lt;/button&gt;\n</code>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Code/index.ts",
    "content": "export { default } from 'rsg-components/Code/CodeRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/ComplexType/ComplexType.spec.tsx",
    "content": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport ComplexType from './ComplexTypeRenderder';\n\nfunction renderComponent(name = 'color', raw = 'red | blue') {\n\treturn render(<ComplexType name={name} raw={raw} />);\n}\n\ndescribe('ComplexType', () => {\n\ttest('should render name', () => {\n\t\tconst { getByRole } = renderComponent();\n\t\texpect(getByRole('button')).toHaveTextContent('color');\n\t});\n\n\ttest('should render raw text in the tooltip', () => {\n\t\tconst { container, getByRole } = renderComponent();\n\t\tfireEvent.focus(getByRole('button'));\n\t\texpect(container.querySelector('[data-tippy-root]')).toHaveTextContent('red | blue');\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/ComplexType/ComplexTypeRenderder.tsx",
    "content": "import React from 'react';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport { MdInfoOutline } from 'react-icons/md';\nimport Text from 'rsg-components/Text';\nimport Tooltip from 'rsg-components/Tooltip';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ space }: Rsg.Theme) => ({\n\tcomplexType: {\n\t\talignItems: 'center',\n\t\tdisplay: 'inline-flex',\n\t},\n\tname: {\n\t\tflexShrink: 0,\n\t},\n\ticon: {\n\t\tmarginLeft: space[0],\n\t\tflexShrink: 0,\n\t},\n});\n\nexport interface ComplexTypeProps extends JssInjectedProps {\n\tname: string;\n\traw: string;\n}\n\nfunction ComplexTypeRenderer({ classes, name, raw }: ComplexTypeProps) {\n\treturn (\n\t\t<Tooltip placement=\"right\" content={raw}>\n\t\t\t<span className={classes.complexType}>\n\t\t\t\t<span className={classes.name}>\n\t\t\t\t\t<Text>{name}</Text>\n\t\t\t\t</span>\n\t\t\t\t<MdInfoOutline className={classes.icon} />\n\t\t\t</span>\n\t\t</Tooltip>\n\t);\n}\n\nexport default Styled<ComplexTypeProps>(styles)(ComplexTypeRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/ComplexType/index.ts",
    "content": "export { default } from 'rsg-components/ComplexType/ComplexTypeRenderder';\n"
  },
  {
    "path": "src/client/rsg-components/Components/Components.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport ReactComponent from '../ReactComponent';\nimport Components from './Components';\nimport ComponentsRenderer from './ComponentsRenderer';\nimport { ExampleModes, UsageModes } from '../../consts';\n\nconst exampleMode = ExampleModes.collapse;\nconst usageMode = UsageModes.collapse;\nconst components = [\n\t{\n\t\tname: 'Foo',\n\t\tpathLine: 'components/foo.js',\n\t\tfilepath: 'components/foo.js',\n\t\tprops: {\n\t\t\tdescription: 'Foo foo',\n\t\t},\n\t},\n\t{\n\t\tname: 'Bar',\n\t\tpathLine: 'components/bar.js',\n\t\tfilepath: 'components/bar.js',\n\t\tprops: {\n\t\t\tdescription: 'Bar bar',\n\t\t},\n\t},\n];\n\nit('should render components list', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<Components components={components} exampleMode={exampleMode} usageMode={usageMode} depth={3} />\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('renderer should render components list layout', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<ComponentsRenderer>\n\t\t\t<ReactComponent\n\t\t\t\tkey={0}\n\t\t\t\tcomponent={components[0]}\n\t\t\t\texampleMode={exampleMode}\n\t\t\t\tusageMode={usageMode}\n\t\t\t\tdepth={3}\n\t\t\t/>\n\t\t\t<ReactComponent\n\t\t\t\tkey={1}\n\t\t\t\tcomponent={components[1]}\n\t\t\t\texampleMode={exampleMode}\n\t\t\t\tusageMode={usageMode}\n\t\t\t\tdepth={3}\n\t\t\t/>\n\t\t</ComponentsRenderer>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Components/Components.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport ReactComponent from 'rsg-components/ReactComponent';\nimport ComponentsRenderer from 'rsg-components/Components/ComponentsRenderer';\n\ninterface ComponentsProps {\n\tcomponents: any[];\n\tdepth: number;\n\texampleMode?: string;\n\tusageMode?: string;\n}\n\nconst Components: React.FunctionComponent<ComponentsProps> = ({\n\tcomponents,\n\tdepth,\n\texampleMode,\n\tusageMode,\n}) => {\n\treturn (\n\t\t<ComponentsRenderer>\n\t\t\t{components.map(component => (\n\t\t\t\t<ReactComponent\n\t\t\t\t\tkey={component.filepath}\n\t\t\t\t\tcomponent={component}\n\t\t\t\t\texampleMode={exampleMode}\n\t\t\t\t\tusageMode={usageMode}\n\t\t\t\t\tdepth={depth}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</ComponentsRenderer>\n\t);\n};\n\nComponents.propTypes = {\n\tcomponents: PropTypes.array.isRequired,\n\tdepth: PropTypes.number.isRequired,\n\texampleMode: PropTypes.string.isRequired,\n\tusageMode: PropTypes.string.isRequired,\n};\n\nexport default Components;\n"
  },
  {
    "path": "src/client/rsg-components/Components/ComponentsRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nexport default function ComponentsRenderer({ children }: { children: React.ReactNode }) {\n\treturn <div>{children}</div>;\n}\nComponentsRenderer.propTypes = {\n\tchildren: PropTypes.node.isRequired,\n};\n"
  },
  {
    "path": "src/client/rsg-components/Components/__snapshots__/Components.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render components list layout 1`] = `\n<div>\n  <ReactComponent\n    component={\n      Object {\n        \"filepath\": \"components/foo.js\",\n        \"name\": \"Foo\",\n        \"pathLine\": \"components/foo.js\",\n        \"props\": Object {\n          \"description\": \"Foo foo\",\n        },\n      }\n    }\n    depth={3}\n    exampleMode=\"collapse\"\n    usageMode=\"collapse\"\n  />\n  <ReactComponent\n    component={\n      Object {\n        \"filepath\": \"components/bar.js\",\n        \"name\": \"Bar\",\n        \"pathLine\": \"components/bar.js\",\n        \"props\": Object {\n          \"description\": \"Bar bar\",\n        },\n      }\n    }\n    depth={3}\n    exampleMode=\"collapse\"\n    usageMode=\"collapse\"\n  />\n</div>\n`;\n\nexports[`should render components list 1`] = `\n<ComponentsRenderer>\n  <ReactComponent\n    component={\n      Object {\n        \"filepath\": \"components/foo.js\",\n        \"name\": \"Foo\",\n        \"pathLine\": \"components/foo.js\",\n        \"props\": Object {\n          \"description\": \"Foo foo\",\n        },\n      }\n    }\n    depth={3}\n    exampleMode=\"collapse\"\n    usageMode=\"collapse\"\n  />\n  <ReactComponent\n    component={\n      Object {\n        \"filepath\": \"components/bar.js\",\n        \"name\": \"Bar\",\n        \"pathLine\": \"components/bar.js\",\n        \"props\": Object {\n          \"description\": \"Bar bar\",\n        },\n      }\n    }\n    depth={3}\n    exampleMode=\"collapse\"\n    usageMode=\"collapse\"\n  />\n</ComponentsRenderer>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Components/index.ts",
    "content": "export { default } from './Components';\n"
  },
  {
    "path": "src/client/rsg-components/ComponentsList/ComponentsList.spec.tsx",
    "content": "/* eslint-disable compat/compat */\nimport React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport ComponentsList from './ComponentsList';\nimport Context from '../Context';\n\nconst context = {\n\tconfig: {\n\t\tpagePerSection: true,\n\t\ttocMode: 'collapse',\n\t},\n};\n\nconst Provider = (props: any) => <Context.Provider value={context} {...props} />;\n\nit('should not render any links when the list is empty', () => {\n\tconst { queryAllByRole } = render(\n\t\t<Provider>\n\t\t\t<ComponentsList items={[]} />\n\t\t</Provider>\n\t);\n\n\texpect(queryAllByRole('link')).toHaveLength(0);\n});\n\nit('should ignore items without visibleName', () => {\n\tconst components = [\n\t\t{\n\t\t\tvisibleName: 'Button',\n\t\t\tslug: 'button',\n\t\t\thref: '#button',\n\t\t},\n\t\t{\n\t\t\tslug: 'input',\n\t\t\thref: '#input',\n\t\t},\n\t];\n\n\tconst { getAllByRole } = render(\n\t\t<Provider>\n\t\t\t<ComponentsList items={components} />\n\t\t</Provider>\n\t);\n\n\texpect(Array.from(getAllByRole('link')).map((node) => (node as HTMLAnchorElement).href)).toEqual([\n\t\t'http://localhost/#button',\n\t]);\n});\n\nit('should show content of items that are open and not what is closed', () => {\n\tconst components = [\n\t\t{\n\t\t\tvisibleName: 'Button',\n\t\t\tname: 'Button',\n\t\t\tslug: 'button',\n\t\t\thref: '#buttton',\n\t\t\tcontent: <div data-testid=\"content\">Content for Button</div>,\n\t\t},\n\t\t{\n\t\t\tvisibleName: 'Input',\n\t\t\tname: 'Input',\n\t\t\tslug: 'input',\n\t\t\thref: '#input',\n\t\t\tcontent: <div data-testid=\"content\">Content for Input</div>,\n\t\t},\n\t];\n\n\tconst { getAllByTestId, getByText } = render(\n\t\t<Provider>\n\t\t\t<ComponentsList items={components} />\n\t\t</Provider>\n\t);\n\n\tfireEvent.click(getByText('Button'));\n\n\texpect(\n\t\tArray.from(getAllByTestId('content')).map((node) => (node as HTMLDivElement).innerHTML)\n\t).toEqual(['Content for Button']);\n});\n\nit('should show content of initialOpen items even if they are not active', () => {\n\tconst components = [\n\t\t{\n\t\t\tvisibleName: 'Button',\n\t\t\tname: 'Button',\n\t\t\tslug: 'button',\n\t\t\thref: '#button',\n\t\t\tcontent: <div data-testid=\"content\">Content for Button</div>,\n\t\t},\n\t\t{\n\t\t\tvisibleName: 'Input',\n\t\t\tname: 'Input',\n\t\t\tslug: 'input',\n\t\t\thref: '#input',\n\t\t\tcontent: <div data-testid=\"content\">Content for Input</div>,\n\t\t\tinitialOpen: true,\n\t\t},\n\t];\n\n\tconst { getAllByTestId, getByText } = render(\n\t\t<Provider>\n\t\t\t<ComponentsList items={components} />\n\t\t</Provider>\n\t);\n\n\tfireEvent.click(getByText('Button'));\n\n\texpect(\n\t\tArray.from(getAllByTestId('content')).map((node) => (node as HTMLDivElement).innerHTML)\n\t).toEqual(['Content for Button', 'Content for Input']);\n});\n\nit('should show content of forcedOpen items even if they are initially collapsed', () => {\n\tconst components = [\n\t\t{\n\t\t\tvisibleName: 'Button',\n\t\t\tname: 'Button',\n\t\t\tslug: 'button',\n\t\t\thref: '#button',\n\t\t\tcontent: <div data-testid=\"content\">Content for Button</div>,\n\t\t\tinitialOpen: true,\n\t\t},\n\t\t{\n\t\t\tvisibleName: 'Input',\n\t\t\tname: 'Input',\n\t\t\tslug: 'input',\n\t\t\thref: '#input',\n\t\t\tcontent: <div data-testid=\"content\">Content for Input</div>,\n\t\t\tinitialOpen: true,\n\t\t\tforcedOpen: true,\n\t\t},\n\t];\n\n\tconst { getAllByTestId, getByText } = render(\n\t\t<Provider>\n\t\t\t<ComponentsList items={components} />\n\t\t</Provider>\n\t);\n\n\tfireEvent.click(getByText('Input'));\n\n\texpect(\n\t\tArray.from(getAllByTestId('content')).map((node) => (node as HTMLDivElement).innerHTML)\n\t).toEqual(['Content for Button', 'Content for Input']);\n});\n"
  },
  {
    "path": "src/client/rsg-components/ComponentsList/ComponentsList.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport ComponentsListRenderer from 'rsg-components/ComponentsList/ComponentsListRenderer';\nimport * as Rsg from '../../../typings';\n\ninterface ComponentsListProps {\n\titems: Rsg.TOCItem[];\n}\n\nconst ComponentsList: React.FunctionComponent<ComponentsListProps> = ({ items }) => {\n\tconst visibleItems = items.filter(item => item.visibleName);\n\n\treturn visibleItems.length > 0 ? <ComponentsListRenderer items={visibleItems} /> : null;\n};\n\nComponentsList.propTypes = {\n\titems: PropTypes.array.isRequired,\n};\n\nexport default ComponentsList;\n"
  },
  {
    "path": "src/client/rsg-components/ComponentsList/ComponentsListRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport cx from 'clsx';\nimport Link from 'rsg-components/Link';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport { useStyleGuideContext } from 'rsg-components/Context';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ color, fontFamily, fontSize, space, mq }: Rsg.Theme) => ({\n\tlist: {\n\t\tmargin: 0,\n\t\tpaddingLeft: space[2],\n\t},\n\titem: {\n\t\tcolor: color.base,\n\t\tdisplay: 'block',\n\t\tmargin: [[space[1], 0, space[1], 0]],\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.base,\n\t\tlistStyle: 'none',\n\t\toverflow: 'hidden',\n\t\ttextOverflow: 'ellipsis',\n\t},\n\tisChild: {\n\t\t[mq.small]: {\n\t\t\tdisplay: 'inline-block',\n\t\t\tmargin: [[0, space[1], 0, 0]],\n\t\t},\n\t},\n\theading: {\n\t\tcolor: color.base,\n\t\tmarginTop: space[1],\n\t\tfontFamily: fontFamily.base,\n\t\tfontWeight: 'bold',\n\t},\n\tisSelected: {\n\t\tfontWeight: 'bold',\n\t},\n});\n\ninterface ComponentsListRendererProps extends JssInjectedProps {\n\titems: Rsg.TOCItem[];\n}\n\nconst ComponentsListSectionRenderer: React.FunctionComponent<Rsg.TOCItem & JssInjectedProps> = ({\n\tclasses,\n\theading,\n\tvisibleName,\n\thref,\n\tcontent,\n\tshouldOpenInNewTab,\n\tselected,\n\tinitialOpen,\n\tforcedOpen,\n}) => {\n\tconst {\n\t\tconfig: { tocMode },\n\t} = useStyleGuideContext();\n\n\tconst [open, setOpen] = tocMode !== 'collapse' ? [true, () => {}] : React.useState(!!initialOpen);\n\treturn (\n\t\t<li\n\t\t\tclassName={cx(classes.item, {\n\t\t\t\t[classes.isChild]: !content && !shouldOpenInNewTab,\n\t\t\t\t[classes.isSelected]: selected,\n\t\t\t})}\n\t\t\tkey={href}\n\t\t>\n\t\t\t<Link\n\t\t\t\tclassName={cx(heading && classes.heading)}\n\t\t\t\thref={href}\n\t\t\t\tonClick={() => setOpen(!open)}\n\t\t\t\ttarget={shouldOpenInNewTab ? '_blank' : undefined}\n\t\t\t\tdata-testid=\"rsg-toc-link\"\n\t\t\t>\n\t\t\t\t{visibleName}\n\t\t\t</Link>\n\t\t\t{open || forcedOpen ? content : null}\n\t\t</li>\n\t);\n};\n\nexport const ComponentsListRenderer: React.FunctionComponent<ComponentsListRendererProps> = ({\n\tclasses,\n\titems,\n}) => {\n\treturn (\n\t\t<ul className={classes.list}>\n\t\t\t{items.map((item) => (\n\t\t\t\t<ComponentsListSectionRenderer key={item.slug} classes={classes} {...item} />\n\t\t\t))}\n\t\t</ul>\n\t);\n};\n\nComponentsListRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\titems: PropTypes.array.isRequired,\n};\n\nexport default Styled<ComponentsListRendererProps>(styles)(ComponentsListRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/ComponentsList/index.ts",
    "content": "export { default } from 'rsg-components/ComponentsList/ComponentsList';\nexport * from 'rsg-components/ComponentsList/ComponentsList';\n"
  },
  {
    "path": "src/client/rsg-components/Context/Context.ts",
    "content": "import React from 'react';\nimport * as Rsg from '../../../typings';\n\nconst StyleGuideContext = React.createContext<StyleGuideContextContents>({\n\tcodeRevision: 0,\n\tcssRevision: '0',\n\tconfig: {} as Rsg.ProcessedStyleguidistConfig,\n\tslots: {},\n\tdisplayMode: 'collapse',\n});\n\nexport default StyleGuideContext;\n\nexport interface SlotObject {\n\tid: string;\n\trender: React.FunctionComponent<any>;\n}\n\nexport interface StyleGuideContextContents {\n\tcodeRevision: number;\n\tcssRevision: string;\n\tconfig: Rsg.ProcessedStyleguidistConfig;\n\tslots: Record<string, (SlotObject | React.FunctionComponent<any>)[]>;\n\tdisplayMode: string;\n}\n\nexport function useStyleGuideContext(): StyleGuideContextContents {\n\treturn React.useContext(StyleGuideContext);\n}\n"
  },
  {
    "path": "src/client/rsg-components/Context/index.ts",
    "content": "export { default } from 'rsg-components/Context/Context';\nexport * from 'rsg-components/Context/Context';\n"
  },
  {
    "path": "src/client/rsg-components/Editor/Editor.spec.tsx",
    "content": "import React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { Editor } from './Editor';\n\nconst code = '<button>MyAwesomeCode</button>';\nconst newCode = '<button>MyNewAwesomeCode</button>';\nconst props = {\n\tclasses: {},\n\tonChange() {},\n\tcode,\n};\ndescribe('Editor', () => {\n\tit('should renderer and editor', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(<Editor {...props} />);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n\n\tit('should update code', () => {\n\t\tconst { rerender, getByText } = render(<Editor {...props} />);\n\n\t\trerender(<Editor {...props} code={newCode} />);\n\n\t\texpect(getByText(newCode));\n\t});\n\n\tit('should call onChange when textarea value changes', () => {\n\t\tconst onChange = jest.fn();\n\t\tconst { getByText } = render(<Editor {...props} onChange={onChange} />);\n\n\t\tconst textarea = getByText(code);\n\t\tfireEvent.change(textarea, { target: { value: newCode } });\n\n\t\texpect(onChange).toBeCalledWith(newCode);\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Editor/Editor.tsx",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport SimpleEditor from 'react-simple-code-editor';\nimport { highlight as prismHighlight, languages } from 'prismjs';\nimport 'prismjs/components/prism-clike';\nimport 'prismjs/components/prism-markup';\nimport 'prismjs/components/prism-javascript';\nimport { Styles } from 'jss';\nimport 'prismjs/components/prism-jsx';\nimport { space } from '../../styles/theme';\nimport prismTheme from '../../styles/prismTheme';\nimport * as Rsg from '../../../typings';\n\nconst highlight = (code: string) => prismHighlight(code, languages.jsx, 'jsx');\n\nconst styles = ({ fontFamily, fontSize, color, borderRadius }: Rsg.Theme): Styles => ({\n\troot: {\n\t\tfontFamily: fontFamily.monospace,\n\t\tfontSize: fontSize.small,\n\t\tbackground: color.codeBackground,\n\t\tborderRadius,\n\t\t'& textarea': {\n\t\t\tisolate: false,\n\t\t\ttransition: 'all ease-in-out .1s',\n\t\t\t// important to override inline styles in react-simple-code-editor\n\t\t\tborder: `1px ${color.border} solid !important`,\n\t\t\tborderRadius,\n\t\t},\n\t\t'& textarea:focus': {\n\t\t\tisolate: false,\n\t\t\toutline: 0,\n\t\t\tborderColor: `${color.link} !important`,\n\t\t\tboxShadow: [[0, 0, 0, 2, color.focus]],\n\t\t},\n\t\t...prismTheme({ color }),\n\t},\n});\n\nexport interface EditorProps extends JssInjectedProps {\n\tcode: string;\n\tonChange: (code: string) => void;\n}\n\ninterface EditorState {\n\tcode: string;\n\tprevCode: string;\n}\n\nexport class Editor extends Component<EditorProps> {\n\tpublic static propTypes = {\n\t\tcode: PropTypes.string.isRequired,\n\t\tonChange: PropTypes.func.isRequired,\n\t\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\t};\n\n\tpublic state = { code: this.props.code, prevCode: this.props.code };\n\n\tpublic static getDerivedStateFromProps(nextProps: EditorProps, prevState: EditorState) {\n\t\tconst { code } = nextProps;\n\t\tif (prevState.prevCode !== code) {\n\t\t\treturn {\n\t\t\t\tprevCode: code,\n\t\t\t\tcode,\n\t\t\t};\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic shouldComponentUpdate(nextProps: EditorProps, nextState: EditorState) {\n\t\treturn nextState.code !== this.state.code;\n\t}\n\n\tprivate handleChange = (code: string) => {\n\t\tthis.setState({ code });\n\t\tthis.props.onChange(code);\n\t};\n\n\tpublic render() {\n\t\treturn (\n\t\t\t<SimpleEditor\n\t\t\t\tclassName={this.props.classes.root}\n\t\t\t\tvalue={this.state.code}\n\t\t\t\tonValueChange={this.handleChange}\n\t\t\t\thighlight={highlight}\n\t\t\t\t// Padding should be passed via a prop (not CSS) for a proper\n\t\t\t\t// cursor position calculation\n\t\t\t\tpadding={space[2]}\n\t\t\t/>\n\t\t);\n\t}\n}\n\nexport default Styled<EditorProps>(styles)(Editor);\n"
  },
  {
    "path": "src/client/rsg-components/Editor/__snapshots__/Editor.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Editor should renderer and editor 1`] = `\n<Editor\n  highlight={[Function]}\n  ignoreTabKey={false}\n  insertSpaces={true}\n  onValueChange={[Function]}\n  padding={16}\n  tabSize={2}\n  value=\"<button>MyAwesomeCode</button>\"\n/>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Editor/index.ts",
    "content": "export { default } from 'rsg-components/Editor/Editor';\n"
  },
  {
    "path": "src/client/rsg-components/Error/Error.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { ErrorRenderer } from './ErrorRenderer';\n\nit('renderer should render error message', () => {\n\tconst error = { toString: () => 'error' };\n\tconst info = { componentStack: 'info' };\n\tconst renderer = createRenderer();\n\trenderer.render(<ErrorRenderer classes={{}} error={error} info={info} />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Error/ErrorRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ fontFamily, fontSize, color, space }: Rsg.Theme) => ({\n\troot: {\n\t\tmargin: space[2],\n\t\tlineHeight: 1.2,\n\t\tfontSize: fontSize.small,\n\t},\n\tstack: {\n\t\tcolor: color.error,\n\t\twhiteSpace: 'pre-wrap',\n\t\tfontFamily: fontFamily.monospace,\n\t},\n\tmessage: {\n\t\tcolor: color.error,\n\t\tfontFamily: fontFamily.base,\n\t},\n});\n\ninterface ErrorProps extends JssInjectedProps {\n\terror: any;\n\tinfo: React.ErrorInfo;\n}\n\nexport const ErrorRenderer: React.FunctionComponent<ErrorProps> = ({ classes, error, info }) => {\n\treturn (\n\t\t<div className={classes.root}>\n\t\t\t<pre className={classes.stack}>\n\t\t\t\t{error.toString()}\n\t\t\t\t{info.componentStack}\n\t\t\t</pre>\n\t\t\t<div className={classes.message}>\n\t\t\t\t<p>\n\t\t\t\t\tThis may be due to an error in a component you are overriding, or a bug in React\n\t\t\t\t\tStyleguidist.\n\t\t\t\t</p>\n\t\t\t\t<p>\n\t\t\t\t\tIf you believe this is a bug,&nbsp;\n\t\t\t\t\t<a\n\t\t\t\t\t\tstyle={{ color: 'inherit' }}\n\t\t\t\t\t\thref=\"https://github.com/styleguidist/react-styleguidist/issues\"\n\t\t\t\t\t>\n\t\t\t\t\t\tplease submit an issue\n\t\t\t\t\t</a>\n\t\t\t\t\t.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n\nErrorRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\terror: PropTypes.object.isRequired,\n\tinfo: PropTypes.any.isRequired,\n};\n\nexport default Styled<ErrorProps>(styles)(ErrorRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Error/__snapshots__/Error.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render error message 1`] = `\n<div>\n  <pre>\n    error\n    info\n  </pre>\n  <div>\n    <p>\n      This may be due to an error in a component you are overriding, or a bug in React Styleguidist.\n    </p>\n    <p>\n      If you believe this is a bug, \n      <a\n        href=\"https://github.com/styleguidist/react-styleguidist/issues\"\n        style={\n          Object {\n            \"color\": \"inherit\",\n          }\n        }\n      >\n        please submit an issue\n      </a>\n      .\n    </p>\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Error/index.ts",
    "content": "export { default } from 'rsg-components/Error/ErrorRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/ExamplePlaceholder/ExamplePlaceholder.spec.tsx",
    "content": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { ExamplePlaceholderRenderer } from './ExamplePlaceholderRenderer';\n\ntest('should render an example placeholder after button click', () => {\n\tconst { getByText, queryByText } = render(\n\t\t<ExamplePlaceholderRenderer classes={{}} name=\"Pizza\" />\n\t);\n\tfireEvent.click(getByText(/add examples to this component/i));\n\texpect(getByText('Pizza.md')).toBeInTheDocument();\n\texpect(queryByText(/add examples to this component/i)).not.toBeInTheDocument();\n});\n"
  },
  {
    "path": "src/client/rsg-components/ExamplePlaceholder/ExamplePlaceholderRenderer.tsx",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport Markdown from 'rsg-components/Markdown';\nimport { DOCS_DOCUMENTING } from '../../../scripts/consts';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ fontFamily, fontSize, color }: Rsg.Theme) => ({\n\tbutton: {\n\t\tpadding: 0,\n\t\tfontSize: fontSize.base,\n\t\tfontFamily: fontFamily.base,\n\t\ttextDecoration: 'underline',\n\t\tcolor: color.light,\n\t\tborder: 0,\n\t\tcursor: 'pointer',\n\t\tbackground: 'transparent',\n\t\t'&:hover, &:active': {\n\t\t\tisolate: false,\n\t\t\tcolor: color.lightest,\n\t\t},\n\t},\n});\n\ninterface ExamplePlaceholderProps extends JssInjectedProps {\n\tname?: string;\n}\n\nexport class ExamplePlaceholderRenderer extends Component<ExamplePlaceholderProps> {\n\tpublic static propTypes = {\n\t\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\t\tname: PropTypes.string,\n\t};\n\n\tpublic state = {\n\t\tisVisible: false,\n\t};\n\n\tpublic handleOpen = () => {\n\t\tthis.setState({ isVisible: true });\n\t};\n\n\tpublic render() {\n\t\tconst { classes, name } = this.props;\n\t\tconst { isVisible } = this.state;\n\t\tif (isVisible) {\n\t\t\treturn (\n\t\t\t\t<Markdown\n\t\t\t\t\ttext={`\nCreate **Readme.md** or **${name}.md** file in the component’s folder like this:\n\n    ${name} example:\n\n    \\`\\`\\`js\n    <${name} pizza=\"\\uD83C\\uDF55\" />\n\t\\`\\`\\`\n\nYou may need to **restart** the style guide server after adding an example file.\n\nRead more in the [documenting components guide](${DOCS_DOCUMENTING}).\n\t\t\t\t\t`}\n\t\t\t\t/>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<button className={classes.button} onClick={this.handleOpen}>\n\t\t\t\tAdd examples to this component\n\t\t\t</button>\n\t\t);\n\t}\n}\n\nexport default Styled<ExamplePlaceholderProps>(styles)(ExamplePlaceholderRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/ExamplePlaceholder/index.ts",
    "content": "export { default } from 'rsg-components/ExamplePlaceholder/ExamplePlaceholderRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Examples/Examples.spec.tsx",
    "content": "import React from 'react';\nimport { render } from '@testing-library/react';\nimport Examples from '.';\nimport Context from '../Context';\nimport slots from '../slots';\nimport { DisplayModes } from '../../consts';\nimport * as Rsg from '../../../typings';\n\nconst evalInContext = (a: string): (() => any) =>\n\t// eslint-disable-next-line no-new-func\n\tnew Function('require', 'const React = require(\"react\");' + a).bind(null, require);\n\nconst examples: Rsg.Example[] = [\n\t{\n\t\ttype: 'code',\n\t\tcontent: '<button>Code: OK</button>',\n\t\tevalInContext,\n\t},\n\t{\n\t\ttype: 'markdown',\n\t\tcontent: 'Markdown: Hello *world*!',\n\t},\n];\n\nconst context = {\n\tconfig: {\n\t\tpreviewDelay: 0,\n\t},\n\tcodeRevision: 1,\n\tdisplayMode: DisplayModes.example,\n\tslots: slots(),\n};\n\nconst Provider = (props: any) => <Context.Provider value={context} {...props} />;\n\ntest('should render examples', () => {\n\tconst { getByText } = render(\n\t\t<Provider>\n\t\t\t<Examples examples={examples} name=\"button\" exampleMode=\"collapse\" />\n\t\t</Provider>\n\t);\n\texpect(getByText(/code: ok/i)).toBeInTheDocument();\n\texpect(getByText(/markdown: hello/i)).toBeInTheDocument();\n});\n\ntest('should not render an example with unknown type', () => {\n\tconst faultyExample = [\n\t\t{\n\t\t\ttype: 'unknown',\n\t\t\tcontent: 'FooBar',\n\t\t} as any,\n\t];\n\tconst { getByTestId } = render(\n\t\t<Provider>\n\t\t\t<Examples examples={faultyExample} name=\"button\" exampleMode=\"collapse\" />\n\t\t</Provider>\n\t);\n\texpect(getByTestId('button-examples')).toBeEmptyDOMElement();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Examples/Examples.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Playground from 'rsg-components/Playground';\nimport Markdown from 'rsg-components/Markdown';\nimport ExamplesRenderer from 'rsg-components/Examples/ExamplesRenderer';\nimport { useStyleGuideContext } from 'rsg-components/Context';\nimport * as Rsg from '../../../typings';\n\nexport interface ExamplesRenderer {\n\texamples: Rsg.Example[];\n\tname?: string;\n\texampleMode?: string;\n}\n\nconst Examples: React.FunctionComponent<ExamplesRenderer> = ({ examples, name, exampleMode }) => {\n\tconst { codeRevision } = useStyleGuideContext();\n\treturn (\n\t\t<ExamplesRenderer name={name}>\n\t\t\t{examples.map((example, index) => {\n\t\t\t\tswitch (example.type) {\n\t\t\t\t\tcase 'code':\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<Playground\n\t\t\t\t\t\t\t\tcode={example.content}\n\t\t\t\t\t\t\t\tevalInContext={example.evalInContext}\n\t\t\t\t\t\t\t\tkey={`${codeRevision}/${index}`}\n\t\t\t\t\t\t\t\tname={name}\n\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\tsettings={example.settings ?? {}}\n\t\t\t\t\t\t\t\texampleMode={exampleMode}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\tcase 'markdown':\n\t\t\t\t\t\treturn <Markdown text={example.content} key={index} />;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t})}\n\t\t</ExamplesRenderer>\n\t);\n};\n\nExamples.propTypes = {\n\texamples: PropTypes.array.isRequired,\n\tname: PropTypes.string.isRequired,\n\texampleMode: PropTypes.string.isRequired,\n};\n\nexport default Examples;\n"
  },
  {
    "path": "src/client/rsg-components/Examples/ExamplesRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\n\nconst styles = () => ({\n\t// Just default jss-isolate rules\n\troot: {},\n});\n\ninterface ExamplesRendererProps extends JssInjectedProps {\n\tchildren?: React.ReactNode;\n\tname?: string;\n}\n\nexport const ExamplesRenderer: React.FunctionComponent<ExamplesRendererProps> = ({\n\tclasses,\n\tname,\n\tchildren,\n}) => {\n\treturn (\n\t\t<article className={classes.root} data-testid={`${name}-examples`}>\n\t\t\t{children}\n\t\t</article>\n\t);\n};\n\nExamplesRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tname: PropTypes.string.isRequired,\n\tchildren: PropTypes.any,\n};\n\nexport default Styled<ExamplesRendererProps>(styles)(ExamplesRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Examples/index.ts",
    "content": "export { default } from 'rsg-components/Examples/Examples';\nexport * from 'rsg-components/Examples/Examples';\n"
  },
  {
    "path": "src/client/rsg-components/Heading/Heading.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\nimport Heading from './index';\n\ndescribe('Heading', () => {\n\tit('should render a heading according to the level', () => {\n\t\tconst actualH3 = renderer.create(<Heading level={3}>The heading</Heading>);\n\t\texpect(actualH3.toJSON()).toMatchSnapshot();\n\n\t\tconst actualH5 = renderer.create(<Heading level={5}>The heading</Heading>);\n\t\texpect(actualH5.toJSON()).toMatchSnapshot();\n\t});\n\n\tit('should render a heading', () => {\n\t\tconst actual = renderer.create(<Heading level={2}>The heading</Heading>);\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Heading/HeadingRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport cx from 'clsx';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ color, fontFamily, fontSize }: Rsg.Theme) => ({\n\theading: {\n\t\tmargin: 0,\n\t\tcolor: color.base,\n\t\tfontFamily: fontFamily.base,\n\t\tfontWeight: 'normal',\n\t},\n\theading1: {\n\t\tfontSize: fontSize.h1,\n\t},\n\theading2: {\n\t\tfontSize: fontSize.h2,\n\t},\n\theading3: {\n\t\tfontSize: fontSize.h3,\n\t},\n\theading4: {\n\t\tfontSize: fontSize.h4,\n\t},\n\theading5: {\n\t\tfontSize: fontSize.h5,\n\t\tfontWeight: 'bold',\n\t},\n\theading6: {\n\t\tfontSize: fontSize.h6,\n\t\tfontStyle: 'italic',\n\t},\n});\n\ninterface HeadingProps extends JssInjectedProps, React.HTMLAttributes<HTMLHeadingElement> {\n\tchildren?: React.ReactNode;\n\tlevel: number;\n}\n\nconst HeadingRenderer: React.FunctionComponent<HeadingProps> = ({\n\tclasses,\n\tlevel,\n\tchildren,\n\t...props\n}) => {\n\tconst Tag = `h${level}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\tconst headingClasses = cx(classes.heading, classes[`heading${level}`]);\n\n\treturn (\n\t\t<Tag {...props} className={headingClasses}>\n\t\t\t{children}\n\t\t</Tag>\n\t);\n};\n\nHeadingRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tlevel: PropTypes.oneOf([1, 2, 3, 4, 5, 6]).isRequired,\n\tchildren: PropTypes.any,\n};\n\nexport default Styled<HeadingProps>(styles)(HeadingRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Heading/__snapshots__/Heading.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Heading should render a heading 1`] = `\n<h2\n  className=\"rsg--heading-0 rsg--heading2-2\"\n>\n  The heading\n</h2>\n`;\n\nexports[`Heading should render a heading according to the level 1`] = `\n<h3\n  className=\"rsg--heading-0 rsg--heading3-3\"\n>\n  The heading\n</h3>\n`;\n\nexports[`Heading should render a heading according to the level 2`] = `\n<h5\n  className=\"rsg--heading-0 rsg--heading5-5\"\n>\n  The heading\n</h5>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Heading/index.ts",
    "content": "export { default } from 'rsg-components/Heading/HeadingRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/JsDoc/JsDoc.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport JsDoc, { getMarkdown } from './JsDoc';\n\nconst tags = {\n\tdeprecated: [\n\t\t{\n\t\t\ttitle: 'description',\n\t\t\tdescription: 'Use *another* method',\n\t\t},\n\t],\n\tversion: [\n\t\t{\n\t\t\ttitle: 'version',\n\t\t\tdescription: '2.0.0',\n\t\t},\n\t],\n\tsince: [\n\t\t{\n\t\t\ttitle: 'since',\n\t\t\tdescription: '1.0.0',\n\t\t},\n\t],\n\tauthor: [\n\t\t{\n\t\t\ttitle: 'author',\n\t\t\tdescription: '[Author 1](#TestLink)',\n\t\t},\n\t\t{\n\t\t\ttitle: 'author',\n\t\t\tdescription: '[Author 2](#TestLink2)',\n\t\t},\n\t],\n\tsee: [\n\t\t{\n\t\t\ttitle: 'see',\n\t\t\tdescription: '[See 1](#TestLink)',\n\t\t},\n\t\t{\n\t\t\ttitle: 'see',\n\t\t\tdescription: '[See 2](#TestLink2)',\n\t\t},\n\t],\n\tlink: [\n\t\t{\n\t\t\ttitle: 'link',\n\t\t\tdescription: '[Link 1](#TestLink)',\n\t\t},\n\t],\n};\n\ndescribe('getMarkdown', () => {\n\tit('should return Markdown for all tags', () => {\n\t\tconst result = getMarkdown(tags);\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should return Markdown for one author', () => {\n\t\tconst author = tags.author ? [tags.author[0]] : undefined;\n\t\tconst result = getMarkdown({\n\t\t\tauthor,\n\t\t});\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should return Markdown for multiple authors', () => {\n\t\tconst result = getMarkdown({\n\t\t\tauthor: tags.author,\n\t\t});\n\t\texpect(result).toMatchSnapshot();\n\t});\n});\n\ndescribe('JsDoc', () => {\n\tit('should render Markdown', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(<JsDoc {...tags} />);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n\n\tit('should render null for empty tags', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(<JsDoc />);\n\n\t\texpect(renderer.getRenderOutput()).toBe(null);\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/JsDoc/JsDoc.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { TagProps, TagObject } from 'react-docgen';\nimport map from 'lodash/map';\nimport Markdown from 'rsg-components/Markdown';\n\nconst plural = (array: TagObject[], caption: string) =>\n\tarray.length === 1 ? caption : `${caption}s`;\nconst list = (array: TagObject[]) => array.map(item => item.description).join(', ');\nconst paragraphs = (array: TagObject[]) => array.map(item => item.description).join('\\n\\n');\n\nconst fields = {\n\tdeprecated: (value: TagObject[]) => `**Deprecated:** ${value[0].description}`,\n\tsee: (value: TagObject[]) => paragraphs(value),\n\tlink: (value: TagObject[]) => paragraphs(value),\n\tauthor: (value: TagObject[]) => `${plural(value, 'Author')}: ${list(value)}`,\n\tversion: (value: TagObject[]) => `Version: ${value[0].description}`,\n\tsince: (value: TagObject[]) => `Since: ${value[0].description}`,\n};\n\nexport function getMarkdown(props: TagProps) {\n\treturn map(fields, (format: (value: TagObject[]) => string, field: keyof TagProps) => {\n\t\tconst tag = props[field];\n\t\treturn tag && format(tag);\n\t})\n\t\t.filter(Boolean)\n\t\t.join('\\n\\n');\n}\n\nexport default function JsDoc(props: TagProps) {\n\tconst markdown = getMarkdown(props);\n\treturn markdown ? <Markdown text={markdown} /> : null;\n}\n\nJsDoc.propTypes = {\n\tdeprecated: PropTypes.array,\n\tsee: PropTypes.array,\n\tlink: PropTypes.array,\n\tauthor: PropTypes.array,\n\tversion: PropTypes.array,\n\tsince: PropTypes.array,\n};\n"
  },
  {
    "path": "src/client/rsg-components/JsDoc/__snapshots__/JsDoc.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`JsDoc should render Markdown 1`] = `\n<Markdown\n  text=\"**Deprecated:** Use *another* method\n\n[See 1](#TestLink)\n\n[See 2](#TestLink2)\n\n[Link 1](#TestLink)\n\nAuthors: [Author 1](#TestLink), [Author 2](#TestLink2)\n\nVersion: 2.0.0\n\nSince: 1.0.0\"\n/>\n`;\n\nexports[`getMarkdown should return Markdown for all tags 1`] = `\n\"**Deprecated:** Use *another* method\n\n[See 1](#TestLink)\n\n[See 2](#TestLink2)\n\n[Link 1](#TestLink)\n\nAuthors: [Author 1](#TestLink), [Author 2](#TestLink2)\n\nVersion: 2.0.0\n\nSince: 1.0.0\"\n`;\n\nexports[`getMarkdown should return Markdown for multiple authors 1`] = `\"Authors: [Author 1](#TestLink), [Author 2](#TestLink2)\"`;\n\nexports[`getMarkdown should return Markdown for one author 1`] = `\"Author: [Author 1](#TestLink)\"`;\n"
  },
  {
    "path": "src/client/rsg-components/JsDoc/index.ts",
    "content": "export { default } from 'rsg-components/JsDoc/JsDoc';\n"
  },
  {
    "path": "src/client/rsg-components/Link/Link.spec.tsx",
    "content": "import { render } from '@testing-library/react';\nimport React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { LinkRenderer } from './LinkRenderer';\n\nconst href = '/foo';\nconst children = 'Foo';\n\nit('renderer should render link', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<LinkRenderer href={href} classes={{}}>\n\t\t\t{children}\n\t\t</LinkRenderer>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should compose passed class names', () => {\n\tconst { getByRole } = render(\n\t\t<LinkRenderer classes={{ link: 'baseLinkClass' }} href={href} className=\"customClass\">\n\t\t\t{children}\n\t\t</LinkRenderer>\n\t);\n\n\tconst a = getByRole('link');\n\texpect(a.className).toBe('baseLinkClass customClass');\n});\n\nit('should properly pass the target attribute', () => {\n\tconst { getByRole } = render(\n\t\t<LinkRenderer href={href} target=\"_blank\" classes={{}}>\n\t\t\t{children}\n\t\t</LinkRenderer>\n\t);\n\n\tconst a = getByRole('link');\n\texpect(a.getAttribute('target')).toBe('_blank');\n});\n"
  },
  {
    "path": "src/client/rsg-components/Link/LinkRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport cx from 'clsx';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ color }: Rsg.Theme) => ({\n\tlink: {\n\t\t'&, &:link, &:visited': {\n\t\t\tfontSize: 'inherit',\n\t\t\tcolor: color.link,\n\t\t\ttextDecoration: 'none',\n\t\t},\n\t\t'&:hover, &:active': {\n\t\t\tisolate: false,\n\t\t\tcolor: color.linkHover,\n\t\t\tcursor: 'pointer',\n\t\t},\n\t},\n});\n\ninterface LinkProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n\tclassName?: string;\n\thref?: string;\n\ttarget?: string;\n\tonClick?: () => void;\n}\n\nexport const LinkRenderer: React.FunctionComponent<LinkProps> = ({\n\tclasses,\n\tchildren,\n\t...props\n}) => {\n\treturn (\n\t\t<a {...props} className={cx(classes.link, props.className)}>\n\t\t\t{children}\n\t\t</a>\n\t);\n};\n\nLinkRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any,\n\tclassName: PropTypes.string,\n\thref: PropTypes.string,\n};\n\nexport default Styled<LinkProps>(styles)(LinkRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Link/__snapshots__/Link.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render link 1`] = `\n<a\n  className=\"\"\n  href=\"/foo\"\n>\n  Foo\n</a>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Link/index.ts",
    "content": "export { default } from 'rsg-components/Link/LinkRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Logo/Logo.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\nimport LogoRenderer from './LogoRenderer';\n\nit('renderer should render header', () => {\n\tconst actual = renderer.create(<LogoRenderer>React Styleguidist</LogoRenderer>);\n\n\texpect(actual.toJSON()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Logo/LogoRenderer.tsx",
    "content": "import React from 'react';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ color, fontFamily, fontSize }: Rsg.Theme) => ({\n\tlogo: {\n\t\tcolor: color.base,\n\t\tmargin: 0,\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.h4,\n\t\tfontWeight: 'normal',\n\t},\n});\n\ninterface Props extends JssInjectedProps {\n\tchildren?: React.ReactNode;\n}\n\nexport const LogoRenderer = ({ classes, children }: Props) => {\n\treturn <h1 className={classes.logo}>{children}</h1>;\n};\n\nexport default Styled<JssInjectedProps>(styles)(LogoRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Logo/__snapshots__/Logo.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render header 1`] = `\n<h1\n  className=\"rsg--logo-0\"\n>\n  React Styleguidist\n</h1>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Logo/index.ts",
    "content": "export { default } from 'rsg-components/Logo/LogoRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Blockquote/Blockquote.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\nimport Blockquote from './index';\n\ndescribe('Markdown Blockquote', () => {\n\tit('should render a blockquote', () => {\n\t\tconst actual = renderer.create(\n\t\t\t<Blockquote>To be, or not to be: that is the question</Blockquote>\n\t\t);\n\n\t\texpect(actual).toMatchSnapshot();\n\t});\n\n\tit('should preserve custom css class', () => {\n\t\tconst actual = renderer.create(\n\t\t\t<Blockquote className=\"test-class\">To be, or not to be: that is the question</Blockquote>\n\t\t);\n\n\t\texpect(actual).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Blockquote/BlockquoteRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport cx from 'clsx';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../../typings';\n\nconst styles = ({ space, color, fontSize, fontFamily }: Rsg.Theme) => ({\n\tblockquote: {\n\t\tmargin: [[space[2], space[4]]],\n\t\tpadding: 0,\n\t\tcolor: color.base,\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.base,\n\t\tlineHeight: 1.5,\n\t},\n});\n\ninterface BlockquoteProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n\tclassName?: string;\n}\n\nexport const BlockquoteRenderer: React.FunctionComponent<BlockquoteProps> = ({\n\tclasses,\n\tclassName,\n\tchildren,\n}) => {\n\tconst blockquoteClasses = cx(classes.blockquote, className);\n\treturn <blockquote className={blockquoteClasses}>{children}</blockquote>;\n};\n\nBlockquoteRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tclassName: PropTypes.string,\n\tchildren: PropTypes.any.isRequired,\n};\n\nexport default Styled<BlockquoteProps>(styles)(BlockquoteRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Blockquote/__snapshots__/Blockquote.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Markdown Blockquote should preserve custom css class 1`] = `\n<blockquote\n  className=\"rsg--blockquote-0 test-class\"\n>\n  To be, or not to be: that is the question\n</blockquote>\n`;\n\nexports[`Markdown Blockquote should render a blockquote 1`] = `\n<blockquote\n  className=\"rsg--blockquote-0\"\n>\n  To be, or not to be: that is the question\n</blockquote>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Blockquote/index.ts",
    "content": "export { default } from 'rsg-components/Markdown/Blockquote/BlockquoteRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Checkbox/Checkbox.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\n\nimport Checkbox from './index';\n\ndescribe('Markdown Checkbox', () => {\n\tit('should render a checkbox input', () => {\n\t\tconst actual = renderer.create(<Checkbox />);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Checkbox/CheckboxRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\n\nconst styles = () => ({\n\tinput: {\n\t\tisolate: false,\n\t\tdisplay: 'inline-block',\n\t\tverticalAlign: 'middle',\n\t},\n});\n\nexport const CheckboxRenderer: React.FunctionComponent<JssInjectedProps> = ({\n\tclasses,\n\t...rest\n}) => {\n\treturn <input {...rest} type=\"checkbox\" className={classes.input} />;\n};\nCheckboxRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n};\n\nexport default Styled(styles)(CheckboxRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Checkbox/__snapshots__/Checkbox.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Markdown Checkbox should render a checkbox input 1`] = `\n<input\n  className=\"rsg--input-0\"\n  type=\"checkbox\"\n/>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Checkbox/index.ts",
    "content": "export { default } from 'rsg-components/Markdown/Checkbox/CheckboxRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Details/Details.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\n\nimport { Details, DetailsSummary } from './index';\n\ndescribe('Markdown Details', () => {\n\tit('should render a Details', () => {\n\t\tconst actual = renderer.create(\n\t\t\t<Details>\n\t\t\t\t<DetailsSummary>Solution</DetailsSummary>\n\t\t\t\tThis is a hidden text.\n\t\t\t</Details>\n\t\t);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Details/DetailsRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../../typings';\n\nconst styles = ({ space, color, fontSize, fontFamily }: Rsg.Theme) => ({\n\tdetails: {\n\t\tmarginBottom: space[2],\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.base,\n\t\tcolor: color.base,\n\t},\n});\n\ninterface DetailsProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n}\n\nexport const DetailsRenderer: React.FunctionComponent<DetailsProps> = ({ classes, children }) => {\n\treturn <details className={classes.details}>{children}</details>;\n};\n\nDetailsRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any.isRequired,\n};\n\nexport default Styled<DetailsProps>(styles)(DetailsRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Details/DetailsSummaryRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Styles } from 'jss';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../../typings';\n\nconst styles = ({ space, color, fontSize, fontFamily }: Rsg.Theme): Styles => ({\n\tsummary: {\n\t\tmarginBottom: space[1],\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.base,\n\t\tcolor: color.base,\n\t\tcursor: 'pointer',\n\t\t'&:focus': {\n\t\t\tisolate: false,\n\t\t\toutline: [[1, 'dotted', color.linkHover]],\n\t\t\toutlineOffset: 2,\n\t\t},\n\t},\n});\n\ninterface DetailsSummaryProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n}\n\nexport const DetailsSummaryRenderer: React.FunctionComponent<DetailsSummaryProps> = ({\n\tclasses,\n\tchildren,\n}) => {\n\treturn <summary className={classes.summary}>{children}</summary>;\n};\n\nDetailsSummaryRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any.isRequired,\n};\n\nexport default Styled<DetailsSummaryProps>(styles)(DetailsSummaryRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Details/__snapshots__/Details.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Markdown Details should render a Details 1`] = `\n<details\n  className=\"rsg--details-0\"\n>\n  <summary\n    className=\"rsg--summary-2\"\n  >\n    Solution\n  </summary>\n  This is a hidden text.\n</details>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Details/index.ts",
    "content": "export { default as Details } from 'rsg-components/Markdown/Details/DetailsRenderer';\nexport { default as DetailsSummary } from 'rsg-components/Markdown/Details/DetailsSummaryRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Hr/Hr.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\n\nimport Hr from './index';\n\ndescribe('Markdown Hr', () => {\n\tit('should render a horizontal rule', () => {\n\t\tconst actual = renderer.create(<Hr />);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Hr/HrRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../../typings';\n\nconst styles = ({ space, color }: Rsg.Theme) => ({\n\thr: {\n\t\tborderBottom: [[1, color.border, 'solid']],\n\t\tmarginTop: 0,\n\t\tmarginBottom: space[2],\n\t},\n});\n\nexport const HrRenderer: React.FunctionComponent<JssInjectedProps> = ({ classes }) => {\n\treturn <hr className={classes.hr} />;\n};\nHrRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n};\n\nexport default Styled<JssInjectedProps>(styles)(HrRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Hr/__snapshots__/Hr.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Markdown Hr should render a horizontal rule 1`] = `\n<hr\n  className=\"rsg--hr-0\"\n/>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Hr/index.ts",
    "content": "export { default } from 'rsg-components/Markdown/Hr/HrRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/List/List.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\n\nimport List from './index';\n\ndescribe('Markdown List', () => {\n\tit('should render an unordered list', () => {\n\t\tconst actual = renderer.create(\n\t\t\t<List>\n\t\t\t\t<li>First</li>\n\t\t\t\t<li>Second</li>\n\t\t\t</List>\n\t\t);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n\n\tit('should render an ordered list', () => {\n\t\tconst actual = renderer.create(\n\t\t\t<List ordered>\n\t\t\t\t<li>First</li>\n\t\t\t\t<li>Second</li>\n\t\t\t</List>\n\t\t);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/List/ListRenderer.tsx",
    "content": "import React, { cloneElement, Children } from 'react';\nimport cx from 'clsx';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../../typings';\n\nconst styles = ({ space, color, fontFamily }: Rsg.Theme) => ({\n\tlist: {\n\t\tmarginTop: 0,\n\t\tmarginBottom: space[2],\n\t\tpaddingLeft: space[3],\n\t\tfontSize: 'inherit',\n\t},\n\tordered: {\n\t\tlistStyleType: 'decimal',\n\t},\n\tli: {\n\t\tcolor: color.base,\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: 'inherit',\n\t\tlineHeight: 1.5,\n\t\tlistStyleType: 'inherit',\n\t},\n});\n\ninterface ListProps extends JssInjectedProps {\n\tordered?: boolean;\n\tchildren: React.ReactNode;\n}\n\nexport const ListRenderer: React.FunctionComponent<ListProps> = ({\n\tclasses,\n\tordered = false,\n\tchildren,\n}) => {\n\tconst Tag = ordered ? 'ol' : 'ul';\n\n\tconst classNames = cx(classes.list, ordered && classes.ordered);\n\n\treturn (\n\t\t<Tag className={classNames}>\n\t\t\t{Children.map(children, (li) =>\n\t\t\t\tReact.isValidElement(li) ? cloneElement(li, { className: classes.li }) : li\n\t\t\t)}\n\t\t</Tag>\n\t);\n};\n\nexport default Styled<ListProps>(styles)(ListRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/List/__snapshots__/List.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Markdown List should render an ordered list 1`] = `\n<ol\n  className=\"rsg--list-0 rsg--ordered-1\"\n>\n  <li\n    className=\"rsg--li-2\"\n  >\n    First\n  </li>\n  <li\n    className=\"rsg--li-2\"\n  >\n    Second\n  </li>\n</ol>\n`;\n\nexports[`Markdown List should render an unordered list 1`] = `\n<ul\n  className=\"rsg--list-0\"\n>\n  <li\n    className=\"rsg--li-2\"\n  >\n    First\n  </li>\n  <li\n    className=\"rsg--li-2\"\n  >\n    Second\n  </li>\n</ul>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/List/index.ts",
    "content": "export { default } from 'rsg-components/Markdown/List/ListRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Markdown.spec.tsx",
    "content": "import { render } from '@testing-library/react';\nimport React from 'react';\nimport renderer from 'react-test-renderer';\nimport Markdown from './Markdown';\n\ndescribe('Markdown', () => {\n\tconst expectSnapshotToMatch = (markdown: string) => {\n\t\tconst actual = renderer.create(<Markdown text={markdown} />);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t};\n\n\tit('should forward DOM attributes onto resulting HTML', () => {\n\t\tconst markdown =\n\t\t\t'<a href=\"test.com\" id=\"preserve-my-id\" class=\"preserve-my-class\">Something</a>';\n\n\t\tconst { getByRole } = render(<Markdown text={markdown} />);\n\n\t\texpect(getByRole('link').getAttribute('id')).toEqual('preserve-my-id');\n\t\texpect(getByRole('link').className).toContain('preserve-my-class');\n\t});\n\n\tit('should render links', () => {\n\t\texpectSnapshotToMatch('a [link](http://test.com)');\n\t});\n\n\tit('should render headings with generated ids', () => {\n\t\texpectSnapshotToMatch(`\n# one\n## two\n### three\n#### four\n##### five\n###### six\n`);\n\t});\n\n\tit('should render paragraphs', () => {\n\t\texpectSnapshotToMatch(`\na paragraph\n\nanother paragraph\n\t\t`);\n\t});\n\n\tit('should render emphasis and strong text', () => {\n\t\texpectSnapshotToMatch(`\nthis text is **strong**\n\nand this is _emphasized_\n\t\t`);\n\t});\n\n\tit('should render unordered lists', () => {\n\t\texpectSnapshotToMatch(`\n* list\n* item\n* three\n`);\n\t});\n\n\tit('should render ordered lists', () => {\n\t\texpectSnapshotToMatch(`\n1. list\n1. item\n1. three\n`);\n\t});\n\n\tit('should render mixed nested lists', () => {\n\t\texpectSnapshotToMatch(`\n* list 1\n* list 2\n  1. Sub-list\n  1. Sub-list\n  1. Sub-list\n* list 3\n`);\n\t});\n\n\tit('should render check-lists', () => {\n\t\texpectSnapshotToMatch(`\n* [ ] to do 1\n* [ ] to do 2\n* [x] to do 3\n`);\n\t});\n\n\tit('should render a blockquote', () => {\n\t\texpectSnapshotToMatch(`\n> This is a blockquote.\n> And this is a second line.\n`);\n\t});\n\n\tit('should render pre-formatted text', () => {\n\t\texpectSnapshotToMatch(`\n    this is preformatted\n    so is this\n`);\n\t});\n\n\tit('should render code blocks without escaping', () => {\n\t\texpectSnapshotToMatch(`\n\\`\\`\\`html\n<foo></foo>\n\\`\\`\\`\n`);\n\t});\n\n\tit('should render inline code with escaping', () => {\n\t\texpectSnapshotToMatch('Foo `<bar>` baz');\n\t});\n\n\tit('should render a horizontal rule', () => {\n\t\texpectSnapshotToMatch(`---`);\n\t});\n\n\tit('should render a table', () => {\n\t\texpectSnapshotToMatch(`\n| heading 1 | heading 2 |\n| --------- | --------- |\n| foo\t\t| bar\t\t|\n| more foo\t| more bar\t|\n`);\n\t});\n\n\tit.only('should ignore single line comments', () => {\n\t\tconst markdown = `Hello World\n<!-- This is a single line comment -->\n`;\n\t\tconst { queryByText } = render(<Markdown text={markdown} />);\n\n\t\texpect(queryByText('This is a single line comment')).toBe(null);\n\t});\n\n\tit('should ignore multiline comments', () => {\n\t\tconst markdown = `Hello World\n<!--\nThis is a\nmultiline\ncomment\n-->\n`;\n\t\tconst { queryByText } = render(<Markdown text={markdown} />);\n\n\t\texpect(\n\t\t\tqueryByText(`This is a\nmultiline\ncomment`)\n\t\t).toBe(null);\n\t});\n});\n\ndescribe('Markdown inline', () => {\n\tconst expectSnapshotToMatch = (markdown: string) => {\n\t\tconst actual = renderer.create(<Markdown text={markdown} inline />);\n\n\t\texpect(actual).toMatchSnapshot();\n\t};\n\n\tit('should render text in a span', () => {\n\t\texpectSnapshotToMatch('Hello world!');\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Markdown.tsx",
    "content": "import React, { isValidElement, PropsWithChildren } from 'react';\nimport PropTypes from 'prop-types';\nimport { compiler } from 'markdown-to-jsx';\nimport stripHtmlComments from 'strip-html-comments';\nimport Link from 'rsg-components/Link';\nimport Text from 'rsg-components/Text';\nimport Para from 'rsg-components/Para';\nimport MarkdownHeading from 'rsg-components/Markdown/MarkdownHeading';\nimport List from 'rsg-components/Markdown/List';\nimport Blockquote from 'rsg-components/Markdown/Blockquote';\nimport PreBase, { PreProps } from 'rsg-components/Markdown/Pre';\nimport Code from 'rsg-components/Code';\nimport Checkbox from 'rsg-components/Markdown/Checkbox';\nimport Hr from 'rsg-components/Markdown/Hr';\nimport { Details, DetailsSummary } from 'rsg-components/Markdown/Details';\nimport { Table, TableHead, TableBody, TableRow, TableCell } from 'rsg-components/Markdown/Table';\n\nconst Pre = (props: PreProps) => {\n\tif (isValidElement(props.children)) {\n\t\t// Avoid rendering <Code> inside <Pre>\n\t\treturn <PreBase {...props.children.props} />;\n\t}\n\treturn <PreBase {...props} />;\n};\nPre.propTypes = {\n\tchildren: PropTypes.node,\n};\n\nexport const baseOverrides = {\n\ta: {\n\t\tcomponent: Link as React.FC,\n\t},\n\th1: {\n\t\tcomponent: MarkdownHeading as React.FC,\n\t\tprops: {\n\t\t\tlevel: 1,\n\t\t},\n\t},\n\th2: {\n\t\tcomponent: MarkdownHeading as React.FC,\n\t\tprops: {\n\t\t\tlevel: 2,\n\t\t},\n\t},\n\th3: {\n\t\tcomponent: MarkdownHeading as React.FC,\n\t\tprops: {\n\t\t\tlevel: 3,\n\t\t},\n\t},\n\th4: {\n\t\tcomponent: MarkdownHeading as React.FC,\n\t\tprops: {\n\t\t\tlevel: 4,\n\t\t},\n\t},\n\th5: {\n\t\tcomponent: MarkdownHeading as React.FC,\n\t\tprops: {\n\t\t\tlevel: 5,\n\t\t},\n\t},\n\th6: {\n\t\tcomponent: MarkdownHeading as React.FC,\n\t\tprops: {\n\t\t\tlevel: 6,\n\t\t},\n\t},\n\tp: {\n\t\tcomponent: Para as React.FC,\n\t\tprops: {\n\t\t\tsemantic: 'p',\n\t\t},\n\t},\n\tem: {\n\t\tcomponent: Text as React.FC,\n\t\tprops: {\n\t\t\tsemantic: 'em',\n\t\t},\n\t},\n\tstrong: {\n\t\tcomponent: Text as React.FC,\n\t\tprops: {\n\t\t\tsemantic: 'strong',\n\t\t},\n\t},\n\tul: {\n\t\tcomponent: List as React.FC,\n\t},\n\tol: {\n\t\tcomponent: List as React.FC,\n\t\tprops: {\n\t\t\tordered: true,\n\t\t},\n\t},\n\tblockquote: {\n\t\tcomponent: Blockquote as React.FC,\n\t},\n\tcode: {\n\t\tcomponent: Code as React.FC,\n\t},\n\tpre: {\n\t\tcomponent: Pre as React.FC<PropsWithChildren>,\n\t},\n\tinput: {\n\t\tcomponent: Checkbox as React.FC,\n\t},\n\thr: {\n\t\tcomponent: Hr as React.FC,\n\t},\n\ttable: {\n\t\tcomponent: Table as React.FC,\n\t},\n\tthead: {\n\t\tcomponent: TableHead as React.FC,\n\t},\n\tth: {\n\t\tcomponent: TableCell as React.FC,\n\t\tprops: {\n\t\t\theader: true,\n\t\t},\n\t},\n\ttbody: {\n\t\tcomponent: TableBody as React.FC,\n\t},\n\ttr: {\n\t\tcomponent: TableRow as React.FC,\n\t},\n\ttd: {\n\t\tcomponent: TableCell as React.FC,\n\t},\n\tdetails: {\n\t\tcomponent: Details as React.FC,\n\t},\n\tsummary: {\n\t\tcomponent: DetailsSummary as React.FC,\n\t},\n};\n\nexport const inlineOverrides = {\n\t...baseOverrides,\n\tp: {\n\t\tcomponent: Text,\n\t},\n};\n\ninterface MarkdownProps {\n\ttext: string;\n\tinline?: boolean;\n}\n\nexport const Markdown: React.FunctionComponent<MarkdownProps> = ({ text, inline }) => {\n\tconst overrides = inline ? inlineOverrides : baseOverrides;\n\treturn compiler(stripHtmlComments(text), { overrides, forceBlock: true });\n};\n\nMarkdown.propTypes = {\n\ttext: PropTypes.string.isRequired,\n\tinline: PropTypes.bool,\n};\n\nexport default Markdown;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/MarkdownHeading/MarkdownHeading.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\nimport MarkdownHeading from './index';\n\ndescribe('Markdown Heading', () => {\n\tit('should render a heading with a wrapper that provides margin and an id', () => {\n\t\tconst actual = renderer.create(\n\t\t\t<MarkdownHeading id=\"the-markdown-heading\" level={2}>\n\t\t\t\tThe markdown heading\n\t\t\t</MarkdownHeading>\n\t\t);\n\n\t\texpect(actual).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/MarkdownHeading/MarkdownHeadingRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport Heading from 'rsg-components/Heading';\nimport * as Rsg from '../../../../typings';\n\nconst styles = ({ space }: Rsg.Theme) => ({\n\tspacing: {\n\t\tmarginBottom: space[2],\n\t},\n});\n\ninterface MarkdownHeadingProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n\tlevel: number;\n\tid?: string;\n}\n\nconst MarkdownHeadingRenderer: React.FunctionComponent<MarkdownHeadingProps> = ({\n\tclasses,\n\tlevel,\n\tchildren,\n\tid,\n}) => {\n\treturn (\n\t\t<div className={classes.spacing}>\n\t\t\t<Heading level={level} id={id}>\n\t\t\t\t{children}\n\t\t\t</Heading>\n\t\t</div>\n\t);\n};\n\nMarkdownHeadingRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tlevel: PropTypes.oneOf([1, 2, 3, 4, 5, 6]).isRequired,\n\tchildren: PropTypes.any,\n\tid: PropTypes.string,\n};\n\nexport default Styled<MarkdownHeadingProps>(styles)(MarkdownHeadingRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/MarkdownHeading/__snapshots__/MarkdownHeading.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Markdown Heading should render a heading with a wrapper that provides margin and an id 1`] = `\n<div\n  className=\"rsg--spacing-0\"\n>\n  <h2\n    className=\"rsg--heading-2 rsg--heading2-4\"\n    id=\"the-markdown-heading\"\n  >\n    The markdown heading\n  </h2>\n</div>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/MarkdownHeading/index.ts",
    "content": "export { default } from 'rsg-components/Markdown/MarkdownHeading/MarkdownHeadingRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Pre/Pre.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\n\nimport Pre from './index';\n\ndescribe('Markdown Pre', () => {\n\tit('should render a pre', () => {\n\t\tconst actual = renderer.create(<Pre>This is pre-formatted text.</Pre>);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n\n\tit('should render highlighted code', () => {\n\t\tconst code = '<button>OK</button>';\n\t\tconst actual = renderer.create(<Pre className=\"lang-html\">{code}</Pre>);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Pre/PreRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport cx from 'clsx';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport prismTheme from '../../../styles/prismTheme';\nimport * as Rsg from '../../../../typings';\n\nconst styles = ({ space, color, fontSize, fontFamily, borderRadius }: Rsg.Theme) => ({\n\tpre: {\n\t\tfontFamily: fontFamily.monospace,\n\t\tfontSize: fontSize.small,\n\t\tlineHeight: 1.5,\n\t\tcolor: color.base,\n\t\twhiteSpace: 'pre-wrap',\n\t\twordWrap: 'normal',\n\t\ttabSize: 2,\n\t\thyphens: 'none',\n\t\tbackgroundColor: color.codeBackground,\n\t\tpadding: [[space[1], space[2]]],\n\t\tborder: [[1, color.codeBackground, 'solid']],\n\t\tborderRadius,\n\t\tmarginTop: 0,\n\t\tmarginBottom: space[2],\n\t\toverflow: 'auto',\n\t\t...prismTheme({ color }),\n\t},\n});\n\nexport interface PreProps {\n\tclassName?: string;\n\tchildren: React.ReactNode;\n}\n\ntype PrePropsWithClasses = JssInjectedProps & PreProps;\n\nexport const PreRenderer: React.FunctionComponent<PrePropsWithClasses> = ({\n\tclasses,\n\tclassName,\n\tchildren,\n}) => {\n\tconst classNames = cx(className, classes.pre);\n\n\tconst isHighlighted = className && className.indexOf('lang-') !== -1;\n\tif (isHighlighted && children) {\n\t\treturn <pre className={classNames} dangerouslySetInnerHTML={{ __html: children.toString() }} />;\n\t}\n\treturn <pre className={classNames}>{children}</pre>;\n};\n\nPreRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tclassName: PropTypes.string,\n\tchildren: PropTypes.any.isRequired,\n};\n\nexport default Styled<PrePropsWithClasses>(styles)(PreRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Pre/__snapshots__/Pre.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Markdown Pre should render a pre 1`] = `\n<pre\n  className=\"rsg--pre-0\"\n>\n  This is pre-formatted text.\n</pre>\n`;\n\nexports[`Markdown Pre should render highlighted code 1`] = `\n<pre\n  className=\"lang-html rsg--pre-0\"\n  dangerouslySetInnerHTML={\n    Object {\n      \"__html\": \"<button>OK</button>\",\n    }\n  }\n/>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Pre/index.ts",
    "content": "export { default } from 'rsg-components/Markdown/Pre/PreRenderer';\nexport * from 'rsg-components/Markdown/Pre/PreRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Table/Table.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\n\nimport { Table, TableHead, TableBody, TableRow, TableCell } from './index';\n\ndescribe('Markdown Table', () => {\n\tit('should render a table', () => {\n\t\tconst actual = renderer.create(\n\t\t\t<Table>\n\t\t\t\t<TableHead>\n\t\t\t\t\t<TableRow>\n\t\t\t\t\t\t<TableCell header>1st header</TableCell>\n\t\t\t\t\t\t<TableCell header>2nd header</TableCell>\n\t\t\t\t\t</TableRow>\n\t\t\t\t</TableHead>\n\t\t\t\t<TableBody>\n\t\t\t\t\t<TableRow>\n\t\t\t\t\t\t<TableCell>1st cell</TableCell>\n\t\t\t\t\t\t<TableCell>2nd cell</TableCell>\n\t\t\t\t\t</TableRow>\n\t\t\t\t</TableBody>\n\t\t\t</Table>\n\t\t);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Table/TableBodyRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\ninterface Props {\n\tchildren?: React.ReactNode;\n}\n\nexport const TableBodyRenderer = ({ children }: Props) => {\n\treturn <tbody>{children}</tbody>;\n};\nTableBodyRenderer.propTypes = {\n\tchildren: PropTypes.node.isRequired,\n};\n\nexport default TableBodyRenderer;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Table/TableCellRenderer.tsx",
    "content": "import React from 'react';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../../typings';\n\nconst styles = ({ space, color, fontSize, fontFamily }: Rsg.Theme) => ({\n\ttd: {\n\t\tpadding: [[space[0], space[2], space[0], 0]],\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.base,\n\t\tcolor: color.base,\n\t\tlineHeight: 1.5,\n\t},\n\tth: {\n\t\tcomposes: '$td',\n\t\tfontWeight: 'bold',\n\t},\n});\n\ninterface TableCellProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n\theader?: boolean;\n}\n\nexport const TableCellRenderer: React.FunctionComponent<TableCellProps> = ({\n\tclasses,\n\theader = false,\n\tchildren,\n}) => {\n\tif (header) {\n\t\treturn <th className={classes.th}>{children}</th>;\n\t}\n\treturn <td className={classes.td}>{children}</td>;\n};\n\nexport default Styled<TableCellProps>(styles)(TableCellRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Table/TableHeadRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../../typings';\n\nconst styles = ({ color }: Rsg.Theme) => ({\n\tthead: {\n\t\tborderBottom: [[1, color.border, 'solid']],\n\t},\n});\n\ninterface TableHeadProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n}\n\nexport const TableHeadRenderer: React.FunctionComponent<TableHeadProps> = ({\n\tclasses,\n\tchildren,\n}) => {\n\treturn <thead className={classes.thead}>{children}</thead>;\n};\n\nTableHeadRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any.isRequired,\n};\n\nexport default Styled<TableHeadProps>(styles)(TableHeadRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Table/TableRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../../typings';\n\nconst styles = ({ space }: Rsg.Theme) => ({\n\ttable: {\n\t\tmarginTop: 0,\n\t\tmarginBottom: space[2],\n\t\tborderCollapse: 'collapse',\n\t},\n});\n\ninterface TableProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n}\n\nexport const TableRenderer: React.FunctionComponent<TableProps> = ({ classes, children }) => {\n\treturn <table className={classes.table}>{children}</table>;\n};\n\nTableRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any.isRequired,\n};\n\nexport default Styled<TableProps>(styles)(TableRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Table/TableRowRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\ninterface Props {\n\tchildren?: React.ReactNode;\n}\n\nexport const TableRowRenderer = ({ children }: Props) => {\n\treturn <tr>{children}</tr>;\n};\nTableRowRenderer.propTypes = {\n\tchildren: PropTypes.node.isRequired,\n};\n\nexport default TableRowRenderer;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Table/__snapshots__/Table.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Markdown Table should render a table 1`] = `\n<table\n  className=\"rsg--table-0\"\n>\n  <thead\n    className=\"rsg--thead-2\"\n  >\n    <tr>\n      <th\n        className=\"rsg--th-4 rsg--td-3\"\n      >\n        1st header\n      </th>\n      <th\n        className=\"rsg--th-4 rsg--td-3\"\n      >\n        2nd header\n      </th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td\n        className=\"rsg--td-3\"\n      >\n        1st cell\n      </td>\n      <td\n        className=\"rsg--td-3\"\n      >\n        2nd cell\n      </td>\n    </tr>\n  </tbody>\n</table>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/Table/index.ts",
    "content": "export { default as Table } from 'rsg-components/Markdown/Table/TableRenderer';\nexport { default as TableHead } from 'rsg-components/Markdown/Table/TableHeadRenderer';\nexport { default as TableBody } from 'rsg-components/Markdown/Table/TableBodyRenderer';\nexport { default as TableRow } from 'rsg-components/Markdown/Table/TableRowRenderer';\nexport { default as TableCell } from 'rsg-components/Markdown/Table/TableCellRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/__snapshots__/Markdown.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Markdown inline should render text in a span 1`] = `\n<span className=\"rsg--text-11 rsg--inheritSize-12 rsg--baseColor-16\">\n  Hello world!\n</span>\n`;\n\nexports[`Markdown should render a blockquote 1`] = `\n<blockquote className=\"rsg--blockquote-25\">\n  <p className=\"rsg--para-2\">\n    This is a blockquote.\nAnd this is a second line.\n  </p>\n</blockquote>\n`;\n\nexports[`Markdown should render a horizontal rule 1`] = `<hr className=\"rsg--hr-28\">`;\n\nexports[`Markdown should render a table 1`] = `\n<table className=\"rsg--table-29\">\n  <thead className=\"rsg--thead-30\">\n    <tr>\n      <th className=\"rsg--th-32 rsg--td-31\">\n        heading 1\n      </th>\n      <th className=\"rsg--th-32 rsg--td-31\">\n        heading 2\n      </th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td className=\"rsg--td-31\">\n        foo\n      </td>\n      <td className=\"rsg--td-31\">\n        bar\n      </td>\n    </tr>\n    <tr>\n      <td className=\"rsg--td-31\">\n        more foo\n      </td>\n      <td className=\"rsg--td-31\">\n        more bar\n      </td>\n    </tr>\n  </tbody>\n</table>\n`;\n\nexports[`Markdown should render check-lists 1`] = `\n<ul className=\"rsg--list-21\">\n  <li className=\"rsg--li-23\">\n    <input type=\"checkbox\"\n           readonly\n           className=\"rsg--input-24\"\n    >\n    to do 1\n  </li>\n  <li className=\"rsg--li-23\">\n    <input type=\"checkbox\"\n           readonly\n           className=\"rsg--input-24\"\n    >\n    to do 2\n  </li>\n  <li className=\"rsg--li-23\">\n    <input type=\"checkbox\"\n           checked\n           readonly\n           className=\"rsg--input-24\"\n    >\n    to do 3\n  </li>\n</ul>\n`;\n\nexports[`Markdown should render code blocks without escaping 1`] = `\n<pre className=\"lang-html rsg--pre-26\">\n  <foo>\n  </foo>\n</pre>\n`;\n\nexports[`Markdown should render emphasis and strong text 1`] = `\n<div>\n  <p className=\"rsg--para-2\">\n    this text is\n    <strong className=\"rsg--text-11 rsg--inheritSize-12 rsg--baseColor-16 rsg--strong-19\">\n      strong\n    </strong>\n  </p>\n  <p className=\"rsg--para-2\">\n    and this is\n    <em className=\"rsg--text-11 rsg--inheritSize-12 rsg--baseColor-16 rsg--em-18\">\n      emphasized\n    </em>\n  </p>\n</div>\n`;\n\nexports[`Markdown should render headings with generated ids 1`] = `\n<div>\n  <div className=\"rsg--spacing-3\">\n    <h1 id=\"one\"\n        className=\"rsg--heading-4 rsg--heading1-5\"\n    >\n      one\n    </h1>\n  </div>\n  <div className=\"rsg--spacing-3\">\n    <h2 id=\"two\"\n        className=\"rsg--heading-4 rsg--heading2-6\"\n    >\n      two\n    </h2>\n  </div>\n  <div className=\"rsg--spacing-3\">\n    <h3 id=\"three\"\n        className=\"rsg--heading-4 rsg--heading3-7\"\n    >\n      three\n    </h3>\n  </div>\n  <div className=\"rsg--spacing-3\">\n    <h4 id=\"four\"\n        className=\"rsg--heading-4 rsg--heading4-8\"\n    >\n      four\n    </h4>\n  </div>\n  <div className=\"rsg--spacing-3\">\n    <h5 id=\"five\"\n        className=\"rsg--heading-4 rsg--heading5-9\"\n    >\n      five\n    </h5>\n  </div>\n  <div className=\"rsg--spacing-3\">\n    <h6 id=\"six\"\n        className=\"rsg--heading-4 rsg--heading6-10\"\n    >\n      six\n    </h6>\n  </div>\n</div>\n`;\n\nexports[`Markdown should render inline code with escaping 1`] = `\n<p className=\"rsg--para-2\">\n  Foo\n  <code className=\"rsg--code-27\">\n    &lt;bar&gt;\n  </code>\n  baz\n</p>\n`;\n\nexports[`Markdown should render links 1`] = `\n<p className=\"rsg--para-2\">\n  a\n  <a href=\"http://test.com\"\n     className=\"rsg--link-0\"\n  >\n    link\n  </a>\n</p>\n`;\n\nexports[`Markdown should render mixed nested lists 1`] = `\n<ul className=\"rsg--list-21\">\n  <li className=\"rsg--li-23\">\n    list 1\n  </li>\n  <li className=\"rsg--li-23\">\n    list 2\n    <ol className=\"rsg--list-21 rsg--ordered-22\">\n      <li className=\"rsg--li-23\">\n        Sub-list\n      </li>\n      <li className=\"rsg--li-23\">\n        Sub-list\n      </li>\n      <li className=\"rsg--li-23\">\n        Sub-list\n      </li>\n    </ol>\n  </li>\n  <li className=\"rsg--li-23\">\n    list 3\n  </li>\n</ul>\n`;\n\nexports[`Markdown should render ordered lists 1`] = `\n<ol className=\"rsg--list-21 rsg--ordered-22\">\n  <li className=\"rsg--li-23\">\n    list\n  </li>\n  <li className=\"rsg--li-23\">\n    item\n  </li>\n  <li className=\"rsg--li-23\">\n    three\n  </li>\n</ol>\n`;\n\nexports[`Markdown should render paragraphs 1`] = `\n<div>\n  <p className=\"rsg--para-2\">\n    a paragraph\n  </p>\n  <p className=\"rsg--para-2\">\n    another paragraph\n  </p>\n</div>\n`;\n\nexports[`Markdown should render pre-formatted text 1`] = `\n<pre className=\"rsg--pre-26\">\n  this is preformatted\nso is this\n</pre>\n`;\n\nexports[`Markdown should render unordered lists 1`] = `\n<ul className=\"rsg--list-21\">\n  <li className=\"rsg--li-23\">\n    list\n  </li>\n  <li className=\"rsg--li-23\">\n    item\n  </li>\n  <li className=\"rsg--li-23\">\n    three\n  </li>\n</ul>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Markdown/index.ts",
    "content": "export { default } from 'rsg-components/Markdown/Markdown';\n"
  },
  {
    "path": "src/client/rsg-components/Message/Message.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { MessageRenderer } from './MessageRenderer';\n\nit('renderer should render message', () => {\n\tconst message = 'Hello *world*!';\n\tconst renderer = createRenderer();\n\trenderer.render(<MessageRenderer classes={{}}>{message}</MessageRenderer>);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('renderer should render message for array', () => {\n\tconst messages = ['Hello *world*!', 'Foo _bar_'];\n\tconst renderer = createRenderer();\n\trenderer.render(<MessageRenderer classes={{}}>{messages}</MessageRenderer>);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Message/MessageRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Markdown from 'rsg-components/Markdown';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ space }: Rsg.Theme) => ({\n\troot: {\n\t\tmarginBottom: space[4],\n\t},\n});\n\ninterface MessageProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n}\n\nexport const MessageRenderer: React.FunctionComponent<MessageProps> = ({ classes, children }) => {\n\treturn (\n\t\t<div className={classes.root}>\n\t\t\t<Markdown\n\t\t\t\ttext={\n\t\t\t\t\tArray.isArray(children)\n\t\t\t\t\t\t? children.join('\\n')\n\t\t\t\t\t\t: typeof children === 'string'\n\t\t\t\t\t\t? children\n\t\t\t\t\t\t: ''\n\t\t\t\t}\n\t\t\t/>\n\t\t</div>\n\t);\n};\n\nMessageRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any.isRequired,\n};\n\nexport default Styled<MessageProps>(styles)(MessageRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Message/__snapshots__/Message.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render message 1`] = `\n<div>\n  <Markdown\n    text=\"Hello *world*!\"\n  />\n</div>\n`;\n\nexports[`renderer should render message for array 1`] = `\n<div>\n  <Markdown\n    text=\"Hello *world*!\nFoo _bar_\"\n  />\n</div>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Message/index.ts",
    "content": "export { default } from 'rsg-components/Message/MessageRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Methods/Methods.spec.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { parse, MethodDescriptor } from 'react-docgen';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport MethodsRenderer, { columns } from './MethodsRenderer';\n\n// Test renderers with clean readable snapshot diffs\nexport default function ColumnsRenderer({ methods }: { methods: MethodDescriptor[] }) {\n\treturn (\n\t\t<ul>\n\t\t\t{methods.map((row, rowIdx) => (\n\t\t\t\t<li key={rowIdx}>\n\t\t\t\t\t{columns.map((col, colIdx) => (\n\t\t\t\t\t\t<div key={colIdx}>{col.render(row)}</div>\n\t\t\t\t\t))}\n\t\t\t\t</li>\n\t\t\t))}\n\t\t</ul>\n\t);\n}\n\nColumnsRenderer.propTypes = {\n\tmethods: PropTypes.array,\n};\n\nfunction render(methods: string[]) {\n\tconst parsed = parse(\n\t\t`\n\t\timport { Component } from 'react';\n\t\texport default class Cmpnt extends Component {\n\t\t\t${methods.join('\\n')}\n\t\t\trender() {\n\t\t\t}\n\t\t}\n\t`,\n\t\tundefined,\n\t\tundefined,\n\t\t{ filename: '' }\n\t);\n\tconst renderer = createRenderer();\n\tif (Array.isArray(parsed) || !parsed.methods) {\n\t\trenderer.render(<div />);\n\t} else {\n\t\trenderer.render(<ColumnsRenderer methods={parsed.methods} />);\n\t}\n\treturn renderer.getRenderOutput();\n}\n\ndescribe('MethodsRenderer', () => {\n\tit('should render a table', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(\n\t\t\t<MethodsRenderer\n\t\t\t\tmethods={[\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'method',\n\t\t\t\t\t\tmodifiers: [],\n\t\t\t\t\t\tparams: [],\n\t\t\t\t\t\tdescription: 'Public',\n\t\t\t\t\t},\n\t\t\t\t]}\n\t\t\t/>\n\t\t);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n});\n\ndescribe('PropsRenderer', () => {\n\tit('should render public method', () => {\n\t\tconst actual = render(['/**\\n * Public\\n * @public\\n */\\nmethod() {}']);\n\n\t\texpect(actual).toMatchSnapshot();\n\t});\n\n\tit('should render parameters', () => {\n\t\tconst actual = render([\n\t\t\t'/**\\n * Public\\n * @public\\n * @param {Number} value - Description\\n */\\nmethod(value) {}',\n\t\t]);\n\n\t\texpect(actual).toMatchSnapshot();\n\t});\n\n\tit('should render returns', () => {\n\t\tconst actual = render([\n\t\t\t'/**\\n * @public\\n * @returns {Number} - Description\\n */\\nmethod() {}',\n\t\t]);\n\n\t\texpect(actual).toMatchSnapshot();\n\t});\n\n\tit('should render JsDoc tags', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(\n\t\t\t<ColumnsRenderer\n\t\t\t\tmethods={[\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Foo',\n\t\t\t\t\t\ttags: {\n\t\t\t\t\t\t\tsince: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttitle: 'since',\n\t\t\t\t\t\t\t\t\tdescription: '1.0.0',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t]}\n\t\t\t/>\n\t\t);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n\n\tit('should render deprecated JsDoc tags', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(\n\t\t\t<ColumnsRenderer\n\t\t\t\tmethods={[\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Foo',\n\t\t\t\t\t\ttags: {\n\t\t\t\t\t\t\tdeprecated: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttitle: 'description',\n\t\t\t\t\t\t\t\t\tdescription: 'Use *another* method',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t]}\n\t\t\t/>\n\t\t);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Methods/MethodsRenderer.tsx",
    "content": "import React from 'react';\nimport Markdown from 'rsg-components/Markdown';\nimport Argument from 'rsg-components/Argument';\nimport Arguments from 'rsg-components/Arguments';\nimport Name from 'rsg-components/Name';\nimport JsDoc from 'rsg-components/JsDoc';\nimport Table from 'rsg-components/Table';\nimport { MethodDescriptor } from 'react-docgen';\n\nconst getRowKey = (row: MethodDescriptor): string => row.name;\n\nexport const columns = [\n\t{\n\t\tcaption: 'Method name',\n\t\t// eslint-disable-next-line react/prop-types\n\t\trender: ({ name, tags = {} }: MethodDescriptor) => (\n\t\t\t<Name deprecated={!!tags.deprecated}>{`${name}()`}</Name>\n\t\t),\n\t},\n\t{\n\t\tcaption: 'Parameters',\n\t\t// eslint-disable-next-line react/prop-types\n\t\trender: ({ params = [] }: MethodDescriptor) => <Arguments args={params} />,\n\t},\n\t{\n\t\tcaption: 'Description',\n\t\t// eslint-disable-next-line react/prop-types\n\t\trender: ({ description, returns, tags = {} }: MethodDescriptor) => (\n\t\t\t<div>\n\t\t\t\t{description && <Markdown text={description} />}\n\t\t\t\t{returns && <Argument block returns {...returns} />}\n\t\t\t\t<JsDoc {...tags} />\n\t\t\t</div>\n\t\t),\n\t},\n];\n\nconst MethodsRenderer: React.FunctionComponent<{ methods: MethodDescriptor[] }> = ({ methods }) => (\n\t<Table columns={columns} rows={methods} getRowKey={getRowKey} />\n);\n\nexport default MethodsRenderer;\n"
  },
  {
    "path": "src/client/rsg-components/Methods/__snapshots__/Methods.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`MethodsRenderer should render a table 1`] = `\n<Styled(Table)\n  columns={\n    Array [\n      Object {\n        \"caption\": \"Method name\",\n        \"render\": [Function],\n      },\n      Object {\n        \"caption\": \"Parameters\",\n        \"render\": [Function],\n      },\n      Object {\n        \"caption\": \"Description\",\n        \"render\": [Function],\n      },\n    ]\n  }\n  getRowKey={[Function]}\n  rows={\n    Array [\n      Object {\n        \"description\": \"Public\",\n        \"modifiers\": Array [],\n        \"name\": \"method\",\n        \"params\": Array [],\n      },\n    ]\n  }\n/>\n`;\n\nexports[`PropsRenderer should render JsDoc tags 1`] = `\n<ul>\n  <li>\n    <div>\n      <Styled(Name)\n        deprecated={false}\n      >\n        Foo()\n      </Styled(Name)>\n    </div>\n    <div>\n      <Styled(Arguments)\n        args={Array []}\n      />\n    </div>\n    <div>\n      <div>\n        <JsDoc\n          since={\n            Array [\n              Object {\n                \"description\": \"1.0.0\",\n                \"title\": \"since\",\n              },\n            ]\n          }\n        />\n      </div>\n    </div>\n  </li>\n</ul>\n`;\n\nexports[`PropsRenderer should render deprecated JsDoc tags 1`] = `\n<ul>\n  <li>\n    <div>\n      <Styled(Name)\n        deprecated={true}\n      >\n        Foo()\n      </Styled(Name)>\n    </div>\n    <div>\n      <Styled(Arguments)\n        args={Array []}\n      />\n    </div>\n    <div>\n      <div>\n        <JsDoc\n          deprecated={\n            Array [\n              Object {\n                \"description\": \"Use *another* method\",\n                \"title\": \"description\",\n              },\n            ]\n          }\n        />\n      </div>\n    </div>\n  </li>\n</ul>\n`;\n\nexports[`PropsRenderer should render parameters 1`] = `\n<ul>\n  <li>\n    <div>\n      <Styled(Name)\n        deprecated={false}\n      >\n        method()\n      </Styled(Name)>\n    </div>\n    <div>\n      <Styled(Arguments)\n        args={\n          Array [\n            Object {\n              \"description\": \"Description\",\n              \"name\": \"value\",\n              \"optional\": false,\n              \"type\": Object {\n                \"name\": \"Number\",\n              },\n            },\n          ]\n        }\n      />\n    </div>\n    <div>\n      <div>\n        <Markdown\n          text=\"Public\"\n        />\n        <JsDoc />\n      </div>\n    </div>\n  </li>\n</ul>\n`;\n\nexports[`PropsRenderer should render public method 1`] = `\n<ul>\n  <li>\n    <div>\n      <Styled(Name)\n        deprecated={false}\n      >\n        method()\n      </Styled(Name)>\n    </div>\n    <div>\n      <Styled(Arguments)\n        args={Array []}\n      />\n    </div>\n    <div>\n      <div>\n        <Markdown\n          text=\"Public\"\n        />\n        <JsDoc />\n      </div>\n    </div>\n  </li>\n</ul>\n`;\n\nexports[`PropsRenderer should render returns 1`] = `\n<ul>\n  <li>\n    <div>\n      <Styled(Name)\n        deprecated={false}\n      >\n        method()\n      </Styled(Name)>\n    </div>\n    <div>\n      <Styled(Arguments)\n        args={Array []}\n      />\n    </div>\n    <div>\n      <div>\n        <Styled(Argument)\n          block={true}\n          description=\"Description\"\n          returns={true}\n          type={\n            Object {\n              \"name\": \"Number\",\n            }\n          }\n        />\n        <JsDoc />\n      </div>\n    </div>\n  </li>\n</ul>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Methods/index.ts",
    "content": "export { default } from 'rsg-components/Methods/MethodsRenderer';\nexport * from 'rsg-components/Methods/MethodsRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Name/Name.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { NameRenderer, styles } from './NameRenderer';\n\nconst props = {\n\tclasses: classes(styles),\n};\n\nit('renderer should render argument name', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<NameRenderer {...props}>Foo</NameRenderer>);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('renderer should render deprecated argument name', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<NameRenderer {...props} deprecated>\n\t\t\tFoo\n\t\t</NameRenderer>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Name/NameRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport cx from 'clsx';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ fontFamily, fontSize, color }: Rsg.Theme) => ({\n\tname: {\n\t\tfontFamily: fontFamily.monospace,\n\t\tfontSize: fontSize.small,\n\t\tcolor: color.name,\n\t},\n\tisDeprecated: {\n\t\tcolor: color.light,\n\t\ttextDecoration: 'line-through',\n\t},\n});\n\ninterface NameProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n\tdeprecated?: boolean;\n}\n\nexport const NameRenderer: React.FunctionComponent<NameProps> = ({\n\tclasses,\n\tchildren,\n\tdeprecated,\n}) => {\n\tconst classNames = cx(classes.name, {\n\t\t[classes.isDeprecated]: deprecated,\n\t});\n\treturn <code className={classNames}>{children}</code>;\n};\n\nNameRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any.isRequired,\n\tdeprecated: PropTypes.bool,\n};\n\nexport default Styled<NameProps>(styles)(NameRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Name/__snapshots__/Name.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render argument name 1`] = `\n<code\n  className=\"name\"\n>\n  Foo\n</code>\n`;\n\nexports[`renderer should render deprecated argument name 1`] = `\n<code\n  className=\"name isDeprecated\"\n>\n  Foo\n</code>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Name/index.ts",
    "content": "export { default } from 'rsg-components/Name/NameRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/NotFound/NotFound.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { NotFoundRenderer } from './NotFoundRenderer';\n\nit('renderer should render not found message', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<NotFoundRenderer classes={{}} />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/NotFound/NotFoundRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Markdown from 'rsg-components/Markdown';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ maxWidth }: Rsg.Theme) => ({\n\troot: {\n\t\tmaxWidth,\n\t\tmargin: [[0, 'auto']],\n\t},\n});\n\nexport const NotFoundRenderer: React.FunctionComponent<JssInjectedProps> = ({ classes }) => {\n\treturn (\n\t\t<div className={classes.root}>\n\t\t\t<Markdown\n\t\t\t\ttext={`\n# Page not found\nThe link you followed may be broken, or the page may have been removed.\n`}\n\t\t\t/>\n\t\t</div>\n\t);\n};\n\nNotFoundRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n};\n\nexport default Styled(styles)(NotFoundRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/NotFound/__snapshots__/NotFound.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render not found message 1`] = `\n<div>\n  <Markdown\n    text=\"\n# Page not found\nThe link you followed may be broken, or the page may have been removed.\n\"\n  />\n</div>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/NotFound/index.ts",
    "content": "export { default } from 'rsg-components/NotFound/NotFoundRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Para/Para.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { ParaRenderer, styles } from './ParaRenderer';\n\nconst props = {\n\tclasses: classes(styles),\n};\n\nit('should render paragraph as a <div>', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<ParaRenderer {...props}>Pizza</ParaRenderer>);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should render paragraph as a <p>', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<ParaRenderer {...props} semantic=\"p\">\n\t\t\tPizza\n\t\t</ParaRenderer>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Para/ParaRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ space, color, fontFamily, fontSize }: Rsg.Theme) => ({\n\tpara: {\n\t\tmarginTop: 0,\n\t\tmarginBottom: space[2],\n\t\tcolor: color.base,\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.text,\n\t\tlineHeight: 1.5,\n\t},\n});\n\ninterface ParaProps extends JssInjectedProps {\n\tsemantic?: 'p';\n\tchildren: React.ReactNode;\n}\n\nexport const ParaRenderer: React.FunctionComponent<ParaProps> = ({\n\tclasses,\n\tsemantic,\n\tchildren,\n}) => {\n\tconst Tag = semantic || 'div';\n\n\treturn <Tag className={classes.para}>{children}</Tag>;\n};\n\nParaRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tsemantic: PropTypes.oneOf(['p']),\n\tchildren: PropTypes.any.isRequired,\n};\n\nexport default Styled<ParaProps>(styles)(ParaRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Para/__snapshots__/Para.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should render paragraph as a <div> 1`] = `\n<div\n  className=\"para\"\n>\n  Pizza\n</div>\n`;\n\nexports[`should render paragraph as a <p> 1`] = `\n<p\n  className=\"para\"\n>\n  Pizza\n</p>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Para/index.ts",
    "content": "export { default } from 'rsg-components/Para/ParaRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Pathline/Pathline.spec.tsx",
    "content": "import { fireEvent, render } from '@testing-library/react';\nimport React from 'react';\nimport copy from 'clipboard-copy';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { PathlineRenderer, styles } from './PathlineRenderer';\n\njest.mock('clipboard-copy');\n\nconst pathline = 'foo/bar';\nconst props = {\n\tclasses: classes(styles),\n};\n\nit('renderer should a path line', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<PathlineRenderer {...props}>{pathline}</PathlineRenderer>);\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\ntest('should copy text on click', () => {\n\tconst { getByRole } = render(<PathlineRenderer {...props}>{pathline}</PathlineRenderer>);\n\tfireEvent.click(getByRole('button'));\n\texpect(copy).toBeCalledWith(pathline);\n});\n"
  },
  {
    "path": "src/client/rsg-components/Pathline/PathlineRenderer.tsx",
    "content": "import React from 'react';\nimport copy from 'clipboard-copy';\nimport { MdContentCopy } from 'react-icons/md';\nimport ToolbarButton from 'rsg-components/ToolbarButton';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ space, fontFamily, fontSize, color }: Rsg.Theme) => ({\n\tpathline: {\n\t\tfontFamily: fontFamily.monospace,\n\t\tfontSize: fontSize.small,\n\t\tcolor: color.light,\n\t\twordBreak: 'break-all',\n\t},\n\tcopyButton: {\n\t\tmarginLeft: space[0],\n\t},\n});\n\ninterface Props extends JssInjectedProps {\n\tchildren?: React.ReactNode;\n}\n\nexport const PathlineRenderer = ({ classes, children }: Props) => {\n\treturn (\n\t\t<div className={classes.pathline}>\n\t\t\t{children}\n\t\t\t<ToolbarButton\n\t\t\t\tsmall\n\t\t\t\tclassName={classes.copyButton}\n\t\t\t\tonClick={() => children && copy(children.toString())}\n\t\t\t\ttitle=\"Copy to clipboard\"\n\t\t\t>\n\t\t\t\t<MdContentCopy />\n\t\t\t</ToolbarButton>\n\t\t</div>\n\t);\n};\n\nexport default Styled<JssInjectedProps>(styles)(PathlineRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Pathline/__snapshots__/Pathline.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should a path line 1`] = `\n<div\n  className=\"pathline\"\n>\n  foo/bar\n  <Styled(ToolbarButton)\n    className=\"copyButton\"\n    onClick={[Function]}\n    small={true}\n    title=\"Copy to clipboard\"\n  >\n    <MdContentCopy />\n  </Styled(ToolbarButton)>\n</div>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Pathline/index.ts",
    "content": "export { default } from 'rsg-components/Pathline/PathlineRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Playground/Playground.spec.tsx",
    "content": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport Playground from './Playground';\nimport slots from '../slots';\nimport Context from '../Context';\n\nconst evalInContext = (a: string) =>\n\t// eslint-disable-next-line no-new-func\n\tnew Function('require', 'const React = require(\"react\");' + a).bind(null, require);\nconst code = '<button>Code: OK</button>';\nconst newCode = '<button>Code: Not OK</button>';\nconst defaultProps = {\n\tindex: 0,\n\tname: 'name',\n\tsettings: {},\n\texampleMode: 'collapse',\n\tevalInContext,\n\tcode,\n};\nconst context = {\n\tconfig: {\n\t\tpreviewDelay: 0,\n\t},\n\tcodeRevision: 0,\n\tslots: slots(),\n};\n\nconst Provider = (props: any) => <Context.Provider value={context} {...props} />;\n\nit('should update code via props', () => {\n\tconst { rerender, getByText } = render(\n\t\t<Provider>\n\t\t\t<Playground {...defaultProps} />\n\t\t</Provider>\n\t);\n\n\texpect(getByText('Code: OK')).toBeInTheDocument();\n\n\trerender(\n\t\t<Provider>\n\t\t\t<Playground {...defaultProps} code={newCode} />\n\t\t</Provider>\n\t);\n\n\texpect(getByText('Code: Not OK')).toBeInTheDocument();\n});\n\nit('should open a code editor', () => {\n\tconst { queryByRole, getByText } = render(\n\t\t<Provider>\n\t\t\t<Playground {...defaultProps} />\n\t\t</Provider>\n\t);\n\n\texpect(queryByRole('textbox')).not.toBeInTheDocument();\n\n\tfireEvent.click(getByText(/view code/i));\n\n\texpect(queryByRole('textbox')).toBeInTheDocument();\n});\n\nit('should not render a code editor if noeditor option passed in example settings', () => {\n\tconst { queryByText } = render(\n\t\t<Provider>\n\t\t\t<Playground {...defaultProps} settings={{ noeditor: true }} />\n\t\t</Provider>\n\t);\n\n\texpect(queryByText(/view code/i)).not.toBeInTheDocument();\n});\n\nit('should open a code editor by default if showcode=true option passed in example settings', () => {\n\tconst { queryByRole } = render(\n\t\t<Provider>\n\t\t\t<Playground {...defaultProps} settings={{ showcode: true }} />\n\t\t</Provider>\n\t);\n\n\texpect(queryByRole('textbox')).toBeInTheDocument();\n});\n\nit('should open a code editor by default if exampleMode=\"expand\" option specified in style guide config', () => {\n\tconst { queryByRole } = render(\n\t\t<Provider\n\t\t\tvalue={{\n\t\t\t\t...context,\n\t\t\t\tconfig: {\n\t\t\t\t\t...context.config,\n\t\t\t\t},\n\t\t\t}}\n\t\t>\n\t\t\t<Playground {...defaultProps} exampleMode=\"expand\" />\n\t\t</Provider>\n\t);\n\n\texpect(queryByRole('textbox')).toBeInTheDocument();\n});\n\nit('showcode option in example settings should overwrite style guide config option', () => {\n\tconst { queryByRole } = render(\n\t\t<Provider\n\t\t\tvalue={{\n\t\t\t\t...context,\n\t\t\t\tconfig: {\n\t\t\t\t\t...context.config,\n\t\t\t\t},\n\t\t\t}}\n\t\t>\n\t\t\t<Playground {...defaultProps} exampleMode=\"expand\" settings={{ showcode: false }} />\n\t\t</Provider>\n\t);\n\n\texpect(queryByRole('textbox')).not.toBeInTheDocument();\n});\n\nit('should not include padded class if padded option is not passed in example settings', () => {\n\tconst { getByTestId } = render(\n\t\t<Provider>\n\t\t\t<Playground {...defaultProps} settings={{ padded: false }} />\n\t\t</Provider>\n\t);\n\n\texpect(getByTestId('preview-wrapper')).not.toHaveAttribute(\n\t\t'class',\n\t\texpect.stringContaining('rsg--padded-')\n\t);\n});\n\nit('should include padded class if padded option is passed in example settings', () => {\n\tconst { getByTestId } = render(\n\t\t<Provider>\n\t\t\t<Playground {...defaultProps} settings={{ padded: true }} />\n\t\t</Provider>\n\t);\n\n\texpect(getByTestId('preview-wrapper')).toHaveAttribute(\n\t\t'class',\n\t\texpect.stringContaining('rsg--padded-')\n\t);\n});\n"
  },
  {
    "path": "src/client/rsg-components/Playground/Playground.tsx",
    "content": "import React, { Component } from 'react';\nimport debounce from 'lodash/debounce';\nimport Preview from 'rsg-components/Preview';\nimport Para from 'rsg-components/Para';\nimport Slot from 'rsg-components/Slot';\nimport PlaygroundRenderer from 'rsg-components/Playground/PlaygroundRenderer';\nimport Context, { StyleGuideContextContents } from 'rsg-components/Context';\nimport { EXAMPLE_TAB_CODE_EDITOR } from '../slots';\nimport { DisplayModes, ExampleModes } from '../../consts';\n\ninterface PlaygroundProps {\n\tevalInContext(code: string): () => any;\n\tindex: number;\n\tname?: string;\n\texampleMode?: string;\n\tcode: string;\n\tsettings: {\n\t\tshowcode?: boolean;\n\t\tnoeditor?: boolean;\n\t\tpadded?: boolean;\n\t\t// TODO: better typing for this\n\t\tprops?: any;\n\t};\n}\n\ninterface PlaygroundState {\n\tcode: string;\n\tprevCode: string;\n\tactiveTab?: string;\n}\n\nclass Playground extends Component<PlaygroundProps, PlaygroundState> {\n\tpublic static contextType = Context;\n\n\tprivate handleChange = debounce((code) => {\n\t\tthis.setState({\n\t\t\tcode,\n\t\t});\n\t}, (this.context as StyleGuideContextContents).config.previewDelay);\n\n\tpublic state: PlaygroundState = {\n\t\tcode: this.props.code,\n\t\tprevCode: this.props.code,\n\t\tactiveTab: this.getInitialActiveTab() ? EXAMPLE_TAB_CODE_EDITOR : undefined,\n\t};\n\n\tpublic static getDerivedStateFromProps(nextProps: PlaygroundProps, prevState: PlaygroundState) {\n\t\tconst { code } = nextProps;\n\t\tif (prevState.prevCode !== code) {\n\t\t\treturn {\n\t\t\t\tprevCode: code,\n\t\t\t\tcode,\n\t\t\t};\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic componentWillUnmount() {\n\t\t// Clear pending changes\n\t\tthis.handleChange.cancel();\n\t}\n\n\tprivate getInitialActiveTab(): boolean {\n\t\tconst expandCode = this.props.exampleMode === ExampleModes.expand;\n\t\treturn this.props.settings.showcode !== undefined ? this.props.settings.showcode : expandCode;\n\t}\n\n\tprivate handleTabChange = (name: string) => {\n\t\tthis.setState((state) => ({\n\t\t\tactiveTab: state.activeTab !== name ? name : undefined,\n\t\t}));\n\t};\n\n\tpublic render() {\n\t\tconst { code, activeTab } = this.state;\n\t\tconst { evalInContext, index, name, settings, exampleMode } = this.props;\n\t\tconst { displayMode } = this.context as StyleGuideContextContents;\n\t\tconst isExampleHidden = exampleMode === ExampleModes.hide;\n\t\tconst isEditorHidden = settings.noeditor || isExampleHidden;\n\t\tconst preview = <Preview code={code} evalInContext={evalInContext} />;\n\n\t\treturn isEditorHidden ? (\n\t\t\t<Para>{preview}</Para>\n\t\t) : (\n\t\t\t<PlaygroundRenderer\n\t\t\t\tname={name}\n\t\t\t\texampleIndex={index}\n\t\t\t\tpadded={!!settings.padded}\n\t\t\t\tpreview={preview}\n\t\t\t\tpreviewProps={settings.props || {}}\n\t\t\t\ttabButtons={\n\t\t\t\t\t<Slot\n\t\t\t\t\t\tname=\"exampleTabButtons\"\n\t\t\t\t\t\tactive={activeTab}\n\t\t\t\t\t\tprops={{ onClick: this.handleTabChange }}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\ttabBody={\n\t\t\t\t\t<Slot\n\t\t\t\t\t\tname=\"exampleTabs\"\n\t\t\t\t\t\tactive={activeTab}\n\t\t\t\t\t\tonlyActive\n\t\t\t\t\t\t// evalInContext passed through to support custom slots that eval code\n\t\t\t\t\t\tprops={{ code, onChange: this.handleChange, evalInContext }}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\ttoolbar={\n\t\t\t\t\t<Slot\n\t\t\t\t\t\tname=\"exampleToolbar\"\n\t\t\t\t\t\tprops={{ name, isolated: displayMode === DisplayModes.example, example: index }}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t);\n\t}\n}\n\nexport default Playground;\n"
  },
  {
    "path": "src/client/rsg-components/Playground/PlaygroundRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport cx from 'clsx';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ space, color, borderRadius }: Rsg.Theme) => ({\n\troot: {\n\t\tmarginBottom: space[4],\n\t},\n\tpreview: {\n\t\tpadding: space[2],\n\t\tborder: [[1, color.border, 'solid']],\n\t\tborderRadius,\n\t\t// the next 2 lines are required to contain floated components\n\t\twidth: '100%',\n\t\tdisplay: 'inline-block',\n\t},\n\tcontrols: {\n\t\tdisplay: 'flex',\n\t\talignItems: 'center',\n\t\tmarginBottom: space[1],\n\t},\n\ttoolbar: {\n\t\tmarginLeft: 'auto',\n\t},\n\ttab: {}, // expose className to allow using it in 'styles' settings\n\tpadded: {\n\t\t// add padding between each example element rendered\n\t\t'& > *': {\n\t\t\tisolate: false,\n\t\t\tmarginLeft: -space[1],\n\t\t\tmarginRight: -space[1],\n\t\t\t'& > *': {\n\t\t\t\tisolate: false,\n\t\t\t\tmarginRight: space[1],\n\t\t\t\tmarginLeft: space[1],\n\t\t\t},\n\t\t},\n\t},\n});\n\ninterface PlaygroundRendererProps extends JssInjectedProps {\n\texampleIndex: number;\n\tname?: string;\n\tpadded: boolean;\n\tpreview: React.ReactNode;\n\t// TODO: need to find a better type here too\n\tpreviewProps: any;\n\ttabButtons: React.ReactNode;\n\ttabBody: React.ReactNode;\n\ttoolbar: React.ReactNode;\n}\n\nexport const PlaygroundRenderer: React.FunctionComponent<PlaygroundRendererProps> = ({\n\tclasses,\n\texampleIndex,\n\tname,\n\tpadded,\n\tpreview,\n\tpreviewProps,\n\ttabButtons,\n\ttabBody,\n\ttoolbar,\n}) => {\n\tconst { className, ...props } = previewProps;\n\tconst previewClasses = cx(classes.preview, className, { [classes.padded]: padded });\n\treturn (\n\t\t<div className={classes.root} data-testid={`${name}-example-${exampleIndex}`}>\n\t\t\t<div className={previewClasses} {...props} data-preview={name} data-testid=\"preview-wrapper\">\n\t\t\t\t{preview}\n\t\t\t</div>\n\t\t\t<div className={classes.controls}>\n\t\t\t\t<div className={classes.tabs}>{tabButtons}</div>\n\t\t\t\t<div className={classes.toolbar}>{toolbar}</div>\n\t\t\t</div>\n\t\t\t<div className={classes.tab}>{tabBody}</div>\n\t\t</div>\n\t);\n};\n\nPlaygroundRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\texampleIndex: PropTypes.number.isRequired,\n\tname: PropTypes.string.isRequired,\n\tpadded: PropTypes.bool.isRequired,\n\tpreview: PropTypes.any.isRequired,\n\tpreviewProps: PropTypes.object.isRequired,\n\ttabButtons: PropTypes.any.isRequired,\n\ttabBody: PropTypes.any.isRequired,\n\ttoolbar: PropTypes.any.isRequired,\n};\n\nexport default Styled<PlaygroundRendererProps>(styles)(PlaygroundRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Playground/index.ts",
    "content": "export { default } from 'rsg-components/Playground/Playground';\n"
  },
  {
    "path": "src/client/rsg-components/PlaygroundError/PlaygroundError.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { PlaygroundErrorRenderer } from './PlaygroundErrorRenderer';\n\nit('renderer should render message', () => {\n\tconst message = 'Hello *world*!';\n\tconst renderer = createRenderer();\n\trenderer.render(<PlaygroundErrorRenderer classes={{}} message={message} />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/PlaygroundError/PlaygroundErrorRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ fontFamily, fontSize, color }: Rsg.Theme) => ({\n\troot: {\n\t\tmargin: 0,\n\t\tlineHeight: 1.2,\n\t\tfontSize: fontSize.small,\n\t\tfontFamily: fontFamily.monospace,\n\t\tcolor: color.error,\n\t\twhiteSpace: 'pre-wrap',\n\t},\n});\n\ninterface PlaygroundErrorProps extends JssInjectedProps {\n\tmessage: string;\n}\n\nexport const PlaygroundErrorRenderer: React.FunctionComponent<PlaygroundErrorProps> = ({\n\tclasses,\n\tmessage,\n}) => <pre className={classes.root}>{message}</pre>;\n\nPlaygroundErrorRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tmessage: PropTypes.string.isRequired,\n};\n\nexport default Styled<PlaygroundErrorProps>(styles)(PlaygroundErrorRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/PlaygroundError/__snapshots__/PlaygroundError.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render message 1`] = `\n<pre>\n  Hello *world*!\n</pre>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/PlaygroundError/index.ts",
    "content": "export { default } from 'rsg-components/PlaygroundError/PlaygroundErrorRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Preview/Preview.spec.tsx",
    "content": "import React from 'react';\nimport { render, waitFor } from '@testing-library/react';\nimport Preview from '.';\nimport Context, { StyleGuideContextContents } from '../Context';\n\n/* eslint-disable no-console */\n\nconst evalInContext = (a: string) =>\n\t// eslint-disable-next-line no-new-func\n\tnew Function('require', 'state', 'setState', 'const React = require(\"react\");' + a).bind(\n\t\tnull,\n\t\trequire\n\t);\nconst code = '<button>Code: OK</button>';\nconst newCode = '<button>Code: Cancel</button>';\n\nconst context = {\n\tconfig: {\n\t\tcompilerConfig: {},\n\t},\n\tcodeRevision: 0,\n} as StyleGuideContextContents;\n\nconst Provider = (props: Record<string, any>) => <Context.Provider value={context} {...props} />;\n\nconst console$error = console.error;\nconst console$clear = console.clear;\n\nafterEach(() => {\n\tconsole.error = console$error;\n\tconsole.clear = console$clear;\n});\n\nit('should unmount Wrapper component', async () => {\n\tconst { unmount, getByTestId } = render(\n\t\t<Provider>\n\t\t\t<Preview code={code} evalInContext={evalInContext} />\n\t\t</Provider>\n\t);\n\n\tconst node = getByTestId('mountNode');\n\n\texpect(node.innerHTML).toMatch('<button');\n\tunmount();\n\tawait waitFor(() => expect(node.innerHTML).toBe(''));\n});\n\nit('should not fail when Wrapper wasn’t mounted', () => {\n\tconst consoleError = jest.fn();\n\tconsole.error = consoleError;\n\n\tconst { unmount, getByTestId } = render(\n\t\t<Provider>\n\t\t\t<Preview code=\"pizza\" evalInContext={evalInContext} />\n\t\t</Provider>\n\t);\n\n\tconst node = getByTestId('mountNode');\n\n\texpect(\n\t\tconsoleError.mock.calls.find((call) =>\n\t\t\tcall[0].toString().includes('ReferenceError: pizza is not defined')\n\t\t)\n\t).toBeTruthy();\n\n\texpect(node.innerHTML).toBe('');\n\tunmount();\n\texpect(node.innerHTML).toBe('');\n});\n\nit('should wrap code in Fragment when it starts with <', () => {\n\tconsole.error = jest.fn();\n\n\tconst { queryAllByRole } = render(\n\t\t<Provider>\n\t\t\t<Preview code=\"<button /><button />\" evalInContext={evalInContext} />\n\t\t</Provider>\n\t);\n\n\t// If two buttons weren't wrapped in a Fragment, we'd see an error in console\n\texpect(console.error).not.toHaveBeenCalled();\n\texpect(queryAllByRole('button')).toHaveLength(2);\n});\n\nit('should update', () => {\n\tconst { rerender, getByText } = render(\n\t\t<Provider>\n\t\t\t<Preview code={code} evalInContext={evalInContext} />\n\t\t</Provider>\n\t);\n\n\texpect(getByText('Code: OK')).toBeInTheDocument();\n\n\trerender(\n\t\t<Provider>\n\t\t\t<Preview code={newCode} evalInContext={evalInContext} />\n\t\t</Provider>\n\t);\n\n\texpect(getByText('Code: Cancel')).toBeInTheDocument();\n});\n\nit('should handle no code', () => {\n\tconsole.error = jest.fn();\n\trender(\n\t\t<Provider>\n\t\t\t<Preview code=\"\" evalInContext={evalInContext} />\n\t\t</Provider>\n\t);\n\n\texpect(console.error).not.toHaveBeenCalled();\n});\n\nit('should handle errors', () => {\n\tconst consoleError = jest.fn();\n\n\tconsole.error = consoleError;\n\trender(\n\t\t<Provider>\n\t\t\t<Preview code={'<invalid code'} evalInContext={evalInContext} />\n\t\t</Provider>\n\t);\n\n\texpect(\n\t\tconsoleError.mock.calls.find((call) =>\n\t\t\tcall[0].toString().includes('SyntaxError: Unexpected token')\n\t\t)\n\t).toBeTruthy();\n});\n\nit('should not clear console on initial mount', () => {\n\tconsole.clear = jest.fn();\n\trender(\n\t\t<Provider>\n\t\t\t<Preview code={code} evalInContext={evalInContext} />\n\t\t</Provider>\n\t);\n\texpect(console.clear).toHaveBeenCalledTimes(0);\n});\n\nit('should clear console on second mount', () => {\n\tconsole.clear = jest.fn();\n\trender(\n\t\t<Provider value={{ ...context, codeRevision: 1 }}>\n\t\t\t<Preview code={code} evalInContext={evalInContext} />\n\t\t</Provider>\n\t);\n\texpect(console.clear).toHaveBeenCalledTimes(1);\n});\n"
  },
  {
    "path": "src/client/rsg-components/Preview/Preview.tsx",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport PlaygroundError from 'rsg-components/PlaygroundError';\nimport ReactExample from 'rsg-components/ReactExample';\nimport Context, { StyleGuideContextContents } from 'rsg-components/Context';\nimport { createRoot, Root } from 'react-dom/client';\n\nconst improveErrorMessage = (message: string) =>\n\tmessage.replace(\n\t\t'Check the render method of `StateHolder`.',\n\t\t'Check the code of your example in a Markdown file or in the editor below.'\n\t);\n\ninterface PreviewProps {\n\tcode: string;\n\tevalInContext(code: string): () => any;\n}\n\ninterface PreviewState {\n\terror: string | null;\n}\n\nexport default class Preview extends Component<PreviewProps, PreviewState> {\n\tpublic static propTypes = {\n\t\tcode: PropTypes.string.isRequired,\n\t\tevalInContext: PropTypes.func.isRequired,\n\t};\n\tpublic static contextType = Context;\n\n\tprivate mountNode: Element | null = null;\n\tprivate reactRoot: Root | null = null;\n\tprivate timeoutId: number | null = null;\n\n\tpublic state: PreviewState = {\n\t\terror: null,\n\t};\n\n\tpublic componentDidMount() {\n\t\t// Clear console after hot reload, do not clear on the first load\n\t\t// to keep any warnings\n\t\tif ((this.context as StyleGuideContextContents).codeRevision > 0) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.clear();\n\t\t}\n\n\t\tthis.executeCode();\n\t}\n\n\tpublic shouldComponentUpdate(nextProps: PreviewProps, nextState: PreviewState) {\n\t\treturn this.state.error !== nextState.error || this.props.code !== nextProps.code;\n\t}\n\n\tpublic componentDidUpdate(prevProps: PreviewProps) {\n\t\tif (this.props.code !== prevProps.code) {\n\t\t\tthis.executeCode();\n\t\t}\n\t}\n\n\tpublic componentWillUnmount() {\n\t\tthis.unmountPreview();\n\t}\n\n\tpublic unmountPreview() {\n\t\tconst self = this;\n\t\tif (self.timeoutId) {\n\t\t\tclearTimeout(self.timeoutId);\n\t\t}\n\t\tconst id = setTimeout(() => {\n\t\t\tif (self.reactRoot) {\n\t\t\t\tself.reactRoot.unmount();\n\t\t\t\tself.reactRoot = null;\n\t\t\t}\n\t\t});\n\t\tself.timeoutId = id;\n\t}\n\n\tprivate executeCode() {\n\t\tthis.setState({\n\t\t\terror: null,\n\t\t});\n\n\t\tconst { code } = this.props;\n\t\tif (!code) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst wrappedComponent: React.FunctionComponentElement<any> = (\n\t\t\t<ReactExample\n\t\t\t\tcode={code}\n\t\t\t\tevalInContext={this.props.evalInContext}\n\t\t\t\tonError={this.handleError}\n\t\t\t\tcompilerConfig={(this.context as StyleGuideContextContents).config.compilerConfig}\n\t\t\t/>\n\t\t);\n\n\t\t/* istanbul ignore next */\n\t\twindow.requestAnimationFrame(() => {\n\t\t\tif (!this.mountNode) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tif (this.reactRoot === null) {\n\t\t\t\t\tthis.reactRoot = createRoot(this.mountNode);\n\t\t\t\t\tthis.reactRoot.render(wrappedComponent);\n\t\t\t\t} else {\n\t\t\t\t\tthis.reactRoot.render(wrappedComponent);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\tthis.handleError(err);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate handleError = (err: Error) => {\n\t\tthis.unmountPreview();\n\n\t\tthis.setState({\n\t\t\terror: improveErrorMessage(err.toString()),\n\t\t});\n\n\t\tconsole.error(err); // eslint-disable-line no-console\n\t};\n\n\tprivate callbackRef = (ref: HTMLDivElement | null) => {\n\t\tthis.mountNode = ref;\n\t\tif (!this.reactRoot && ref) {\n\t\t\tthis.reactRoot = createRoot(ref);\n\t\t}\n\t};\n\n\tpublic render() {\n\t\tconst { error } = this.state;\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<div data-testid=\"mountNode\" ref={this.callbackRef} />\n\t\t\t\t{error && <PlaygroundError message={error} />}\n\t\t\t</>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "src/client/rsg-components/Preview/index.ts",
    "content": "export { default } from 'rsg-components/Preview/Preview';\n"
  },
  {
    "path": "src/client/rsg-components/Props/Props.spec.tsx",
    "content": "/* eslint-disable react/prop-types */\nimport React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { parse } from 'react-docgen';\nimport PropsRenderer, { columns, getRowKey } from './PropsRenderer';\nimport { unquote, getType, showSpaces, PropDescriptor } from './util';\n\nconst propsToArray = (props: any) => Object.keys(props).map(name => ({ ...props[name], name }));\n\nconst getText = (node: { innerHTML: string }): string =>\n\tnode.innerHTML\n\t\t.replace(/<\\/?(div|li|p).*?>/g, '\\n')\n\t\t.replace(/<.*?>/g, ' ')\n\t\t.replace(/[\\r\\n]+/g, '\\n')\n\t\t.replace(/ +/g, ' ')\n\t\t.trim();\n\n// Test renderers with clean readable snapshot diffs\nexport default function ColumnsRenderer({ props }: { props: PropDescriptor[] }) {\n\treturn (\n\t\t<>\n\t\t\t{props.map((row, rowIdx) => (\n\t\t\t\t<React.Fragment key={rowIdx}>\n\t\t\t\t\t{columns.map((col, colIdx) => (\n\t\t\t\t\t\t<div key={colIdx}>\n\t\t\t\t\t\t\t{col.caption}: {col.render(row)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</React.Fragment>\n\t\t\t))}\n\t\t</>\n\t);\n}\n\nfunction renderJs(propTypes: string[], defaultProps: string[] = []) {\n\tconst props = parse(\n\t\t`\n\t\timport { Component } from 'react';\n\t\timport PropTypes from 'prop-types';\n\t\texport default class Cmpnt extends Component {\n\t\t\tstatic propTypes = {\n\t\t\t\t${propTypes.join(',')}\n\t\t\t}\n\t\t\tstatic defaultProps = {\n\t\t\t\t${defaultProps.join(',')}\n\t\t\t}\n\t\t\trender() {\n\t\t\t}\n\t\t}\n\t`,\n\t\tundefined,\n\t\tundefined,\n\t\t{ filename: '' }\n\t);\n\tif (Array.isArray(props)) {\n\t\treturn render(<div />);\n\t}\n\treturn render(<ColumnsRenderer props={propsToArray(props.props)} />);\n}\n\nfunction renderFlow(propsType: string[], defaultProps: string[] = [], preparations: string[] = []) {\n\tconst props = parse(\n\t\t`\n\t\t// @flow\n\t\timport * as React from 'react';\n\t\t${preparations.join(';')}\n\t\ttype Props = {\n\t\t\t${propsType.join(',')}\n\t\t};\n\t\texport default class Cmpnt extends React.Component<Props> {\n\t\t\tstatic defaultProps = {\n\t\t\t\t${defaultProps.join(',')}\n\t\t\t}\n\t\t\trender() {\n\t\t\t}\n\t\t}\n\t`,\n\t\tundefined,\n\t\tundefined,\n\t\t{ filename: '' }\n\t);\n\tif (Array.isArray(props)) {\n\t\treturn render(<div />);\n\t}\n\treturn render(<ColumnsRenderer props={propsToArray(props.props)} />);\n}\n\nfunction renderTypeScript(\n\tpropsType: string[],\n\tdefaultProps: string[] = [],\n\tpreparations: string[] = []\n) {\n\tconst props = parse(\n\t\t`\n\t\timport * as React from 'react';\n\t\t${preparations.join(';')}\n\t\ttype Props = {\n\t\t\t${propsType.join(';')}\n\t\t};\n\t\texport default class Cmpnt extends React.Component<Props> {\n\t\t\tstatic defaultProps = {\n\t\t\t\t${defaultProps.join(',')}\n\t\t\t}\n\t\t\trender() {\n\t\t\t}\n\t\t}\n\t`,\n\t\tundefined,\n\t\tundefined,\n\t\t{ filename: 'Component.tsx' }\n\t);\n\tif (Array.isArray(props)) {\n\t\treturn render(<div />);\n\t}\n\treturn render(<ColumnsRenderer props={propsToArray(props.props)} />);\n}\n\ndescribe('PropsRenderer', () => {\n\ttest('should render a table', async () => {\n\t\tconst { findAllByRole } = render(\n\t\t\t<PropsRenderer\n\t\t\t\tprops={[\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'color',\n\t\t\t\t\t\ttype: { name: 'string' },\n\t\t\t\t\t\trequired: false,\n\t\t\t\t\t\tdefaultValue: { value: 'tomato' },\n\t\t\t\t\t\tdescription: 'Butiful',\n\t\t\t\t\t},\n\t\t\t\t]}\n\t\t\t/>\n\t\t);\n\t\texpect((await findAllByRole('columnheader')).map(node => node.textContent)).toEqual([\n\t\t\t'Prop name',\n\t\t\t'Type',\n\t\t\t'Default',\n\t\t\t'Description',\n\t\t]);\n\t\texpect((await findAllByRole('cell')).map(node => node.textContent)).toEqual([\n\t\t\t'color',\n\t\t\t'string',\n\t\t\t'tomato',\n\t\t\t'Butiful',\n\t\t]);\n\t});\n});\n\ndescribe('props columns', () => {\n\ttest('should render PropTypes.string', () => {\n\t\tconst { container } = renderJs(['color: PropTypes.string']);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: color \n\t\tType: string \n\t\tDefault: \n\t\tDescription:\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.string with a default value', () => {\n\t\tconst { container } = renderJs(['color: PropTypes.string'], ['color: \"pink\"']);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: color \n\t\tType: string \n\t\tDefault: pink \n\t\tDescription:\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.string.isRequired', () => {\n\t\tconst { container } = renderJs(['color: PropTypes.string.isRequired']);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: color \n\t\tType: string \n\t\tDefault: Required \n\t\tDescription:\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.arrayOf', () => {\n\t\tconst { container } = renderJs(['colors: PropTypes.arrayOf(PropTypes.string)']);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: colors \n\t\tType: string[] \n\t\tDefault: \n\t\tDescription:\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.arrayOf(PropTypes.shape)', () => {\n\t\tconst { container } = renderJs([\n\t\t\t'foos: PropTypes.arrayOf(PropTypes.shape({bar: PropTypes.number, baz: PropTypes.any}))',\n\t\t]);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: foos \n\t\tType: shape[] \n\t\tDefault: \n\t\tDescription: \n\t\t bar : number \n\t\t baz : any\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.arrayOf(PropTypes.exact)', () => {\n\t\tconst { container } = renderJs([\n\t\t\t'foos: PropTypes.arrayOf(PropTypes.exact({bar: PropTypes.number, baz: PropTypes.any}))',\n\t\t]);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: foos \n\t\tType: exact[] \n\t\tDefault: \n\t\tDescription: \n\t\t bar : number \n\t\t baz : any\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.instanceOf', () => {\n\t\tconst { container } = renderJs(['num: PropTypes.instanceOf(Number)']);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: num \n\t\tType: Number \n\t\tDefault: \n\t\tDescription:\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.shape', () => {\n\t\tconst { container } = renderJs([\n\t\t\t'foo: PropTypes.shape({bar: PropTypes.number.isRequired, baz: PropTypes.any})',\n\t\t]);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: foo \n\t\tType: shape \n\t\tDefault: \n\t\tDescription: \n\t\t bar : number — Required \n\t\t baz : any\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.exact', () => {\n\t\tconst { container } = renderJs([\n\t\t\t'foo: PropTypes.exact({bar: PropTypes.number.isRequired, baz: PropTypes.any})',\n\t\t]);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: foo \n\t\tType: exact \n\t\tDefault: \n\t\tDescription: \n\t\t bar : number — Required \n\t\t baz : any\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.shape with formatted defaultProps', () => {\n\t\tconst { getByText } = renderJs(\n\t\t\t[\n\t\t\t\t`\n\t\t\t\tfoo: PropTypes.shape({\n\t\t\t\t\tbar: PropTypes.number.isRequired,\n\t\t\t\t\tbaz: PropTypes.any,\n\t\t\t\t})\n\t\t\t`,\n\t\t\t],\n\t\t\t[\n\t\t\t\t`\n\t\t\t\tfoo: {\n\t\t\t\t\tbar: 123, baz() {\n\t\t\t\t\t\treturn 'foo';\n\t\t\t\t\t},\n\t\t\t\t\tbing() {\n\t\t\t\t\t\treturn 'badaboom';\n\t\t\t\t\t},\n\t\t\t\t\ttrotskij: () => 1935,\n\t\t\t\t\tqwarc: { si: 'señor', },\n\t\t\t\t}\n\t\t\t`,\n\t\t\t]\n\t\t);\n\n\t\texpect(getByText('Shape').title).toMatchInlineSnapshot(`\n\t\t\"{\n\t\t  \\\\\"bar\\\\\": 123,\n\t\t  \\\\\"qwarc\\\\\": {\n\t\t    \\\\\"si\\\\\": \\\\\"señor\\\\\"\n\t\t  }\n\t\t}\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.shape defaultProps, falling back to Object', () => {\n\t\tconst { container, getByText } = renderJs(\n\t\t\t[\n\t\t\t\t`\n\t\t\t\tfoo: PropTypes.shape({\n\t\t\t\t\tbar: PropTypes.number.isRequired,\n\t\t\t\t\tbaz: PropTypes.any,\n\t\t\t\t})\n\t\t\t`,\n\t\t\t],\n\t\t\t[\n\t\t\t\t`\n\t\t\t\tfoo: somethingThatDoesntExist\n\t\t\t`,\n\t\t\t]\n\t\t);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: foo \n\t\tType: shape \n\t\tDefault: Shape \n\t\tDescription: \n\t\t bar : number — Required \n\t\t baz : any\"\n\t`);\n\n\t\t// FIXME: This doesn't look correct, where's foo?\n\t\texpect(getByText('Shape').title).toMatchInlineSnapshot(`\"somethingThatDoesntExist\"`);\n\t});\n\n\ttest('should render PropTypes.shape with description', () => {\n\t\tconst { container } = renderJs([\n\t\t\t`foo: PropTypes.shape({\n\t\t\t/**\n\t\t\t * Number\n\t\t\t */\n\t\t\tbar: PropTypes.number.isRequired,\n\t\t\t/** Any */\n\t\t\tbaz: PropTypes.any\n\t\t})`,\n\t\t]);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: foo \n\t\tType: shape \n\t\tDefault: \n\t\tDescription: \n\t\t bar : number — Required — Number \n\t\t baz : any — Any\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.exact with description', () => {\n\t\tconst { container } = renderJs([\n\t\t\t`foo: PropTypes.exact({\n\t\t\t/**\n\t\t\t * Number\n\t\t\t */\n\t\t\tbar: PropTypes.number.isRequired,\n\t\t\t/** Any */\n\t\t\tbaz: PropTypes.any\n\t\t})`,\n\t\t]);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: foo \n\t\tType: exact \n\t\tDefault: \n\t\tDescription: \n\t\t bar : number — Required — Number \n\t\t baz : any — Any\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.objectOf', () => {\n\t\tconst { container } = renderJs(['colors: PropTypes.objectOf(PropTypes.string)']);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: colors \n\t\tType: {string} \n\t\tDefault: \n\t\tDescription:\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.objectOf(PropTypes.shape)', () => {\n\t\tconst { container } = renderJs([\n\t\t\t`colors: PropTypes.objectOf(\n\t\t\tPropTypes.shape({\n\t\t\t\tbar: PropTypes.number.isRequired,\n\t\t\t\tbaz: PropTypes.any\n\t\t\t})\n\t\t)`,\n\t\t]);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: colors \n\t\tType: {shape} \n\t\tDefault: \n\t\tDescription: \n\t\t bar : number — Required \n\t\t baz : any\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.objectOf(PropTypes.exact)', () => {\n\t\tconst { container } = renderJs([\n\t\t\t`colors: PropTypes.objectOf(\n\t\t\tPropTypes.exact({\n\t\t\t\tbar: PropTypes.number.isRequired,\n\t\t\t\tbaz: PropTypes.any\n\t\t\t})\n\t\t)`,\n\t\t]);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: colors \n\t\tType: {exact} \n\t\tDefault: \n\t\tDescription: \n\t\t bar : number — Required \n\t\t baz : any\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.oneOf', () => {\n\t\tconst { container } = renderJs(['size: PropTypes.oneOf([\"small\", \"normal\", \"large\"])']);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: size \n\t\tType: enum \n\t\tDefault: \n\t\tDescription: \n\t\t One of: small , normal , large\"\n\t`);\n\t});\n\n\ttest('should render PropTypes.oneOfType', () => {\n\t\tconst { container } = renderJs([\n\t\t\t'union: PropTypes.oneOfType([PropTypes.string, PropTypes.number])',\n\t\t]);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: union \n\t\tType: union \n\t\tDefault: \n\t\tDescription: \n\t\t One of type: string , number\"\n\t`);\n\t});\n\n\ttest('should render description in Markdown', () => {\n\t\tconst { container } = renderJs(['/**\\n * Label\\n */\\ncolor: PropTypes.string']);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: color \n\t\tType: string \n\t\tDefault: \n\t\tDescription: \n\t\tLabel\"\n\t`);\n\t});\n\n\ttest('should render unknown proptype for a prop when a relevant proptype is not assigned', () => {\n\t\tconst { container } = renderJs([], ['color: \"pink\"']);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: color \n\t\tType: \n\t\tDefault: pink \n\t\tDescription:\"\n\t`);\n\t});\n\n\ttest('should render function body in tooltip', () => {\n\t\tconst { getByText } = renderJs(['fn: PropTypes.func'], ['fn: (e) => console.log(e)']);\n\n\t\texpect(getByText('Function').title).toMatchInlineSnapshot(`\"(e) => console.log(e)\"`);\n\t});\n\n\ttest('should render function defaultValue as code when undefined', () => {\n\t\tconst { container } = renderJs(['fn: PropTypes.func'], ['fn: undefined']);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: fn \n\t\tType: func \n\t\tDefault: undefined \n\t\tDescription:\"\n\t`);\n\t});\n\n\ttest('should render function defaultValue as code when null', () => {\n\t\tconst { container } = renderJs(['fn: PropTypes.func'], ['fn: null']);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: fn \n\t\tType: func \n\t\tDefault: null \n\t\tDescription:\"\n\t`);\n\t});\n\n\ttest('should render arguments from JsDoc tags', () => {\n\t\tconst props: any = [\n\t\t\t{\n\t\t\t\tname: 'size',\n\t\t\t\ttype: {\n\t\t\t\t\tname: 'number',\n\t\t\t\t},\n\t\t\t\trequired: false,\n\t\t\t\tdescription: 'Test description',\n\t\t\t\ttags: {\n\t\t\t\t\targ: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Foo',\n\t\t\t\t\t\t\tdescription: 'Converts foo to bar',\n\t\t\t\t\t\t\ttype: { type: 'NameExpression', name: 'Array' },\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tparam: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Bar',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\t\tconst { container } = render(<ColumnsRenderer props={props} />);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: size \n\t\tType: number \n\t\tDefault: \n\t\tDescription: \n\t\tTest description\n\t\t Arguments \n\t\t Foo : Array — Converts foo to bar Bar\"\n\t`);\n\t});\n\n\ttest('should render return from JsDoc tags', () => {\n\t\tconst getProps = (tag: string): any => [\n\t\t\t{\n\t\t\t\tname: 'size',\n\t\t\t\ttype: {\n\t\t\t\t\tname: 'number',\n\t\t\t\t},\n\t\t\t\trequired: false,\n\t\t\t\tdescription: 'Test description',\n\t\t\t\ttags: {\n\t\t\t\t\t[tag]: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttitle: 'Foo',\n\t\t\t\t\t\t\tdescription: 'Returns foo from bar',\n\t\t\t\t\t\t\ttype: { type: 'NameExpression', name: 'Array' },\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\tconst { container: returnContainer } = render(<ColumnsRenderer props={getProps('return')} />);\n\n\t\texpect(getText(returnContainer)).toMatchInlineSnapshot(`\n\t\t\"Prop name: size \n\t\tType: number \n\t\tDefault: \n\t\tDescription: \n\t\tTest description\n\t\tReturns Array — Returns foo from bar\"\n\t`);\n\n\t\tconst { container: returnsContainer } = render(<ColumnsRenderer props={getProps('returns')} />);\n\n\t\texpect(getText(returnsContainer)).toMatchInlineSnapshot(`\n\t\t\"Prop name: size \n\t\tType: number \n\t\tDefault: \n\t\tDescription: \n\t\tTest description\n\t\tReturns Array — Returns foo from bar\"\n\t`);\n\t});\n\n\ttest('should render name as deprecated when tag deprecated is present', () => {\n\t\tconst props: any[] = [\n\t\t\t{\n\t\t\t\tname: 'size',\n\t\t\t\ttype: {\n\t\t\t\t\tname: 'number',\n\t\t\t\t},\n\t\t\t\trequired: false,\n\t\t\t\tdescription: 'Test description',\n\t\t\t\ttags: {\n\t\t\t\t\tdeprecated: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttitle: 'deprecated',\n\t\t\t\t\t\t\tdescription: 'Do not use.',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\t\tconst { container } = render(<ColumnsRenderer props={props} />);\n\n\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\"Prop name: size \n\t\tType: number \n\t\tDefault: \n\t\tDescription: \n\t\tTest description\n\t\t Deprecated: Do not use.\"\n\t`);\n\t});\n\n\tdescribe.each([\n\t\t[\n\t\t\t'flowType',\n\t\t\trenderFlow,\n\t\t\t{ enum: { declaration: \"type MyEnum = 'One' | 'Two'\", expect: { type: 'enum' } } },\n\t\t],\n\t\t[\n\t\t\t'TypeScript',\n\t\t\trenderTypeScript,\n\t\t\t{ enum: { declaration: 'enum MyEnum { One, Two }', expect: { type: 'MyEnum' } } },\n\t\t],\n\t])('%s', (_, renderFn, options) => {\n\t\ttest('should render type string', () => {\n\t\t\tconst { container } = renderFn(['foo: string']);\n\n\t\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\t\"Prop name: foo \n\t\t\tType: string \n\t\t\tDefault: Required \n\t\t\tDescription:\"\n\t\t`);\n\t\t});\n\n\t\ttest('should render optional type string', () => {\n\t\t\tconst { container } = renderFn(['foo?: string']);\n\n\t\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\t\"Prop name: foo \n\t\t\tType: string \n\t\t\tDefault: \n\t\t\tDescription:\"\n\t\t`);\n\t\t});\n\n\t\ttest('should render type string with a default value', () => {\n\t\t\tconst { container } = renderFn(['foo?: string'], ['foo: \"bar\"']);\n\n\t\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\t\"Prop name: foo \n\t\t\tType: string \n\t\t\tDefault: bar \n\t\t\tDescription:\"\n\t\t`);\n\t\t});\n\n\t\ttest('should render object type with body in tooltip', () => {\n\t\t\tconst { container, getByRole } = renderFn(['foo: { bar: string }']);\n\t\t\tfireEvent.focus(getByRole('button'));\n\n\t\t\texpect(getByRole('button')).toHaveTextContent('object');\n\t\t\texpect(container.querySelector('[data-tippy-root]')).toHaveTextContent('{ bar: string }');\n\t\t});\n\n\t\ttest('should render function type with body in tooltip', () => {\n\t\t\tconst { container, getByRole } = renderFn(['foo: () => void']);\n\t\t\tfireEvent.focus(getByRole('button'));\n\n\t\t\texpect(getByRole('button')).toHaveTextContent('function');\n\t\t\texpect(container.querySelector('[data-tippy-root]')).toHaveTextContent('() => void');\n\t\t});\n\n\t\ttest('should render union type with body in tooltip', () => {\n\t\t\tconst { container, getByRole } = renderFn(['foo: \"bar\" | number']);\n\t\t\tfireEvent.focus(getByRole('button'));\n\n\t\t\texpect(getByRole('button')).toHaveTextContent('union');\n\t\t\texpect(container.querySelector('[data-tippy-root]')).toHaveTextContent('\"bar\" | number');\n\t\t});\n\n\t\ttest('should render enum type', () => {\n\t\t\tconst { container } = renderFn(['foo: MyEnum'], [], [options.enum.declaration]);\n\t\t\tif (options.enum.expect.type === 'enum') {\n\t\t\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\t\t\t\"Prop name: foo \n\t\t\t\t\tType: ${options.enum.expect.type} \n\t\t\t\t\tDefault: Required \n\t\t\t\t\tDescription: \n\t\t\t\t\t One of: One , Two\"\n\t\t\t\t`);\n\t\t\t} else {\n\t\t\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\t\t\t\"Prop name: foo \n\t\t\t\t\tType: ${options.enum.expect.type} \n\t\t\t\t\tDefault: Required \n\t\t\t\t\tDescription:\"\n\t\t\t\t`);\n\t\t\t}\n\t\t});\n\n\t\ttest('should render tuple type with body in tooltip', () => {\n\t\t\tconst { container, getByRole } = renderFn(['foo: [\"bar\", number]']);\n\n\t\t\tfireEvent.focus(getByRole('button'));\n\n\t\t\texpect(getByRole('button')).toHaveTextContent('tuple');\n\t\t\texpect(container.querySelector('[data-tippy-root]')).toHaveTextContent('[\"bar\", number]');\n\t\t});\n\n\t\ttest('should render custom class type', () => {\n\t\t\tconst { container } = renderFn(['foo: React.ReactNode']);\n\n\t\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\t\"Prop name: foo \n\t\t\tType: React.ReactNode \n\t\t\tDefault: Required \n\t\t\tDescription:\"\n\t\t`);\n\t\t});\n\n\t\ttest('should render unknown when a relevant prop type is not assigned', () => {\n\t\t\tconst { container } = renderFn([], ['color: \"pink\"']);\n\n\t\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\t\"Prop name: color \n\t\t\tType: \n\t\t\tDefault: pink \n\t\t\tDescription:\"\n\t\t`);\n\t\t});\n\n\t\ttest('should render literal type', () => {\n\t\t\tconst { container } = renderFn(['foo: 1']);\n\n\t\t\texpect(getText(container)).toMatchInlineSnapshot(`\n\t\t\t\"Prop name: foo \n\t\t\tType: 1 \n\t\t\tDefault: Required \n\t\t\tDescription:\"\n\t\t`);\n\t\t});\n\t});\n});\n\ndescribe('unquote', () => {\n\ttest('should remove double quotes around the string', () => {\n\t\tconst result = unquote('\"foo\"');\n\t\texpect(result).toBe('foo');\n\t});\n\n\ttest('should remove single quotes around the string', () => {\n\t\tconst result = unquote(\"'foo'\");\n\t\texpect(result).toBe('foo');\n\t});\n\n\ttest('should not remove quotes in the middle of the string', () => {\n\t\tconst result = unquote('foo\"bar');\n\t\texpect(result).toBe('foo\"bar');\n\t});\n});\n\ndescribe('getType', () => {\n\ttest('should return not .type but .flowType property', () => {\n\t\tconst result = getType({\n\t\t\ttype: 'foo',\n\t\t\tflowType: 'bar',\n\t\t} as any);\n\t\texpect(result).toBe('bar');\n\t});\n\n\ttest('should return not .type but .tsType property', () => {\n\t\tconst result = getType({\n\t\t\ttype: 'foo',\n\t\t\ttsType: 'bar',\n\t\t} as any);\n\t\texpect(result).toBe('bar');\n\t});\n\n\ttest('should return .type property', () => {\n\t\tconst result = getType({\n\t\t\ttype: 'foo',\n\t\t} as any);\n\t\texpect(result).toBe('foo');\n\t});\n});\n\ndescribe('showSpaces', () => {\n\ttest('should replace leading and trailing spaces with a visible character', () => {\n\t\tconst result = showSpaces(' pizza ');\n\t\texpect(result).toBe('␣pizza␣');\n\t});\n});\n\ndescribe('getRowKey', () => {\n\ttest('should return type name', () => {\n\t\tconst result = getRowKey({ name: 'number' });\n\t\texpect(result).toBe('number');\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Props/PropsRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Arguments from 'rsg-components/Arguments';\nimport Argument from 'rsg-components/Argument';\nimport JsDoc from 'rsg-components/JsDoc';\nimport Markdown from 'rsg-components/Markdown';\nimport Name from 'rsg-components/Name';\nimport Para from 'rsg-components/Para';\nimport Table from 'rsg-components/Table';\nimport renderTypeColumn from './renderType';\nimport renderExtra from './renderExtra';\nimport renderDefault from './renderDefault';\nimport { PropDescriptor } from './util';\n\nfunction renderDescription(prop: PropDescriptor) {\n\tconst { description, tags = {} } = prop;\n\tconst extra = renderExtra(prop);\n\tconst args = [...(tags.arg || []), ...(tags.argument || []), ...(tags.param || [])];\n\tconst returnDocumentation = (tags.return && tags.return[0]) || (tags.returns && tags.returns[0]);\n\n\treturn (\n\t\t<div>\n\t\t\t{description && <Markdown text={description} />}\n\t\t\t{extra && <Para>{extra}</Para>}\n\t\t\t<JsDoc {...tags} />\n\t\t\t{args.length > 0 && <Arguments args={args} heading />}\n\t\t\t{returnDocumentation && <Argument {...{ ...returnDocumentation, name: '' }} returns />}\n\t\t</div>\n\t);\n}\n\nfunction renderName(prop: PropDescriptor) {\n\tconst { name, tags = {} } = prop;\n\treturn <Name deprecated={!!tags.deprecated}>{name}</Name>;\n}\n\nexport function getRowKey(row: { name: string }) {\n\treturn row.name;\n}\n\nexport const columns = [\n\t{\n\t\tcaption: 'Prop name',\n\t\trender: renderName,\n\t},\n\t{\n\t\tcaption: 'Type',\n\t\trender: renderTypeColumn,\n\t},\n\t{\n\t\tcaption: 'Default',\n\t\trender: renderDefault,\n\t},\n\t{\n\t\tcaption: 'Description',\n\t\trender: renderDescription,\n\t},\n];\n\ninterface PropsProps {\n\tprops: PropDescriptor[];\n}\n\nconst PropsRenderer: React.FunctionComponent<PropsProps> = ({ props }) => {\n\treturn <Table columns={columns} rows={props} getRowKey={getRowKey} />;\n};\n\nPropsRenderer.propTypes = {\n\tprops: PropTypes.array.isRequired,\n};\n\nexport default PropsRenderer;\n"
  },
  {
    "path": "src/client/rsg-components/Props/index.ts",
    "content": "export { default } from 'rsg-components/Props/PropsRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Props/renderDefault.tsx",
    "content": "import React from 'react';\nimport Text from 'rsg-components/Text';\nimport Code from 'rsg-components/Code';\nimport { showSpaces, unquote, PropDescriptor } from './util';\n\nconst defaultValueBlacklist = ['null', 'undefined'];\n\nexport default function renderDefault(prop: PropDescriptor): React.ReactNode {\n\t// Workaround for issue https://github.com/reactjs/react-docgen/issues/221\n\t// If prop has defaultValue it can not be required\n\tif (prop.defaultValue) {\n\t\tconst defaultValueString = showSpaces(unquote(String(prop.defaultValue.value)));\n\t\tif (prop.type || prop.flowType || prop.tsType) {\n\t\t\tconst propName = prop.type\n\t\t\t\t? prop.type.name\n\t\t\t\t: prop.flowType\n\t\t\t\t? prop.flowType.type\n\t\t\t\t: prop.tsType && prop.tsType.type;\n\n\t\t\tif (defaultValueBlacklist.indexOf(prop.defaultValue.value) > -1) {\n\t\t\t\treturn <Code>{defaultValueString}</Code>;\n\t\t\t} else if (propName === 'func' || propName === 'function') {\n\t\t\t\treturn (\n\t\t\t\t\t<Text size=\"small\" color=\"light\" underlined title={defaultValueString}>\n\t\t\t\t\t\tFunction\n\t\t\t\t\t</Text>\n\t\t\t\t);\n\t\t\t} else if (propName === 'shape' || propName === 'object') {\n\t\t\t\ttry {\n\t\t\t\t\t// We eval source code to be able to format the defaultProp here. This\n\t\t\t\t\t// can be considered safe, as it is the source code that is evaled,\n\t\t\t\t\t// which is from a known source and safe by default\n\t\t\t\t\t// eslint-disable-next-line no-eval\n\t\t\t\t\tconst object = eval(`(${prop.defaultValue.value})`);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Text size=\"small\" color=\"light\" underlined title={JSON.stringify(object, null, 2)}>\n\t\t\t\t\t\t\tShape\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t);\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// eval will throw if it contains a reference to a property not in the\n\t\t\t\t\t// local scope. To avoid any breakage we fall back to rendering the\n\t\t\t\t\t// prop without any formatting\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Text size=\"small\" color=\"light\" underlined title={prop.defaultValue.value}>\n\t\t\t\t\t\t\tShape\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn <Code>{defaultValueString}</Code>;\n\t} else if (prop.required) {\n\t\treturn (\n\t\t\t<Text size=\"small\" color=\"light\">\n\t\t\t\tRequired\n\t\t\t</Text>\n\t\t);\n\t}\n\treturn '';\n}\n"
  },
  {
    "path": "src/client/rsg-components/Props/renderExtra.tsx",
    "content": "import React from 'react';\nimport Group from 'react-group';\nimport Type from 'rsg-components/Type';\nimport Code from 'rsg-components/Code';\nimport Name from 'rsg-components/Name';\nimport Markdown from 'rsg-components/Markdown';\nimport { PropTypeDescriptor } from 'react-docgen';\n\nimport { unquote, getType, showSpaces, PropDescriptor, TypeDescriptor } from './util';\nimport renderDefault from './renderDefault';\nimport { renderType } from './renderType';\n\nfunction renderEnum(type: PropTypeDescriptor | TypeDescriptor): React.ReactNode {\n\tif (!Array.isArray(type.value)) {\n\t\treturn <span>{type.value}</span>;\n\t}\n\n\tconst values = type.value.map(({ value }) => (\n\t\t<Code key={value}>{showSpaces(unquote(value))}</Code>\n\t));\n\treturn (\n\t\t<span>\n\t\t\tOne of: <Group separator=\", \">{values}</Group>\n\t\t</span>\n\t);\n}\n\nfunction renderUnion(type: PropTypeDescriptor | TypeDescriptor): React.ReactNode {\n\tif (!Array.isArray(type.value)) {\n\t\treturn <span>{type.value}</span>;\n\t}\n\n\tconst values = type.value.map((value, index) => (\n\t\t<Type key={`${value.name}-${index}`}>{renderType(value)}</Type>\n\t));\n\treturn (\n\t\t<span>\n\t\t\tOne of type: <Group separator=\", \">{values}</Group>\n\t\t</span>\n\t);\n}\n\nfunction renderShape(props: Record<string, PropDescriptor>) {\n\treturn Object.keys(props).map(name => {\n\t\tconst prop = props[name];\n\t\tconst defaultValue = renderDefault(prop);\n\t\tconst description = prop.description;\n\t\treturn (\n\t\t\t<div key={name}>\n\t\t\t\t<Name>{name}</Name>\n\t\t\t\t{': '}\n\t\t\t\t<Type>{renderType(prop)}</Type>\n\t\t\t\t{defaultValue && ' — '}\n\t\t\t\t{defaultValue}\n\t\t\t\t{description && ' — '}\n\t\t\t\t{description && <Markdown text={description} inline />}\n\t\t\t</div>\n\t\t);\n\t});\n}\n\nexport default function renderExtra(prop: PropDescriptor): React.ReactNode {\n\tconst type = getType(prop);\n\tif (!type) {\n\t\treturn null;\n\t}\n\tswitch (type.name) {\n\t\tcase 'enum':\n\t\t\treturn renderEnum(type);\n\t\tcase 'union':\n\t\t\treturn renderUnion(type);\n\t\tcase 'shape':\n\t\t\treturn prop.type && renderShape(prop.type.value);\n\t\tcase 'exact':\n\t\t\treturn prop.type && renderShape(prop.type.value);\n\t\tcase 'arrayOf':\n\t\t\tif (type.value.name === 'shape' || type.value.name === 'exact') {\n\t\t\t\treturn prop.type && renderShape(prop.type.value.value);\n\t\t\t}\n\t\t\treturn null;\n\t\tcase 'objectOf':\n\t\t\tif (type.value.name === 'shape' || type.value.name === 'exact') {\n\t\t\t\treturn prop.type && renderShape(prop.type.value.value);\n\t\t\t}\n\t\t\treturn null;\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n"
  },
  {
    "path": "src/client/rsg-components/Props/renderType.tsx",
    "content": "import React from 'react';\nimport { PropTypeDescriptor } from 'react-docgen';\nimport Type from 'rsg-components/Type';\nimport ComplexType from 'rsg-components/ComplexType';\n\nimport { getType, PropDescriptor, TypeDescriptor } from './util';\n\ninterface ExtendedPropTypeDescriptor extends Omit<PropTypeDescriptor, 'name'> {\n\tname: string;\n}\n\nexport function renderType(type: ExtendedPropTypeDescriptor): string {\n\tif (!type) {\n\t\treturn 'unknown';\n\t}\n\n\tconst { name } = type;\n\n\tswitch (name) {\n\t\tcase 'arrayOf':\n\t\t\treturn `${type.value.name}[]`;\n\t\tcase 'objectOf':\n\t\t\treturn `{${renderType(type.value)}}`;\n\t\tcase 'instanceOf':\n\t\t\treturn type.value;\n\t\tdefault:\n\t\t\treturn name;\n\t}\n}\n\nfunction renderAdvancedType(type: PropTypeDescriptor | TypeDescriptor): React.ReactNode {\n\tswitch (type.name) {\n\t\tcase 'enum':\n\t\t\treturn <Type>{type.name}</Type>;\n\t\tcase 'literal':\n\t\t\treturn <Type>{type.value}</Type>;\n\t\tcase 'signature':\n\t\t\treturn <ComplexType name={type.type} raw={type.raw} />;\n\t\tcase 'union':\n\t\tcase 'tuple':\n\t\t\treturn <ComplexType name={type.name} raw={type.raw} />;\n\t\tdefault:\n\t\t\treturn <Type>{(type as any).raw || (type as any).name}</Type>;\n\t}\n}\n\nexport default function renderTypeColumn(prop: PropDescriptor): React.ReactNode {\n\tconst type = getType(prop);\n\tif (!type) {\n\t\treturn null;\n\t}\n\tif (prop.flowType || prop.tsType) {\n\t\treturn renderAdvancedType(type);\n\t}\n\treturn <Type>{renderType(type)}</Type>;\n}\n"
  },
  {
    "path": "src/client/rsg-components/Props/util.ts",
    "content": "import { PropDescriptor as BasePropDescriptor, PropTypeDescriptor } from 'react-docgen';\n\n/**\n * Remove quotes around given string.\n */\nexport function unquote(string?: string): string | undefined {\n\treturn string && string.replace(/^['\"]|['\"]$/g, '');\n}\n\nexport interface PropDescriptor extends BasePropDescriptor {\n\tflowType?: TypeDescriptor;\n\ttsType?: TypeDescriptor;\n}\n\n/**\n * Return prop type object.\n *\n * @param {object} prop\n * @returns {object}\n */\nexport function getType(prop: PropDescriptor): PropTypeDescriptor | TypeDescriptor | undefined {\n\tif (prop.flowType) {\n\t\tif (\n\t\t\tprop.flowType.name === 'union' &&\n\t\t\tprop.flowType.elements.every((elem: { name: string }) => elem.name === 'literal')\n\t\t) {\n\t\t\treturn {\n\t\t\t\t...prop.flowType,\n\t\t\t\tname: 'enum',\n\t\t\t\tvalue: prop.flowType.elements,\n\t\t\t};\n\t\t}\n\t\treturn prop.flowType;\n\t}\n\tif (prop.tsType) {\n\t\treturn prop.tsType;\n\t}\n\treturn prop.type;\n}\n\n/**\n * Show starting and ending whitespace around given string.\n */\nexport function showSpaces(string?: string): string | undefined {\n\treturn string && string.replace(/^\\s|\\s$/g, '␣');\n}\n\nexport interface TypeEnumDescriptor {\n\tname: 'enum';\n\ttype: string;\n\tvalue: TypeDescriptor[];\n}\n\ninterface TypeLiteralDescriptor {\n\tname: 'literal';\n\ttype: string;\n\tvalue: string;\n}\n\ninterface TypeSignatureDescriptor {\n\tname: 'signature';\n\ttype: string;\n\traw: string;\n\tvalue: string;\n}\n\ninterface TypeUnionDescriptor {\n\tname: 'union' | 'tuple';\n\telements: TypeDescriptor[];\n\ttype: string;\n\traw: string;\n\tvalue?: string;\n}\n\nexport type TypeDescriptor =\n\t| TypeEnumDescriptor\n\t| TypeLiteralDescriptor\n\t| TypeSignatureDescriptor\n\t| TypeUnionDescriptor;\n"
  },
  {
    "path": "src/client/rsg-components/ReactComponent/ReactComponent.spec.tsx",
    "content": "import React from 'react';\nimport { render } from '@testing-library/react';\nimport ReactComponent from './ReactComponent';\nimport slots from '../slots';\nimport Context from '../Context';\nimport { DisplayModes } from '../../consts';\nimport * as Rsg from '../../../typings';\n\nconst context = {\n\tconfig: {\n\t\tpagePerSection: false,\n\t},\n\tdisplayMode: DisplayModes.all,\n\tslots: slots(),\n};\n\nconst Provider = (props: any) => <Context.Provider value={context} {...props} />;\n\nconst evalInContext = (a: string) =>\n\t// eslint-disable-next-line no-new-func\n\tnew Function('require', 'const React = require(\"react\");' + a).bind(null, require);\n\nconst component = {\n\tname: 'Foo',\n\tvisibleName: 'Foo',\n\tslug: 'foo',\n\thref: '#foo',\n\tpathLine: 'foo/bar.js',\n\tprops: {\n\t\tdescription: 'Bar',\n\t\tmethods: [],\n\t\texamples: [],\n\t},\n\tmetadata: {},\n};\n\nconst componentWithEverything: Rsg.Component = {\n\tname: 'Foo',\n\tvisibleName: 'Foo',\n\tslug: 'foo',\n\tpathLine: 'foo/bar.js',\n\tprops: {\n\t\tdescription: 'Bar',\n\t\tmethods: [\n\t\t\t{\n\t\t\t\tname: 'set',\n\t\t\t\tparams: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'newValue',\n\t\t\t\t\t\tdescription: 'New value for the counter.',\n\t\t\t\t\t\ttype: { type: 'NameExpression', name: 'Number' },\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\treturns: null,\n\t\t\t\tdescription: 'Sets the counter to a particular value.',\n\t\t\t},\n\t\t],\n\t\texamples: [\n\t\t\t{\n\t\t\t\ttype: 'code',\n\t\t\t\tcontent: '<button>Code: OK</button>',\n\t\t\t\tevalInContext,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: 'markdown',\n\t\t\t\tcontent: 'Markdown: Hello *world*!',\n\t\t\t},\n\t\t],\n\t},\n\tmetadata: {\n\t\ttags: ['one', 'two'],\n\t},\n};\n\ntest('should render an example placeholder', () => {\n\tconst { getByText } = render(\n\t\t<Provider>\n\t\t\t<ReactComponent component={component} depth={3} exampleMode=\"collapse\" usageMode=\"collapse\" />\n\t\t</Provider>\n\t);\n\texpect(getByText(/add examples to this component/i)).toBeInTheDocument();\n});\n\ntest('should render examples', () => {\n\tconst { getByText } = render(\n\t\t<Provider>\n\t\t\t<ReactComponent\n\t\t\t\tcomponent={componentWithEverything}\n\t\t\t\tdepth={3}\n\t\t\t\texampleMode=\"collapse\"\n\t\t\t\tusageMode=\"collapse\"\n\t\t\t/>\n\t\t</Provider>\n\t);\n\texpect(getByText(/code: ok/i)).toBeInTheDocument();\n\texpect(getByText(/markdown: hello/i)).toBeInTheDocument();\n});\n\ntest('should render usage closed by default when usageMode is \"collapse\"', () => {\n\tconst { getByText } = render(\n\t\t<Provider>\n\t\t\t<ReactComponent\n\t\t\t\tcomponent={componentWithEverything}\n\t\t\t\tdepth={3}\n\t\t\t\texampleMode=\"collapse\"\n\t\t\t\tusageMode=\"collapse\"\n\t\t\t/>\n\t\t</Provider>\n\t);\n\texpect(getByText(/props & methods/i)).toHaveAttribute('aria-pressed', 'false');\n});\n\ntest('should render usage opened by default when usageMode is \"expand\"', () => {\n\tconst { getByText } = render(\n\t\t<Provider>\n\t\t\t<ReactComponent\n\t\t\t\tcomponent={componentWithEverything}\n\t\t\t\tdepth={3}\n\t\t\t\texampleMode=\"collapse\"\n\t\t\t\tusageMode=\"expand\"\n\t\t\t/>\n\t\t</Provider>\n\t);\n\texpect(getByText(/props & methods/i)).toHaveAttribute('aria-pressed', 'true');\n});\n\ntest('should not render usage when usageMode is \"hide\"', () => {\n\tconst { queryByText } = render(\n\t\t<Provider>\n\t\t\t<ReactComponent\n\t\t\t\tcomponent={componentWithEverything}\n\t\t\t\tdepth={3}\n\t\t\t\texampleMode=\"collapse\"\n\t\t\t\tusageMode=\"hide\"\n\t\t\t/>\n\t\t</Provider>\n\t);\n\texpect(queryByText(/props & methods/i)).not.toBeInTheDocument();\n});\n\ntest('should not render anything when component has no name', () => {\n\tconst { container } = render(\n\t\t<Provider>\n\t\t\t<ReactComponent\n\t\t\t\tcomponent={{ slug: 'foo', props: {} }}\n\t\t\t\tdepth={3}\n\t\t\t\texampleMode=\"collapse\"\n\t\t\t\tusageMode=\"collapse\"\n\t\t\t/>\n\t\t</Provider>\n\t);\n\texpect(container).toBeEmptyDOMElement();\n});\n\ntest('should not render component in isolation mode by default', () => {\n\tconst { getByLabelText } = render(\n\t\t<Provider>\n\t\t\t<ReactComponent component={component} depth={3} exampleMode=\"collapse\" usageMode=\"collapse\" />\n\t\t</Provider>\n\t);\n\texpect(getByLabelText(/open isolated/i)).toBeInTheDocument();\n});\n\ntest('should render component in isolation mode', () => {\n\tconst { getByLabelText } = render(\n\t\t<Provider\n\t\t\tvalue={{\n\t\t\t\t...context,\n\t\t\t\tdisplayMode: DisplayModes.component,\n\t\t\t}}\n\t\t>\n\t\t\t<ReactComponent component={component} depth={3} exampleMode=\"collapse\" usageMode=\"collapse\" />\n\t\t</Provider>\n\t);\n\texpect(getByLabelText(/show all components/i)).toBeInTheDocument();\n});\n\ntest('should prefix description with deprecated label when @deprecated is present in tags', () => {\n\tconst { getByText } = render(\n\t\t<Provider>\n\t\t\t<ReactComponent\n\t\t\t\tcomponent={{\n\t\t\t\t\t...component,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\ttags: {\n\t\t\t\t\t\t\tdeprecated: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttitle: 'deprecated',\n\t\t\t\t\t\t\t\t\tdescription: 'I am deprecated',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}}\n\t\t\t\tdepth={3}\n\t\t\t\texampleMode=\"collapse\"\n\t\t\t\tusageMode=\"collapse\"\n\t\t\t/>\n\t\t</Provider>\n\t);\n\texpect(getByText(/deprecated:/i)).toBeInTheDocument();\n});\n"
  },
  {
    "path": "src/client/rsg-components/ReactComponent/ReactComponent.tsx",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport Examples from 'rsg-components/Examples';\nimport SectionHeading from 'rsg-components/SectionHeading';\nimport JsDoc from 'rsg-components/JsDoc';\nimport Markdown from 'rsg-components/Markdown';\nimport Slot from 'rsg-components/Slot';\nimport ReactComponentRenderer from 'rsg-components/ReactComponent/ReactComponentRenderer';\nimport Context, { StyleGuideContextContents } from 'rsg-components/Context';\nimport ExamplePlaceholderDefault from 'rsg-components/ExamplePlaceholder';\nimport { DOCS_TAB_USAGE } from '../slots';\nimport { DisplayModes, UsageModes } from '../../consts';\nimport * as Rsg from '../../../typings';\n\nconst ExamplePlaceholder =\n\tprocess.env.STYLEGUIDIST_ENV !== 'production' ? ExamplePlaceholderDefault : () => <div />;\n\ninterface ReactComponentProps {\n\tcomponent: Rsg.Component;\n\tdepth: number;\n\texampleMode?: string;\n\tusageMode?: string;\n}\n\ninterface ReactComponentState {\n\tactiveTab?: string;\n}\n\nexport default class ReactComponent extends Component<ReactComponentProps, ReactComponentState> {\n\tpublic static propTypes = {\n\t\tcomponent: PropTypes.object.isRequired,\n\t\tdepth: PropTypes.number.isRequired,\n\t\texampleMode: PropTypes.string.isRequired,\n\t\tusageMode: PropTypes.string.isRequired,\n\t};\n\n\tpublic static contextType = Context;\n\n\tpublic state = {\n\t\tactiveTab: this.props.usageMode === UsageModes.expand ? DOCS_TAB_USAGE : undefined,\n\t};\n\n\tprivate handleTabChange = (name: string) => {\n\t\tthis.setState((state) => ({\n\t\t\tactiveTab: state.activeTab !== name ? name : undefined,\n\t\t}));\n\t};\n\n\tpublic render() {\n\t\tconst { activeTab } = this.state;\n\t\tconst {\n\t\t\tdisplayMode,\n\t\t\tconfig: { pagePerSection },\n\t\t} = this.context as StyleGuideContextContents;\n\t\tconst { component, depth, usageMode, exampleMode } = this.props;\n\t\tconst { name, visibleName, slug = '-', filepath, pathLine, href } = component;\n\t\tconst { description = '', examples = [], tags = {} } = component.props || {};\n\t\tif (!name) {\n\t\t\treturn null;\n\t\t}\n\t\tconst showUsage = usageMode !== UsageModes.hide;\n\n\t\treturn (\n\t\t\t<ReactComponentRenderer\n\t\t\t\tname={name}\n\t\t\t\tslug={slug}\n\t\t\t\tfilepath={filepath}\n\t\t\t\tpathLine={pathLine}\n\t\t\t\tdocs={<JsDoc {...tags} />}\n\t\t\t\tdescription={description && <Markdown text={description} />}\n\t\t\t\theading={\n\t\t\t\t\t<SectionHeading\n\t\t\t\t\t\tid={slug}\n\t\t\t\t\t\tpagePerSection={pagePerSection}\n\t\t\t\t\t\tdeprecated={!!tags.deprecated}\n\t\t\t\t\t\tslotName=\"componentToolbar\"\n\t\t\t\t\t\tslotProps={{\n\t\t\t\t\t\t\t...component,\n\t\t\t\t\t\t\tisolated: displayMode !== DisplayModes.all,\n\t\t\t\t\t\t}}\n\t\t\t\t\t\thref={href}\n\t\t\t\t\t\tdepth={depth}\n\t\t\t\t\t>\n\t\t\t\t\t\t{visibleName}\n\t\t\t\t\t</SectionHeading>\n\t\t\t\t}\n\t\t\t\texamples={\n\t\t\t\t\texamples.length > 0 ? (\n\t\t\t\t\t\t<Examples examples={examples} name={name} exampleMode={exampleMode} />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<ExamplePlaceholder name={name} />\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\ttabButtons={\n\t\t\t\t\tshowUsage && (\n\t\t\t\t\t\t<Slot\n\t\t\t\t\t\t\tname=\"docsTabButtons\"\n\t\t\t\t\t\t\tactive={activeTab}\n\t\t\t\t\t\t\tprops={{ ...component, onClick: this.handleTabChange }}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\ttabBody={<Slot name=\"docsTabs\" active={activeTab} onlyActive props={component} />}\n\t\t\t/>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "src/client/rsg-components/ReactComponent/ReactComponentRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Pathline from 'rsg-components/Pathline';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ color, fontSize, space }: Rsg.Theme) => ({\n\troot: {\n\t\tmarginBottom: space[6],\n\t},\n\theader: {\n\t\tmarginBottom: space[3],\n\t},\n\ttabs: {\n\t\tmarginBottom: space[3],\n\t},\n\ttabButtons: {\n\t\tmarginBottom: space[1],\n\t},\n\ttabBody: {\n\t\toverflowX: 'auto',\n\t\tmaxWidth: '100%',\n\t\tWebkitOverflowScrolling: 'touch',\n\t},\n\tdocs: {\n\t\tcolor: color.base,\n\t\tfontSize: fontSize.text,\n\t},\n});\n\ninterface ReactComponentRendererProps extends JssInjectedProps {\n\tname: string;\n\theading: React.ReactNode;\n\tfilepath?: string;\n\tslug?: string;\n\tpathLine?: string;\n\ttabButtons?: React.ReactNode;\n\ttabBody?: React.ReactNode;\n\tdescription?: React.ReactNode;\n\tdocs?: React.ReactNode;\n\texamples?: React.ReactNode;\n\tisolated?: boolean;\n}\n\nexport const ReactComponentRenderer: React.FunctionComponent<ReactComponentRendererProps> = ({\n\tclasses,\n\tname,\n\theading,\n\tpathLine,\n\tdescription,\n\tdocs,\n\texamples,\n\ttabButtons,\n\ttabBody,\n}) => {\n\treturn (\n\t\t<div className={classes.root} data-testid={`${name}-container`}>\n\t\t\t<header className={classes.header}>\n\t\t\t\t{heading}\n\t\t\t\t{pathLine && <Pathline>{pathLine}</Pathline>}\n\t\t\t</header>\n\t\t\t{(description || docs) && (\n\t\t\t\t<div className={classes.docs}>\n\t\t\t\t\t{description}\n\t\t\t\t\t{docs}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{tabButtons && (\n\t\t\t\t<div className={classes.tabs}>\n\t\t\t\t\t<div className={classes.tabButtons}>{tabButtons}</div>\n\t\t\t\t\t<div className={classes.tabBody}>{tabBody}</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{examples}\n\t\t</div>\n\t);\n};\n\nReactComponentRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tname: PropTypes.string.isRequired,\n\theading: PropTypes.any.isRequired,\n\tfilepath: PropTypes.string,\n\tpathLine: PropTypes.string,\n\ttabButtons: PropTypes.any,\n\ttabBody: PropTypes.any,\n\tdescription: PropTypes.any,\n\tdocs: PropTypes.any,\n\texamples: PropTypes.any,\n\tisolated: PropTypes.bool,\n};\n\nexport default Styled<ReactComponentRendererProps>(styles)(ReactComponentRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/ReactComponent/index.ts",
    "content": "export { default } from 'rsg-components/ReactComponent/ReactComponent';\nexport * from 'rsg-components/ReactComponent/ReactComponent';\n"
  },
  {
    "path": "src/client/rsg-components/ReactExample/ReactExample.spec.tsx",
    "content": "import { fireEvent, render } from '@testing-library/react';\nimport React from 'react';\nimport noop from 'lodash/noop';\nimport renderer from 'react-test-renderer';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport ReactExample from '.';\n\nconst evalInContext = (a: string): (() => any) =>\n\t// eslint-disable-next-line no-new-func\n\tnew Function('require', 'const React = require(\"react\");' + a).bind(null, require);\n\nit('should render code', () => {\n\tconst testRenderer = createRenderer();\n\ttestRenderer.render(\n\t\t<ReactExample code={'<button>OK</button>'} evalInContext={evalInContext} onError={noop} />\n\t);\n\n\texpect(testRenderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should wrap code in Fragment when it starts with <', () => {\n\tconst actual = renderer.create(\n\t\t<div>\n\t\t\t<ReactExample code=\"<span /><span />\" evalInContext={evalInContext} onError={noop} />\n\t\t</div>\n\t);\n\n\texpect(actual.toJSON()).toMatchSnapshot();\n});\n\nit('should handle errors', () => {\n\tconst onError = jest.fn();\n\n\tconst testRenderer = createRenderer();\n\ttestRenderer.render(\n\t\t<ReactExample code={'<invalid code'} evalInContext={evalInContext} onError={onError} />\n\t);\n\n\texpect(onError).toHaveBeenCalledTimes(1);\n});\n\nit('should set initial state with hooks', () => {\n\tconst code = `\nconst [count, setCount] = React.useState(0);\n<button>{count}</button>\n\t`;\n\tconst { getByRole } = render(\n\t\t<ReactExample code={code} evalInContext={evalInContext} onError={noop} />\n\t);\n\n\texpect(getByRole('button').textContent).toEqual('0');\n});\n\nit('should update state with hooks', () => {\n\tconst code = `\nconst [count, setCount] = React.useState(0);\n<button onClick={() => setCount(count+1)}>{count}</button>\n\t`;\n\tconst { getByRole } = render(\n\t\t<ReactExample code={code} evalInContext={evalInContext} onError={noop} />\n\t);\n\tfireEvent.click(getByRole('button'));\n\n\texpect(getByRole('button').textContent).toEqual('1');\n});\n"
  },
  {
    "path": "src/client/rsg-components/ReactExample/ReactExample.tsx",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { TransformOptions } from 'buble';\nimport Wrapper from 'rsg-components/Wrapper';\nimport compileCode from '../../utils/compileCode';\nimport splitExampleCode from '../../utils/splitExampleCode';\n\n/* eslint-disable react/no-multi-comp */\n\ninterface ReactExampleProps {\n\tcode: string;\n\tevalInContext(code: string): () => any;\n\tonError(err: Error): void;\n\tcompilerConfig?: TransformOptions;\n}\n\nexport default class ReactExample extends Component<ReactExampleProps> {\n\tpublic static propTypes = {\n\t\tcode: PropTypes.string.isRequired,\n\t\tevalInContext: PropTypes.func.isRequired,\n\t\tonError: PropTypes.func.isRequired,\n\t\tcompilerConfig: PropTypes.object,\n\t};\n\n\tpublic shouldComponentUpdate(nextProps: ReactExampleProps) {\n\t\treturn this.props.code !== nextProps.code;\n\t}\n\n\t// Run example code and return the last top-level expression\n\tprivate getExampleComponent(compiledCode: string): () => any {\n\t\treturn this.props.evalInContext(`\n\t\t\t${compiledCode}\n\t\t`);\n\t}\n\n\tpublic render() {\n\t\tconst { code, compilerConfig = {}, onError } = this.props;\n\t\tconst compiledCode = compileCode(code, compilerConfig, onError);\n\t\tif (!compiledCode) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst { example } = splitExampleCode(compiledCode);\n\t\tconst ExampleComponent = this.getExampleComponent(example);\n\t\tconst wrappedComponent = (\n\t\t\t<Wrapper onError={onError}>\n\t\t\t\t<ExampleComponent />\n\t\t\t</Wrapper>\n\t\t);\n\t\treturn wrappedComponent;\n\t}\n}\n"
  },
  {
    "path": "src/client/rsg-components/ReactExample/__snapshots__/ReactExample.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should render code 1`] = `\n<Wrapper\n  onError={[Function]}\n>\n  <bound anonymous />\n</Wrapper>\n`;\n\nexports[`should wrap code in Fragment when it starts with < 1`] = `\n<div>\n  <span />\n  <span />\n</div>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/ReactExample/index.ts",
    "content": "export { default } from 'rsg-components/ReactExample/ReactExample';\n"
  },
  {
    "path": "src/client/rsg-components/Ribbon/Ribbon.spec.tsx",
    "content": "import React from 'react';\nimport { render } from '@testing-library/react';\nimport Ribbon from './Ribbon';\nimport Context from '../Context';\n\nconst url = 'http://example.com/';\nconst text = 'Share the repo';\n\nit('should render ribbon if the ribbon is present in the config', () => {\n\tconst { getByRole } = render(\n\t\t<Context.Provider value={{ config: { ribbon: { url } } } as any}>\n\t\t\t<Ribbon />\n\t\t</Context.Provider>\n\t);\n\n\texpect(getByRole('link')).toHaveAttribute('href', url);\n});\n\nit('should render ribbon with custom text', () => {\n\tconst { getByText } = render(\n\t\t<Context.Provider\n\t\t\tvalue={\n\t\t\t\t{\n\t\t\t\t\tconfig: {\n\t\t\t\t\t\tribbon: {\n\t\t\t\t\t\t\turl,\n\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t} as any\n\t\t\t}\n\t\t>\n\t\t\t<Ribbon />\n\t\t</Context.Provider>\n\t);\n\n\texpect(getByText(text)).toBeInTheDocument();\n});\n\nit('should not render anything if the ribbon is not present in the config', () => {\n\tconst { queryByRole } = render(\n\t\t<Context.Provider value={{ config: {} } as any}>\n\t\t\t<Ribbon />\n\t\t</Context.Provider>\n\t);\n\n\texpect(queryByRole('link')).not.toBeInTheDocument();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Ribbon/Ribbon.tsx",
    "content": "import React from 'react';\nimport RibbonRenderer from 'rsg-components/Ribbon/RibbonRenderer';\nimport { useStyleGuideContext } from 'rsg-components/Context';\n\nexport default function Ribbon() {\n\tconst {\n\t\tconfig: { ribbon },\n\t} = useStyleGuideContext();\n\treturn ribbon ? <RibbonRenderer {...ribbon} /> : null;\n}\n"
  },
  {
    "path": "src/client/rsg-components/Ribbon/RibbonRenderer.tsx",
    "content": "import React from 'react';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ color, space, fontSize, fontFamily }: Rsg.Theme) => ({\n\troot: {\n\t\tposition: 'fixed',\n\t\ttop: 0,\n\t\tright: 0,\n\t\twidth: 149,\n\t\theight: 149,\n\t\tzIndex: 999,\n\t},\n\tlink: {\n\t\tfontFamily: fontFamily.base,\n\t\tposition: 'relative',\n\t\tright: -37,\n\t\ttop: -22,\n\t\tdisplay: 'block',\n\t\twidth: 190,\n\t\tpadding: [[space[0], space[2]]],\n\t\ttextAlign: 'center',\n\t\tcolor: color.ribbonText,\n\t\tfontSize: fontSize.base,\n\t\tbackground: color.ribbonBackground,\n\t\ttextDecoration: 'none',\n\t\ttextShadow: [[0, '-1px', 0, 'rgba(0,0,0,.15)']],\n\t\ttransformOrigin: [[0, 0]],\n\t\ttransform: 'rotate(45deg)',\n\t\tcursor: 'pointer',\n\t},\n});\n\ninterface RibbonProps extends JssInjectedProps {\n\turl: string;\n\ttext?: string;\n}\n\nexport const RibbonRenderer: React.FunctionComponent<RibbonProps> = ({\n\tclasses,\n\turl,\n\ttext = 'Fork me on GitHub',\n}) => {\n\treturn (\n\t\t<footer className={classes.root}>\n\t\t\t<a href={url} className={classes.link}>\n\t\t\t\t{text}\n\t\t\t</a>\n\t\t</footer>\n\t);\n};\n\nexport default Styled<RibbonProps>(styles)(RibbonRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Ribbon/index.ts",
    "content": "export { default } from 'rsg-components/Ribbon/Ribbon';\n"
  },
  {
    "path": "src/client/rsg-components/Section/Section.spec.tsx",
    "content": "import React from 'react';\nimport { render } from '@testing-library/react';\nimport Section from 'rsg-components/Section';\nimport Context from '../Context';\nimport slots from '../slots';\nimport { DisplayModes } from '../../consts';\n\nconst context = {\n\tconfig: {\n\t\tpagePerSection: false,\n\t},\n\tdisplayMode: DisplayModes.all,\n\tslots: slots(),\n} as any;\n\nconst Provider = (props: any) => <Context.Provider value={context} {...props} />;\n\ntest('should render nested sections', () => {\n\tconst { getByTestId } = render(\n\t\t<Provider>\n\t\t\t<Section\n\t\t\t\tsection={{\n\t\t\t\t\tname: 'Outer section',\n\t\t\t\t\tslug: 'outer-section',\n\t\t\t\t\tusageMode: 'collapse',\n\t\t\t\t\texampleMode: 'collapse',\n\t\t\t\t\tsections: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Nested section',\n\t\t\t\t\t\t\tslug: 'nested-section',\n\t\t\t\t\t\t\tusageMode: 'collapse',\n\t\t\t\t\t\t\texampleMode: 'collapse',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}}\n\t\t\t\tdepth={3}\n\t\t\t/>\n\t\t</Provider>\n\t);\n\texpect(getByTestId('section-outer-section')).toContainElement(\n\t\tgetByTestId('section-nested-section')\n\t);\n});\n\ntest('should render components inside a section', () => {\n\tconst { getByTestId, getByText } = render(\n\t\t<Provider>\n\t\t\t<Section\n\t\t\t\tsection={{\n\t\t\t\t\tname: 'Components',\n\t\t\t\t\tslug: 'components',\n\t\t\t\t\tusageMode: 'collapse',\n\t\t\t\t\texampleMode: 'collapse',\n\t\t\t\t\tcomponents: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Foo',\n\t\t\t\t\t\t\tvisibleName: 'Foo',\n\t\t\t\t\t\t\tslug: 'foo',\n\t\t\t\t\t\t\tpathLine: 'components/foo.js',\n\t\t\t\t\t\t\tfilepath: 'components/foo.js',\n\t\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\t\tdescription: 'Foo foo',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Bar',\n\t\t\t\t\t\t\tvisibleName: 'Bar',\n\t\t\t\t\t\t\tslug: 'bar',\n\t\t\t\t\t\t\tpathLine: 'components/bar.js',\n\t\t\t\t\t\t\tfilepath: 'components/bar.js',\n\t\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\t\tdescription: 'Bar bar',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}}\n\t\t\t\tdepth={3}\n\t\t\t/>\n\t\t</Provider>\n\t);\n\texpect(getByTestId('section-components')).toContainElement(getByText('components/foo.js'));\n\texpect(getByTestId('section-components')).toContainElement(getByText('components/bar.js'));\n});\n\ntest('should not render section in isolation mode by default', () => {\n\tconst { getByLabelText } = render(\n\t\t<Provider>\n\t\t\t<Section\n\t\t\t\tsection={{\n\t\t\t\t\tname: 'A',\n\t\t\t\t\tslug: 'a',\n\t\t\t\t\tusageMode: 'collapse',\n\t\t\t\t\texampleMode: 'collapse',\n\t\t\t\t}}\n\t\t\t\tdepth={3}\n\t\t\t/>\n\t\t</Provider>\n\t);\n\texpect(getByLabelText(/open isolated/i)).toBeInTheDocument();\n});\n\ntest('should render section in isolation mode', () => {\n\tconst { queryByLabelText } = render(\n\t\t<Provider\n\t\t\tvalue={{\n\t\t\t\t...context,\n\t\t\t\tdisplayMode: DisplayModes.section,\n\t\t\t}}\n\t\t>\n\t\t\t<Section\n\t\t\t\tsection={{\n\t\t\t\t\tname: 'A',\n\t\t\t\t\tslug: 'a',\n\t\t\t\t\tusageMode: 'collapse',\n\t\t\t\t\texampleMode: 'collapse',\n\t\t\t\t}}\n\t\t\t\tdepth={3}\n\t\t\t/>\n\t\t</Provider>\n\t);\n\texpect(queryByLabelText(/open isolated/i)).toBeNull();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Section/Section.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Examples from 'rsg-components/Examples';\nimport Components from 'rsg-components/Components';\nimport Sections from 'rsg-components/Sections';\nimport SectionRenderer from 'rsg-components/Section/SectionRenderer';\nimport { useStyleGuideContext } from 'rsg-components/Context';\nimport { DisplayModes } from '../../consts';\nimport * as Rsg from '../../../typings';\n\nconst Section: React.FunctionComponent<{\n\tsection: Rsg.Section;\n\tdepth: number;\n}> = ({ section, depth }) => {\n\tconst {\n\t\tdisplayMode,\n\t\tconfig: { pagePerSection },\n\t} = useStyleGuideContext();\n\tconst {\n\t\tname,\n\t\tslug,\n\t\tfilepath,\n\t\tcontent,\n\t\tcomponents,\n\t\tsections,\n\t\tdescription,\n\t\texampleMode,\n\t\tusageMode,\n\t} = section;\n\n\tconst contentJsx = Array.isArray(content) ? (\n\t\t<Examples examples={content} name={name} exampleMode={exampleMode} />\n\t) : null;\n\tconst componentsJsx = components && (\n\t\t<Components\n\t\t\tusageMode={usageMode}\n\t\t\texampleMode={exampleMode}\n\t\t\tcomponents={components}\n\t\t\tdepth={depth + 1}\n\t\t/>\n\t);\n\n\tconst sectionsJsx = sections && <Sections sections={sections} depth={depth + 1} />;\n\n\treturn (\n\t\t<SectionRenderer\n\t\t\tdescription={description}\n\t\t\tpagePerSection={pagePerSection}\n\t\t\tname={name}\n\t\t\tslug={slug}\n\t\t\tfilepath={filepath}\n\t\t\tcontent={contentJsx}\n\t\t\tcomponents={componentsJsx}\n\t\t\tsections={sectionsJsx}\n\t\t\tisolated={displayMode !== DisplayModes.all}\n\t\t\tdepth={depth}\n\t\t/>\n\t);\n};\n\nSection.propTypes = {\n\tsection: PropTypes.any.isRequired,\n\tdepth: PropTypes.number.isRequired,\n};\n\nexport default Section;\n"
  },
  {
    "path": "src/client/rsg-components/Section/SectionRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport SectionHeading from 'rsg-components/SectionHeading';\nimport Markdown from 'rsg-components/Markdown';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ space }: Rsg.Theme) => ({\n\troot: {\n\t\tmarginBottom: space[4],\n\t},\n});\n\ninterface SectionRendererProps extends JssInjectedProps {\n\tslug: string;\n\tdepth: number;\n\tname?: string;\n\tdescription?: string;\n\tcontent?: React.ReactNode;\n\tcomponents?: React.ReactNode;\n\tsections?: React.ReactNode;\n\tisolated?: boolean;\n\tpagePerSection?: boolean;\n\t[prop: string]: any;\n}\n\nexport const SectionRenderer: React.FunctionComponent<SectionRendererProps> = (allProps) => {\n\tconst {\n\t\tclasses,\n\t\tname,\n\t\tslug,\n\t\tcontent,\n\t\tcomponents,\n\t\tsections,\n\t\tdepth,\n\t\tdescription,\n\t\tpagePerSection,\n\t} = allProps;\n\n\treturn (\n\t\t<section className={classes.root} data-testid={`section-${slug}`}>\n\t\t\t{name && (\n\t\t\t\t<SectionHeading\n\t\t\t\t\tdepth={depth}\n\t\t\t\t\tid={slug}\n\t\t\t\t\tslotName=\"sectionToolbar\"\n\t\t\t\t\tpagePerSection={pagePerSection}\n\t\t\t\t\tslotProps={allProps}\n\t\t\t\t>\n\t\t\t\t\t{name}\n\t\t\t\t</SectionHeading>\n\t\t\t)}\n\t\t\t{description && <Markdown text={description} />}\n\t\t\t{content}\n\t\t\t{sections}\n\t\t\t{components}\n\t\t</section>\n\t);\n};\n\nSectionRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tname: PropTypes.string,\n\tdescription: PropTypes.string,\n\tslug: PropTypes.string.isRequired,\n\tcontent: PropTypes.any,\n\tcomponents: PropTypes.any,\n\tsections: PropTypes.any,\n\tisolated: PropTypes.bool,\n\tdepth: PropTypes.number.isRequired,\n\tpagePerSection: PropTypes.bool,\n};\n\nexport default Styled<SectionRendererProps>(styles)(SectionRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Section/index.ts",
    "content": "export { default } from 'rsg-components/Section/Section';\nexport * from 'rsg-components/Section/Section';\n"
  },
  {
    "path": "src/client/rsg-components/SectionHeading/SectionHeading.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport SectionHeading from './index';\nimport SectionHeadingRenderer from './SectionHeadingRenderer';\n\ndescribe('SectionHeading', () => {\n\tconst FakeToolbar = () => <div>Fake toolbar</div>;\n\n\ttest('should forward slot properties to the toolbar', () => {\n\t\tconst testRenderer = createRenderer();\n\t\ttestRenderer.render(\n\t\t\t<SectionHeading\n\t\t\t\tid=\"section\"\n\t\t\t\tslotName=\"slot\"\n\t\t\t\thref=\"/#section\"\n\t\t\t\tslotProps={{ foo: 1, bar: 'baz' }}\n\t\t\t\tdepth={2}\n\t\t\t>\n\t\t\t\tA Section\n\t\t\t</SectionHeading>\n\t\t);\n\n\t\texpect(testRenderer.getRenderOutput()).toMatchSnapshot();\n\t});\n\n\ttest('render a section heading', () => {\n\t\tconst actual = renderer.create(\n\t\t\t<SectionHeadingRenderer id=\"section\" href=\"/section\" depth={2} toolbar={<FakeToolbar />}>\n\t\t\t\tA Section\n\t\t\t</SectionHeadingRenderer>\n\t\t);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n\n\ttest('render a deprecated section heading', () => {\n\t\tconst actual = renderer.create(\n\t\t\t<SectionHeadingRenderer\n\t\t\t\tid=\"section\"\n\t\t\t\thref=\"/section\"\n\t\t\t\tdepth={2}\n\t\t\t\ttoolbar={<FakeToolbar />}\n\t\t\t\tdeprecated\n\t\t\t>\n\t\t\t\tA Section\n\t\t\t</SectionHeadingRenderer>\n\t\t);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n\n\ttest('prevent the heading level from exceeding the maximum allowed by the Heading component', () => {\n\t\tconst actual = renderer.create(\n\t\t\t<SectionHeadingRenderer id=\"section\" href=\"/section\" depth={7} toolbar={<FakeToolbar />}>\n\t\t\t\tA Section\n\t\t\t</SectionHeadingRenderer>\n\t\t);\n\n\t\texpect(actual.toJSON()).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/SectionHeading/SectionHeading.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Slot from 'rsg-components/Slot';\nimport SectionHeadingRenderer from 'rsg-components/SectionHeading/SectionHeadingRenderer';\n\ninterface SectionHeadingProps {\n\tchildren?: React.ReactNode;\n\tid: string;\n\tslotName: string;\n\tslotProps: Record<string, unknown>;\n\tdepth: number;\n\thref?: string;\n\tdeprecated?: boolean;\n\tpagePerSection?: boolean;\n}\n\nconst SectionHeading: React.FunctionComponent<SectionHeadingProps> = ({\n\tslotName,\n\tslotProps,\n\tchildren,\n\tid,\n\thref,\n\t...rest\n}) => {\n\treturn (\n\t\t<SectionHeadingRenderer\n\t\t\ttoolbar={<Slot name={slotName} props={slotProps} />}\n\t\t\tid={id}\n\t\t\thref={href}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{children}\n\t\t</SectionHeadingRenderer>\n\t);\n};\n\nSectionHeading.propTypes = {\n\tchildren: PropTypes.any,\n\tid: PropTypes.string.isRequired,\n\tslotName: PropTypes.string.isRequired,\n\tslotProps: PropTypes.any.isRequired,\n\tdepth: PropTypes.number.isRequired,\n\tdeprecated: PropTypes.bool,\n\tpagePerSection: PropTypes.bool,\n};\n\nexport default SectionHeading;\n"
  },
  {
    "path": "src/client/rsg-components/SectionHeading/SectionHeadingRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport cx from 'clsx';\nimport Heading from 'rsg-components/Heading';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ color, space }: Rsg.Theme) => ({\n\twrapper: {\n\t\tdisplay: 'flex',\n\t\tflexDirection: 'row',\n\t\talignItems: 'center',\n\t\tmarginBottom: space[1],\n\t},\n\ttoolbar: {\n\t\tmarginLeft: 'auto',\n\t},\n\tsectionName: {\n\t\t'&:hover, &:active': {\n\t\t\tisolate: false,\n\t\t\ttextDecoration: 'underline',\n\t\t\tcursor: 'pointer',\n\t\t},\n\t},\n\tisDeprecated: {\n\t\tcolor: color.light,\n\t\t'&, &:hover': {\n\t\t\ttextDecoration: 'line-through',\n\t\t},\n\t},\n});\n\ninterface SectionHeadingRendererProps extends JssInjectedProps {\n\tchildren?: React.ReactNode;\n\ttoolbar?: React.ReactNode;\n\tid: string;\n\thref?: string;\n\tdepth: number;\n\tdeprecated?: boolean;\n}\n\nconst SectionHeadingRenderer: React.FunctionComponent<SectionHeadingRendererProps> = ({\n\tclasses,\n\tchildren,\n\ttoolbar,\n\tid,\n\thref,\n\tdepth,\n\tdeprecated,\n}) => {\n\tconst headingLevel = Math.min(6, depth);\n\tconst sectionNameClasses = cx(classes.sectionName, {\n\t\t[classes.isDeprecated]: deprecated,\n\t});\n\n\treturn (\n\t\t<div className={classes.wrapper}>\n\t\t\t<Heading level={headingLevel} id={id}>\n\t\t\t\t<a href={href} className={sectionNameClasses}>\n\t\t\t\t\t{children}\n\t\t\t\t</a>\n\t\t\t</Heading>\n\t\t\t<div className={classes.toolbar}>{toolbar}</div>\n\t\t</div>\n\t);\n};\n\nSectionHeadingRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any,\n\ttoolbar: PropTypes.any,\n\tid: PropTypes.string.isRequired,\n\thref: PropTypes.string,\n\tdepth: PropTypes.number.isRequired,\n\tdeprecated: PropTypes.bool,\n};\n\nexport default Styled<SectionHeadingRendererProps>(styles)(SectionHeadingRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/SectionHeading/__snapshots__/SectionHeading.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`SectionHeading prevent the heading level from exceeding the maximum allowed by the Heading component 1`] = `\n<div\n  className=\"rsg--wrapper-0\"\n>\n  <h6\n    className=\"rsg--heading-5 rsg--heading6-11\"\n    id=\"section\"\n  >\n    <a\n      className=\"rsg--sectionName-2\"\n      href=\"/section\"\n    >\n      A Section\n    </a>\n  </h6>\n  <div\n    className=\"rsg--toolbar-1\"\n  >\n    <div>\n      Fake toolbar\n    </div>\n  </div>\n</div>\n`;\n\nexports[`SectionHeading render a deprecated section heading 1`] = `\n<div\n  className=\"rsg--wrapper-0\"\n>\n  <h2\n    className=\"rsg--heading-5 rsg--heading2-7\"\n    id=\"section\"\n  >\n    <a\n      className=\"rsg--sectionName-2 rsg--isDeprecated-3\"\n      href=\"/section\"\n    >\n      A Section\n    </a>\n  </h2>\n  <div\n    className=\"rsg--toolbar-1\"\n  >\n    <div>\n      Fake toolbar\n    </div>\n  </div>\n</div>\n`;\n\nexports[`SectionHeading render a section heading 1`] = `\n<div\n  className=\"rsg--wrapper-0\"\n>\n  <h2\n    className=\"rsg--heading-5 rsg--heading2-7\"\n    id=\"section\"\n  >\n    <a\n      className=\"rsg--sectionName-2\"\n      href=\"/section\"\n    >\n      A Section\n    </a>\n  </h2>\n  <div\n    className=\"rsg--toolbar-1\"\n  >\n    <div>\n      Fake toolbar\n    </div>\n  </div>\n</div>\n`;\n\nexports[`SectionHeading should forward slot properties to the toolbar 1`] = `\n<Styled(SectionHeading)\n  depth={2}\n  href=\"/#section\"\n  id=\"section\"\n  toolbar={\n    <Slot\n      name=\"slot\"\n      props={\n        Object {\n          \"bar\": \"baz\",\n          \"foo\": 1,\n        }\n      }\n    />\n  }\n>\n  A Section\n</Styled(SectionHeading)>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/SectionHeading/index.ts",
    "content": "export { default } from 'rsg-components/SectionHeading/SectionHeading';\n"
  },
  {
    "path": "src/client/rsg-components/Sections/Sections.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport noop from 'lodash/noop';\nimport Section from '../Section';\nimport Sections from './Sections';\nimport StyledSectionsRenderer, { SectionsRenderer } from './SectionsRenderer';\n\nconst sections = [\n\t{\n\t\tname: 'Foo',\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: 'code',\n\t\t\t\tcontent: '<button>OK</button>',\n\t\t\t\tevalInContext: noop,\n\t\t\t},\n\t\t],\n\t\tcomponents: [],\n\t},\n\t{\n\t\tname: 'Bar',\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: 'markdown',\n\t\t\t\tcontent: 'Hello *world*!',\n\t\t\t},\n\t\t],\n\t\tcomponents: [],\n\t},\n\t{\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'One',\n\t\t\t\tcontent: [],\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'Two',\n\t\t\t\tcontent: [],\n\t\t\t},\n\t\t],\n\t},\n] as any;\n\nit('should render component renderer', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<Sections sections={sections} depth={3} />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('render should render styled component', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<StyledSectionsRenderer>\n\t\t\t<Section key={0} section={sections[0]} depth={3} />\n\t\t\t<Section key={1} section={sections[1]} depth={3} />\n\t\t\t<Section key={2} section={sections[2]} depth={3} />\n\t\t</StyledSectionsRenderer>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('render should render component', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<SectionsRenderer classes={{}}>\n\t\t\t<Section key={0} section={sections[0]} depth={3} />\n\t\t\t<Section key={1} section={sections[1]} depth={3} />\n\t\t\t<Section key={2} section={sections[2]} depth={3} />\n\t\t</SectionsRenderer>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Sections/Sections.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Section from 'rsg-components/Section';\nimport SectionsRenderer from 'rsg-components/Sections/SectionsRenderer';\nimport * as Rsg from '../../../typings';\n\nconst Sections: React.FunctionComponent<{\n\tsections: Rsg.Section[];\n\tdepth: number;\n\troot?: boolean;\n}> = ({ sections, depth }) => {\n\treturn (\n\t\t<SectionsRenderer>\n\t\t\t{sections\n\t\t\t\t.filter(section => !section.externalLink)\n\t\t\t\t.map((section, idx) => (\n\t\t\t\t\t<Section key={idx} section={section} depth={depth} />\n\t\t\t\t))}\n\t\t</SectionsRenderer>\n\t);\n};\n\nSections.propTypes = {\n\tsections: PropTypes.array.isRequired,\n\tdepth: PropTypes.number.isRequired,\n\troot: PropTypes.bool,\n};\n\nexport default Sections;\n"
  },
  {
    "path": "src/client/rsg-components/Sections/SectionsRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\n\nconst styles = () => ({\n\t// Just default jss-isolate rules\n\troot: {},\n});\n\ninterface SectionsRendererProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n}\n\nexport const SectionsRenderer: React.FunctionComponent<SectionsRendererProps> = ({\n\tclasses,\n\tchildren,\n}) => {\n\treturn <section className={classes.root}>{children}</section>;\n};\n\nSectionsRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any,\n};\n\nexport default Styled<SectionsRendererProps>(styles)(SectionsRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Sections/__snapshots__/Sections.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`render should render component 1`] = `\n<section>\n  <Section\n    depth={3}\n    section={\n      Object {\n        \"components\": Array [],\n        \"content\": Array [\n          Object {\n            \"content\": \"<button>OK</button>\",\n            \"evalInContext\": [Function],\n            \"type\": \"code\",\n          },\n        ],\n        \"name\": \"Foo\",\n      }\n    }\n  />\n  <Section\n    depth={3}\n    section={\n      Object {\n        \"components\": Array [],\n        \"content\": Array [\n          Object {\n            \"content\": \"Hello *world*!\",\n            \"type\": \"markdown\",\n          },\n        ],\n        \"name\": \"Bar\",\n      }\n    }\n  />\n  <Section\n    depth={3}\n    section={\n      Object {\n        \"sections\": Array [\n          Object {\n            \"content\": Array [],\n            \"name\": \"One\",\n          },\n          Object {\n            \"content\": Array [],\n            \"name\": \"Two\",\n          },\n        ],\n      }\n    }\n  />\n</section>\n`;\n\nexports[`render should render styled component 1`] = `\n<SectionsRenderer\n  classes={\n    Object {\n      \"root\": \"rsg--root-0\",\n    }\n  }\n>\n  <Section\n    depth={3}\n    section={\n      Object {\n        \"components\": Array [],\n        \"content\": Array [\n          Object {\n            \"content\": \"<button>OK</button>\",\n            \"evalInContext\": [Function],\n            \"type\": \"code\",\n          },\n        ],\n        \"name\": \"Foo\",\n      }\n    }\n  />\n  <Section\n    depth={3}\n    section={\n      Object {\n        \"components\": Array [],\n        \"content\": Array [\n          Object {\n            \"content\": \"Hello *world*!\",\n            \"type\": \"markdown\",\n          },\n        ],\n        \"name\": \"Bar\",\n      }\n    }\n  />\n  <Section\n    depth={3}\n    section={\n      Object {\n        \"sections\": Array [\n          Object {\n            \"content\": Array [],\n            \"name\": \"One\",\n          },\n          Object {\n            \"content\": Array [],\n            \"name\": \"Two\",\n          },\n        ],\n      }\n    }\n  />\n</SectionsRenderer>\n`;\n\nexports[`should render component renderer 1`] = `\n<Styled(Sections)>\n  <Section\n    depth={3}\n    section={\n      Object {\n        \"components\": Array [],\n        \"content\": Array [\n          Object {\n            \"content\": \"<button>OK</button>\",\n            \"evalInContext\": [Function],\n            \"type\": \"code\",\n          },\n        ],\n        \"name\": \"Foo\",\n      }\n    }\n  />\n  <Section\n    depth={3}\n    section={\n      Object {\n        \"components\": Array [],\n        \"content\": Array [\n          Object {\n            \"content\": \"Hello *world*!\",\n            \"type\": \"markdown\",\n          },\n        ],\n        \"name\": \"Bar\",\n      }\n    }\n  />\n  <Section\n    depth={3}\n    section={\n      Object {\n        \"sections\": Array [\n          Object {\n            \"content\": Array [],\n            \"name\": \"One\",\n          },\n          Object {\n            \"content\": Array [],\n            \"name\": \"Two\",\n          },\n        ],\n      }\n    }\n  />\n</Styled(Sections)>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Sections/index.ts",
    "content": "export { default } from 'rsg-components/Sections/Sections';\n"
  },
  {
    "path": "src/client/rsg-components/Slot/Slot.spec.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { render, fireEvent } from '@testing-library/react';\nimport Slot from './Slot';\nimport Context from '../Context';\n\nconst Button = ({ active, children, ...props }: any) => {\n\treturn (\n\t\t<button {...props} aria-current={active}>\n\t\t\t{children}\n\t\t</button>\n\t);\n};\nButton.propTypes = {\n\tactive: PropTypes.bool,\n\tchildren: PropTypes.node,\n};\n\nconst Button1 = (props: any) => <Button {...props}>Button1</Button>;\nconst Button2 = (props: any) => <Button {...props}>Button2</Button>;\n\nconst fillsWithIds = [\n\t{\n\t\tid: 'one',\n\t\trender: Button1,\n\t},\n\t{\n\t\tid: 'two',\n\t\trender: Button2,\n\t},\n];\n\nit('should render slots and pass props', () => {\n\tconst { getByText, getAllByRole } = render(\n\t\t<Context.Provider\n\t\t\tvalue={\n\t\t\t\t{\n\t\t\t\t\tslots: {\n\t\t\t\t\t\tslot: [Button1, Button2],\n\t\t\t\t\t},\n\t\t\t\t} as any\n\t\t\t}\n\t\t>\n\t\t\t<Slot name=\"slot\" props={{ role: 'pizza' }} />\n\t\t</Context.Provider>\n\t);\n\n\texpect(getByText('Button1')).toBeInTheDocument();\n\texpect(getByText('Button2')).toBeInTheDocument();\n\texpect(getAllByRole('pizza')).toHaveLength(2);\n});\n\nit('should render slots in id/render format', () => {\n\tconst { getByText } = render(\n\t\t<Context.Provider\n\t\t\tvalue={\n\t\t\t\t{\n\t\t\t\t\tslots: {\n\t\t\t\t\t\tslot: fillsWithIds,\n\t\t\t\t\t},\n\t\t\t\t} as any\n\t\t\t}\n\t\t>\n\t\t\t<Slot name=\"slot\" props={{ id: 'Pizza' }} />\n\t\t</Context.Provider>\n\t);\n\n\texpect(getByText('Button1')).toBeInTheDocument();\n\texpect(getByText('Button2')).toBeInTheDocument();\n});\n\nit('should pass active flag to active slot', () => {\n\tconst { getByText } = render(\n\t\t<Context.Provider\n\t\t\tvalue={\n\t\t\t\t{\n\t\t\t\t\tslots: {\n\t\t\t\t\t\tslot: fillsWithIds,\n\t\t\t\t\t},\n\t\t\t\t} as any\n\t\t\t}\n\t\t>\n\t\t\t<Slot name=\"slot\" active=\"two\" />\n\t\t</Context.Provider>\n\t);\n\n\texpect(getByText('Button1')).toHaveAttribute('aria-current', 'false');\n\texpect(getByText('Button2')).toHaveAttribute('aria-current', 'true');\n});\n\nit('should render only active slot if onlyActive=true', () => {\n\tconst { queryByText } = render(\n\t\t<Context.Provider\n\t\t\tvalue={\n\t\t\t\t{\n\t\t\t\t\tslots: {\n\t\t\t\t\t\tslot: fillsWithIds,\n\t\t\t\t\t},\n\t\t\t\t} as any\n\t\t\t}\n\t\t>\n\t\t\t<Slot name=\"slot\" active=\"two\" onlyActive />\n\t\t</Context.Provider>\n\t);\n\n\texpect(queryByText('Button1')).not.toBeInTheDocument();\n\texpect(queryByText('Button2')).toBeInTheDocument();\n});\n\nit('should pass slot ID to onClick handler', () => {\n\tconst onClick = jest.fn();\n\tconst { getByText } = render(\n\t\t<Context.Provider\n\t\t\tvalue={\n\t\t\t\t{\n\t\t\t\t\tslots: {\n\t\t\t\t\t\tslot: fillsWithIds,\n\t\t\t\t\t},\n\t\t\t\t} as any\n\t\t\t}\n\t\t>\n\t\t\t<Slot name=\"slot\" props={{ onClick }} />\n\t\t</Context.Provider>\n\t);\n\n\tfireEvent.click(getByText('Button2'));\n\n\texpect(onClick).toHaveBeenCalledTimes(1);\n\texpect(onClick.mock.calls[0][0]).toBe('two');\n});\n\nit('should return null if all slots render null', () => {\n\tconst { queryByText } = render(\n\t\t<Context.Provider\n\t\t\tvalue={\n\t\t\t\t{\n\t\t\t\t\tslots: {\n\t\t\t\t\t\tslot: [() => null],\n\t\t\t\t\t},\n\t\t\t\t} as any\n\t\t\t}\n\t\t>\n\t\t\t<Slot name=\"slot\" props={{ id: 'Pizza' }} />\n\t\t</Context.Provider>\n\t);\n\n\texpect(queryByText('Button1')).not.toBeInTheDocument();\n\texpect(queryByText('Button2')).not.toBeInTheDocument();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Slot/Slot.tsx",
    "content": "// Inspired by https://github.com/camwest/react-slot-fill\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport { useStyleGuideContext, SlotObject } from 'rsg-components/Context';\n\ninterface SlotProps {\n\tname: string;\n\tactive?: string;\n\tonlyActive?: boolean;\n\tprops?: {\n\t\tonClick?: (id: string, ...attrs: any[]) => void;\n\t\tactive?: boolean;\n\t\tname?: string;\n\t\t[propId: string]: any;\n\t};\n\tclassName?: string;\n}\n\nexport default function Slot({ name, active, onlyActive, className, props = {} }: SlotProps) {\n\tconst { slots } = useStyleGuideContext();\n\tconst fills = slots[name];\n\tif (!fills) {\n\t\tthrow new Error(`Slot \"${name}\" not found, available slots: ${Object.keys(slots).join(', ')}`);\n\t}\n\n\tconst rendered = fills.map((Fill, index) => {\n\t\t// { id: 'pizza', render: ({ foo }) => <div>{foo}</div> }\n\t\tconst { id, render } = Fill as SlotObject;\n\t\tlet fillProps = props;\n\t\tif (id && render) {\n\t\t\t// Render only specified fill\n\t\t\tif (onlyActive && id !== active) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// eslint-disable-next-line react/prop-types\n\t\t\tconst { onClick } = props;\n\t\t\tfillProps = {\n\t\t\t\t...props,\n\t\t\t\tname: id,\n\t\t\t\t// Set active prop to active fill\n\t\t\t\tactive: active ? id === active : undefined,\n\t\t\t\t// Pass fill ID to onClick event handler\n\t\t\t\tonClick: onClick && ((...attrs) => onClick(id, ...attrs)),\n\t\t\t};\n\t\t\tconst Render = render;\n\t\t\treturn <Render key={index} {...fillProps} />;\n\t\t}\n\t\tconst FillAsComponent = Fill as React.FunctionComponent<any>;\n\t\treturn <FillAsComponent key={index} {...fillProps} />;\n\t});\n\n\tconst filtered = rendered.filter(Boolean);\n\tif (filtered.length === 0) {\n\t\treturn null;\n\t}\n\n\treturn <div className={className}>{filtered}</div>;\n}\n\nSlot.propTypes = {\n\tname: PropTypes.string.isRequired,\n\tactive: PropTypes.string,\n\tonlyActive: PropTypes.bool,\n\tprops: PropTypes.object,\n\tclassName: PropTypes.string,\n};\n"
  },
  {
    "path": "src/client/rsg-components/Slot/index.ts",
    "content": "export { default } from 'rsg-components/Slot/Slot';\n"
  },
  {
    "path": "src/client/rsg-components/StyleGuide/StyleGuide.spec.tsx",
    "content": "import React from 'react';\nimport { render, within } from '@testing-library/react';\nimport StyleGuide, { StyleGuideProps } from './StyleGuide';\nimport slots from '../slots';\nimport { DisplayModes } from '../../consts';\nimport * as Rsg from '../../../typings';\n\nconst sections: Rsg.Section[] = [\n\t{\n\t\texampleMode: 'collapse',\n\t\tusageMode: 'collapse',\n\t\tslug: 'section',\n\t\tcomponents: [\n\t\t\t{\n\t\t\t\tname: 'Foo',\n\t\t\t\tvisibleName: 'Foo',\n\t\t\t\thref: '#foo',\n\t\t\t\tslug: 'foo',\n\t\t\t\tpathLine: 'components/foo.js',\n\t\t\t\tfilepath: 'components/foo.js',\n\t\t\t\tprops: {\n\t\t\t\t\tdescription: 'Foo foo',\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'Bar',\n\t\t\t\tvisibleName: 'Bar',\n\t\t\t\thref: '#bar',\n\t\t\t\tslug: 'bar',\n\t\t\t\tpathLine: 'components/bar.js',\n\t\t\t\tfilepath: 'components/bar.js',\n\t\t\t\tprops: {\n\t\t\t\t\tdescription: 'Bar bar',\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t},\n];\n\nconst config = {\n\ttitle: 'HelloStyleGuide',\n\tversion: '1.0.0',\n\tshowSidebar: true,\n} as Rsg.ProcessedStyleguidistConfig;\n\nconst defaultProps: StyleGuideProps = {\n\tcodeRevision: 1,\n\tcssRevision: '1',\n\tconfig,\n\tpagePerSection: false,\n\tsections: [],\n\tallSections: [],\n\tslots: slots(),\n\tpatterns: ['components/**.js'],\n};\n\ntest('should render components', () => {\n\tconst { getByText } = render(\n\t\t<StyleGuide {...defaultProps} sections={sections} allSections={sections} />\n\t);\n\texpect(getByText('components/foo.js')).toBeInTheDocument();\n\texpect(getByText('components/bar.js')).toBeInTheDocument();\n});\n\ntest('should render welcome screen', () => {\n\tconst { getByText } = render(<StyleGuide {...defaultProps} welcomeScreen />);\n\texpect(getByText('Welcome to React Styleguidist!')).toBeInTheDocument();\n});\n\ntest('should render a sidebar if showSidebar is not set', () => {\n\tconst { getByTestId } = render(\n\t\t<StyleGuide {...defaultProps} sections={sections} allSections={sections} />\n\t);\n\tconst sidebar = within(getByTestId('sidebar'));\n\tconst links = sidebar.getAllByRole('link');\n\texpect(links.map((node: any) => node.href)).toEqual([\n\t\t'http://localhost/#foo',\n\t\t'http://localhost/#bar',\n\t]);\n\texpect(links.map(node => node.textContent)).toEqual(['Foo', 'Bar']);\n});\n\ntest('should not render a sidebar if showSidebar is false', () => {\n\tconst { queryByTestId } = render(\n\t\t<StyleGuide\n\t\t\t{...defaultProps}\n\t\t\tconfig={{\n\t\t\t\t...config,\n\t\t\t\tshowSidebar: false,\n\t\t\t}}\n\t\t\tsections={sections}\n\t\t\tallSections={sections}\n\t\t/>\n\t);\n\texpect(queryByTestId('sidebar')).not.toBeInTheDocument();\n});\n\ntest('should not render a sidebar in isolation mode', () => {\n\tconst { queryByTestId } = render(\n\t\t<StyleGuide\n\t\t\t{...defaultProps}\n\t\t\tsections={sections}\n\t\t\tallSections={sections}\n\t\t\tdisplayMode={DisplayModes.component}\n\t\t/>\n\t);\n\texpect(queryByTestId('sidebar')).not.toBeInTheDocument();\n});\n\ntest('should render a sidebar if pagePerSection is true', () => {\n\tconst { getByTestId } = render(\n\t\t<StyleGuide\n\t\t\t{...defaultProps}\n\t\t\tsections={sections}\n\t\t\tallSections={sections}\n\t\t\tdisplayMode={DisplayModes.all}\n\t\t\tpagePerSection\n\t\t/>\n\t);\n\texpect(getByTestId('sidebar')).toBeInTheDocument();\n});\n\ndescribe('error handling', () => {\n\tconst console$error = console.error;\n\tbeforeAll(() => {\n\t\tconsole.error = jest.fn();\n\t});\n\tafterAll(() => {\n\t\tconsole.error = console$error;\n\t});\n\ttest('should render an error when componentDidCatch() is triggered', () => {\n\t\tconst { getByText } = render(\n\t\t\t<StyleGuide {...defaultProps} patterns={null as any} welcomeScreen />\n\t\t);\n\t\texpect(getByText(/Page not found/i)).toBeInTheDocument();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/StyleGuide/StyleGuide.tsx",
    "content": "import React, { Component } from 'react';\nimport TableOfContents from 'rsg-components/TableOfContents';\nimport StyleGuideRenderer from 'rsg-components/StyleGuide/StyleGuideRenderer';\nimport Sections from 'rsg-components/Sections';\nimport Welcome from 'rsg-components/Welcome';\nimport Error from 'rsg-components/Error';\nimport NotFound from 'rsg-components/NotFound';\nimport Context from 'rsg-components/Context';\nimport { HOMEPAGE } from '../../../scripts/consts';\nimport { DisplayModes } from '../../consts';\nimport * as Rsg from '../../../typings';\n\n/**\n * This function will return true, if the sidebar should be visible and false otherwise.\n *\n * These sorted conditions (highest precedence first) define the visibility\n * state of the sidebar.\n *\n * - Sidebar is hidden for isolated example views\n * - Sidebar is always visible when pagePerSection\n * - Sidebar is hidden when showSidebar is set to false\n * - Sidebar is visible when showSidebar is set to true for non-isolated views\n *\n * @param {string} displayMode\n * @param {boolean} showSidebar\n * @param {boolean} pagePerSection\n * @returns {boolean}\n */\nfunction hasSidebar(displayMode: string | undefined, showSidebar: boolean): boolean {\n\treturn displayMode === DisplayModes.notFound || (showSidebar && displayMode === DisplayModes.all);\n}\n\nexport interface StyleGuideProps {\n\tcodeRevision: number;\n\tcssRevision: string;\n\tconfig: Rsg.ProcessedStyleguidistConfig;\n\tslots: any;\n\tsections: Rsg.Section[];\n\twelcomeScreen?: boolean;\n\tpatterns?: string[];\n\tdisplayMode?: string;\n\tallSections?: Rsg.Section[];\n\tpagePerSection?: boolean;\n}\n\ninterface StyleGuideState {\n\terror: Error | boolean;\n\tinfo: React.ErrorInfo | null;\n}\n\nexport default class StyleGuide extends Component<StyleGuideProps, StyleGuideState> {\n\tpublic state = {\n\t\terror: false,\n\t\tinfo: null,\n\t};\n\n\tpublic componentDidCatch(error: Error, info: React.ErrorInfo) {\n\t\tthis.setState({\n\t\t\terror,\n\t\t\tinfo,\n\t\t});\n\t}\n\n\tpublic render() {\n\t\tconst { error, info }: StyleGuideState = this.state;\n\t\tconst {\n\t\t\tconfig,\n\t\t\tsections,\n\t\t\twelcomeScreen,\n\t\t\tpatterns,\n\t\t\tdisplayMode = DisplayModes.all,\n\t\t\tallSections,\n\t\t\tpagePerSection,\n\t\t\tcodeRevision,\n\t\t\tcssRevision,\n\t\t\tslots,\n\t\t} = this.props;\n\n\t\tif (error && info) {\n\t\t\treturn <Error error={error} info={info} />;\n\t\t}\n\n\t\tif (welcomeScreen && patterns) {\n\t\t\treturn <Welcome patterns={patterns} />;\n\t\t}\n\n\t\treturn (\n\t\t\t<Context.Provider\n\t\t\t\tvalue={{\n\t\t\t\t\tcodeRevision,\n\t\t\t\t\tconfig,\n\t\t\t\t\tslots,\n\t\t\t\t\tdisplayMode: displayMode || DisplayModes.all,\n\t\t\t\t\tcssRevision,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<StyleGuideRenderer\n\t\t\t\t\tkey={cssRevision}\n\t\t\t\t\ttitle={config.title}\n\t\t\t\t\tversion={config.version}\n\t\t\t\t\thomepageUrl={HOMEPAGE}\n\t\t\t\t\ttoc={\n\t\t\t\t\t\tallSections ? (\n\t\t\t\t\t\t\t<TableOfContents\n\t\t\t\t\t\t\t\tsections={allSections}\n\t\t\t\t\t\t\t\tuseRouterLinks={pagePerSection}\n\t\t\t\t\t\t\t\ttocMode={config.tocMode}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null\n\t\t\t\t\t}\n\t\t\t\t\thasSidebar={hasSidebar(displayMode, config.showSidebar)}\n\t\t\t\t>\n\t\t\t\t\t{sections.length ? <Sections sections={sections} depth={1} /> : <NotFound />}\n\t\t\t\t</StyleGuideRenderer>\n\t\t\t</Context.Provider>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "src/client/rsg-components/StyleGuide/StyleGuideRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Logo from 'rsg-components/Logo';\nimport Markdown from 'rsg-components/Markdown';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport cx from 'clsx';\nimport Ribbon from 'rsg-components/Ribbon';\nimport Version from 'rsg-components/Version';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ color, fontFamily, fontSize, sidebarWidth, mq, space, maxWidth }: Rsg.Theme) => ({\n\troot: {\n\t\tminHeight: '100vh',\n\t\tbackgroundColor: color.baseBackground,\n\t},\n\thasSidebar: {\n\t\tpaddingLeft: sidebarWidth,\n\t\t[mq.small]: {\n\t\t\tpaddingLeft: 0,\n\t\t},\n\t},\n\tcontent: {\n\t\tmaxWidth,\n\t\tpadding: [[space[2], space[4]]],\n\t\tmargin: [[0, 'auto']],\n\t\t[mq.small]: {\n\t\t\tpadding: space[2],\n\t\t},\n\t\tdisplay: 'block',\n\t},\n\tsidebar: {\n\t\tbackgroundColor: color.sidebarBackground,\n\t\tborder: [[color.border, 'solid']],\n\t\tborderWidth: [[0, 1, 0, 0]],\n\t\tposition: 'fixed',\n\t\ttop: 0,\n\t\tleft: 0,\n\t\tbottom: 0,\n\t\twidth: sidebarWidth,\n\t\toverflow: 'auto',\n\t\tWebkitOverflowScrolling: 'touch',\n\t\t[mq.small]: {\n\t\t\tposition: 'static',\n\t\t\twidth: 'auto',\n\t\t\tborderWidth: [[1, 0, 0, 0]],\n\t\t\tpaddingBottom: space[0],\n\t\t},\n\t},\n\tlogo: {\n\t\tpadding: space[2],\n\t\tborderBottom: [[1, color.border, 'solid']],\n\t},\n\tfooter: {\n\t\tdisplay: 'block',\n\t\tcolor: color.light,\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.small,\n\t},\n});\n\ninterface StyleGuideRendererProps extends JssInjectedProps {\n\ttitle: string;\n\tversion?: string;\n\thomepageUrl: string;\n\tchildren: React.ReactNode;\n\ttoc?: React.ReactNode;\n\thasSidebar?: boolean;\n}\n\nexport const StyleGuideRenderer: React.FunctionComponent<StyleGuideRendererProps> = ({\n\tclasses,\n\ttitle,\n\tversion,\n\thomepageUrl,\n\tchildren,\n\ttoc,\n\thasSidebar,\n}) => {\n\treturn (\n\t\t<div className={cx(classes.root, hasSidebar && classes.hasSidebar)}>\n\t\t\t<main className={classes.content}>\n\t\t\t\t{children}\n\t\t\t\t<footer className={classes.footer}>\n\t\t\t\t\t<Markdown text={`Created with [React Styleguidist](${homepageUrl})`} />\n\t\t\t\t</footer>\n\t\t\t</main>\n\t\t\t{hasSidebar && (\n\t\t\t\t<div className={classes.sidebar} data-testid=\"sidebar\">\n\t\t\t\t\t<header className={classes.logo}>\n\t\t\t\t\t\t<Logo>{title}</Logo>\n\t\t\t\t\t\t{version && <Version>{version}</Version>}\n\t\t\t\t\t</header>\n\t\t\t\t\t{toc}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<Ribbon />\n\t\t</div>\n\t);\n};\n\nStyleGuideRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\ttitle: PropTypes.string.isRequired,\n\tversion: PropTypes.string,\n\thomepageUrl: PropTypes.string.isRequired,\n\tchildren: PropTypes.any.isRequired,\n\ttoc: PropTypes.any.isRequired,\n\thasSidebar: PropTypes.bool,\n};\n\nexport default Styled<StyleGuideRendererProps>(styles)(StyleGuideRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/StyleGuide/index.ts",
    "content": "export { default } from 'rsg-components/StyleGuide/StyleGuide';\n"
  },
  {
    "path": "src/client/rsg-components/Styled/Styled.spec.tsx",
    "content": "import React, { Component } from 'react';\nimport { render } from '@testing-library/react';\nimport '@testing-library/jest-dom/extend-expect';\nimport Styled, { JssInjectedProps } from './Styled';\nimport Context from '../Context';\n\nconst context = {\n\tconfig: {\n\t\ttheme: {},\n\t\tstyles: {},\n\t},\n};\n\nconst Provider = (props: any) => <Context.Provider value={context} {...props} />;\n\n/* eslint-disable react/prefer-stateless-function, react/prop-types */\n\nconst styles = () => ({\n\tfoo: {\n\t\tcolor: 'red',\n\t},\n});\n\ninterface MockProps extends JssInjectedProps {\n\ttestId?: string;\n}\n\nclass TestRenderer extends Component<MockProps> {\n\tpublic render() {\n\t\treturn <div className={this.props.classes.foo} data-testid={this.props.testId} />;\n\t}\n}\n\ntest('should set displayName', () => {\n\tconst WrappedComponent = Styled(styles)(TestRenderer);\n\texpect(WrappedComponent.displayName).toBe('Styled(Test)');\n});\n\ntest('should wrap a component and pass props and classes', () => {\n\tconst WrappedComponent = Styled<MockProps>(styles)(TestRenderer);\n\tconst { getByTestId } = render(\n\t\t<Provider>\n\t\t\t<WrappedComponent testId=\"element\" />\n\t\t</Provider>\n\t);\n\texpect(getByTestId('element')).toHaveAttribute('class', expect.stringMatching(/^rsg--foo-\\d+$/));\n});\n"
  },
  {
    "path": "src/client/rsg-components/Styled/Styled.tsx",
    "content": "import React, { Component, ComponentType } from 'react';\nimport { Styles, StyleSheet, Classes } from 'jss';\nimport Context, { StyleGuideContextContents } from 'rsg-components/Context';\nimport createStyleSheet from '../../styles/createStyleSheet';\nimport * as Rsg from '../../../typings';\n\nexport interface JssInjectedProps {\n\tclasses: Classes;\n}\n\nexport default function StyleHOC<P extends JssInjectedProps>(\n\tstyles: (t: Rsg.Theme) => Styles<string>\n): (WrappedComponent: ComponentType<P>) => ComponentType<Omit<P, keyof JssInjectedProps>> {\n\treturn (WrappedComponent: ComponentType<P>) => {\n\t\tconst componentName = WrappedComponent.name.replace(/Renderer$/, '');\n\t\treturn class extends Component<Omit<P, keyof JssInjectedProps>> {\n\t\t\tpublic static displayName = `Styled(${componentName})`;\n\t\t\tpublic static contextType = Context;\n\t\t\tprivate sheet: StyleSheet;\n\t\t\tpublic constructor(\n\t\t\t\tprops: Omit<P, keyof JssInjectedProps>,\n\t\t\t\tcontext: StyleGuideContextContents\n\t\t\t) {\n\t\t\t\tsuper(props, context);\n\t\t\t\tthis.sheet = createStyleSheet(\n\t\t\t\t\tstyles,\n\t\t\t\t\t// the protection here is useful for tests\n\t\t\t\t\tcontext.config || {},\n\t\t\t\t\tcomponentName,\n\t\t\t\t\tcontext.cssRevision\n\t\t\t\t);\n\t\t\t\tthis.sheet.update(props).attach();\n\t\t\t}\n\n\t\t\tpublic componentDidUpdate(nextProps: P) {\n\t\t\t\tthis.sheet.update(nextProps);\n\t\t\t}\n\n\t\t\tpublic render() {\n\t\t\t\treturn <WrappedComponent {...({ ...this.props, classes: this.sheet.classes } as P)} />;\n\t\t\t}\n\t\t};\n\t};\n}\n"
  },
  {
    "path": "src/client/rsg-components/Styled/index.ts",
    "content": "export { default } from 'rsg-components/Styled/Styled';\nexport * from 'rsg-components/Styled/Styled';\n"
  },
  {
    "path": "src/client/rsg-components/TabButton/TabButton.spec.tsx",
    "content": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport TabButton from './index';\n\ntest('should call onClick handler when the button is clicked', () => {\n\tconst onClick = jest.fn();\n\tconst { getByText } = render(\n\t\t<TabButton name=\"pizza\" onClick={onClick}>\n\t\t\tPizza\n\t\t</TabButton>\n\t);\n\tfireEvent.click(getByText(/pizza/i));\n\texpect(onClick).toBeCalledTimes(1);\n});\n"
  },
  {
    "path": "src/client/rsg-components/TabButton/TabButtonRenderer.tsx",
    "content": "import React from 'react';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport { Styles } from 'jss';\nimport cx from 'clsx';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({\n\tspace,\n\tcolor,\n\tfontFamily,\n\tfontSize,\n\tbuttonTextTransform,\n}: Rsg.Theme): Styles => ({\n\tbutton: {\n\t\tpadding: [[space[1], 0]],\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.base,\n\t\tcolor: color.light,\n\t\tbackground: 'transparent',\n\t\ttextTransform: buttonTextTransform,\n\t\ttransition: 'color 750ms ease-out',\n\t\tborder: 'none',\n\t\tcursor: 'pointer',\n\t\t'&:hover, &:focus': {\n\t\t\tisolate: false,\n\t\t\toutline: 0,\n\t\t\tcolor: color.linkHover,\n\t\t\ttransition: 'color 150ms ease-in',\n\t\t},\n\t\t'&:focus:not($isActive)': {\n\t\t\tisolate: false,\n\t\t\toutline: [[1, 'dotted', color.linkHover]],\n\t\t},\n\t\t'& + &': {\n\t\t\tisolate: false,\n\t\t\tmarginLeft: space[1],\n\t\t},\n\t},\n\tisActive: {\n\t\tborderBottom: [[2, color.linkHover, 'solid']],\n\t},\n});\n\ninterface TabButtonProps extends JssInjectedProps {\n\tclassName?: string;\n\tname: string;\n\tonClick: (e: React.MouseEvent) => void;\n\tactive?: boolean;\n\tchildren: React.ReactNode;\n}\n\nexport const TabButtonRenderer: React.FunctionComponent<TabButtonProps> = ({\n\tclasses,\n\tname,\n\tclassName,\n\tonClick,\n\tactive = false,\n\tchildren,\n}) => {\n\tconst classNames = cx(classes.button, className, {\n\t\t[classes.isActive]: active,\n\t});\n\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tname={name}\n\t\t\tclassName={classNames}\n\t\t\tonClick={onClick}\n\t\t\taria-pressed={active}\n\t\t>\n\t\t\t{children}\n\t\t</button>\n\t);\n};\n\nexport default Styled<TabButtonProps>(styles)(TabButtonRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/TabButton/index.ts",
    "content": "export { default } from 'rsg-components/TabButton/TabButtonRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Table/Table.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { TableRenderer, styles } from './TableRenderer';\n\nconst columns = [\n\t{\n\t\tcaption: 'Name',\n\t\t// eslint-disable-next-line react/prop-types\n\t\trender: ({ name }: { name: string }) => <span>name: {name}</span>,\n\t},\n\t{\n\t\tcaption: 'Type',\n\t\t// eslint-disable-next-line react/prop-types\n\t\trender: ({ type }: { type: string }) => <span>type: {type}</span>,\n\t},\n];\nconst rows = [\n\t{ name: 'Quattro formaggi', type: 'pizza' },\n\t{ name: 'Tiramisu', type: 'desert' },\n\t{ name: 'Unicorn', type: 'animal' },\n];\nconst props = {\n\tclasses: classes(styles),\n\tgetRowKey: (row: { name: string }) => row.name,\n};\n\nit('should render a table', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<TableRenderer {...props} columns={columns} rows={rows} />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Table/TableRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ space, color, fontFamily, fontSize }: Rsg.Theme) => ({\n\ttable: {\n\t\twidth: '100%',\n\t\tborderCollapse: 'collapse',\n\t\tmarginBottom: space[4],\n\t},\n\ttableHead: {\n\t\tborderBottom: [[1, color.border, 'solid']],\n\t},\n\tcellHeading: {\n\t\tcolor: color.base,\n\t\tpaddingRight: space[2],\n\t\tpaddingBottom: space[1],\n\t\ttextAlign: 'left',\n\t\tfontFamily: fontFamily.base,\n\t\tfontWeight: 'bold',\n\t\tfontSize: fontSize.small,\n\t\twhiteSpace: 'nowrap',\n\t},\n\tcell: {\n\t\tcolor: color.base,\n\t\tpaddingRight: space[2],\n\t\tpaddingTop: space[1],\n\t\tpaddingBottom: space[1],\n\t\tverticalAlign: 'top',\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.small,\n\t\t'&:last-child': {\n\t\t\tisolate: false,\n\t\t\twidth: '99%',\n\t\t\tpaddingRight: 0,\n\t\t},\n\t\t'& p:last-child': {\n\t\t\tisolate: false,\n\t\t\tmarginBottom: 0,\n\t\t},\n\t},\n});\n\ninterface TableProps extends JssInjectedProps {\n\tcolumns: {\n\t\tcaption: string;\n\t\trender(row: any): React.ReactNode;\n\t}[];\n\trows: any[];\n\tgetRowKey(row: any): string;\n}\n\nexport const TableRenderer: React.FunctionComponent<TableProps> = ({\n\tclasses,\n\tcolumns,\n\trows,\n\tgetRowKey,\n}) => {\n\treturn (\n\t\t<table className={classes.table}>\n\t\t\t<thead className={classes.tableHead}>\n\t\t\t\t<tr>\n\t\t\t\t\t{columns.map(({ caption }) => (\n\t\t\t\t\t\t<th key={caption} className={classes.cellHeading}>\n\t\t\t\t\t\t\t{caption}\n\t\t\t\t\t\t</th>\n\t\t\t\t\t))}\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\t{rows.map(row => (\n\t\t\t\t\t<tr key={getRowKey(row)}>\n\t\t\t\t\t\t{columns.map(({ render }, index) => (\n\t\t\t\t\t\t\t<td key={index} className={classes.cell}>\n\t\t\t\t\t\t\t\t{render(row)}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tr>\n\t\t\t\t))}\n\t\t\t</tbody>\n\t\t</table>\n\t);\n};\n\nTableRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tcolumns: PropTypes.arrayOf(\n\t\tPropTypes.shape({\n\t\t\tcaption: PropTypes.string.isRequired,\n\t\t\trender: PropTypes.func.isRequired,\n\t\t}).isRequired\n\t).isRequired,\n\trows: PropTypes.arrayOf(PropTypes.object).isRequired,\n\tgetRowKey: PropTypes.func.isRequired,\n};\n\nexport default Styled<TableProps>(styles)(TableRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Table/__snapshots__/Table.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should render a table 1`] = `\n<table\n  className=\"table\"\n>\n  <thead\n    className=\"tableHead\"\n  >\n    <tr>\n      <th\n        className=\"cellHeading\"\n      >\n        Name\n      </th>\n      <th\n        className=\"cellHeading\"\n      >\n        Type\n      </th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td\n        className=\"cell\"\n      >\n        <span>\n          name: \n          Quattro formaggi\n        </span>\n      </td>\n      <td\n        className=\"cell\"\n      >\n        <span>\n          type: \n          pizza\n        </span>\n      </td>\n    </tr>\n    <tr>\n      <td\n        className=\"cell\"\n      >\n        <span>\n          name: \n          Tiramisu\n        </span>\n      </td>\n      <td\n        className=\"cell\"\n      >\n        <span>\n          type: \n          desert\n        </span>\n      </td>\n    </tr>\n    <tr>\n      <td\n        className=\"cell\"\n      >\n        <span>\n          name: \n          Unicorn\n        </span>\n      </td>\n      <td\n        className=\"cell\"\n      >\n        <span>\n          type: \n          animal\n        </span>\n      </td>\n    </tr>\n  </tbody>\n</table>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Table/index.ts",
    "content": "export { default } from 'rsg-components/Table/TableRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/TableOfContents/TableOfContents.spec.tsx",
    "content": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport TableOfContents from './TableOfContents';\nimport { TableOfContentsRenderer } from './TableOfContentsRenderer';\nimport Context from '../Context';\n\nconst components = [\n\t{\n\t\tvisibleName: 'Button',\n\t\tname: 'Button',\n\t\thref: '#button',\n\t\tslug: 'button',\n\t},\n\t{\n\t\tvisibleName: 'Input',\n\t\tname: 'Input',\n\t\thref: '#input',\n\t\tslug: 'input',\n\t},\n\t{\n\t\tvisibleName: 'Textarea',\n\t\tname: 'Textarea',\n\t\thref: '#textarea',\n\t\tslug: 'textarea',\n\t},\n];\n\nconst sections = [\n\t{\n\t\tvisibleName: 'Introduction',\n\t\tname: 'Introduction',\n\t\thref: '#introduction',\n\t\tslug: 'introduction',\n\t\tcontent: 'intro.md',\n\t},\n\t{\n\t\tvisibleName: 'Buttons',\n\t\tname: 'Buttons',\n\t\thref: '#buttons',\n\t\tslug: 'buttons',\n\t\tcomponents: [\n\t\t\t{\n\t\t\t\tvisibleName: 'Button',\n\t\t\t\tname: 'Button',\n\t\t\t\thref: '#button',\n\t\t\t\tslug: 'button',\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tvisibleName: 'Forms',\n\t\tname: 'Forms',\n\t\thref: '#forms',\n\t\tslug: 'forms',\n\t\tcomponents: [\n\t\t\t{\n\t\t\t\tvisibleName: 'Input',\n\t\t\t\tname: 'Input',\n\t\t\t\thref: '#input',\n\t\t\t\tslug: 'input',\n\t\t\t},\n\t\t\t{\n\t\t\t\tvisibleName: 'Textarea',\n\t\t\t\tname: 'Textarea',\n\t\t\t\thref: '#textarea',\n\t\t\t\tslug: 'textarea',\n\t\t\t},\n\t\t],\n\t},\n];\n\nit('should filter list when search field contains a query', () => {\n\tconst searchTerm = 'put';\n\tconst { getByPlaceholderText, getAllByTestId, getByTestId } = render(\n\t\t<TableOfContents\n\t\t\tsections={[\n\t\t\t\t{\n\t\t\t\t\tvisibleName: 'Input',\n\t\t\t\t\thref: '#input',\n\t\t\t\t\tcomponents,\n\t\t\t\t},\n\t\t\t]}\n\t\t\ttocMode=\"expand\"\n\t\t/>\n\t);\n\texpect(getAllByTestId('rsg-toc-link').length).toBe(3);\n\tfireEvent.change(getByPlaceholderText('Filter by name'), { target: { value: searchTerm } });\n\texpect(getAllByTestId('rsg-toc-link')).toHaveLength(1);\n\texpect(getByTestId('rsg-toc-link')).toHaveTextContent('Input');\n});\n\nit('should filter section names', () => {\n\tconst searchTerm = 'frm';\n\tconst { getByPlaceholderText, getAllByTestId, getByTestId } = render(\n\t\t<TableOfContents sections={sections} />\n\t);\n\texpect(getAllByTestId('rsg-toc-link').length).toBe(6);\n\tfireEvent.change(getByPlaceholderText('Filter by name'), { target: { value: searchTerm } });\n\texpect(getAllByTestId('rsg-toc-link')).toHaveLength(1);\n\texpect(getByTestId('rsg-toc-link')).toHaveTextContent('Forms');\n});\n\nit('should call a callback when input value changed', () => {\n\tconst onSearchTermChange = jest.fn();\n\tconst searchTerm = 'foo';\n\tconst newSearchTerm = 'bar';\n\tconst { getByRole } = render(\n\t\t<TableOfContentsRenderer\n\t\t\tclasses={{}}\n\t\t\tsearchTerm={searchTerm}\n\t\t\tonSearchTermChange={onSearchTermChange}\n\t\t>\n\t\t\t<div>foo</div>\n\t\t</TableOfContentsRenderer>\n\t);\n\n\tfireEvent.change(getByRole('textbox'), { target: { value: newSearchTerm } });\n\n\texpect(onSearchTermChange).toBeCalledWith(newSearchTerm);\n});\n\nit('should render content of subsections of a section that has no components', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<TableOfContents\n\t\t\tsections={[{ sections: [{ content: 'intro.md' }, { content: 'chapter.md' }] }]}\n\t\t/>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchInlineSnapshot(`\n\t\t<Styled(TableOfContents)\n\t\t  onSearchTermChange={[Function]}\n\t\t  searchTerm=\"\"\n\t\t>\n\t\t  <ComponentsList\n\t\t    items={\n\t\t      Array [\n\t\t        Object {\n\t\t          \"components\": Array [],\n\t\t          \"content\": undefined,\n\t\t          \"forcedOpen\": false,\n\t\t          \"heading\": false,\n\t\t          \"initialOpen\": true,\n\t\t          \"sections\": Array [],\n\t\t          \"selected\": false,\n\t\t          \"shouldOpenInNewTab\": false,\n\t\t        },\n\t\t        Object {\n\t\t          \"components\": Array [],\n\t\t          \"content\": undefined,\n\t\t          \"forcedOpen\": false,\n\t\t          \"heading\": false,\n\t\t          \"initialOpen\": true,\n\t\t          \"sections\": Array [],\n\t\t          \"selected\": false,\n\t\t          \"shouldOpenInNewTab\": false,\n\t\t        },\n\t\t      ]\n\t\t    }\n\t\t  />\n\t\t</Styled(TableOfContents)>\n\t`);\n});\n\nit('should render components of a single top section as root', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<TableOfContents sections={[{ components }]} />);\n\n\texpect(renderer.getRenderOutput()).toMatchInlineSnapshot(`\n<Styled(TableOfContents)\n  onSearchTermChange={[Function]}\n  searchTerm=\"\"\n>\n  <ComponentsList\n    items={\n      Array [\n        Object {\n          \"components\": Array [],\n          \"content\": undefined,\n          \"forcedOpen\": false,\n          \"heading\": false,\n          \"href\": \"#button\",\n          \"initialOpen\": true,\n          \"name\": \"Button\",\n          \"sections\": Array [],\n          \"selected\": false,\n          \"shouldOpenInNewTab\": false,\n          \"slug\": \"button\",\n          \"visibleName\": \"Button\",\n        },\n        Object {\n          \"components\": Array [],\n          \"content\": undefined,\n          \"forcedOpen\": false,\n          \"heading\": false,\n          \"href\": \"#input\",\n          \"initialOpen\": true,\n          \"name\": \"Input\",\n          \"sections\": Array [],\n          \"selected\": false,\n          \"shouldOpenInNewTab\": false,\n          \"slug\": \"input\",\n          \"visibleName\": \"Input\",\n        },\n        Object {\n          \"components\": Array [],\n          \"content\": undefined,\n          \"forcedOpen\": false,\n          \"heading\": false,\n          \"href\": \"#textarea\",\n          \"initialOpen\": true,\n          \"name\": \"Textarea\",\n          \"sections\": Array [],\n          \"selected\": false,\n          \"shouldOpenInNewTab\": false,\n          \"slug\": \"textarea\",\n          \"visibleName\": \"Textarea\",\n        },\n      ]\n    }\n  />\n</Styled(TableOfContents)>\n`);\n});\n\nit('should render as the link will open in a new window only if external presents as true', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<TableOfContents\n\t\t\tsections={[\n\t\t\t\t{\n\t\t\t\t\tsections: [\n\t\t\t\t\t\t{ content: 'intro.md', href: 'http://example.com' },\n\t\t\t\t\t\t{ content: 'chapter.md', href: 'http://example.com', external: true },\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t]}\n\t\t/>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchInlineSnapshot(`\n<Styled(TableOfContents)\n  onSearchTermChange={[Function]}\n  searchTerm=\"\"\n>\n  <ComponentsList\n    items={\n      Array [\n        Object {\n          \"components\": Array [],\n          \"content\": undefined,\n          \"forcedOpen\": false,\n          \"heading\": false,\n          \"href\": \"http://example.com\",\n          \"initialOpen\": true,\n          \"sections\": Array [],\n          \"selected\": false,\n          \"shouldOpenInNewTab\": false,\n        },\n        Object {\n          \"components\": Array [],\n          \"content\": undefined,\n          \"external\": true,\n          \"forcedOpen\": false,\n          \"heading\": false,\n          \"href\": \"http://example.com\",\n          \"initialOpen\": true,\n          \"sections\": Array [],\n          \"selected\": false,\n          \"shouldOpenInNewTab\": false,\n        },\n      ]\n    }\n  />\n</Styled(TableOfContents)>\n`);\n});\n\n/**\n * testing this layer with no mocking makes no sense...\n */\nit('should render components with useRouterLinks', () => {\n\tconst { getAllByRole } = render(\n\t\t<TableOfContents\n\t\t\tuseRouterLinks\n\t\t\tsections={[\n\t\t\t\t{\n\t\t\t\t\tsections: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvisibleName: '1',\n\t\t\t\t\t\t\tname: 'Components',\n\t\t\t\t\t\t\thref: '#/Components',\n\t\t\t\t\t\t\tslug: 'components',\n\t\t\t\t\t\t\tcontent: 'intro.md',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvisibleName: '2',\n\t\t\t\t\t\t\tcontent: 'chapter.md',\n\t\t\t\t\t\t\thref: '#/Chap',\n\t\t\t\t\t\t\tslug: 'chap',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t]}\n\t\t/>\n\t);\n\n\texpect((getAllByRole('link')[0] as any).href).toMatch(/\\/#\\/Components$/);\n});\n\n/**\n * testing this layer with no mocking makes no sense...\n * This test should not exist but for good coverage policy this is necessary\n */\nit('should detect sections containing current selection when tocMode is collapse', () => {\n\tconst context = {\n\t\tconfig: {\n\t\t\ttocMode: 'collapse',\n\t\t},\n\t};\n\n\tconst Provider = (props: any) => <Context.Provider value={context} {...props} />;\n\n\tconst { getByText } = render(\n\t\t<Provider>\n\t\t\t<TableOfContents\n\t\t\t\ttocMode=\"collapse\"\n\t\t\t\tsections={[\n\t\t\t\t\t{\n\t\t\t\t\t\tsections: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvisibleName: '1',\n\t\t\t\t\t\t\t\thref: '#/components',\n\t\t\t\t\t\t\t\tslug: 'components',\n\t\t\t\t\t\t\t\tsections: [{ visibleName: '1.1', href: '#/button', slug: 'button' }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvisibleName: '2',\n\t\t\t\t\t\t\t\thref: '#/chap',\n\t\t\t\t\t\t\t\tslug: 'chap',\n\t\t\t\t\t\t\t\tcontent: 'chapter.md',\n\t\t\t\t\t\t\t\tsections: [{ visibleName: '2.1', href: '#/chapter-1', slug: 'chapter-1' }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvisibleName: '3',\n\t\t\t\t\t\t\t\thref: 'http://react-styleguidist.com',\n\t\t\t\t\t\t\t\tslug: 'react-styleguidist',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t]}\n\t\t\t\tloc={{ pathname: '', hash: 'button' }}\n\t\t\t/>\n\t\t</Provider>\n\t);\n\n\texpect(getByText('1.1')).not.toBeEmptyDOMElement();\n});\n\nit('should show sections with expand: true when tocMode is collapse', () => {\n\tconst { getByText } = render(\n\t\t<TableOfContents\n\t\t\ttocMode=\"collapse\"\n\t\t\tsections={[\n\t\t\t\t{\n\t\t\t\t\tsections: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvisibleName: '1',\n\t\t\t\t\t\t\texpand: true,\n\t\t\t\t\t\t\thref: '#/components',\n\t\t\t\t\t\t\tslug: 'components',\n\t\t\t\t\t\t\tsections: [{ visibleName: '1.1', href: '#/button', slug: 'button' }],\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvisibleName: '2',\n\t\t\t\t\t\t\thref: '#/chap',\n\t\t\t\t\t\t\tslug: 'chap',\n\t\t\t\t\t\t\tcontent: 'chapter.md',\n\t\t\t\t\t\t\tsections: [{ visibleName: '2.1', href: '#/chapter-1', slug: 'chapter-1' }],\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvisibleName: '3',\n\t\t\t\t\t\t\thref: 'http://react-styleguidist.com',\n\t\t\t\t\t\t\tslug: 'react-styleguidist',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t]}\n\t\t/>\n\t);\n\texpect(getByText('1.1')).toBeVisible();\n});\n"
  },
  {
    "path": "src/client/rsg-components/TableOfContents/TableOfContents.tsx",
    "content": "import React, { Component } from 'react';\nimport ComponentsList from 'rsg-components/ComponentsList';\nimport TableOfContentsRenderer from 'rsg-components/TableOfContents/TableOfContentsRenderer';\nimport filterSectionsByName from '../../utils/filterSectionsByName';\nimport { getHash } from '../../utils/handleHash';\nimport * as Rsg from '../../../typings';\n\ninterface TableOfContentsProps {\n\tsections: Rsg.Section[];\n\tuseRouterLinks?: boolean;\n\ttocMode?: string;\n\tloc?: { hash: string; pathname: string };\n}\n\nexport default class TableOfContents extends Component<TableOfContentsProps> {\n\tpublic state = {\n\t\tsearchTerm: '',\n\t};\n\n\tprivate renderLevel(\n\t\tsections: Rsg.TOCItem[],\n\t\tuseRouterLinks = false,\n\t\thashPath: string[] = [],\n\t\tuseHashId = false\n\t): { content: React.ReactElement; containsSelected: boolean } {\n\t\t// Match selected component in both basic routing and pagePerSection routing.\n\t\tconst { hash, pathname } = this.props.loc ?? window.location;\n\t\tconst windowHash = pathname + (useRouterLinks ? hash : getHash(hash));\n\n\t\tlet childrenContainSelected = false;\n\t\tconst processedItems = sections.map((section) => {\n\t\t\tconst children = [...(section.sections || []), ...(section.components || [])];\n\t\t\tconst sectionDepth = section.sectionDepth || 0;\n\t\t\tconst childHashPath =\n\t\t\t\tsectionDepth === 0 && useHashId\n\t\t\t\t\t? hashPath\n\t\t\t\t\t: [...hashPath, section.name ? section.name : '-'];\n\n\t\t\tconst { content, containsSelected } =\n\t\t\t\tchildren.length > 0\n\t\t\t\t\t? this.renderLevel(children, useRouterLinks, childHashPath, sectionDepth === 0)\n\t\t\t\t\t: { content: undefined, containsSelected: false };\n\n\t\t\tconst selected =\n\t\t\t\t(!useRouterLinks && section.href ? getHash(section.href) : section.href) === windowHash;\n\n\t\t\tif (containsSelected || selected) {\n\t\t\t\tchildrenContainSelected = true;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...section,\n\t\t\t\theading: !!section.name && children.length > 0,\n\t\t\t\tcontent,\n\t\t\t\tselected,\n\t\t\t\tshouldOpenInNewTab: !!section.external && !!section.externalLink,\n\t\t\t\tinitialOpen: this.props.tocMode !== 'collapse' || containsSelected || section.expand,\n\t\t\t\tforcedOpen: !!this.state.searchTerm.length,\n\t\t\t};\n\t\t});\n\t\treturn {\n\t\t\tcontent: <ComponentsList items={processedItems} />,\n\t\t\tcontainsSelected: childrenContainSelected,\n\t\t};\n\t}\n\n\tprivate renderSections() {\n\t\tconst { searchTerm } = this.state;\n\t\tconst { sections, useRouterLinks } = this.props;\n\t\t// If there is only one section, we treat it as a root section\n\t\t// In this case the name of the section won't be rendered and it won't get left padding\n\t\t// Since a section can contain only other sections,\n\t\t// we need to make sure not to loose the subsections.\n\t\t// We will treat those subsections as the new roots.\n\t\tconst firstLevel =\n\t\t\tsections.length === 1\n\t\t\t\t? // only use subsections if there actually are subsections\n\t\t\t\t  sections[0].sections && sections[0].sections.length\n\t\t\t\t\t? sections[0].sections\n\t\t\t\t\t: sections[0].components\n\t\t\t\t: sections;\n\t\tconst filtered = firstLevel\n\t\t\t? filterSectionsByName(firstLevel as Rsg.TOCItem[], searchTerm)\n\t\t\t: firstLevel || [];\n\n\t\treturn this.renderLevel(filtered, useRouterLinks).content;\n\t}\n\n\tpublic render() {\n\t\tconst handleSearchTermChange = (searchTerm: string) => this.setState({ searchTerm });\n\t\treturn (\n\t\t\t<TableOfContentsRenderer\n\t\t\t\tsearchTerm={this.state.searchTerm}\n\t\t\t\tonSearchTermChange={handleSearchTermChange}\n\t\t\t>\n\t\t\t\t{this.renderSections()}\n\t\t\t</TableOfContentsRenderer>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "src/client/rsg-components/TableOfContents/TableOfContentsRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Styles } from 'jss';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ space, color, fontFamily, fontSize, borderRadius }: Rsg.Theme): Styles => ({\n\troot: {\n\t\tfontFamily: fontFamily.base,\n\t},\n\tsearch: {\n\t\tpadding: space[2],\n\t},\n\tinput: {\n\t\tdisplay: 'block',\n\t\twidth: '100%',\n\t\tpadding: space[1],\n\t\tcolor: color.base,\n\t\tbackgroundColor: color.baseBackground,\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.base,\n\t\tborder: [[1, color.border, 'solid']],\n\t\tborderRadius,\n\t\ttransition: 'all ease-in-out .1s',\n\t\t'&:focus': {\n\t\t\tisolate: false,\n\t\t\tborderColor: color.link,\n\t\t\tboxShadow: [[0, 0, 0, 2, color.focus]],\n\t\t\toutline: 0,\n\t\t},\n\t\t'&::placeholder': {\n\t\t\tisolate: false,\n\t\t\tfontFamily: fontFamily.base,\n\t\t\tfontSize: fontSize.base,\n\t\t\tcolor: color.light,\n\t\t},\n\t},\n});\n\ninterface TableOfContentsRendererProps extends JssInjectedProps {\n\tchildren?: React.ReactNode;\n\tsearchTerm: string;\n\tonSearchTermChange(term: string): void;\n}\n\nexport const TableOfContentsRenderer: React.FunctionComponent<TableOfContentsRendererProps> = ({\n\tclasses,\n\tchildren,\n\tsearchTerm,\n\tonSearchTermChange,\n}) => {\n\treturn (\n\t\t<div>\n\t\t\t<div className={classes.root}>\n\t\t\t\t<nav>\n\t\t\t\t\t<div className={classes.search}>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tvalue={searchTerm}\n\t\t\t\t\t\t\tclassName={classes.input}\n\t\t\t\t\t\t\tplaceholder=\"Filter by name\"\n\t\t\t\t\t\t\taria-label=\"Filter by name\"\n\t\t\t\t\t\t\tonChange={(event) => onSearchTermChange(event.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t\t{children}\n\t\t\t\t</nav>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n\nTableOfContentsRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any,\n\tsearchTerm: PropTypes.string.isRequired,\n\tonSearchTermChange: PropTypes.func.isRequired,\n};\n\nexport default Styled<TableOfContentsRendererProps>(styles)(TableOfContentsRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/TableOfContents/index.ts",
    "content": "export { default } from 'rsg-components/TableOfContents/TableOfContents';\n"
  },
  {
    "path": "src/client/rsg-components/Text/Text.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { TextRenderer, styles } from './TextRenderer';\n\nconst props = {\n\tclasses: classes(styles),\n};\n\ndescribe('Text', () => {\n\tit('should render text', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(<TextRenderer {...props}>Pizza</TextRenderer>);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n\n\tit('should render underlined text', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(\n\t\t\t<TextRenderer {...props} underlined>\n\t\t\t\tPizza\n\t\t\t</TextRenderer>\n\t\t);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n\n\tit('should render sized text', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(\n\t\t\t<TextRenderer {...props} size=\"small\">\n\t\t\t\tPizza\n\t\t\t</TextRenderer>\n\t\t);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n\n\tit('should render colored text', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(\n\t\t\t<TextRenderer {...props} color=\"light\">\n\t\t\t\tPizza\n\t\t\t</TextRenderer>\n\t\t);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n\n\tit('should render text with a semantic tag and styles', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(\n\t\t\t<TextRenderer {...props} semantic=\"strong\">\n\t\t\t\tPizza\n\t\t\t</TextRenderer>\n\t\t);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n\n\tit('should render text with a title', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(\n\t\t\t<TextRenderer {...props} title=\"Pasta\">\n\t\t\t\tPizza\n\t\t\t</TextRenderer>\n\t\t);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Text/TextRenderer.tsx",
    "content": "import React from 'react';\nimport cx from 'clsx';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ fontFamily, fontSize, color }: Rsg.Theme) => ({\n\ttext: {\n\t\tfontFamily: fontFamily.base,\n\t},\n\tinheritSize: {\n\t\tfontSize: 'inherit',\n\t},\n\tsmallSize: {\n\t\tfontSize: fontSize.small,\n\t},\n\tbaseSize: {\n\t\tfontSize: fontSize.base,\n\t},\n\ttextSize: {\n\t\tfontSize: fontSize.text,\n\t},\n\tbaseColor: {\n\t\tcolor: color.base,\n\t},\n\tlightColor: {\n\t\tcolor: color.light,\n\t},\n\tem: {\n\t\tfontStyle: 'italic',\n\t},\n\tstrong: {\n\t\tfontWeight: 'bold',\n\t},\n\tisUnderlined: {\n\t\tborderBottom: [[1, 'dotted', color.lightest]],\n\t},\n});\n\nexport interface TextProps extends JssInjectedProps {\n\tsemantic?: 'em' | 'strong';\n\tsize?: 'inherit' | 'small' | 'base' | 'text';\n\tcolor?: 'base' | 'light';\n\tunderlined?: boolean;\n\tchildren: React.ReactNode;\n\t[intrinsicAttribute: string]: any;\n}\n\nexport const TextRenderer: React.FunctionComponent<TextProps> = ({\n\tclasses,\n\tsemantic,\n\tsize = 'inherit',\n\tcolor = 'base',\n\tunderlined = false,\n\tchildren,\n\t...props\n}) => {\n\tconst Tag = semantic || 'span';\n\tconst classNames = cx(classes.text, classes[`${size}Size`], classes[`${color}Color`], {\n\t\t[classes[Tag]]: !!semantic,\n\t\t[classes.isUnderlined]: underlined,\n\t});\n\n\treturn (\n\t\t<Tag {...props} className={classNames}>\n\t\t\t{children}\n\t\t</Tag>\n\t);\n};\n\nexport default Styled<TextProps>(styles)(TextRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Text/__snapshots__/Text.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Text should render colored text 1`] = `\n<span\n  className=\"text inheritSize lightColor\"\n>\n  Pizza\n</span>\n`;\n\nexports[`Text should render sized text 1`] = `\n<span\n  className=\"text smallSize baseColor\"\n>\n  Pizza\n</span>\n`;\n\nexports[`Text should render text 1`] = `\n<span\n  className=\"text inheritSize baseColor\"\n>\n  Pizza\n</span>\n`;\n\nexports[`Text should render text with a semantic tag and styles 1`] = `\n<strong\n  className=\"text inheritSize baseColor strong\"\n>\n  Pizza\n</strong>\n`;\n\nexports[`Text should render text with a title 1`] = `\n<span\n  className=\"text inheritSize baseColor\"\n  title=\"Pasta\"\n>\n  Pizza\n</span>\n`;\n\nexports[`Text should render underlined text 1`] = `\n<span\n  className=\"text inheritSize baseColor isUnderlined\"\n>\n  Pizza\n</span>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Text/index.ts",
    "content": "export { default } from 'rsg-components/Text/TextRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/ToolbarButton/ToolbarButton.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { ToolbarButtonRenderer, styles } from './ToolbarButtonRenderer';\n\nconst props = {\n\tclasses: classes(styles),\n\ttitle: 'Pizza button',\n};\n\nit('should render a button', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<ToolbarButtonRenderer {...props} onClick={() => {}}>\n\t\t\tpizza\n\t\t</ToolbarButtonRenderer>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should render a link', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<ToolbarButtonRenderer {...props} href=\"/foo\">\n\t\t\tpizza\n\t\t</ToolbarButtonRenderer>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should pass a class name to a button', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<ToolbarButtonRenderer {...props} onClick={() => {}} className=\"foo-class\">\n\t\t\tpizza\n\t\t</ToolbarButtonRenderer>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should pass a class name to a link', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<ToolbarButtonRenderer {...props} href=\"/foo\" className=\"foo-class\">\n\t\t\tpizza\n\t\t</ToolbarButtonRenderer>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should render a button with small styles', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(\n\t\t<ToolbarButtonRenderer {...props} onClick={() => {}} small>\n\t\t\tbutterbrot\n\t\t</ToolbarButtonRenderer>\n\t);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/ToolbarButton/ToolbarButtonRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport cx from 'clsx';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ space, color }: Rsg.Theme) => ({\n\tbutton: {\n\t\tpadding: 2, // Increase clickable area a bit\n\t\tcolor: color.light,\n\t\tbackground: 'transparent',\n\t\ttransition: 'color 750ms ease-out',\n\t\tcursor: 'pointer',\n\t\t'&:hover, &:focus': {\n\t\t\tisolate: false,\n\t\t\tcolor: color.linkHover,\n\t\t\ttransition: 'color 150ms ease-in',\n\t\t},\n\t\t'&:focus': {\n\t\t\tisolate: false,\n\t\t\toutline: [[1, 'dotted', color.linkHover]],\n\t\t},\n\t\t'& + &': {\n\t\t\tisolate: false,\n\t\t\tmarginLeft: space[1],\n\t\t},\n\t\t// Style react-icons icon passed as children\n\t\t'& svg': {\n\t\t\twidth: space[3],\n\t\t\theight: space[3],\n\t\t\tcolor: 'currentColor',\n\t\t\tcursor: 'inherit',\n\t\t},\n\t},\n\tisSmall: {\n\t\t'& svg': {\n\t\t\twidth: 14,\n\t\t\theight: 14,\n\t\t},\n\t},\n});\n\ninterface ToolbarButtonProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n\tclassName?: string;\n\thref?: string;\n\tonClick?: () => void;\n\ttitle?: string;\n\tsmall?: boolean;\n\ttestId?: string;\n}\n\nexport const ToolbarButtonRenderer: React.FunctionComponent<ToolbarButtonProps> = ({\n\tclasses,\n\tclassName,\n\tonClick,\n\thref,\n\ttitle,\n\tsmall,\n\ttestId,\n\tchildren,\n}) => {\n\tconst classNames = cx(classes.button, className, {\n\t\t[classes.isSmall]: small,\n\t});\n\n\tif (href !== undefined) {\n\t\treturn (\n\t\t\t<a href={href} title={title} className={classNames} aria-label={title} data-testid={testId}>\n\t\t\t\t{children}\n\t\t\t</a>\n\t\t);\n\t}\n\n\treturn (\n\t\t<button type=\"button\" onClick={onClick} title={title} className={classNames} aria-label={title}>\n\t\t\t{children}\n\t\t</button>\n\t);\n};\n\nToolbarButtonRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tclassName: PropTypes.string,\n\thref: PropTypes.string,\n\tonClick: PropTypes.func,\n\ttitle: PropTypes.string,\n\tsmall: PropTypes.bool,\n\ttestId: PropTypes.string,\n\tchildren: PropTypes.any,\n};\n\nexport default Styled<ToolbarButtonProps>(styles)(ToolbarButtonRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/ToolbarButton/__snapshots__/ToolbarButton.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should pass a class name to a button 1`] = `\n<button\n  aria-label=\"Pizza button\"\n  className=\"button foo-class\"\n  onClick={[Function]}\n  title=\"Pizza button\"\n  type=\"button\"\n>\n  pizza\n</button>\n`;\n\nexports[`should pass a class name to a link 1`] = `\n<a\n  aria-label=\"Pizza button\"\n  className=\"button foo-class\"\n  href=\"/foo\"\n  title=\"Pizza button\"\n>\n  pizza\n</a>\n`;\n\nexports[`should render a button 1`] = `\n<button\n  aria-label=\"Pizza button\"\n  className=\"button\"\n  onClick={[Function]}\n  title=\"Pizza button\"\n  type=\"button\"\n>\n  pizza\n</button>\n`;\n\nexports[`should render a button with small styles 1`] = `\n<button\n  aria-label=\"Pizza button\"\n  className=\"button isSmall\"\n  onClick={[Function]}\n  title=\"Pizza button\"\n  type=\"button\"\n>\n  butterbrot\n</button>\n`;\n\nexports[`should render a link 1`] = `\n<a\n  aria-label=\"Pizza button\"\n  className=\"button\"\n  href=\"/foo\"\n  title=\"Pizza button\"\n>\n  pizza\n</a>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/ToolbarButton/index.ts",
    "content": "export { default } from 'rsg-components/ToolbarButton/ToolbarButtonRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Tooltip/Tooltip.spec.tsx",
    "content": "import React from 'react';\nimport { render, fireEvent, waitFor } from '@testing-library/react';\nimport Tooltip, { TooltipPlacement } from './TooltipRenderer';\n\nfunction renderComponent(content = 'tooltip', placement?: TooltipPlacement) {\n\treturn render(\n\t\t<Tooltip content={content} placement={placement}>\n\t\t\t<div data-testid=\"child\" />\n\t\t</Tooltip>\n\t);\n}\n\ndescribe('Tooltip', () => {\n\ttest('should render child component as is', () => {\n\t\tconst { container, getByTestId } = renderComponent();\n\t\texpect(container).toContainElement(getByTestId('child'));\n\t});\n\n\ttest('should render content in the tooltop body', () => {\n\t\tconst { container, getByRole } = renderComponent();\n\t\tfireEvent.focus(getByRole('button'));\n\t\texpect(container.querySelector('[data-tippy-root]')).toHaveTextContent('tooltip');\n\t});\n\n\ttest('should show the tooltip by focus in', async () => {\n\t\tconst { container, getByRole } = renderComponent();\n\t\tfireEvent.focus(getByRole('button'));\n\t\tawait waitFor(() =>\n\t\t\texpect(container.querySelector('[data-state=\"visible\"]')).toBeInTheDocument()\n\t\t);\n\t});\n\n\ttest('should show the tooltip by click', async () => {\n\t\tconst { container, getByRole } = renderComponent();\n\t\tfireEvent.click(getByRole('button'));\n\t\tawait waitFor(() =>\n\t\t\texpect(container.querySelector('[data-state=\"visible\"]')).toBeInTheDocument()\n\t\t);\n\t});\n\n\ttest('should show the tooltip by mouse enter', async () => {\n\t\tconst { container, getByRole } = renderComponent();\n\t\tfireEvent.mouseEnter(getByRole('button'));\n\t\tawait waitFor(() =>\n\t\t\texpect(container.querySelector('[data-state=\"visible\"]')).toBeInTheDocument()\n\t\t);\n\t});\n\n\tdescribe.each([['top'], ['right'], ['left'], ['bottom']])(\n\t\t'Test placement attribute',\n\t\tplacement => {\n\t\t\ttest(`should have ${placement} in data-placement attribute`, async () => {\n\t\t\t\t// @ts-ignore\n\t\t\t\tconst { container, getByRole } = renderComponent(undefined, placement);\n\t\t\t\tfireEvent.focus(getByRole('button'));\n\t\t\t\tawait waitFor(() =>\n\t\t\t\t\texpect(container.querySelector('[data-state=\"visible\"]')).toBeInTheDocument()\n\t\t\t\t);\n\t\t\t\texpect(container.querySelector('[data-placement]')).toHaveAttribute(\n\t\t\t\t\t'data-placement',\n\t\t\t\t\tplacement\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t);\n});\n"
  },
  {
    "path": "src/client/rsg-components/Tooltip/TooltipRenderer.tsx",
    "content": "import React from 'react';\nimport Tippy from '@tippyjs/react';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ space, color, borderRadius, fontSize }: Rsg.Theme) => ({\n\ttooltip: {\n\t\t'&.tippy-box': {\n\t\t\ttransitionProperty: [['opacity']],\n\t\t\t'&[data-state=\"hidden\"]': {\n\t\t\t\topacity: 0,\n\t\t\t},\n\t\t},\n\t\t'& .tippy-content': {\n\t\t\tpadding: space[0],\n\t\t\tborder: `1px ${color.border} solid`,\n\t\t\tborderRadius,\n\t\t\tbackground: color.baseBackground,\n\t\t\tboxShadow: [[0, 2, 4, 'rgba(0,0,0,.15)']],\n\t\t\tfontSize: fontSize.small,\n\t\t\tcolor: color.type,\n\t\t},\n\t},\n});\n\nexport type TooltipPlacement = 'top' | 'right' | 'bottom' | 'left';\n\nexport interface TooltipProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n\tcontent: React.ReactNode;\n\tplacement?: TooltipPlacement;\n}\n\nfunction TooltipRenderer({ classes, children, content, placement = 'top' }: TooltipProps) {\n\treturn (\n\t\t<Tippy\n\t\t\tcontent={content}\n\t\t\tclassName={classes.tooltip}\n\t\t\tinteractive\n\t\t\tplacement={placement}\n\t\t\ttrigger=\"click mouseenter focus\"\n\t\t\tarrow={false}\n\t\t>\n\t\t\t<span role=\"button\" tabIndex={0}>\n\t\t\t\t{children}\n\t\t\t</span>\n\t\t</Tippy>\n\t);\n}\n\nexport default Styled<TooltipProps>(styles)(TooltipRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Tooltip/index.ts",
    "content": "export { default } from 'rsg-components/Tooltip/TooltipRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Type/Type.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { TypeRenderer, styles } from './TypeRenderer';\n\nconst props = {\n\tclasses: classes(styles),\n};\n\nit('renderer should render type', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<TypeRenderer {...props}>Array</TypeRenderer>);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Type/TypeRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nexport const styles = ({ fontFamily, fontSize, color }: Rsg.Theme) => ({\n\ttype: {\n\t\tfontFamily: fontFamily.monospace,\n\t\tfontSize: fontSize.small,\n\t\tcolor: color.type,\n\t},\n});\n\ninterface TypeProps extends JssInjectedProps {\n\tchildren: React.ReactNode;\n}\n\nexport const TypeRenderer: React.FunctionComponent<TypeProps> = ({ classes, children }) => {\n\treturn <span className={classes.type}>{children}</span>;\n};\n\nTypeRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any.isRequired,\n};\n\nexport default Styled<TypeProps>(styles)(TypeRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Type/__snapshots__/Type.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render type 1`] = `\n<span\n  className=\"type\"\n>\n  Array\n</span>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Type/index.ts",
    "content": "export { default } from 'rsg-components/Type/TypeRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Usage/Usage.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { PropTypeDescriptor, MethodDescriptor } from 'react-docgen';\nimport Usage from './Usage';\n\nconst props = [\n\t{\n\t\tname: 'children',\n\t\ttype: { name: 'string' } as PropTypeDescriptor,\n\t\trequired: true,\n\t\tdescription: 'Button label.',\n\t},\n];\nconst methods: MethodDescriptor[] = [\n\t{\n\t\tname: 'set',\n\t\tparams: [\n\t\t\t{\n\t\t\t\tname: 'newValue',\n\t\t\t\tdescription: 'New value for the counter.',\n\t\t\t\ttype: { name: 'Number' },\n\t\t\t},\n\t\t],\n\t\treturns: null,\n\t\tdescription: 'Sets the counter to a particular value.',\n\t},\n];\n\ndescribe('Usage', () => {\n\tit('should render props table', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(<Usage props={{ props }} />);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n\n\tit('should render methods table', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(<Usage props={{ methods }} />);\n\n\t\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n\t});\n\n\tit('should render nothing without props and methods', () => {\n\t\tconst renderer = createRenderer();\n\t\trenderer.render(<Usage props={{}} />);\n\n\t\texpect(renderer.getRenderOutput()).toBe(null);\n\t});\n});\n"
  },
  {
    "path": "src/client/rsg-components/Usage/Usage.tsx",
    "content": "import React from 'react';\nimport { MethodDescriptor } from 'react-docgen';\nimport { PropDescriptor } from 'rsg-components/Props/util';\nimport Props from 'rsg-components/Props';\nimport Methods from 'rsg-components/Methods';\nimport isEmpty from 'lodash/isEmpty';\n\nconst Usage: React.FunctionComponent<{\n\tprops: { methods?: MethodDescriptor[]; props?: PropDescriptor[] };\n}> = ({ props: { props, methods } }) => {\n\tconst propsNode = props && !isEmpty(props) && <Props props={props} />;\n\tconst methodsNode = methods && !isEmpty(methods) && <Methods methods={methods} />;\n\n\tif (!propsNode && !methodsNode) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div>\n\t\t\t{propsNode}\n\t\t\t{methodsNode}\n\t\t</div>\n\t);\n};\n\nexport default Usage;\n"
  },
  {
    "path": "src/client/rsg-components/Usage/__snapshots__/Usage.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Usage should render methods table 1`] = `\n<div>\n  <MethodsRenderer\n    methods={\n      Array [\n        Object {\n          \"description\": \"Sets the counter to a particular value.\",\n          \"name\": \"set\",\n          \"params\": Array [\n            Object {\n              \"description\": \"New value for the counter.\",\n              \"name\": \"newValue\",\n              \"type\": Object {\n                \"name\": \"Number\",\n              },\n            },\n          ],\n          \"returns\": null,\n        },\n      ]\n    }\n  />\n</div>\n`;\n\nexports[`Usage should render props table 1`] = `\n<div>\n  <PropsRenderer\n    props={\n      Array [\n        Object {\n          \"description\": \"Button label.\",\n          \"name\": \"children\",\n          \"required\": true,\n          \"type\": Object {\n            \"name\": \"string\",\n          },\n        },\n      ]\n    }\n  />\n</div>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Usage/index.ts",
    "content": "export { default } from 'rsg-components/Usage/Usage';\n"
  },
  {
    "path": "src/client/rsg-components/Version/Version.spec.tsx",
    "content": "import React from 'react';\nimport renderer from 'react-test-renderer';\nimport VersionRenderer from './VersionRenderer';\n\nit('renderer should render version', () => {\n\tconst actual = renderer.create(<VersionRenderer>1.2.3-a</VersionRenderer>);\n\n\texpect(actual.toJSON()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Version/VersionRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ color, fontFamily, fontSize }: Rsg.Theme) => ({\n\tversion: {\n\t\tcolor: color.light,\n\t\tmargin: [[5, 0, 0, 0]],\n\t\tfontFamily: fontFamily.base,\n\t\tfontSize: fontSize.base,\n\t\tfontWeight: 'normal',\n\t},\n});\n\ninterface VersionProps extends JssInjectedProps {\n\tchildren?: React.ReactNode;\n}\n\nexport const VersionRenderer: React.FunctionComponent<VersionProps> = ({ classes, children }) => {\n\treturn (\n\t\t<p aria-label=\"version\" className={classes.version}>\n\t\t\t{children}\n\t\t</p>\n\t);\n};\n\nVersionRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tchildren: PropTypes.any,\n};\n\nexport default Styled<VersionProps>(styles)(VersionRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Version/__snapshots__/Version.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render version 1`] = `\n<p\n  aria-label=\"version\"\n  className=\"rsg--version-0\"\n>\n  1.2.3-a\n</p>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Version/index.ts",
    "content": "export { default } from 'rsg-components/Version/VersionRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Welcome/Welcome.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport { WelcomeRenderer } from './WelcomeRenderer';\n\nit('renderer should render welcome screen', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<WelcomeRenderer classes={{}} patterns={['foo/*.js', 'bar/*.js']} />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/Welcome/WelcomeRenderer.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Markdown from 'rsg-components/Markdown';\nimport Styled, { JssInjectedProps } from 'rsg-components/Styled';\nimport { DOCS_COMPONENTS } from '../../../scripts/consts';\nimport * as Rsg from '../../../typings';\n\nconst styles = ({ space, maxWidth }: Rsg.Theme) => ({\n\troot: {\n\t\tmaxWidth,\n\t\tmargin: [[0, 'auto']],\n\t\tpadding: space[4],\n\t},\n});\n\ninterface WelcomeProps extends JssInjectedProps {\n\tpatterns: string[];\n}\n\nexport const WelcomeRenderer: React.FunctionComponent<WelcomeProps> = ({ classes, patterns }) => {\n\treturn (\n\t\t<div className={classes.root}>\n\t\t\t<Markdown\n\t\t\t\ttext={`\n# Welcome to React Styleguidist!\n\n**We couldn’t find any components** using these patterns:\n\n${patterns.map(p => `- \\`${p}\\``).join('\\n')}\n\nCreate **styleguide.config.js** file in your project root directory like this:\n\n    module.exports = {\n      components: 'src/components/**/*.js'\n    };\n\nRead more in the [locating components guide](${DOCS_COMPONENTS}).\n\t\t\t\t`}\n\t\t\t/>\n\t\t</div>\n\t);\n};\n\nWelcomeRenderer.propTypes = {\n\tclasses: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,\n\tpatterns: PropTypes.array.isRequired,\n};\n\nexport default Styled<WelcomeProps>(styles)(WelcomeRenderer);\n"
  },
  {
    "path": "src/client/rsg-components/Welcome/__snapshots__/Welcome.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`renderer should render welcome screen 1`] = `\n<div>\n  <Markdown\n    text=\"\n# Welcome to React Styleguidist!\n\n**We couldn’t find any components** using these patterns:\n\n- \\`foo/*.js\\`\n- \\`bar/*.js\\`\n\nCreate **styleguide.config.js** file in your project root directory like this:\n\n    module.exports = {\n      components: 'src/components/**/*.js'\n    };\n\nRead more in the [locating components guide](https://react-styleguidist.js.org/docs/components).\n\t\t\t\t\"\n  />\n</div>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Welcome/index.ts",
    "content": "export { default } from 'rsg-components/Welcome/WelcomeRenderer';\n"
  },
  {
    "path": "src/client/rsg-components/Wrapper/Wrapper.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport Wrapper from './Wrapper';\n\nit('should render children', () => {\n\tconst children = <span>Hello</span>;\n\tconst renderer = createRenderer();\n\trenderer.render(<Wrapper onError={() => {}}>{children}</Wrapper>);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should call onError handler when React invokes error handler', () => {\n\tconst onError = jest.fn();\n\tconst renderer = createRenderer();\n\trenderer.render(<Wrapper onError={onError}>blah</Wrapper>);\n\n\t// faux error\n\tconst err = new Error('err');\n\tconst inst = renderer.getMountedInstance() as Wrapper;\n\tif (inst && inst.componentDidCatch) {\n\t\tinst.componentDidCatch(err);\n\t}\n\n\texpect(onError).toHaveBeenCalledTimes(1);\n\texpect(onError).toHaveBeenCalledWith(err);\n});\n"
  },
  {
    "path": "src/client/rsg-components/Wrapper/Wrapper.ts",
    "content": "import { Component } from 'react';\nimport PropTypes from 'prop-types';\n\ninterface Props {\n\tonError: (e: Error) => void;\n\tchildren?: React.ReactNode;\n}\nexport default class Wrapper extends Component<Props> {\n\tpublic static propTypes = {\n\t\tchildren: PropTypes.node.isRequired,\n\t\tonError: PropTypes.func.isRequired,\n\t};\n\n\tpublic componentDidCatch(error: Error) {\n\t\tthis.props.onError(error);\n\t}\n\n\tpublic render() {\n\t\treturn this.props.children;\n\t}\n}\n"
  },
  {
    "path": "src/client/rsg-components/Wrapper/__snapshots__/Wrapper.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should render children 1`] = `\n<span>\n  Hello\n</span>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/Wrapper/index.ts",
    "content": "export { default } from 'rsg-components/Wrapper/Wrapper';\n"
  },
  {
    "path": "src/client/rsg-components/slots/CodeTabButton.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport TabButton from 'rsg-components/TabButton';\n\nconst CodeTabButton = (props: any) => <TabButton {...props}>View Code</TabButton>;\n\nCodeTabButton.propTypes = {\n\tonClick: PropTypes.func.isRequired,\n\tname: PropTypes.string.isRequired,\n\tactive: PropTypes.bool,\n};\n\nexport default CodeTabButton;\n"
  },
  {
    "path": "src/client/rsg-components/slots/IsolateButton.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport IsolateButton from './IsolateButton';\n\nit('should renderer a link to isolated mode', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<IsolateButton name=\"Pizza\" href=\"/#pizza\" />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should renderer a link to example isolated mode', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<IsolateButton name=\"Pizza\" href=\"/#pizza\" example={3} />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should renderer a link home in isolated mode', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<IsolateButton name=\"Pizza\" href=\"/#pizza\" isolated />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/client/rsg-components/slots/IsolateButton.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { MdFullscreen, MdFullscreenExit } from 'react-icons/md';\nimport ToolbarButton from 'rsg-components/ToolbarButton';\nimport getUrl from '../../utils/getUrl';\n\nexport interface IsolateButtonProps {\n\tname: string;\n\texample?: number;\n\tisolated?: boolean;\n\thref: string;\n}\n\nconst IsolateButton = ({ name, example, isolated, href }: IsolateButtonProps) => {\n\tif (isolated && !href) {\n\t\treturn null;\n\t}\n\n\tconst testID = example ? `${name}-${example}-isolate-button` : `${name}-isolate-button`;\n\n\treturn isolated ? (\n\t\t<ToolbarButton href={href} title=\"Show all components\" testId={testID}>\n\t\t\t<MdFullscreenExit />\n\t\t</ToolbarButton>\n\t) : (\n\t\t<ToolbarButton\n\t\t\thref={getUrl({ name, example, isolated: true })}\n\t\t\ttitle=\"Open isolated\"\n\t\t\ttestId={testID}\n\t\t>\n\t\t\t<MdFullscreen />\n\t\t</ToolbarButton>\n\t);\n};\n\nIsolateButton.propTypes = {\n\tname: PropTypes.string.isRequired,\n\texample: PropTypes.number,\n\tisolated: PropTypes.bool,\n};\n\nexport default IsolateButton;\n"
  },
  {
    "path": "src/client/rsg-components/slots/UsageTabButton.spec.tsx",
    "content": "import React from 'react';\nimport { createRenderer } from 'react-test-renderer/shallow';\nimport UsageTabButton from './UsageTabButton';\n\nconst props = {\n\tname: 'Pizza',\n\tonClick: () => {},\n};\n\nit('should renderer a button', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<UsageTabButton {...props} props={{ props: [{ name: 'foo' }] }} />);\n\n\texpect(renderer.getRenderOutput()).toMatchSnapshot();\n});\n\nit('should renderer null if there are not props or methods', () => {\n\tconst renderer = createRenderer();\n\trenderer.render(<UsageTabButton {...props} props={{}} />);\n\n\texpect(renderer.getRenderOutput()).toBe(null);\n});\n"
  },
  {
    "path": "src/client/rsg-components/slots/UsageTabButton.tsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport TabButton from 'rsg-components/TabButton';\nimport isEmpty from 'lodash/isEmpty';\n\nexport interface UsageTabButtonProps {\n\tname: string;\n\tonClick: (e: React.MouseEvent) => void;\n\tactive?: boolean;\n\tprops: {\n\t\tprops?: any[];\n\t\tmethods?: any[];\n\t};\n}\n\nconst UsageTabButton = (props: UsageTabButtonProps) => {\n\tconst component = props.props;\n\tconst showButton = !isEmpty(component.props) || !isEmpty(component.methods);\n\treturn showButton ? <TabButton {...props}>Props & methods</TabButton> : null;\n};\n\nUsageTabButton.propTypes = {\n\tonClick: PropTypes.func.isRequired,\n\tname: PropTypes.string.isRequired,\n\tprops: PropTypes.shape({\n\t\tprops: PropTypes.array,\n\t\tmethods: PropTypes.array,\n\t}).isRequired,\n\tactive: PropTypes.bool,\n};\n\nexport default UsageTabButton;\n"
  },
  {
    "path": "src/client/rsg-components/slots/__snapshots__/IsolateButton.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should renderer a link home in isolated mode 1`] = `\n<Styled(ToolbarButton)\n  href=\"/#pizza\"\n  testId=\"Pizza-isolate-button\"\n  title=\"Show all components\"\n>\n  <MdFullscreenExit />\n</Styled(ToolbarButton)>\n`;\n\nexports[`should renderer a link to example isolated mode 1`] = `\n<Styled(ToolbarButton)\n  href=\"/#!/Pizza/3\"\n  testId=\"Pizza-3-isolate-button\"\n  title=\"Open isolated\"\n>\n  <MdFullscreen />\n</Styled(ToolbarButton)>\n`;\n\nexports[`should renderer a link to isolated mode 1`] = `\n<Styled(ToolbarButton)\n  href=\"/#!/Pizza\"\n  testId=\"Pizza-isolate-button\"\n  title=\"Open isolated\"\n>\n  <MdFullscreen />\n</Styled(ToolbarButton)>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/slots/__snapshots__/UsageTabButton.spec.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should renderer a button 1`] = `\n<Styled(TabButton)\n  name=\"Pizza\"\n  onClick={[Function]}\n  props={\n    Object {\n      \"props\": Array [\n        Object {\n          \"name\": \"foo\",\n        },\n      ],\n    }\n  }\n>\n  Props & methods\n</Styled(TabButton)>\n`;\n"
  },
  {
    "path": "src/client/rsg-components/slots/index.ts",
    "content": "import Editor from 'rsg-components/Editor';\nimport Usage from 'rsg-components/Usage';\nimport IsolateButton from 'rsg-components/slots/IsolateButton';\nimport CodeTabButton from 'rsg-components/slots/CodeTabButton';\nimport UsageTabButton from 'rsg-components/slots/UsageTabButton';\nimport * as Rsg from '../../../typings';\n\nexport const EXAMPLE_TAB_CODE_EDITOR = 'rsg-code-editor';\nexport const DOCS_TAB_USAGE = 'rsg-usage';\n\nconst toolbar = [IsolateButton];\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport default (config?: Rsg.ProcessedStyleguidistConfig) => {\n\treturn {\n\t\tsectionToolbar: toolbar,\n\t\tcomponentToolbar: toolbar,\n\t\texampleToolbar: toolbar,\n\t\texampleTabButtons: [\n\t\t\t{\n\t\t\t\tid: EXAMPLE_TAB_CODE_EDITOR,\n\t\t\t\trender: CodeTabButton,\n\t\t\t},\n\t\t],\n\t\texampleTabs: [\n\t\t\t{\n\t\t\t\tid: EXAMPLE_TAB_CODE_EDITOR,\n\t\t\t\trender: Editor,\n\t\t\t},\n\t\t],\n\t\tdocsTabButtons: [\n\t\t\t{\n\t\t\t\tid: DOCS_TAB_USAGE,\n\t\t\t\trender: UsageTabButton,\n\t\t\t},\n\t\t],\n\t\tdocsTabs: [\n\t\t\t{\n\t\t\t\tid: DOCS_TAB_USAGE,\n\t\t\t\trender: Usage,\n\t\t\t},\n\t\t],\n\t};\n};\n"
  },
  {
    "path": "src/client/styles/__tests__/createStyleSheet.spec.ts",
    "content": "import * as theme from '../theme';\nimport createStyleSheet from '../createStyleSheet';\nimport * as Rsg from '../../../typings';\n\nconst customThemeColor = '#123456';\nconst customThemeBorderColor = '#654321';\nconst customThemeMaxWidth = 9999;\n\nconst customStyleBorderColor = '#ABCDEF';\n\nconst customThemeLinkColor = '#CCCAAA';\n\nconst testComponentName = 'TestComponentName';\nconst testRuleName = 'testRule';\n\nconst styles = ({ color, borderRadius, maxWidth }: Rsg.Theme) => ({\n\t[testRuleName]: {\n\t\tcolor: color.base,\n\t\tbackgroundColor: color.baseBackground,\n\t\tborderColor: color.border,\n\t\tborderRadius,\n\t\tmaxWidth,\n\t},\n});\n\nconst config = {\n\ttheme: {\n\t\tcolor: {\n\t\t\tbase: customThemeColor,\n\t\t\tborder: customThemeBorderColor,\n\t\t\tlink: customThemeLinkColor,\n\t\t},\n\t\tmaxWidth: customThemeMaxWidth,\n\t},\n\tstyles: {\n\t\t[testComponentName]: {\n\t\t\t[testRuleName]: {\n\t\t\t\tborderColor: customStyleBorderColor,\n\t\t\t},\n\t\t},\n\t},\n};\n\nconst configWithStylesAsAFunction = {\n\t...config,\n\tstyles: (locTheme: Rsg.Theme) => {\n\t\treturn {\n\t\t\t[testComponentName]: {\n\t\t\t\t[testRuleName]: {\n\t\t\t\t\tborderColor: locTheme.color.link,\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t},\n};\n\ndescribe('createStyleSheet', () => {\n\tit('should use theme variables', () => {\n\t\tconst styleSheet = createStyleSheet(styles, config, testComponentName, '1');\n\t\tconst style = (styleSheet.getRule(testRuleName) as any).style;\n\n\t\texpect(style['background-color']).toBe(theme.color.baseBackground);\n\t\texpect(style['border-radius']).toBe(`${theme.borderRadius}px`);\n\t});\n\n\tit('should override theme variables with config theme', () => {\n\t\tconst styleSheet = createStyleSheet(styles, config, testComponentName, '2');\n\t\tconst style = (styleSheet.getRule(testRuleName) as any).style;\n\n\t\texpect(style.color).toBe(customThemeColor);\n\t\texpect(style['max-width']).toBe(`${customThemeMaxWidth}px`);\n\t});\n\n\tit('should override config theme variables with config styles', () => {\n\t\tconst styleSheet = createStyleSheet(styles, config, testComponentName, '3');\n\t\tconst style = (styleSheet.getRule(testRuleName) as any).style;\n\n\t\texpect(style['border-color']).toBe(customStyleBorderColor);\n\t});\n\n\tit('should override config theme variables with config styles as a function', () => {\n\t\tconst styleSheet = createStyleSheet(\n\t\t\tstyles,\n\t\t\tconfigWithStylesAsAFunction,\n\t\t\ttestComponentName,\n\t\t\t'4'\n\t\t);\n\t\tconst style = (styleSheet.getRule(testRuleName) as any).style;\n\n\t\texpect(style['border-color']).toBe(customThemeLinkColor);\n\t});\n});\n"
  },
  {
    "path": "src/client/styles/__tests__/setupjss.spec.ts",
    "content": "import jssBase from 'jss';\nimport jss from '../setupjss';\n\ndescribe('setupjss', () => {\n\tit('should renerate prefixed class names', () => {\n\t\tconst { classes } = jss.createStyleSheet({\n\t\t\troot: {},\n\t\t});\n\t\texpect(classes.root).toMatch(/^rsg--\\w+-\\d+$/);\n\t});\n\n\tit('jss-global plugin should be enabled', () => {\n\t\tconst css = jss\n\t\t\t.createStyleSheet({\n\t\t\t\t'@global body': {\n\t\t\t\t\tcolor: 'red',\n\t\t\t\t},\n\t\t\t})\n\t\t\t.toString();\n\t\texpect(css).toMatch(/^body {/);\n\t});\n\n\tit('jss plugins should be enabled', () => {\n\t\tconst stylesheet = jss.createStyleSheet({\n\t\t\troot: {\n\t\t\t\tbackgroundColor: 'tomato',\n\t\t\t\twidth: 1,\n\t\t\t\t'&:hover': {\n\t\t\t\t\tcolor: 'snow',\n\t\t\t\t},\n\t\t\t},\n\t\t\tchild: {\n\t\t\t\tcomposes: '$root',\n\t\t\t\tcolor: 'blue',\n\t\t\t},\n\t\t});\n\n\t\tconst root = (stylesheet.getRule('root') as any).style;\n\t\texpect(root).toEqual(expect.any(Object));\n\t\texpect(root['background-color']).toBe('tomato');\n\t\texpect(root.width).toBe('1px');\n\t\texpect(stylesheet.classes.root).toMatch(/^rsg--root-\\d+$/);\n\n\t\tconst child = (stylesheet.getRule('child') as any).style;\n\t\texpect(child).toEqual(expect.any(Object));\n\t\texpect(child.color).toBe('blue');\n\t\texpect(stylesheet.classes.child).toMatch(/^rsg--child-\\d+ rsg--root-\\d+$/);\n\n\t\tconst hover = (stylesheet as any).rules.map['.rsg--root-2:hover'];\n\t\texpect(hover).toEqual(expect.any(Object));\n\t\texpect(hover.style.color).toBe('snow');\n\t});\n\n\tit('base jss instance setup shoud not affect Styleguidist styles', () => {\n\t\tjssBase.setup();\n\n\t\tconst stylesheet = jss.createStyleSheet({\n\t\t\troot: {\n\t\t\t\twidth: 1,\n\t\t\t},\n\t\t});\n\n\t\texpect(stylesheet.classes.root).toMatch(/^rsg--root-\\d+$/);\n\n\t\tconst root = (stylesheet.getRule('root') as any).style;\n\t\texpect(root.width).toBe('1px');\n\t});\n});\n"
  },
  {
    "path": "src/client/styles/createStyleSheet.ts",
    "content": "import merge from 'lodash/merge';\nimport memoize from 'lodash/memoize';\nimport { Styles, StyleSheet } from 'jss';\nimport jss from './setupjss';\nimport * as theme from './theme';\nimport { RecursivePartial } from '../../typings/RecursivePartial';\nimport * as Rsg from '../../typings';\n\n/**\n * By default lodash/memoize only uses the first argument\n * for cache rendering. It works well if the first prameter\n * is enough.\n * We are Hot Module Replacing (HMR) stylesheets.\n * Therefore, we cannot cache stylesheet only by component.\n * We need to add cssRevisions to the key fo when the css files update,\n * the revision will update and we should update the stylesheet.\n */\nexport default memoize(\n\t(\n\t\tstyles: (t: Rsg.Theme) => Styles<string>,\n\t\tconfig: Rsg.ProcessedStyleguidistCSSConfig,\n\t\tcomponentName: string,\n\t\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t\tcssRevision: string\n\t): StyleSheet<string> => {\n\t\tconst mergedTheme = merge<RecursivePartial<Rsg.Theme>, Rsg.Theme, RecursivePartial<Rsg.Theme>>(\n\t\t\t{},\n\t\t\ttheme,\n\t\t\tconfig.theme\n\t\t);\n\n\t\tconst customStyles =\n\t\t\ttypeof config.styles === 'function' ? config.styles(mergedTheme) : config.styles;\n\n\t\tconst mergedStyles: Styles<string> = merge(\n\t\t\t{},\n\t\t\tstyles(mergedTheme),\n\t\t\tcustomStyles && customStyles[componentName]\n\t\t);\n\n\t\treturn jss.createStyleSheet(mergedStyles, { meta: componentName, link: true });\n\t},\n\t// calculate the cache key here\n\t(styles, config, componentName, cssRevision) => `${componentName}_${cssRevision}`\n);\n"
  },
  {
    "path": "src/client/styles/index.ts",
    "content": "import './setupjss';\nimport './styles';\n"
  },
  {
    "path": "src/client/styles/nonInheritedProps.ts",
    "content": "/* eslint-disable */\n/**\n * List of non-inheritable properties.\n *\n * Borrowed from https://github.com/suitcss/preprocessor/blob/master/lib/encapsulation.js\n */\nexport default {\n\tanimation: 'none 0s ease 0s 1 normal none running',\n\t'backface-visibility': 'visible',\n\tbackground: 'transparent none repeat 0 0 / auto auto padding-box border-box scroll',\n\tborder: 'medium none currentColor',\n\t'border-image': 'none',\n\t'border-radius': '0',\n\tbottom: 'auto',\n\t'box-shadow': 'none',\n\tclear: 'none',\n\tclip: 'auto',\n\tcolumns: 'auto',\n\t'column-count': 'auto',\n\t'column-fill': 'balance',\n\t'column-gap': 'normal',\n\t'column-rule': 'medium none currentColor',\n\t'column-span': '1',\n\t'column-width': 'auto',\n\tcontent: 'normal',\n\t'counter-increment': 'none',\n\t'counter-reset': 'none',\n\tfloat: 'none',\n\theight: 'auto',\n\thyphens: 'none',\n\tleft: 'auto',\n\tmargin: '0',\n\t'max-height': 'none',\n\t'max-width': 'none',\n\t'min-height': '0',\n\t'min-width': '0',\n\topacity: '1',\n\toutline: 'medium none invert',\n\toverflow: 'visible',\n\t'overflow-x': 'visible',\n\t'overflow-y': 'visible',\n\tpadding: '0',\n\t'page-break-after': 'auto',\n\t'page-break-before': 'auto',\n\t'page-break-inside': 'auto',\n\tperspective: 'none',\n\t'perspective-origin': '50% 50%',\n\tposition: 'static',\n\tright: 'auto',\n\t'table-layout': 'auto',\n\t'text-decoration': 'none',\n\ttop: 'auto',\n\ttransform: 'none',\n\t'transform-origin': '50% 50% 0',\n\t'transform-style': 'flat',\n\ttransition: 'none 0s ease 0s',\n\t'unicode-bidi': 'normal',\n\t'vertical-align': 'baseline',\n\twidth: 'auto',\n\t'z-index': 'auto',\n};\n"
  },
  {
    "path": "src/client/styles/prismTheme.ts",
    "content": "import * as Rsg from '../../typings';\n\nconst prismTheme = ({ color }: Pick<Rsg.Theme, 'color'>) => ({\n\t'&': {\n\t\tcolor: color.codeBase,\n\t},\n\t[`& .token.comment,\n& .token.prolog,\n& .token.doctype,\n& .token.cdata`]: {\n\t\tisolate: false,\n\t\tcolor: color.codeComment,\n\t},\n\t[`& .token.punctuation`]: {\n\t\tisolate: false,\n\t\tcolor: color.codePunctuation,\n\t},\n\t[`& .namespace`]: {\n\t\tisolate: false,\n\t\topacity: 0.7,\n\t},\n\t[`& .token.property,\n& .token.tag,\n& .token.boolean,\n& .token.number,\n& .token.constant,\n& .token.symbol`]: {\n\t\tisolate: false,\n\t\tcolor: color.codeProperty,\n\t},\n\t[`& .token.deleted`]: {\n\t\tisolate: false,\n\t\tcolor: color.codeDeleted,\n\t},\n\t[`& .token.selector,\n& .token.attr-name,\n& .token.string,\n& .token.char,\n& .token.builtin`]: {\n\t\tisolate: false,\n\t\tcolor: color.codeString,\n\t},\n\t[`& .token.inserted`]: {\n\t\tisolate: false,\n\t\tcolor: color.codeInserted,\n\t},\n\t[`& .token.operator,\n& .token.entity,\n& .token.url,\n& .language-css .token.string,\n& .style .token.string`]: {\n\t\tisolate: false,\n\t\tcolor: color.codeOperator,\n\t},\n\t[`& .token.atrule,\n& .token.attr-value,\n& .token.keyword`]: {\n\t\tisolate: false,\n\t\tcolor: color.codeKeyword,\n\t},\n\t[`& .token.function,\n& .token.class-name`]: {\n\t\tisolate: false,\n\t\tcolor: color.codeFunction,\n\t},\n\t[`& .token.regex,\n& .token.important,\n& .token.variable`]: {\n\t\tisolate: false,\n\t\tcolor: color.codeVariable,\n\t},\n\t[`& .token.important,\n& .token.bold`]: {\n\t\tisolate: false,\n\t\tfontWeight: 'bold',\n\t},\n\t[`& .token.italic`]: {\n\t\tisolate: false,\n\t\tfontStyle: 'italic',\n\t},\n\t[`& .token.entity`]: {\n\t\tisolate: false,\n\t\tcursor: 'help',\n\t},\n});\n\nexport default prismTheme;\n"
  },
  {
    "path": "src/client/styles/setupjss.ts",
    "content": "import { create } from 'jss';\nimport global from 'jss-plugin-global';\nimport isolate from 'jss-plugin-isolate';\nimport nested from 'jss-plugin-nested';\nimport camelCase from 'jss-plugin-camel-case';\nimport defaultUnit from 'jss-plugin-default-unit';\nimport compose from 'jss-plugin-compose';\nimport nonInheritedProps from './nonInheritedProps';\n\nconst createGenerateId = () => {\n\tlet counter = 0;\n\treturn (rule: { key: string }) => `rsg--${rule.key}-${counter++}`;\n};\n\nconst jss = create({\n\tcreateGenerateId,\n\tplugins: [\n\t\tglobal(),\n\t\tisolate({\n\t\t\treset: {\n\t\t\t\t// Reset all inherited and non-inherited properties\n\t\t\t\t...nonInheritedProps,\n\n\t\t\t\t// “Global” styles for all components\n\t\t\t\tboxSizing: 'border-box',\n\n\t\t\t\t// Allow inheritance because it may be set on body and should be available for user components\n\t\t\t\tcolor: 'inherit',\n\t\t\t\tfont: 'inherit',\n\t\t\t\tfontFamily: 'inherit',\n\t\t\t\tfontSize: 'inherit',\n\t\t\t\tfontWeight: 'inherit',\n\t\t\t\tlineHeight: 'inherit',\n\t\t\t},\n\t\t}),\n\t\tnested(),\n\t\tcamelCase(),\n\t\tdefaultUnit(),\n\t\tcompose(),\n\t],\n});\n\nexport default jss;\n"
  },
  {
    "path": "src/client/styles/styles.ts",
    "content": "import jss from './setupjss';\n\nconst styles = {\n\t// Global styles\n\tbody: {\n\t\tisolate: false,\n\t\tmargin: 0,\n\t\tpadding: 0,\n\t\tminWidth: 0,\n\t\tmaxWidth: '100%',\n\t\tborder: 0,\n\t},\n};\n\n// Attach styles to body\nconst { body } = jss.createStyleSheet(styles).attach().classes;\ndocument.body.classList.add(body);\n"
  },
  {
    "path": "src/client/styles/theme.ts",
    "content": "export const spaceFactor = 8;\nexport const space = [\n\tspaceFactor / 2, // 4\n\tspaceFactor, // 8\n\tspaceFactor * 2, // 16\n\tspaceFactor * 3, // 24\n\tspaceFactor * 4, // 32\n\tspaceFactor * 5, // 40\n\tspaceFactor * 6, // 48\n];\n\nexport const color = {\n\tbase: '#333',\n\tlight: '#767676',\n\tlightest: '#ccc',\n\tlink: '#1673b1',\n\tlinkHover: '#e90',\n\tfocus: 'rgba(22, 115, 177, 0.25)',\n\tborder: '#e8e8e8',\n\tname: '#690',\n\ttype: '#905',\n\terror: '#c00',\n\tbaseBackground: '#fff',\n\tcodeBackground: '#f5f5f5',\n\tsidebarBackground: '#f5f5f5',\n\tribbonBackground: '#e90',\n\tribbonText: '#fff',\n\t// Based on default Prism theme\n\tcodeBase: '#333',\n\tcodeComment: '#6d6d6d',\n\tcodePunctuation: '#999',\n\tcodeProperty: '#905',\n\tcodeDeleted: '#905',\n\tcodeString: '#690',\n\tcodeInserted: '#690',\n\tcodeOperator: '#9a6e3a',\n\tcodeKeyword: '#1673b1',\n\tcodeFunction: '#DD4A68',\n\tcodeVariable: '#e90',\n};\n\nexport const fontFamily = {\n\tbase: [\n\t\t'-apple-system',\n\t\t'BlinkMacSystemFont',\n\t\t'\"Segoe UI\"',\n\t\t'\"Roboto\"',\n\t\t'\"Oxygen\"',\n\t\t'\"Ubuntu\"',\n\t\t'\"Cantarell\"',\n\t\t'\"Fira Sans\"',\n\t\t'\"Droid Sans\"',\n\t\t'\"Helvetica Neue\"',\n\t\t'sans-serif',\n\t],\n\tmonospace: ['Consolas', '\"Liberation Mono\"', 'Menlo', 'monospace'],\n};\n\nexport const fontSize = {\n\tbase: 15,\n\ttext: 16,\n\tsmall: 13,\n\th1: 48,\n\th2: 36,\n\th3: 24,\n\th4: 18,\n\th5: 16,\n\th6: 16,\n};\n\nexport const mq = {\n\tsmall: '@media (max-width: 600px)',\n};\n\nexport const borderRadius = 3;\nexport const maxWidth = 1000;\nexport const sidebarWidth = 200;\n\nexport const buttonTextTransform = 'uppercase';\n"
  },
  {
    "path": "src/client/utils/__tests__/__snapshots__/filterSectionsByName.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`filterSectionsByName should recursively filter sections and components by name 1`] = `\nArray [\n  Object {\n    \"components\": Array [],\n    \"name\": \"General\",\n    \"sections\": Array [\n      Object {\n        \"components\": Array [\n          Object {\n            \"name\": \"Button\",\n          },\n        ],\n        \"name\": \"Particles\",\n        \"sections\": Array [],\n      },\n    ],\n  },\n]\n`;\n\nexports[`filterSectionsByName should skip sections without matches inside 1`] = `\nArray [\n  Object {\n    \"components\": Array [],\n    \"name\": \"General\",\n    \"sections\": Array [],\n  },\n]\n`;\n"
  },
  {
    "path": "src/client/utils/__tests__/__snapshots__/getAst.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`getAst return AST 1`] = `\nNode {\n  \"body\": Array [\n    Node {\n      \"end\": 2,\n      \"expression\": Node {\n        \"end\": 2,\n        \"raw\": \"42\",\n        \"start\": 0,\n        \"type\": \"Literal\",\n        \"value\": 42,\n      },\n      \"start\": 0,\n      \"type\": \"ExpressionStatement\",\n    },\n  ],\n  \"end\": 2,\n  \"sourceType\": \"module\",\n  \"start\": 0,\n  \"type\": \"Program\",\n}\n`;\n"
  },
  {
    "path": "src/client/utils/__tests__/__snapshots__/getRouteData.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`getRouteData should return first section if pagePerSection and hash is empty 1`] = `\nObject {\n  \"displayMode\": \"all\",\n  \"sections\": Array [\n    Object {\n      \"components\": Array [\n        Object {\n          \"module\": 1,\n          \"name\": \"Button\",\n          \"props\": Object {\n            \"displayName\": \"Button\",\n            \"examples\": Array [\n              Object {\n                \"content\": \"const a = 0\",\n                \"evalInContext\": [Function],\n                \"type\": \"code\",\n              },\n              Object {\n                \"content\": \"# title\",\n                \"type\": \"markdown\",\n              },\n            ],\n          },\n        },\n        Object {\n          \"module\": 2,\n          \"name\": \"Image\",\n          \"props\": Object {\n            \"displayName\": \"Image\",\n          },\n        },\n      ],\n      \"exampleMode\": \"collapse\",\n      \"name\": \"Components\",\n      \"sectionDepth\": 0,\n      \"sections\": Array [],\n      \"slug\": \"components\",\n      \"usageMode\": \"collapse\",\n    },\n  ],\n}\n`;\n\nexports[`getRouteData should return not found if pagePerSection and hash is #/Buttons/Label/Not 1`] = `\nObject {\n  \"displayMode\": \"notFound\",\n  \"sections\": Array [],\n}\n`;\n\nexports[`getRouteData should return one component 1`] = `\nObject {\n  \"displayMode\": \"component\",\n  \"sections\": Array [\n    Object {\n      \"components\": Array [\n        Object {\n          \"module\": 1,\n          \"name\": \"Button\",\n          \"props\": Object {\n            \"displayName\": \"Button\",\n            \"examples\": Array [\n              Object {\n                \"content\": \"const a = 0\",\n                \"evalInContext\": [Function],\n                \"type\": \"code\",\n              },\n              Object {\n                \"content\": \"# title\",\n                \"type\": \"markdown\",\n              },\n            ],\n          },\n        },\n      ],\n      \"exampleMode\": \"collapse\",\n      \"slug\": \"components\",\n      \"usageMode\": \"collapse\",\n    },\n  ],\n}\n`;\n\nexports[`getRouteData should return one component if pagePerSection and hash is #/Buttons/Label 1`] = `\nObject {\n  \"displayMode\": \"all\",\n  \"sections\": Array [\n    Object {\n      \"components\": Array [\n        Object {\n          \"module\": 1,\n          \"name\": \"Label\",\n        },\n      ],\n      \"exampleMode\": \"collapse\",\n      \"slug\": \"buttons\",\n      \"usageMode\": \"collapse\",\n    },\n  ],\n}\n`;\n\nexports[`getRouteData should return one example from a component 1`] = `\nObject {\n  \"displayMode\": \"example\",\n  \"sections\": Array [\n    Object {\n      \"components\": Array [\n        Object {\n          \"module\": 1,\n          \"name\": \"Button\",\n          \"props\": Object {\n            \"displayName\": \"Button\",\n            \"examples\": Array [\n              Object {\n                \"content\": \"# title\",\n                \"type\": \"markdown\",\n              },\n            ],\n          },\n        },\n      ],\n      \"exampleMode\": \"collapse\",\n      \"slug\": \"components\",\n      \"usageMode\": \"collapse\",\n    },\n  ],\n}\n`;\n\nexports[`getRouteData should return one example from a section 1`] = `\nObject {\n  \"displayMode\": \"example\",\n  \"sections\": Array [\n    Object {\n      \"components\": Array [],\n      \"content\": Array [\n        Object {\n          \"content\": \"# title\",\n          \"type\": \"markdown\",\n        },\n      ],\n      \"exampleMode\": \"collapse\",\n      \"name\": \"Section\",\n      \"sectionDepth\": 0,\n      \"sections\": Array [],\n      \"slug\": \"section\",\n      \"usageMode\": \"collapse\",\n    },\n  ],\n}\n`;\n\nexports[`getRouteData should return one section 1`] = `\nObject {\n  \"displayMode\": \"section\",\n  \"sections\": Array [\n    Object {\n      \"components\": Array [],\n      \"content\": Array [\n        Object {\n          \"content\": \"const a = 0\",\n          \"evalInContext\": [Function],\n          \"type\": \"code\",\n        },\n        Object {\n          \"content\": \"# title\",\n          \"type\": \"markdown\",\n        },\n      ],\n      \"exampleMode\": \"collapse\",\n      \"name\": \"Section\",\n      \"sectionDepth\": 0,\n      \"sections\": Array [],\n      \"slug\": \"section\",\n      \"usageMode\": \"collapse\",\n    },\n  ],\n}\n`;\n\nexports[`getRouteData should return one section if pagePerSection and hash is #/Section 1`] = `\nObject {\n  \"displayMode\": \"all\",\n  \"sections\": Array [\n    Object {\n      \"components\": Array [],\n      \"content\": Array [\n        Object {\n          \"content\": \"const a = 0\",\n          \"evalInContext\": [Function],\n          \"type\": \"code\",\n        },\n        Object {\n          \"content\": \"# title\",\n          \"type\": \"markdown\",\n        },\n      ],\n      \"exampleMode\": \"collapse\",\n      \"name\": \"Section\",\n      \"sectionDepth\": 0,\n      \"sections\": Array [],\n      \"slug\": \"section\",\n      \"usageMode\": \"collapse\",\n    },\n  ],\n}\n`;\n\nexports[`getRouteData should return one section without components if pagePerSection and hash is #/Buttons 1`] = `\nObject {\n  \"displayMode\": \"all\",\n  \"sections\": Array [\n    Object {\n      \"components\": Array [],\n      \"exampleMode\": \"collapse\",\n      \"name\": \"Buttons\",\n      \"sectionDepth\": 2,\n      \"sections\": Array [],\n      \"slug\": \"buttons\",\n      \"usageMode\": \"collapse\",\n    },\n  ],\n}\n`;\n"
  },
  {
    "path": "src/client/utils/__tests__/compileCode.spec.ts",
    "content": "import compileCode from '../compileCode';\nimport config from '../../../scripts/schemas/config';\n\nconst compilerConfig = config.compilerConfig.default;\n\ndescribe('compileCode', () => {\n\ttest('compile ES6 to ES5', () => {\n\t\tconst result = compileCode(`const {foo, bar} = baz`, compilerConfig);\n\t\texpect(result).toMatchInlineSnapshot(`\n\"var foo = baz.foo;\nvar bar = baz.bar;\"\n`);\n\t});\n\n\ttest('transform imports to require()', () => {\n\t\tconst result = compileCode(`import foo from 'bar'`, compilerConfig);\n\t\texpect(result).toMatchInlineSnapshot(`\n\"const bar$0 = require('bar');\nconst foo = bar$0.default || bar$0;\"\n`);\n\t});\n\n\ttest('transform async/await is not throw an error', () => {\n\t\tconst onError = jest.fn();\n\t\tconst result = compileCode(\n\t\t\t`async function asyncFunction() { return await Promise.resolve(); }`,\n\t\t\tcompilerConfig,\n\t\t\tonError\n\t\t);\n\t\texpect(onError).not.toHaveBeenCalled();\n\t\texpect(result).toMatchInlineSnapshot(\n\t\t\t`\"async function asyncFunction() { return await Promise.resolve(); }\"`\n\t\t);\n\t});\n\n\ttest('transform imports to require() in front of JSX', () => {\n\t\tconst result = compileCode(\n\t\t\t`\nimport foo from 'bar';\nimport Button from 'button';\n<Button />`,\n\t\t\tcompilerConfig\n\t\t);\n\t\texpect(result).toMatchInlineSnapshot(`\n\"\nconst bar$0 = require('bar');\nconst foo = bar$0.default || bar$0;\nconst button$0 = require('button');\nconst Button = button$0.default || button$0;\nReact.createElement( Button, null )\"\n`);\n\t});\n\n\ttest('wrap JSX in Fragment if adjacent on line 1', () => {\n\t\tconst result = compileCode(`<span /><span />`, compilerConfig);\n\t\texpect(result).toMatchInlineSnapshot(\n\t\t\t`\"React.createElement( React.Fragment, null, React.createElement( 'span', null ), React.createElement( 'span', null ) );\"`\n\t\t);\n\t});\n\n\ttest('don’t wrap JSX in Fragment if there is only one statement', () => {\n\t\tconst result = compileCode(`<Button />;`, compilerConfig);\n\t\texpect(result).toMatchInlineSnapshot(`\"React.createElement( Button, null );\"`);\n\t});\n\n\ttest('don’t wrap JSX in Fragment if it’s in the middle', () => {\n\t\tconst result = compileCode(\n\t\t\t`const {foo, bar} = baz;\n<div>\n  <button>Click</button>\n</div>`,\n\t\t\tcompilerConfig\n\t\t);\n\t\texpect(result).toMatchInlineSnapshot(`\n\"var foo = baz.foo;\nvar bar = baz.bar;\nReact.createElement( 'div', null,\n  React.createElement( 'button', null, \\\\\"Click\\\\\" )\n)\"\n`);\n\t});\n\n\ttest('tagged template literals', () => {\n\t\tconst result = compileCode(\n\t\t\t`const Button = styled.button\\`\n\tcolor: tomato;\n\\`;\n<Button />\n`,\n\t\t\tcompilerConfig\n\t\t);\n\t\texpect(result).toMatchInlineSnapshot(`\n\"var templateObject = Object.freeze([\\\\\"\\\\\\\\n\\\\\\\\tcolor: tomato;\\\\\\\\n\\\\\"]);\nvar Button = styled.button(templateObject);\nReact.createElement( Button, null )\n\"\n`);\n\t});\n\n\ttest('onError callback', () => {\n\t\tconst onError = jest.fn();\n\t\tconst result = compileCode(`=`, compilerConfig, onError);\n\t\texpect(result).toBe('');\n\t\texpect(onError).toHaveBeenCalledWith(\n\t\t\texpect.objectContaining({ message: 'Unexpected token (1:0)' })\n\t\t);\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/filterComponentExamples.spec.ts",
    "content": "import deepfreeze from 'deepfreeze';\nimport filterComponentExamples from '../filterComponentExamples';\nimport * as Rsg from '../../../typings';\n\nconst examples: Rsg.Example[] = ['a', 'b', 'c', 'd'].map(x => ({ type: 'markdown', content: x }));\n\nconst component = deepfreeze({\n\tprops: {\n\t\texamples,\n\t},\n\tother: 'info',\n});\n\ndescribe('filterComponentExamples', () => {\n\tit('should return a shallow copy of a component with example filtered by given index', () => {\n\t\tconst result = filterComponentExamples(component, 2);\n\t\texpect(result).toEqual({\n\t\t\tprops: {\n\t\t\t\texamples: [{ type: 'markdown', content: 'c' }],\n\t\t\t},\n\t\t\tother: 'info',\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/filterComponentsByExactName.spec.ts",
    "content": "import deepfreeze from 'deepfreeze';\nimport filterComponentsByExactName from '../filterComponentsByExactName';\n\nconst components = deepfreeze([\n\t{\n\t\tname: 'Button',\n\t},\n\t{\n\t\tname: 'Image',\n\t},\n]);\n\ndescribe('filterComponentsByExactName', () => {\n\tit('should return components with exact name', () => {\n\t\tconst result = filterComponentsByExactName(components, 'Image');\n\t\texpect(result.map(x => x.name)).toEqual(['Image']);\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/filterComponentsByName.spec.ts",
    "content": "import deepfreeze from 'deepfreeze';\nimport filterComponentsByName from '../filterComponentsByName';\n\nconst components = deepfreeze([\n\t{\n\t\tname: 'Button',\n\t},\n\t{\n\t\tname: 'Image',\n\t},\n\t{\n\t\tname: 'Input',\n\t},\n\t{\n\t\tname: 'Link',\n\t},\n\t{\n\t\tname: 'Textarea',\n\t},\n]);\n\ndescribe('filterComponentsByName', () => {\n\tit('should return initial list with empty query', () => {\n\t\tconst result = filterComponentsByName(components, '');\n\t\texpect(result).toEqual(components);\n\t});\n\n\tit('should return filtered list, should ignore case', () => {\n\t\tconst result = filterComponentsByName(components, 'button');\n\t\texpect(result).toEqual([{ name: 'Button' }]);\n\t});\n\n\tit('should return empty list when nothing found', () => {\n\t\tconst result = filterComponentsByName(components, 'pizza');\n\t\texpect(result).toEqual([]);\n\t});\n\n\tit('should return all components if all of them match query', () => {\n\t\t// It doesn’t happen when RegExp has global flag for some reason\n\t\tconst components2 = [\n\t\t\t{ name: 'Button' },\n\t\t\t{ name: 'CounterButton' },\n\t\t\t{ name: 'PushButton' },\n\t\t\t{ name: 'RandomButtom' },\n\t\t\t{ name: 'WrappedButton' },\n\t\t];\n\t\tconst result = filterComponentsByName(components2, 'bu');\n\t\texpect(result).toEqual(components2);\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/filterComponentsInSectionsByExactName.spec.ts",
    "content": "import deepfreeze from 'deepfreeze';\nimport filterComponentsInSectionsByExactName from '../filterComponentsInSectionsByExactName';\n\nconst sections = deepfreeze([\n\t{\n\t\tname: 'General',\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Particles',\n\t\t\t\tcomponents: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Button',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Image',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n]);\n\ndescribe('filterComponentsInSectionsByExactName', () => {\n\tit('should return components at any level with exact name', () => {\n\t\tconst result = filterComponentsInSectionsByExactName(sections, 'Image', true)[0];\n\t\texpect(result.components && result.components.map(x => x.name)).toEqual(['Image']);\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/filterSectionExamples.spec.ts",
    "content": "import deepfreeze from 'deepfreeze';\nimport filterSectionExamples from '../filterSectionExamples';\n\nconst section = deepfreeze({\n\tcontent: ['a', 'b', 'c', 'd'],\n\tother: 'info',\n});\n\ndescribe('filterSectionExamples', () => {\n\tit('should return a shallow copy of a section with example filtered by given index', () => {\n\t\tconst result = filterSectionExamples(section as any, 2);\n\t\texpect(result).toEqual({\n\t\t\tcontent: ['c'],\n\t\t\tother: 'info',\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/filterSectionsByName.spec.ts",
    "content": "import deepfreeze from 'deepfreeze';\nimport filterSectionsByName from '../filterSectionsByName';\n\nconst sections = deepfreeze([\n\t{\n\t\tname: 'General',\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Particles',\n\t\t\t\tcomponents: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Button',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Image',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n]);\n\ndescribe('filterSectionsByName', () => {\n\tit('should recursively filter sections and components by name', () => {\n\t\tconst result = filterSectionsByName(sections, 'button');\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should skip sections without matches inside', () => {\n\t\tconst result = filterSectionsByName(sections, 'general');\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should return empty array if no components of sections match query', () => {\n\t\tconst result = filterSectionsByName(sections, 'pizza');\n\t\texpect(result).toEqual([]);\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/findSection.spec.ts",
    "content": "import findSection from '../findSection';\n\nconst sections = [\n\t{\n\t\tname: 'General',\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Particles',\n\t\t\t\tcomponents: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Button',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Image',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n];\n\ndescribe('findSection', () => {\n\tit('should return top level section', () => {\n\t\tconst result = findSection(sections, 'General');\n\t\texpect(result).toEqual(sections[0]);\n\t});\n\n\tit('should return nested sections', () => {\n\t\tconst result = findSection(sections, 'Particles');\n\t\texpect(result).toEqual(sections[0].sections[0]);\n\t});\n\n\tit('should return undefined when no sections found', () => {\n\t\tconst result = findSection(sections, 'Pizza');\n\t\texpect(result).toBeFalsy();\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/getAst.spec.ts",
    "content": "import getAst from '../getAst';\n\ndescribe('getAst', () => {\n\ttest('return AST', () => {\n\t\tconst result = getAst(`42`);\n\t\texpect(result).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/getComponent.spec.ts",
    "content": "import getComponent from '../getComponent';\n\ndescribe('getComponent', () => {\n\tdescribe('if there is a default export in the module', () => {\n\t\tit('should return that', () => {\n\t\t\tconst module = { default: 'useMe' };\n\t\t\tconst actual = getComponent(module);\n\t\t\texpect(actual).toBe(module.default);\n\t\t});\n\t});\n\n\tdescribe('if it is a CommonJS module and exports a function', () => {\n\t\tit('should return the module', () => {\n\t\t\tconst testCases = [() => {}, function() {}, class Class {}];\n\t\t\ttestCases.forEach(testCase => {\n\t\t\t\tconst actual = getComponent(testCase);\n\t\t\t\texpect(actual).toBe(testCase);\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('if there is only one named export in the module', () => {\n\t\tit('should return that', () => {\n\t\t\tconst module = { oneNamedExport: 'isLonely' };\n\t\t\tconst actual = getComponent(module);\n\t\t\texpect(actual).toBe(module.oneNamedExport);\n\t\t});\n\t});\n\n\tdescribe('if there is a named export whose name matches the name argument', () => {\n\t\tit('should return that', () => {\n\t\t\tconst name = 'Component';\n\t\t\tconst module = { [name]: 'isNamed', OtherComponent: 'isAlsoNamed' };\n\t\t\tconst actual = getComponent(module, name);\n\t\t\texpect(actual).toBe(module[name]);\n\t\t});\n\t});\n\n\tdescribe('if there is more than one named export and no matching name', () => {\n\t\tit('should fall back on returning the module as a whole', () => {\n\t\t\tconst name = 'Component';\n\t\t\tconst module = { RandomName: 'isNamed', confusingExport: 123 };\n\t\t\tconst actual = getComponent(module, name);\n\t\t\texpect(actual).toBe(module);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/getFilterRegExp.spec.ts",
    "content": "import getFilterRegExp from '../getFilterRegExp';\n\ndescribe('getFilterRegExp', () => {\n\tit('should return a RegExp', () => {\n\t\tconst result = getFilterRegExp('');\n\t\texpect(result instanceof RegExp).toBe(true);\n\t});\n\n\tit('RegExp should fuzzy match a string', () => {\n\t\tconst result = getFilterRegExp('btn');\n\t\texpect('button').toMatch(result);\n\t});\n\n\tit('RegExp should not match when string is different', () => {\n\t\tconst result = getFilterRegExp('buttons');\n\t\texpect('button').not.toMatch(result);\n\t});\n\n\tit('should not throw when query contains special characters', () => {\n\t\tconst fn = () => getFilterRegExp('\\\\');\n\t\texpect(fn).not.toThrow();\n\t});\n\n\tit('RegExp should ignore non-alphanumeric characters', () => {\n\t\tconst result = getFilterRegExp('#$b()tn');\n\t\texpect('button').toMatch(result);\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/getInfoFromHash.spec.ts",
    "content": "import getInfoFromHash from '../getInfoFromHash';\n\ndescribe('getInfoFromHash', () => {\n\tit('should return important part of hash if it contains component name', () => {\n\t\tconst result = getInfoFromHash('#!/Button');\n\t\texpect(result).toEqual({\n\t\t\tisolate: true,\n\t\t\thashArray: ['Button'],\n\t\t\ttargetName: 'Button',\n\t\t\ttargetIndex: undefined,\n\t\t});\n\t});\n\n\tit('should return an empty object if hash contains no component name', () => {\n\t\tconst result = getInfoFromHash('Button');\n\t\texpect(result).toEqual({});\n\t});\n\n\tit('should return the decoded targetName when router name is not English such as Chinese', () => {\n\t\tconst result = getInfoFromHash('#!/Api%20%E7%BB%84%E4%BB%B6');\n\t\texpect(result).toEqual({\n\t\t\tisolate: true,\n\t\t\thashArray: ['Api 组件'],\n\t\t\ttargetName: 'Api 组件',\n\t\t\ttargetIndex: undefined,\n\t\t});\n\t});\n\n\tit('hashArray should return an array of each deep and isolate should return false when the url starts with #/', () => {\n\t\tconst result = getInfoFromHash('#/Documentation/Files/Buttons');\n\t\texpect(result).toEqual({\n\t\t\tisolate: false,\n\t\t\thashArray: ['Documentation', 'Files', 'Buttons'],\n\t\t\ttargetName: 'Documentation',\n\t\t\ttargetIndex: undefined,\n\t\t});\n\t});\n\n\tit('should extract target index when the URL ends with a number', () => {\n\t\tconst result = getInfoFromHash('#/Documentation/Files/Buttons/5');\n\t\texpect(result).toEqual({\n\t\t\tisolate: false,\n\t\t\thashArray: ['Documentation', 'Files', 'Buttons'],\n\t\t\ttargetName: 'Documentation',\n\t\t\ttargetIndex: 5,\n\t\t});\n\t});\n\n\tit('should return a proper parsed result even though the hash starts with a number', () => {\n\t\tconst result = getInfoFromHash('#/1.Documentation');\n\t\texpect(result).toEqual({\n\t\t\tisolate: false,\n\t\t\thashArray: ['1.Documentation'],\n\t\t\ttargetName: '1.Documentation',\n\t\t\ttargetIndex: undefined,\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/getPageTitle.spec.ts",
    "content": "import getPageTitle from '../getPageTitle';\n\nconst baseTitle = 'Styleguide';\n\ndescribe('getPageTitle', () => {\n\tit('should return style guide title for the all view', () => {\n\t\tconst result = getPageTitle([], baseTitle, 'all');\n\t\texpect(result).toBe(baseTitle);\n\t});\n\n\tit('should return component name for component isolation mode', () => {\n\t\tconst name = 'Component';\n\t\tconst result = getPageTitle([{ components: [{ name }] }], baseTitle, 'component');\n\t\texpect(result).toMatch(name);\n\t});\n\n\tit('should return component name for example isolation mode', () => {\n\t\tconst name = 'Component';\n\t\tconst result = getPageTitle([{ components: [{ name }] }], baseTitle, 'example');\n\t\texpect(result).toMatch(name);\n\t});\n\n\tit('should return section name for example isolation mode of a example content', () => {\n\t\tconst sectionName = 'Section';\n\t\tconst result = getPageTitle(\n\t\t\t[{ name: sectionName, content: [], components: [] }],\n\t\t\tbaseTitle,\n\t\t\t'example'\n\t\t);\n\t\texpect(result).toMatch(sectionName);\n\t});\n\n\tit('should return section name for example isolation mode, if no components are passed', () => {\n\t\tconst name = 'Section';\n\t\tconst result = getPageTitle([{ name }], baseTitle, 'example');\n\t\texpect(result).toMatch(name);\n\t});\n\n\tit('should return section name for section isolation mode', () => {\n\t\tconst name = 'Section';\n\t\tconst result = getPageTitle([{ name }], baseTitle, 'section');\n\t\texpect(result).toMatch(name);\n\t});\n\n\tit('should return Error 404 for notFound isolation mode', () => {\n\t\tconst name = 'Section';\n\t\tconst result = getPageTitle([{ name }], baseTitle, 'notFound');\n\t\texpect(result).toMatch('Page not found');\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/getRouteData.spec.ts",
    "content": "import deepfreeze from 'deepfreeze';\nimport getRouteData from '../getRouteData';\nimport { DisplayModes } from '../../consts';\nimport * as Rsg from '../../../typings';\n\nconst example0: Rsg.Example = {\n\ttype: 'code',\n\tcontent: 'const a = 0',\n\tevalInContext: () => () => 3,\n};\n\nconst example1: Rsg.Example = {\n\ttype: 'markdown',\n\tcontent: '# title',\n};\n\nconst sections: Rsg.Section[] = deepfreeze([\n\t{\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Components',\n\t\t\t\tslug: 'components',\n\t\t\t\tcomponents: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Button',\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tdisplayName: 'Button',\n\t\t\t\t\t\t\texamples: [example0, example1],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmodule: 1,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Image',\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tdisplayName: 'Image',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmodule: 2,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tsections: [],\n\t\t\t\texampleMode: 'collapse',\n\t\t\t\tusageMode: 'collapse',\n\t\t\t\tsectionDepth: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'Section',\n\t\t\t\tslug: 'section',\n\t\t\t\tcontent: [example0, example1],\n\t\t\t\tcomponents: [],\n\t\t\t\tsections: [],\n\t\t\t\texampleMode: 'collapse',\n\t\t\t\tusageMode: 'collapse',\n\t\t\t\tsectionDepth: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'Buttons',\n\t\t\t\tslug: 'buttons',\n\t\t\t\tcomponents: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Label',\n\t\t\t\t\t\tmodule: 1,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'RandomButton',\n\t\t\t\t\t\tmodule: 2,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tsections: [],\n\t\t\t\texampleMode: 'collapse',\n\t\t\t\tusageMode: 'collapse',\n\t\t\t\tsectionDepth: 2,\n\t\t\t},\n\t\t],\n\t},\n]);\n\ndescribe('getRouteData', () => {\n\tit('should return \"all\" mode by default', () => {\n\t\tconst result = getRouteData([], '');\n\t\texpect(result.displayMode).toBe(DisplayModes.all);\n\t});\n\n\tit('should return one component', () => {\n\t\tconst result = getRouteData(sections, '#!/Button');\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should return one section', () => {\n\t\tconst result = getRouteData(sections, '#!/Section');\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should return one example from a component', () => {\n\t\tconst result = getRouteData(sections, '#!/Button/1');\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should return one example from a section', () => {\n\t\tconst result = getRouteData(sections, '#!/Section/1');\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should return first section if pagePerSection and hash is empty', () => {\n\t\tconst subSection = sections[0].sections as Rsg.Section[];\n\t\tconst result = getRouteData(subSection, '', true);\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should return one section if pagePerSection and hash is #/Section', () => {\n\t\tconst result = getRouteData(sections, '#/Section', true);\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should return one section without components if pagePerSection and hash is #/Buttons', () => {\n\t\tconst result = getRouteData(sections, '#/Buttons', true);\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should return one component if pagePerSection and hash is #/Buttons/Label', () => {\n\t\tconst result = getRouteData(sections, '#/Buttons/Label', true);\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\tit('should return not found if pagePerSection and hash is #/Buttons/Label/Not', () => {\n\t\tconst result = getRouteData(sections, '#/Buttons/Label/Not', true);\n\t\texpect(result).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/getUrl.spec.ts",
    "content": "import getUrl from '../getUrl';\n\ndescribe('getUrl', () => {\n\tconst loc = {\n\t\torigin: 'http://example.com',\n\t\tpathname: '/styleguide/',\n\t\thash: '#/Components',\n\t};\n\tconst locHashedURL = {\n\t\torigin: 'http://example.com',\n\t\tpathname: '/styleguide/',\n\t\thash: '#button',\n\t};\n\tconst name = 'FooBar';\n\tconst slug = 'foobar';\n\n\tit('should return a home URL', () => {\n\t\tconst result = getUrl({}, loc);\n\t\texpect(result).toBe('/styleguide/');\n\t});\n\n\tit('should return an absolute home URL', () => {\n\t\tconst result = getUrl({ absolute: true }, loc);\n\t\texpect(result).toBe('http://example.com/styleguide/');\n\t});\n\n\tit('should return an anchor URL', () => {\n\t\tconst result = getUrl({ name, slug, anchor: true }, loc);\n\t\texpect(result).toBe('/styleguide/#foobar');\n\t});\n\n\tit('should return an absolute anchor URL', () => {\n\t\tconst result = getUrl({ name, slug, anchor: true, absolute: true }, loc);\n\t\texpect(result).toBe('http://example.com/styleguide/#foobar');\n\t});\n\n\tit('should return an isolated URL', () => {\n\t\tconst result = getUrl({ name, slug, isolated: true }, loc);\n\t\texpect(result).toBe('/styleguide/#!/Components/FooBar');\n\t});\n\n\tit('should return an absolute isolated URL', () => {\n\t\tconst result = getUrl({ name, slug, isolated: true, absolute: true }, loc);\n\t\texpect(result).toBe('http://example.com/styleguide/#!/Components/FooBar');\n\t});\n\n\tit('should return an isolated example URL', () => {\n\t\tconst result = getUrl({ name, slug, example: 3, isolated: true }, loc);\n\t\texpect(result).toBe('/styleguide/#!/Components/FooBar/3');\n\t});\n\n\tit('should return an isolated example for a HashedURL', () => {\n\t\tconst result = getUrl({ name, slug, example: 0, isolated: true }, locHashedURL);\n\t\texpect(result).toBe('/styleguide/#!/FooBar/0');\n\t});\n\n\tit('should return an isolated example=0 URL', () => {\n\t\tconst result = getUrl({ name, slug, example: 0, isolated: true }, loc);\n\t\texpect(result).toBe('/styleguide/#!/Components/FooBar/0');\n\t});\n\n\tit('should return an absolute isolated example URL', () => {\n\t\tconst result = getUrl({ name, slug, example: 3, isolated: true, absolute: true }, loc);\n\t\texpect(result).toBe('http://example.com/styleguide/#!/Components/FooBar/3');\n\t});\n\n\tit('should return a nochrome URL', () => {\n\t\tconst result = getUrl({ name, slug, nochrome: true }, loc);\n\t\texpect(result).toBe('/styleguide/?nochrome#!/Components/FooBar');\n\t});\n\n\tit('should return an absolute nochrome URL', () => {\n\t\tconst result = getUrl({ name, slug, nochrome: true, absolute: true }, loc);\n\t\texpect(result).toBe('http://example.com/styleguide/?nochrome#!/Components/FooBar');\n\t});\n\n\tit('should return a route path', () => {\n\t\tconst result = getUrl({ name, slug, hashPath: ['Documentation'] }, loc);\n\t\texpect(result).toBe('/styleguide/#/Documentation/FooBar');\n\t});\n\n\tit('should return a route path with encoded name if name has inappropriate symbols', () => {\n\t\tconst result = getUrl({ name: '@foo/components', slug, hashPath: ['Documentation'] }, loc);\n\t\texpect(result).toBe('/styleguide/#/Documentation/%40foo%2Fcomponents');\n\t});\n\n\tit('should return a route path with encoded name if sections (hashPath) has inappropriate symbols', () => {\n\t\texpect(\n\t\t\tgetUrl({ name: '@foo/components', slug, hashPath: ['@foo/bar-documentation'] }, loc)\n\t\t).toBe('/styleguide/#/%40foo%2Fbar-documentation/%40foo%2Fcomponents');\n\n\t\texpect(\n\t\t\tgetUrl(\n\t\t\t\t{\n\t\t\t\t\tname: '@foo/components',\n\t\t\t\t\tslug,\n\t\t\t\t\thashPath: ['@foo/bar-documentation', '@foo/bar-activations-section'],\n\t\t\t\t},\n\t\t\t\tloc\n\t\t\t)\n\t\t).toBe(\n\t\t\t'/styleguide/#/%40foo%2Fbar-documentation/%40foo%2Fbar-activations-section/%40foo%2Fcomponents'\n\t\t);\n\t});\n\n\tit('should return a route path with a param id=foobar', () => {\n\t\tconst result = getUrl({ name, slug, hashPath: ['Documentation'], useSlugAsIdParam: true }, loc);\n\t\texpect(result).toBe('/styleguide/#/Documentation?id=foobar');\n\t});\n\n\tit('should return a param id=foobar', () => {\n\t\tconst result = getUrl({ name, slug, takeHash: true, useSlugAsIdParam: true }, loc);\n\t\texpect(result).toBe('/styleguide/#/Components?id=foobar');\n\t});\n\n\tit('should return to param id = foobar even if the hash has parameters', () => {\n\t\tconst result = getUrl(\n\t\t\t{ name, slug, takeHash: true, useSlugAsIdParam: true },\n\t\t\t{\n\t\t\t\t...loc,\n\t\t\t\thash: '#/Components?foo=foobar',\n\t\t\t}\n\t\t);\n\t\texpect(result).toBe('/styleguide/#/Components?id=foobar');\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/handleHash.spec.ts",
    "content": "import { hasInHash, getHash, getHashAsArray, getParameterByName } from '../handleHash';\n\ndescribe('handleHash', () => {\n\tconst isolateHash = '#!/';\n\tconst routeHash = '#/';\n\n\tit('hasInHash should return true if has #!/', () => {\n\t\tconst result = hasInHash('#!/FooBar', isolateHash);\n\t\texpect(result).toBe(true);\n\t});\n\n\tit('hasInHash should return false if does not have #!/', () => {\n\t\tconst result = hasInHash('#/FooBar', isolateHash);\n\t\texpect(result).toBe(false);\n\t});\n\n\tit('hasInHash should return true if has #/', () => {\n\t\tconst result = hasInHash('#/FooBar', routeHash);\n\t\texpect(result).toBe(true);\n\t});\n\n\tit('hasInHash should return false if does not have #/', () => {\n\t\tconst result = hasInHash('#!/FooBar', routeHash);\n\t\texpect(result).toBe(false);\n\t});\n\n\tit('getHash should return FooBar', () => {\n\t\tconst result = getHash('#/FooBar', routeHash);\n\t\texpect(result).toBe('FooBar');\n\t});\n\n\tit('getHash should return FooBar without params', () => {\n\t\tconst result = getHash('#/FooBar?id=Example/Perfect', routeHash);\n\t\texpect(result).toBe('FooBar');\n\t});\n\n\tit('getHash should return decode value', () => {\n\t\tconst result = getHash('#!/Api%20%E7%BB%84%E4%BB%B6', isolateHash);\n\t\texpect(result).toBe('Api 组件');\n\t});\n\n\tit('getHashAsArray should return array', () => {\n\t\tconst result = getHashAsArray('#!/FooBar/Component', isolateHash);\n\t\texpect(result).toEqual(['FooBar', 'Component']);\n\t});\n\n\tit('getHashAsArray should return array with an encoded component name', () => {\n\t\tconst result = getHashAsArray('#/Documentation/Files/%40foo%2Fcomponents', routeHash);\n\t\texpect(result).toEqual(['Documentation', 'Files', '@foo/components']);\n\t});\n\n\tit('getHashAsArray should return array without params', () => {\n\t\tconst result = getHashAsArray('#/FooBar/Component?id=Example/Perfect', routeHash);\n\t\texpect(result).toEqual(['FooBar', 'Component']);\n\t});\n\n\tit('getParameterByName should return Example when has id param', () => {\n\t\tconst result = getParameterByName('#/FooBar/Component?id=Example', 'id');\n\t\texpect(result).toBe('Example');\n\t});\n\n\tit('getParameterByName should return null when do not has params', () => {\n\t\tconst result = getParameterByName('#/FooBar/Component', 'id');\n\t\texpect(result).toEqual(null);\n\t});\n\n\tit('getParameterByName should return null when do not has id params', () => {\n\t\tconst result = getParameterByName('#/FooBar/Component?foobar=3', 'id');\n\t\texpect(result).toEqual(null);\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/processComponents.spec.ts",
    "content": "import deepfreeze from 'deepfreeze';\nimport processComponents from '../processComponents';\n\nconst options = { useRouterLinks: false };\n\ndescribe('processComponents', () => {\n\tit('should set components’ displayName to a name property', () => {\n\t\tconst components = deepfreeze([\n\t\t\t{\n\t\t\t\tprops: {\n\t\t\t\t\tdisplayName: 'Foo',\n\t\t\t\t},\n\t\t\t},\n\t\t]);\n\t\tconst result = processComponents(components, options);\n\t\texpect(result[0].name).toBe('Foo');\n\t});\n\n\tit('should calculate href', () => {\n\t\tconst components = deepfreeze([\n\t\t\t{\n\t\t\t\tslug: 'foo',\n\t\t\t\tprops: {\n\t\t\t\t\tdisplayName: 'Foo',\n\t\t\t\t},\n\t\t\t},\n\t\t]);\n\t\tconst result = processComponents(components, options);\n\t\texpect(result[0].href).toBe('/#foo');\n\t});\n\n\tdescribe('should set visibleName property on the component', () => {\n\t\tit('from an visibleName component prop if available', () => {\n\t\t\tconst components = deepfreeze([\n\t\t\t\t{\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tdisplayName: 'Foo',\n\t\t\t\t\t\tvisibleName: 'Foo Bar',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]);\n\t\t\tconst result = processComponents(components, options);\n\t\t\texpect(result[0].visibleName).toBe('Foo Bar');\n\t\t});\n\n\t\tit('from an displayName component prop if visibleName prop is not available', () => {\n\t\t\tconst components = deepfreeze([\n\t\t\t\t{\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tdisplayName: 'Foo',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]);\n\t\t\tconst result = processComponents(components, options);\n\t\t\texpect(result[0].visibleName).toBe('Foo');\n\t\t});\n\t});\n\n\tit('should append @example doclet to all examples', () => {\n\t\tconst components = deepfreeze([\n\t\t\t{\n\t\t\t\tprops: {\n\t\t\t\t\tdisplayName: 'Foo',\n\t\t\t\t\texamples: [1, 2] as any[],\n\t\t\t\t\texample: [3, 4] as any[],\n\t\t\t\t},\n\t\t\t},\n\t\t]);\n\t\tconst result = processComponents(components, options);\n\t\texpect(result[0].props && result[0].props.examples).toEqual([1, 2, 3, 4]);\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/processSections.spec.ts",
    "content": "import deepfreeze from 'deepfreeze';\nimport processSections from '../processSections';\n\nconst sections = deepfreeze([\n\t{\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Components',\n\t\t\t\tslug: 'components',\n\t\t\t\tcomponents: [\n\t\t\t\t\t{\n\t\t\t\t\t\tslug: 'button',\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tdisplayName: 'Button',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n]);\n\nconst options = { useRouterLinks: false, hashPath: [] };\n\ndescribe('processSections', () => {\n\ttest('should recursively process all sections and components', () => {\n\t\tconst result = processSections(sections, options);\n\t\tconst sectionsExpected = result[0].sections || [];\n\t\tconst comp = sectionsExpected.length\n\t\t\t? sectionsExpected[0].components && sectionsExpected[0].components[0]\n\t\t\t: undefined;\n\t\texpect(comp?.name).toBe('Button');\n\t\texpect(comp?.href).toBe('/#button');\n\t});\n\n\ttest('should set visibleName property on each section', () => {\n\t\tconst result = processSections(sections, options);\n\t\tconst sectionsExpected = result[0].sections || [];\n\t\texpect(sectionsExpected[0].visibleName).toBe('Components');\n\t});\n\n\ttest('should recursively process all nested sections when useRouterLinks is true has passed', () => {\n\t\tconst result = processSections([{ name: 'Component', sections: [{ name: 'Button' }] }], {\n\t\t\tuseRouterLinks: true,\n\t\t});\n\t\texpect(result?.[0].href).toBe('/#/Component');\n\t\texpect(result?.[0].sections?.[0].href).toBe('/#/Component/Button');\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/renderStyleguide.spec.ts",
    "content": "import { render } from '@testing-library/react';\nimport renderStyleguide from '../renderStyleguide';\n\nconst dummyLocation = { hash: '', search: '', pathname: '' };\n\nconst styleguide = {\n\tconfig: {\n\t\ttitle: 'My Style Guide',\n\t\tpagePerSection: false,\n\t},\n\twelcomeScreen: false,\n\tpatterns: ['components/**.js'],\n\tsections: [\n\t\t{\n\t\t\texampleMode: 'collapse',\n\t\t\tusageMode: 'collapse',\n\t\t\tslug: 'section',\n\t\t\tcomponents: [\n\t\t\t\t{\n\t\t\t\t\tslug: 'foo',\n\t\t\t\t\tpathLine: 'components/foo.js',\n\t\t\t\t\tfilepath: 'components/foo.js',\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tdisplayName: 'Button',\n\t\t\t\t\t\tdescription: 'Foo foo',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tslug: 'bar',\n\t\t\t\t\tpathLine: 'components/bar.js',\n\t\t\t\t\tfilepath: 'components/bar.js',\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tdisplayName: 'Image',\n\t\t\t\t\t\tdescription: 'Bar bar',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t],\n} as any;\nconst codeRevision = 1;\nconst doc = {\n\ttitle: 'test',\n};\nconst history = {\n\treplaceState: () => {},\n};\n\ntest('should render the style guide', () => {\n\tconst { getByText } = render(\n\t\trenderStyleguide(styleguide, codeRevision, dummyLocation, doc, history)\n\t);\n\texpect(getByText('components/foo.js')).toBeInTheDocument();\n\texpect(getByText('components/bar.js')).toBeInTheDocument();\n});\n\ntest('should change document title', () => {\n\trenderStyleguide(styleguide, codeRevision, dummyLocation, doc, history);\n\texpect(doc.title).toBe('My Style Guide');\n});\n\ntest('should change document title in isolated mode', () => {\n\tconst location = { hash: '#!/Button', pathname: '', search: '' };\n\n\trenderStyleguide(styleguide, codeRevision, location, doc, history);\n\texpect(doc.title).toBe('Button — My Style Guide');\n});\n\ntest('should remove #/ from the address bar', () => {\n\tconst location = { hash: '#/', pathname: '/pizza', search: '?foo=bar' };\n\tconst historyWithSpy = { replaceState: jest.fn() };\n\n\trenderStyleguide(styleguide, codeRevision, location, doc, historyWithSpy);\n\texpect(historyWithSpy.replaceState).toBeCalledWith('', 'My Style Guide', '/pizza?foo=bar');\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/splitExampleCode.spec.ts",
    "content": "import splitExampleCode from '../splitExampleCode';\n\ndescribe('splitExampleCode', () => {\n\ttest('basic example', () => {\n\t\tconst result = splitExampleCode(`var a = 1;\nReact.createElement('i', null, a);`);\n\t\texpect(result).toEqual({\n\t\t\thead: 'var a = 1',\n\t\t\texample: `var a = 1;\nreturn (React.createElement('i', null, a));`,\n\t\t});\n\t});\n\n\ttest('JSX not only in the last expression', () => {\n\t\tconst result = splitExampleCode(`function Wrapper(ref) {\n\tvar children = ref.children;\n\treturn React.createElement('div', {id: 'foo'}, children);\n}\n\n;React.createElement(Wrapper, null,\n\tReact.createElement(Wrapper, null, React.createElement(Icon, {name: \"plus\"})),\n\tReact.createElement(Wrapper, null, React.createElement(Icon, {name: \"clip\"}))\n)`);\n\t\texpect(result).toEqual({\n\t\t\texample: `function Wrapper(ref) {\n\tvar children = ref.children;\n\treturn React.createElement('div', {id: 'foo'}, children);\n}\n\n;\nreturn (React.createElement(Wrapper, null,\n\tReact.createElement(Wrapper, null, React.createElement(Icon, {name: \"plus\"})),\n\tReact.createElement(Wrapper, null, React.createElement(Icon, {name: \"clip\"}))\n));`,\n\t\t\thead: `function Wrapper(ref) {\n\tvar children = ref.children;\n\treturn React.createElement('div', {id: 'foo'}, children);\n}\n\n`,\n\t\t});\n\t});\n\n\ttest('single expression', () => {\n\t\tconst result = splitExampleCode('pizza');\n\t\texpect(result).toEqual({\n\t\t\thead: '',\n\t\t\texample: `;\nreturn (pizza);`,\n\t\t});\n\t});\n\n\ttest('empty string', () => {\n\t\tconst result = splitExampleCode('');\n\t\texpect(result).toEqual({\n\t\t\thead: '',\n\t\t\texample: '',\n\t\t});\n\t});\n\n\ttest('comment', () => {\n\t\tconst result = splitExampleCode('/* ~ */');\n\t\texpect(result).toEqual({\n\t\t\thead: '',\n\t\t\texample: '/* ~ */',\n\t\t});\n\t});\n\n\ttest('error', () => {\n\t\tconst result = splitExampleCode('?');\n\t\texpect(result).toEqual({\n\t\t\thead: '',\n\t\t\texample: '?',\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/__tests__/transpileImports.spec.ts",
    "content": "import transpileImports from '../transpileImports';\n\ndescribe('transpileImports', () => {\n\ttest('transpile default imports', () => {\n\t\tconst result = transpileImports(`import B from 'cat'`);\n\t\texpect(result).toMatchInlineSnapshot(`\n\"const cat$0 = require('cat');\nconst B = cat$0.default || cat$0;\"\n`);\n\t});\n\n\ttest('transpile named imports', () => {\n\t\tconst result = transpileImports(`import {B} from 'cat'`);\n\t\texpect(result).toMatchInlineSnapshot(`\n\"const cat$0 = require('cat');\nconst B = cat$0.B;\"\n`);\n\t});\n\n\ttest('transpile mixed imports', () => {\n\t\tconst result = transpileImports(`import A, {B} from 'cat'`);\n\t\texpect(result).toMatchInlineSnapshot(`\n\"const cat$0 = require('cat');\nconst A = cat$0.default || cat$0;\nconst B = cat$0.B;\"\n`);\n\t});\n\n\ttest('transpile multiple import statements', () => {\n\t\tconst result = transpileImports(`/**\n* Some important comment\n*/\nimport 'dog'\n/* Less important comments */\nimport B from 'cat'\n// Absolutely not important comment\nimport C from 'capybara'\nimport D from 'hamster' // One more comment\nimport E from 'snake'\n`);\n\t\texpect(result).toMatchInlineSnapshot(`\n\"/**\n* Some important comment\n*/\nrequire('dog');\n/* Less important comments */\nconst cat$0 = require('cat');\nconst B = cat$0.default || cat$0;\n// Absolutely not important comment\nconst capybara$0 = require('capybara');\nconst C = capybara$0.default || capybara$0;\nconst hamster$0 = require('hamster');\nconst D = hamster$0.default || hamster$0; // One more comment\nconst snake$0 = require('snake');\nconst E = snake$0.default || snake$0;\n\"\n`);\n\t});\n\n\ttest('transpile multiline named imports without trailing comma', () => {\n\t\tconst result = transpileImports(`import {\n  B,\n  C\n} from 'cat'\n`);\n\t\texpect(result).toMatchInlineSnapshot(`\n\"const cat$0 = require('cat');\nconst B = cat$0.B;\nconst C = cat$0.C;\n\"\n`);\n\t});\n\n\ttest('transpile multiline named imports with trailing comma', () => {\n\t\tconst result = transpileImports(`import {\n  B,\n  C,\n} from 'cat'\n`);\n\t\texpect(result).toMatchInlineSnapshot(`\n\"const cat$0 = require('cat');\nconst B = cat$0.B;\nconst C = cat$0.C;\n\"\n`);\n\t});\n\n\tdescribe.each([\n\t\t['./cat/capybara/hamster', '__cat_capybara_hamster'],\n\t\t['../cat/capybara/hamster', '___cat_capybara_hamster'],\n\t\t['cat/capybara/hamster', 'cat_capybara_hamster'],\n\t])('transpile default imports via relative path', (modulePath, transpiled) => {\n\t\ttest(`${modulePath}`, () => {\n\t\t\tconst result = transpileImports(`import B from '${modulePath}'`);\n\t\t\texpect(result).toMatchInlineSnapshot(`\n\t\"const ${transpiled}$0 = require('${modulePath}');\n\tconst B = ${transpiled}$0.default || ${transpiled}$0;\"\n\t`);\n\t\t});\n\t});\n\n\ttest('return code if there are no imports', () => {\n\t\tconst code = `<Button />`;\n\t\tconst result = transpileImports(code);\n\t\texpect(result).toEqual(code);\n\t});\n\n\ttest('return code if there is an import and a syntax error', () => {\n\t\tconst code = `import foo from 'foo';&`;\n\t\tconst result = transpileImports(code);\n\t\texpect(result).toEqual(code);\n\t});\n});\n"
  },
  {
    "path": "src/client/utils/compileCode.ts",
    "content": "import { transform, TransformOptions } from 'buble';\nimport transpileImports from './transpileImports';\n\nconst compile = (code: string, config: TransformOptions): string => transform(code, config).code;\n\nconst startsWithJsx = (code: string): boolean => !!code.trim().match(/^</);\n\nconst wrapCodeInFragment = (code: string): string => `<React.Fragment>${code}</React.Fragment>;`;\n\n/*\n * 1. Wrap code in React Fragment if it starts with JSX element\n * 2. Transform import statements into require() calls\n * 3. Compile code using Buble\n */\nexport default function compileCode(\n\tcode: string,\n\tcompilerConfig: TransformOptions,\n\tonError?: (err: Error) => void\n): string {\n\ttry {\n\t\tlet compiledCode;\n\n\t\ttry {\n\t\t\tcompiledCode = compile(code, compilerConfig);\n\t\t} catch (err) {\n\t\t\tif (\n\t\t\t\terr instanceof SyntaxError &&\n\t\t\t\terr.message.startsWith('Adjacent JSX elements must be wrapped in an enclosing tag')\n\t\t\t) {\n\t\t\t\tconst wrappedCode = startsWithJsx(code) ? wrapCodeInFragment(code) : code;\n\t\t\t\tcompiledCode = compile(wrappedCode, compilerConfig);\n\t\t\t} else if (onError && err instanceof Error) {\n\t\t\t\tonError(err);\n\t\t\t}\n\t\t}\n\n\t\treturn compiledCode ? transpileImports(compiledCode) : '';\n\t} catch (err) {\n\t\tif (onError && err instanceof Error) {\n\t\t\tonError(err);\n\t\t}\n\t}\n\treturn '';\n}\n"
  },
  {
    "path": "src/client/utils/filterComponentExamples.ts",
    "content": "import * as Rsg from '../../typings';\n\n/**\n * Return a copy of the given component with the examples array filtered\n * to contain only the specified index:\n * filterComponentExamples({ examples: [1,2,3], ...other }, 2) → { examples: [3], ...other }\n *\n * @param {object} component\n * @param {number} index\n * @returns {object}\n */\nexport default function filterComponentExamples(\n\tcomponent: Rsg.Component,\n\tindex: number\n): Rsg.Component {\n\treturn {\n\t\t...component,\n\t\tprops: {\n\t\t\t...component.props,\n\t\t\texamples:\n\t\t\t\tcomponent.props && component.props.examples ? [component.props.examples[index]] : [],\n\t\t},\n\t};\n}\n"
  },
  {
    "path": "src/client/utils/filterComponentsByExactName.ts",
    "content": "import * as Rsg from '../../typings';\n\n/**\n * Filters list of components by component name.\n *\n * @param {Array} components\n * @param {string} name\n * @return {Array}\n */\nexport default function filterComponentsByExactName(\n\tcomponents: Rsg.Component[],\n\tname: string\n): Rsg.Component[] {\n\treturn components.filter(component => component.name === name);\n}\n"
  },
  {
    "path": "src/client/utils/filterComponentsByName.ts",
    "content": "import getFilterRegExp from './getFilterRegExp';\nimport * as Rsg from '../../typings';\n\n/**\n * Fuzzy filters components list by component name.\n *\n * @param {array} components\n * @param {string} query\n * @return {array}\n */\nexport default function filterComponentsByName(\n\tcomponents: Rsg.Component[],\n\tquery: string\n): Rsg.Component[] {\n\tconst regExp = getFilterRegExp(query);\n\treturn components.filter(({ name }) => regExp.test(name as string));\n}\n"
  },
  {
    "path": "src/client/utils/filterComponentsInSectionsByExactName.ts",
    "content": "import filterComponentsByExactName from './filterComponentsByExactName';\nimport * as Rsg from '../../typings';\n\n/**\n * Recursively filters all components in all sections by component name.\n *\n * @param {object} sections\n * @param {string} name\n * @param {boolean} recursive\n * @return {Array}\n */\nexport default function filterComponentsInSectionsByExactName(\n\tsections: Rsg.Section[],\n\tname: string,\n\trecursive: boolean\n): Rsg.Section[] {\n\tconst filteredSections: Rsg.Section[] = [];\n\tsections.forEach(section => {\n\t\tif (section.components) {\n\t\t\tconst filteredComponents = filterComponentsByExactName(section.components, name);\n\t\t\tif (filteredComponents.length) {\n\t\t\t\tfilteredSections.push({\n\t\t\t\t\tslug: section.slug,\n\t\t\t\t\texampleMode: section.exampleMode,\n\t\t\t\t\tusageMode: section.usageMode,\n\t\t\t\t\tcomponents: filteredComponents,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tif (section.sections && recursive) {\n\t\t\tfilteredSections.push(\n\t\t\t\t...filterComponentsInSectionsByExactName(section.sections, name, recursive)\n\t\t\t);\n\t\t}\n\t});\n\treturn filteredSections;\n}\n"
  },
  {
    "path": "src/client/utils/filterSectionExamples.ts",
    "content": "import * as Rsg from '../../typings';\n\n/**\n * Return a copy of the given section with the examples array filtered\n * to contain only the specified index\n *\n * @param {object} section\n * @param {number} index\n * @returns {object}\n */\nexport default function filterSectionExamples(section: Rsg.Section, index = -1): Rsg.Section {\n\tconst content = Array.isArray(section.content) ? [section.content[index]] : [];\n\treturn {\n\t\t...section,\n\t\tcontent,\n\t};\n}\n"
  },
  {
    "path": "src/client/utils/filterSectionsByName.ts",
    "content": "import getFilterRegExp from './getFilterRegExp';\nimport filterComponentsByName from './filterComponentsByName';\nimport * as Rsg from '../../typings';\n\n/**\n * Fuzzy filters sections by section or component name.\n *\n * @param {Array} sections\n * @param {string} query\n * @return {Array}\n */\nexport default function filterSectionsByName(\n\tsections: Rsg.TOCItem[],\n\tquery: string\n): Rsg.TOCItem[] {\n\tconst regExp = getFilterRegExp(query);\n\n\treturn sections\n\t\t.map(section => {\n\t\t\treturn {\n\t\t\t\t...section,\n\t\t\t\tsections: section.sections ? filterSectionsByName(section.sections, query) : [],\n\t\t\t\tcomponents: section.components ? filterComponentsByName(section.components, query) : [],\n\t\t\t};\n\t\t})\n\t\t.filter(\n\t\t\tsection =>\n\t\t\t\tsection.components.length > 0 ||\n\t\t\t\tsection.sections.length > 0 ||\n\t\t\t\tregExp.test(section.name || '-')\n\t\t);\n}\n"
  },
  {
    "path": "src/client/utils/findSection.ts",
    "content": "import find from 'lodash/find';\nimport * as Rsg from '../../typings';\n\n/**\n * Recursively finds a section with a given name (exact match)\n *\n * @param  {Array}  sections\n * @param  {string} name\n * @return {object}\n */\nexport default function findSection(\n\tsections: Rsg.Section[],\n\tname: string\n): Rsg.Section | undefined {\n\t// We're using Lodash because IE11 doesn't support Array.find.\n\tconst found = find(sections, { name });\n\tif (found) {\n\t\treturn found;\n\t}\n\n\tfor (let i = 0; i < sections.length; i++) {\n\t\tconst section = sections[i];\n\t\tif (!section.sections || section.sections.length === 0) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst foundInSubsection = findSection(section.sections, name);\n\t\tif (foundInSubsection) {\n\t\t\treturn foundInSubsection;\n\t\t}\n\t}\n\n\treturn undefined;\n}\n"
  },
  {
    "path": "src/client/utils/getAst.ts",
    "content": "import { Parser, Node, Options } from 'acorn';\n\nexport interface Program extends Node {\n\tbody: Node[];\n}\n\nexport const ACORN_OPTIONS: Options = {\n\tecmaVersion: 2019,\n\tsourceType: 'module',\n};\n\n/**\n * Parse source code with Acorn and return AST, returns undefined in case of errors\n */\nexport default function getAst(code: string): Program | undefined {\n\ttry {\n\t\treturn (Parser.parse(code, {\n\t\t\t...ACORN_OPTIONS,\n\t\t// types of acorn are too simplistic and we have to use the body\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any \n\t\t}) as any) as Program;\n\t} catch (err) {\n\t\treturn undefined;\n\t}\n}\n"
  },
  {
    "path": "src/client/utils/getComponent.ts",
    "content": "type Module = DefaultExport | { [name: string]: any };\n\ninterface DefaultExport {\n\tdefault: any;\n}\n\nfunction isDefaultExport(module: Module): module is DefaultExport {\n\treturn !!module.default;\n}\n\n/**\n * Given a component module and a name,\n * return the appropriate export.\n * See /docs/Components.md\n */\nexport default function getComponent(module: Module, name?: string): Module {\n\t//\n\t// If the module defines a default export, return that\n\t// e.g.\n\t//\n\t// ```\n\t// export default function Component() { ... }\n\t// ```\n\t//\n\tif (isDefaultExport(module)) {\n\t\treturn module.default;\n\t}\n\n\t// If it is a CommonJS module which exports a function, return that\n\t// e.g.\n\t//\n\t// ```\n\t// function Component() { ... }\n\t// module.exports = Component;\n\t// ```\n\t//\n\tif (!module.__esModule && typeof module === 'function') {\n\t\treturn module;\n\t}\n\n\t// If the module exports just one named export, return that\n\t// e.g.\n\t//\n\t// ```\n\t// export function Component() { ... }\n\t// ```\n\t//\n\tconst namedExports = Object.keys(module);\n\tif (namedExports.length === 1) {\n\t\treturn module[namedExports[0]];\n\t}\n\n\t// If the module exports a named export with the same name as the\n\t// understood Component identifier, return that\n\t// e.g.\n\t//\n\t// ```\n\t// // /component.js\n\t// export function someUtil() { ... }\n\t// export Component() { ... } // if identifier is Component, return this named export\n\t// ```\n\t//\n\t// Else return the module itself\n\t//\n\treturn (name ? module[name] : undefined) || module;\n}\n"
  },
  {
    "path": "src/client/utils/getFilterRegExp.ts",
    "content": "/**\n * RegExp to fuzzy filter components list by component name.\n *\n * @param {string} query\n * @return {RegExp}\n */\nexport default function getFilterRegExp(query: string): RegExp {\n\tquery = query\n\t\t.replace(/[^a-z0-9]/gi, '')\n\t\t.split('')\n\t\t.join('.*');\n\treturn new RegExp(query, 'i');\n}\n"
  },
  {
    "path": "src/client/utils/getInfoFromHash.ts",
    "content": "import { hasInHash, getHashAsArray } from './handleHash';\n\nfunction hasDigitsOnly(item: string): boolean {\n\treturn item.match(/^\\d+$/) !== null;\n}\n\n/**\n * Returns an object containing component/section name and, optionally, an example index\n * from hash part or page URL:\n * #!/Button → { targetName: 'Button' }\n * #!/Button/1 → { targetName: 'Button', targetIndex: 1 }\n *\n * @param {string} hash\n * @returns {object}\n */\nexport default function getInfoFromHash(\n\thash: string\n): {\n\tisolate?: boolean;\n\thashArray?: string[];\n\ttargetName?: string;\n\ttargetIndex?: number;\n} {\n\tconst shouldIsolate = hasInHash(hash, '#!/');\n\tif (shouldIsolate || hasInHash(hash, '#/')) {\n\t\tconst hashArray = getHashAsArray(hash, shouldIsolate ? '#!/' : '#/');\n\t\tconst targetHash = hashArray[hashArray.length - 1];\n\t\treturn {\n\t\t\tisolate: shouldIsolate,\n\t\t\thashArray: hashArray.filter(item => !hasDigitsOnly(item)),\n\t\t\ttargetName: hashArray[0],\n\t\t\ttargetIndex: hasDigitsOnly(targetHash) ? parseInt(targetHash, 10) : undefined,\n\t\t};\n\t}\n\treturn {};\n}\n"
  },
  {
    "path": "src/client/utils/getPageTitle.ts",
    "content": "import get from 'lodash/get';\nimport { DisplayModes } from '../consts';\nimport * as Rsg from '../../typings';\n\n/**\n * Return page title:\n * “Style Guide Title” for all components view;\n * “Component Name — Style Guide Title” for isolated component or example view.\n * “Section Name — Style Guide Title” for isolated section view.\n *\n * @param {object} sections\n * @param {string} baseTitle\n * @param {string} displayMode\n * @return {string}\n */\nexport default function getPageTitle(\n\tsections: Rsg.Section[],\n\tbaseTitle: string,\n\tdisplayMode: string\n): string {\n\tif (displayMode === DisplayModes.notFound) {\n\t\treturn 'Page not found';\n\t}\n\tif (sections.length) {\n\t\tif (\n\t\t\tdisplayMode === DisplayModes.component ||\n\t\t\t(displayMode === DisplayModes.example && sections[0].components)\n\t\t) {\n\t\t\tconst name = get(sections[0], 'components.0.name', sections[0].name);\n\t\t\treturn `${name} — ${baseTitle}`;\n\t\t} else if (displayMode === DisplayModes.section || displayMode === DisplayModes.example) {\n\t\t\treturn `${sections[0].name} — ${baseTitle}`;\n\t\t}\n\t}\n\treturn baseTitle;\n}\n"
  },
  {
    "path": "src/client/utils/getRouteData.ts",
    "content": "import isFinite from 'lodash/isFinite';\nimport filterComponentExamples from './filterComponentExamples';\nimport filterComponentsInSectionsByExactName from './filterComponentsInSectionsByExactName';\nimport filterSectionExamples from './filterSectionExamples';\nimport findSection from './findSection';\nimport getInfoFromHash from './getInfoFromHash';\nimport { DisplayModes } from '../consts';\nimport * as Rsg from '../../typings';\n\n/**\n * Return sections / components / examples to show on a screen according to a current route.\n *\n * Default: show all sections and components.\n * #!/Button: show only Button section or Button component\n * #!/Button/1: show only the second example (index 1) of Button component\n *\n * @param {object} sections\n * @param {string} hash\n * @param {boolean} pagePerSection\n * @returns {object}\n */\nexport default function getRouteData(\n\tsections: Rsg.Section[],\n\thash: string,\n\tpagePerSection = false\n): { sections: Rsg.Section[]; displayMode: string } {\n\t// Parse URL hash to check if the components list must be filtered\n\tconst infoFromHash = getInfoFromHash(hash);\n\n\t// Name of the filtered component/section to show isolated (/#!/Button → Button)\n\tlet { targetName, hashArray } = infoFromHash;\n\n\tconst {\n\t\t// Index of the fenced block example of the filtered component isolate (/#!/Button/1 → 1)\n\t\ttargetIndex,\n\t\tisolate,\n\t} = infoFromHash;\n\n\tlet displayMode = isolate ? DisplayModes.example : DisplayModes.all;\n\n\tif (pagePerSection && !targetName && sections[0] && sections[0].name) {\n\t\t// For default takes the first section when pagePerSection enabled\n\t\ttargetName = sections[0].name;\n\t\thashArray = [targetName];\n\t}\n\n\tif (targetName) {\n\t\tlet filteredSections: Rsg.Section[] = [];\n\n\t\tif (pagePerSection && hashArray) {\n\t\t\t// hashArray could be an array as [\"Documentation\", \"Files\", \"Button\"]\n\t\t\t// each hashArray's element represent each section name with the same deep\n\t\t\t// so it should be filter each section to trying to find each one of array on the same deep\n\t\t\thashArray.forEach((hashName, index) => {\n\t\t\t\t// Filter the requested component if required but only on the first depth\n\t\t\t\t// so in the next time of iteration, it will be trying to filter only on the second depth and so on\n\t\t\t\tfilteredSections = filterComponentsInSectionsByExactName(sections, hashName, !!isolate);\n\n\t\t\t\t// If filteredSections exists, its because is an array of an component\n\t\t\t\t// else it is an array of sections and depending his sectionDepth\n\t\t\t\t// his children could be filtered or not\n\t\t\t\tif (filteredSections.length) {\n\t\t\t\t\tsections = filteredSections;\n\t\t\t\t} else {\n\t\t\t\t\tlet section = findSection(sections, hashName);\n\t\t\t\t\tif (section) {\n\t\t\t\t\t\t// Only if hashName is the last of hashArray his children should be filtered\n\t\t\t\t\t\t// because else there are possibilities to keep on filtering to try find the next section\n\t\t\t\t\t\tconst isLastHashName = !hashArray || !hashArray[index + 1];\n\n\t\t\t\t\t\t// When sectionDepth is bigger than 0, their children should be filtered\n\t\t\t\t\t\tconst shouldFilterTheirChildren = (section.sectionDepth || 0) > 0 && isLastHashName;\n\n\t\t\t\t\t\tif (shouldFilterTheirChildren) {\n\t\t\t\t\t\t\t// Filter his sections and components\n\t\t\t\t\t\t\tsection = {\n\t\t\t\t\t\t\t\t...section,\n\t\t\t\t\t\t\t\tsections: [],\n\t\t\t\t\t\t\t\tcomponents: [],\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsections = [section];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsections = [];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tif (!sections.length) {\n\t\t\t\tdisplayMode = DisplayModes.notFound;\n\t\t\t}\n\t\t\t// The targetName takes the last of hashArray\n\t\t\ttargetName = hashArray[hashArray.length - 1];\n\t\t} else {\n\t\t\t// Filter the requested component if required\n\t\t\tfilteredSections = filterComponentsInSectionsByExactName(sections, targetName, true);\n\t\t\tif (filteredSections.length) {\n\t\t\t\tsections = filteredSections;\n\t\t\t\tdisplayMode = DisplayModes.component;\n\t\t\t} else {\n\t\t\t\tconst section = findSection(sections, targetName);\n\t\t\t\tsections = section ? [section] : [];\n\t\t\t\tdisplayMode = DisplayModes.section;\n\t\t\t}\n\t\t}\n\n\t\t// If a single component or section is filtered and a fenced block index is specified hide all other examples\n\t\tif (isFinite(targetIndex)) {\n\t\t\tif (filteredSections.length === 1) {\n\t\t\t\tconst filteredComponents = filteredSections[0].components;\n\t\t\t\tsections = [\n\t\t\t\t\t{\n\t\t\t\t\t\t...filteredSections[0],\n\t\t\t\t\t\tcomponents:\n\t\t\t\t\t\t\tfilteredComponents && typeof targetIndex === 'number'\n\t\t\t\t\t\t\t\t? [filterComponentExamples(filteredComponents[0], targetIndex)]\n\t\t\t\t\t\t\t\t: [],\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t\tdisplayMode = DisplayModes.example;\n\t\t\t} else if (sections.length === 1) {\n\t\t\t\tsections = [filterSectionExamples(sections[0], targetIndex)];\n\t\t\t\tdisplayMode = DisplayModes.example;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { sections, displayMode };\n}\n"
  },
  {
    "path": "src/client/utils/getUrl.ts",
    "content": "/* Returns the HashPath to be included in the isolated page view url */\nfunction getCurrentHashPath(\n\tstripFragment: RegExp,\n\tstripTrailingSlash: RegExp,\n\tcurrentHash: string\n): string {\n\t/*This pattern matches urls like http://hostname.com/#button etc.,\n\tthese urls are generated when we click on a component in the side nav-bar.\n\tThis will verify whether the first character after the '#' symbol is an alphanumeric char or \"_\".\n\tthis pattern used to validate the components names.*/\n\tconst hashUrlPattern = /^#[a-zA-Z0-9_]/; // Ex. matches \"#button\",\"#1button\",\"#_button\"\n\n\t/* This pattern matches \"#!/\" string pattern in the 'currentHash' const\n\tthis url pattern is used to show isolated page view mode in this project. */\n\tconst isolatedPageViewUrlPattern = /^#!\\//; // Ex. matches \"#!/button\"\n\n\tif (hashUrlPattern.test(currentHash)) {\n\t\treturn '';\n\t} else {\n\t\treturn currentHash && !isolatedPageViewUrlPattern.test(currentHash)\n\t\t\t? currentHash.replace(stripFragment, '').replace(stripTrailingSlash, '') + '/'\n\t\t\t: '';\n\t}\n}\n\n/**\n * Gets the URL fragment for an isolated or nochrome link.\n *\n * @param {string} $.currentHash The current hash fragment of the page\n * @param {string} $.encodedName The URL encoded name of the component\n * @return {string}\n */\nfunction buildIsolatedOrNoChromeFragment({\n\tcurrentHash,\n\tencodedName,\n}: {\n\tcurrentHash: string;\n\tencodedName: string;\n}): string {\n\tconst stripFragment = /^#\\/?/;\n\tconst stripTrailingSlash = /\\/$/;\n\n\tconst currentHashPath = getCurrentHashPath(stripFragment, stripTrailingSlash, currentHash);\n\treturn `#!/${currentHashPath}${encodedName}`;\n}\n\ninterface GetUrlOptions {\n\tname: string;\n\tslug: string;\n\t/**\n\t * Example index\n\t */\n\texample: number;\n\tanchor: boolean;\n\t/**\n\t * Isolated mode\n\t */\n\tisolated: boolean;\n\t/**\n\t * No chrome? (Can be combined with anchor or isolated)\n\t */\n\tnochrome: boolean;\n\t/**\n\t * Absolute URL? (Can be combined with other flags)\n\t */\n\tabsolute: boolean;\n\thashPath: string[] | false;\n\tuseSlugAsIdParam: boolean;\n\ttakeHash: boolean;\n}\n\n/**\n * Get component / section URL.\n *\n * @param {GetUrlOptions} options\n * @param location Location object (will use current page location by default)\n * @return {string}\n */\nexport default function getUrl(\n\t{\n\t\tname,\n\t\tslug,\n\t\texample,\n\t\tanchor,\n\t\tisolated,\n\t\tnochrome,\n\t\tabsolute,\n\t\thashPath,\n\t\tuseSlugAsIdParam,\n\t\ttakeHash,\n\t}: Partial<GetUrlOptions> = {},\n\t{\n\t\torigin,\n\t\tpathname,\n\t\thash = '',\n\t}: {\n\t\torigin: string;\n\t\tpathname: string;\n\t\thash: string;\n\t} = window.location\n): string {\n\tlet url = pathname;\n\n\tconst currentHash = hash.indexOf('?') > -1 ? hash.substring(0, hash.indexOf('?')) : hash;\n\n\tif (takeHash) {\n\t\turl += currentHash;\n\t}\n\n\tif (nochrome) {\n\t\turl += '?nochrome';\n\t}\n\n\tconst encodedName = encodeURIComponent(name || '');\n\n\tif (anchor) {\n\t\turl += `#${slug}`;\n\t} else if (isolated || nochrome) {\n\t\turl += buildIsolatedOrNoChromeFragment({ currentHash, encodedName });\n\t}\n\n\tif (hashPath) {\n\t\tlet encodedHashPath = hashPath.map(encodeURIComponent);\n\t\tif (!useSlugAsIdParam) {\n\t\t\tencodedHashPath = [...encodedHashPath, encodedName];\n\t\t}\n\t\turl += `#/${encodedHashPath.join('/')}`;\n\t}\n\n\tif (useSlugAsIdParam) {\n\t\turl += `?id=${slug}`;\n\t}\n\n\tif (example !== undefined) {\n\t\turl += `/${example}`;\n\t}\n\n\tif (absolute) {\n\t\treturn origin + url;\n\t}\n\n\treturn url;\n}\n"
  },
  {
    "path": "src/client/utils/handleHash.ts",
    "content": "import escapeRegExp from 'lodash/escapeRegExp';\n\n// We’re using this file to handle the hash to develop the routes, there are two types of hash '#/' and '#!/'\n// However, it is a temporal solution because is necessary using a library third-party that it is his focus\n// You can find more information here:\n// https://github.com/styleguidist/react-styleguidist/pull/993\nconst defaultPrependHash = '#/';\nconst separator = '/';\nconst hashValRegexp = /(.*)\\?/;\n\nfunction trimHash(hash: string, prependHash?: string): string {\n\tif (!hash) {\n\t\treturn '';\n\t}\n\tconst regexp = new RegExp('^' + escapeRegExp(prependHash || defaultPrependHash), 'g');\n\treturn hash.replace(regexp, '');\n}\n\nconst trimParams = (hash: string): string => {\n\tconst result = hashValRegexp.exec(hash);\n\treturn (result && result[1]) || hash;\n};\n\n/**\n * If hash has a certain element\n *\n * @param {string} hash\n * @param {string} search\n * @return {boolean}\n */\nexport const hasInHash = (hash: string, search: string): boolean => {\n\treturn hash !== '' && hash.indexOf(search) > -1;\n};\n\n/**\n * Get hash value without '#', prependHash and parameters\n *\n * @param {string} hash\n * @param {string} prependHash\n * @return {string}\n */\nexport const getHash = (hash: string, prependHash?: string) => {\n\treturn decodeURIComponent(trimParams(trimHash(hash, prependHash)));\n};\n\n/**\n * Get hash value split into an Array.\n *\n * @param {string} hash\n * @param {string} prependHash\n * @return {Array.<string>}\n */\nexport const getHashAsArray = (hash: string, prependHash?: string): string[] => {\n\treturn trimParams(trimHash(hash, prependHash))\n\t\t.split(separator)\n\t\t.map(decodeURIComponent);\n};\n\n/**\n * Get a parameter by name in hash\n *\n * @param {string} hash\n * @param {string} name\n * @return {string}\n */\nexport const getParameterByName = (hash: string, name: string): string | null => {\n\tname = name.replace(/[[\\]]/g, '\\\\$&');\n\tconst regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)');\n\tconst results = regex.exec(hash);\n\tif (!results) {\n\t\treturn null;\n\t}\n\tif (!results[2]) {\n\t\treturn '';\n\t}\n\treturn decodeURIComponent(results[2].replace(/\\+/g, ' '));\n};\n"
  },
  {
    "path": "src/client/utils/processComponents.ts",
    "content": "import * as Rsg from '../../typings';\nimport getUrl from './getUrl';\n\nexport interface HrefOptions {\n\thashPath?: string[];\n\tuseRouterLinks: boolean;\n\tuseHashId?: boolean;\n}\n\n/**\n * Do things that are hard or impossible to do in a loader: we don’t have access to component name\n * and props in the styleguide-loader because we’re using `require` to load the component module.\n *\n * @param {Array} components\n * @return {Array}\n */\nexport default function processComponents(\n\tcomponents: Rsg.Component[],\n\t{ useRouterLinks, useHashId, hashPath }: HrefOptions\n): Rsg.Component[] {\n\treturn components.map(component => {\n\t\tconst newComponent: Rsg.Component = component.props\n\t\t\t? {\n\t\t\t\t\t...component,\n\n\t\t\t\t\t// Add .name shortcuts for names instead of .props.displayName.\n\t\t\t\t\tname: component.props.displayName,\n\t\t\t\t\tvisibleName: component.props.visibleName || component.props.displayName,\n\n\t\t\t\t\tprops: {\n\t\t\t\t\t\t...component.props,\n\t\t\t\t\t\t// Append @example doclet to all examples\n\t\t\t\t\t\texamples: [...(component.props.examples || []), ...(component.props.example || [])],\n\t\t\t\t\t},\n\t\t\t\t\thref:\n\t\t\t\t\t\tcomponent.href ||\n\t\t\t\t\t\tgetUrl({\n\t\t\t\t\t\t\tname: component.props.displayName,\n\t\t\t\t\t\t\tslug: component.slug,\n\t\t\t\t\t\t\tanchor: !useRouterLinks,\n\t\t\t\t\t\t\thashPath: useRouterLinks ? hashPath : false,\n\t\t\t\t\t\t\tuseSlugAsIdParam: useRouterLinks ? useHashId : false,\n\t\t\t\t\t\t}),\n\t\t\t  }\n\t\t\t: {};\n\n\t\treturn newComponent;\n\t});\n}\n"
  },
  {
    "path": "src/client/utils/processSections.ts",
    "content": "import * as Rsg from '../../typings';\nimport processComponents, { HrefOptions } from './processComponents';\nimport getUrl from './getUrl';\n\n/**\n * Recursively process each component in all sections.\n *\n * @param {Array} sections\n * @return {Array}\n */\nexport default function processSections(\n\tsections: Rsg.Section[],\n\t{ useRouterLinks, useHashId = false, hashPath = [] }: HrefOptions\n): Rsg.Section[] {\n\treturn sections.map((section) => {\n\t\tconst options = {\n\t\t\tuseRouterLinks: Boolean(useRouterLinks && section.name),\n\t\t\tuseHashId: section.sectionDepth === 0,\n\t\t\thashPath: [...hashPath, section.name ? section.name : '-'],\n\t\t};\n\t\tconst href =\n\t\t\tsection.href ||\n\t\t\tgetUrl({\n\t\t\t\tname: section.name,\n\t\t\t\tslug: section.slug,\n\t\t\t\tanchor: !useRouterLinks,\n\t\t\t\thashPath: useRouterLinks ? hashPath : false,\n\t\t\t\tuseSlugAsIdParam: useRouterLinks ? useHashId : false,\n\t\t\t});\n\n\t\treturn {\n\t\t\t...section,\n\t\t\t// flag the section as an external link to avoid rendering it later\n\t\t\texternalLink: !!section.href,\n\t\t\thref,\n\t\t\tvisibleName: section.name,\n\t\t\tcomponents: processComponents(section.components || [], options),\n\t\t\tsections: processSections(section.sections || [], options),\n\t\t};\n\t});\n}\n"
  },
  {
    "path": "src/client/utils/renderStyleguide.tsx",
    "content": "import React from 'react';\nimport hashSum from 'hash-sum';\nimport slots from 'rsg-components/slots';\nimport StyleGuide from 'rsg-components/StyleGuide';\nimport getPageTitle from './getPageTitle';\nimport getRouteData from './getRouteData';\nimport processSections from './processSections';\nimport * as Rsg from '../../typings';\n\ninterface StyleguideObject {\n\tsections: Rsg.Section[];\n\tconfig: Rsg.ProcessedStyleguidistConfig;\n\tpatterns: string[];\n\twelcomeScreen?: boolean;\n}\n\n/**\n * @param {object} styleguide An object returned by styleguide-loader\n * @param {number} codeRevision\n * @param {Location} [loc]\n * @param {Document} [doc]\n * @param {History} [hist]\n * @return {React.ReactElement}\n */\nexport default function renderStyleguide(\n\tstyleguide: StyleguideObject,\n\tcodeRevision: number,\n\tloc: { hash: string; pathname: string; search: string } = window.location,\n\tdoc: { title: string } = document,\n\thist: { replaceState: (name: string, title: string, url: string) => void } = window.history\n): React.ReactElement {\n\tconst allSections = processSections(styleguide.sections, {\n\t\tuseRouterLinks: styleguide.config.pagePerSection,\n\t});\n\n\tconst { title, pagePerSection, theme, styles } = styleguide.config;\n\tconst { sections, displayMode } = getRouteData(allSections, loc.hash, pagePerSection);\n\n\t// Update page title\n\tdoc.title = getPageTitle(sections, title, displayMode);\n\n\t// If the current hash location was set to just `/` (e.g. when navigating back from isolated view to overview)\n\t// replace the URL with one without hash, to present the user with a single address of the overview screen\n\tif (loc.hash === '#/') {\n\t\tconst url = loc.pathname + loc.search;\n\t\thist.replaceState('', doc.title, url);\n\t}\n\n\treturn (\n\t\t<StyleGuide\n\t\t\tcodeRevision={codeRevision}\n\t\t\t// only caclulate css revisions in dev when hot is on to avoid\n\t\t\t// stringifying the styles in production\n\t\t\tcssRevision={module.hot ? hashSum({ theme, styles }) : '0'}\n\t\t\tconfig={styleguide.config}\n\t\t\tslots={slots(styleguide.config)}\n\t\t\twelcomeScreen={styleguide.welcomeScreen}\n\t\t\tpatterns={styleguide.patterns}\n\t\t\tsections={sections}\n\t\t\tallSections={allSections}\n\t\t\tdisplayMode={displayMode}\n\t\t\tpagePerSection={pagePerSection}\n\t\t/>\n\t);\n}\n"
  },
  {
    "path": "src/client/utils/rewriteImports.ts",
    "content": "// Temporary copy to fix\n// https://github.com/lukeed/rewrite-imports/issues/10\n\nconst UNNAMED = /import\\s*['\"]([^'\"]+)['\"];?/gi;\nconst NAMED = /import\\s*(\\*\\s*as)?\\s*(\\w*?)\\s*,?\\s*(?:\\{([\\s\\S]*?)\\})?\\s*from\\s*['\"]([^'\"]+)['\"];?/gi;\n\nfunction alias(key: string): { key: string; name: string } {\n\tkey = key.trim();\n\tconst name = key.split(' as ');\n\tif (name.length > 1) {\n\t\tkey = name.shift() as string;\n\t}\n\treturn { key, name: name[0] };\n}\n\nlet num: number;\nfunction generate(keys: string[], dep: string, base: string, fn: string): string {\n\tconst tmp = dep.replace(/\\W/g, '_') + '$' + num++; // uniqueness\n\tconst name = alias(tmp).name;\n\n\tdep = `${fn}('${dep}')`;\n\n\tlet obj;\n\tlet out = `const ${name} = ${dep};`;\n\n\tif (base) {\n\t\tout += `\\nconst ${base} = ${tmp}.default || ${tmp};`;\n\t}\n\n\tkeys.forEach(key => {\n\t\tobj = alias(key);\n\t\tout += `\\nconst ${obj.name} = ${tmp}.${obj.key};`;\n\t});\n\n\treturn out;\n}\n\nexport default function(str: string, fn = 'require'): string {\n\tnum = 0;\n\treturn str\n\t\t.replace(NAMED, (_, asterisk, base, req: string | undefined, dep: string) =>\n\t\t\tgenerate(req ? req.split(',').filter(d => d.trim()) : [], dep, base, fn)\n\t\t)\n\t\t.replace(UNNAMED, (_, dep) => `${fn}('${dep}');`);\n}\n"
  },
  {
    "path": "src/client/utils/splitExampleCode.ts",
    "content": "import find from 'lodash/find';\nimport getAst from './getAst';\n\n// Strip semicolon (;) at the end\nconst unsemicolon = (s: string): string => s.replace(/;\\s*$/, '');\n\n/**\n * Take source code and returns:\n * 1. Code before the last top-level expression.\n * 2. Code with the last top-level expression wrapped in a return statement\n *    (kind of an implicit return).\n *\n * Example:\n * var a = 1; React.createElement('i', null, a); // =>\n * 1. var a = 1\n * 2. var a = 1; return (React.createElement('i', null, a));\n */\nexport default function splitExampleCode(code: string): { head: string; example: string } {\n\tconst ast = getAst(code);\n\tif (!ast) {\n\t\treturn { head: '', example: code };\n\t}\n\n\tconst firstExpression = find(ast.body.reverse(), { type: 'ExpressionStatement' });\n\tif (!firstExpression) {\n\t\treturn { head: '', example: code };\n\t}\n\n\tconst { start, end } = firstExpression;\n\tconst head = unsemicolon(code.substring(0, start));\n\tconst firstExpressionCode = unsemicolon(code.substring(start, end));\n\tconst example = `${head};\\nreturn (${firstExpressionCode});`;\n\n\treturn {\n\t\thead,\n\t\texample,\n\t};\n}\n"
  },
  {
    "path": "src/client/utils/transpileImports.ts",
    "content": "import { walk } from 'estree-walker';\nimport rewriteImports from './rewriteImports';\nimport getAst from './getAst';\n\nconst hasImports = (code: string): boolean => !!code.match(/import[\\S\\s]+?['\"]([^'\"]+)['\"];?/m);\n\n/**\n * Replace ECMAScript imports with require() calls\n */\nexport default function transpileImports(code: string): string {\n\t// Don't do anything when the code has nothing that looks like an import\n\tif (!hasImports(code)) {\n\t\treturn code;\n\t}\n\n\t// Ignore errors, they should be caught by Buble\n\tconst ast = getAst(code);\n\tif (!ast) {\n\t\treturn code;\n\t}\n\n\tlet offset = 0;\n\t// estree walkers type is incompatible with acorns output\n\t// it is working here out of luck and typescript is demonstrating it \n\t// we have to go through the any part to keep the nodes with their `node.start`\n\t// and `node.stop`\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any \n\twalk(ast as any, {\n\t\t// import foo from 'foo'\n\t\t// import 'foo'\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any \n\t\tenter: (node: any) => {\n\t\t\tif (node.type === 'ImportDeclaration' && node.source) {\n\t\t\t\tconst start = node.start + offset;\n\t\t\t\tconst end = node.end + offset;\n\n\t\t\t\tconst statement = code.substring(start, end);\n\t\t\t\tconst transpiledStatement = rewriteImports(statement);\n\n\t\t\t\tcode = code.substring(0, start) + transpiledStatement + code.substring(end);\n\n\t\t\t\toffset += transpiledStatement.length - statement.length;\n\t\t\t}\n\t\t},\n\t});\n\n\treturn code;\n}\n"
  },
  {
    "path": "src/loaders/__tests__/examples-loader.spec.ts",
    "content": "import examplesLoader from '../examples-loader';\n\n/* eslint-disable no-new-func */\n\nconst query = {\n\tfile: '../foo.js',\n\tdisplayName: 'FooComponent',\n\tshouldShowDefaultExample: false,\n};\n\nconst subComponentQuery = {\n\tfile: '../fooSub.js',\n\tdisplayName: 'FooComponent.SubComponent',\n\tshouldShowDefaultExample: false,\n};\n\nconst getQueryOptions = (options = {}) => ({ ...query, ...options });\nconst getSubComponentQueryOptions = (options = {}) => ({ ...subComponentQuery, ...options });\n\nit('should return valid, parsable JS', () => {\n\tconst exampleMarkdown = `\n# header\n\n\t<div/>\n\ntext\n\n\\`\\`\\`\n<span/>\n\\`\\`\\`\n`;\n\tconst result = examplesLoader.call(\n\t\t{\n\t\t\tgetOptions: () => getQueryOptions(),\n\t\t\t_styleguidist: {},\n\t\t} as any,\n\t\texampleMarkdown\n\t);\n\n\texpect(result).toBeTruthy();\n\texpect(() => new Function(result)).not.toThrowError(SyntaxError);\n});\n\nit('should replace all occurrences of __COMPONENT__ with provided query.displayName', () => {\n\tconst exampleMarkdown = `\n<div>\n\t<__COMPONENT__>\n\t\t<span>text</span>\n\t\t<span>Name of component: __COMPONENT__</span>\n\t</__COMPONENT__>\n\t<__COMPONENT__ />\n</div>\n`;\n\n\tconst result = examplesLoader.call(\n\t\t{\n\t\t\tgetOptions: () => getQueryOptions({ shouldShowDefaultExample: true }),\n\t\t\t_styleguidist: {},\n\t\t} as any,\n\t\texampleMarkdown\n\t);\n\texpect(result).not.toMatch(/__COMPONENT__/);\n\tconst componentHtml = result.match(/<div>(.*?)<\\/div>/);\n\texpect(componentHtml && componentHtml[0]).toMatchInlineSnapshot(\n\t\t`\"<div>\\\\\\\\n\\\\\\\\t<FooComponent>\\\\\\\\n\\\\\\\\t\\\\\\\\t<span>text</span>\\\\\\\\n\\\\\\\\t\\\\\\\\t<span>Name of component: FooComponent</span>\\\\\\\\n\\\\\\\\t</FooComponent>\\\\\\\\n\\\\\\\\t<FooComponent />\\\\\\\\n</div>\"`\n\t);\n});\n\nit('should pass updateExample function from config to chunkify', () => {\n\tconst exampleMarkdown = `\n\\`\\`\\`jsx static\n<h1>Hello world!</h2>\n\\`\\`\\`\n`;\n\tconst updateExample = jest.fn((props) => props);\n\texamplesLoader.call(\n\t\t{\n\t\t\tgetOptions: () => getQueryOptions(),\n\t\t\tresourcePath: '/path/to/foo/examples/file',\n\t\t\t_styleguidist: {\n\t\t\t\tupdateExample,\n\t\t\t},\n\t\t} as any,\n\t\texampleMarkdown\n\t);\n\texpect(updateExample).toBeCalledWith(\n\t\t{\n\t\t\tcontent: '<h1>Hello world!</h2>',\n\t\t\tsettings: { static: true },\n\t\t\tlang: 'jsx',\n\t\t},\n\t\t'/path/to/foo/examples/file'\n\t);\n});\n\nit('should generate require map when require() is used', () => {\n\tconst exampleMarkdown = `\nOne:\n\n    const _ = require('lodash');\n\t<X/>\n\nTwo:\n\n\t<Y/>\n`;\n\tconst result = examplesLoader.call(\n\t\t{\n\t\t\tgetOptions: () => getQueryOptions(),\n\t\t\t_styleguidist: {},\n\t\t} as any,\n\t\texampleMarkdown\n\t);\n\n\texpect(result).toBeTruthy();\n\texpect(() => new Function(result)).not.toThrowError(SyntaxError);\n\texpect(result).toMatch(`'lodash': require('lodash')`);\n\texpect(result).toMatch(`'react': require('react')`);\n});\n\nit('should generate require map when import is used', () => {\n\tconst exampleMarkdown = `\nOne:\n\n    import _ from 'lodash';\n\t<X/>\n`;\n\tconst result = examplesLoader.call(\n\t\t{\n\t\t\tgetOptions: () => getQueryOptions(),\n\t\t\t_styleguidist: {},\n\t\t} as any,\n\t\texampleMarkdown\n\t);\n\n\texpect(result).toBeTruthy();\n\texpect(() => new Function(result)).not.toThrowError(SyntaxError);\n\texpect(result).toMatch(`'lodash': require('lodash')`);\n\texpect(result).toMatch(`'react': require('react')`);\n});\n\nit('should work with multiple JSX element on the root level', () => {\n\tconst exampleMarkdown = `\n\t<X/>\n\t<Y/>\n`;\n\tconst result = examplesLoader.call(\n\t\t{\n\t\t\tgetOptions: () => getQueryOptions(),\n\t\t\t_styleguidist: {},\n\t\t} as any,\n\t\texampleMarkdown\n\t);\n\n\texpect(result).toBeTruthy();\n\texpect(() => new Function(result)).not.toThrowError(SyntaxError);\n});\n\nit('should prepend example code with React require()', () => {\n\tconst exampleMarkdown = `<X/>`;\n\tconst result = examplesLoader.call(\n\t\t{\n\t\t\tgetOptions: () => getQueryOptions(),\n\t\t\t_styleguidist: {},\n\t\t} as any,\n\t\texampleMarkdown\n\t);\n\n\texpect(result).toBeTruthy();\n\texpect(() => new Function(result)).not.toThrowError(SyntaxError);\n\texpect(result).toMatch(\n\t\t`const React$0 = require('react');\\\\nconst React = React$0.default || (React$0['React'] || React$0);`\n\t);\n});\n\nit('should prepend example code with component require()', () => {\n\tconst exampleMarkdown = `<X/>`;\n\tconst result = examplesLoader.call(\n\t\t{\n\t\t\tgetOptions: () => getQueryOptions(),\n\t\t\t_styleguidist: {},\n\t\t} as any,\n\t\texampleMarkdown\n\t);\n\n\texpect(result).toBeTruthy();\n\texpect(() => new Function(result)).not.toThrowError(SyntaxError);\n\texpect(result).toMatch(\n\t\t`const FooComponent$0 = require('../foo.js');\\\\nconst FooComponent = FooComponent$0.default || (FooComponent$0['FooComponent'] || FooComponent$0);`\n\t);\n});\n\nit('should prepend example code with root component require() for sub components', () => {\n\tconst exampleMarkdown = `<X/>`;\n\tconst result = examplesLoader.call(\n\t\t{\n\t\t\tgetOptions: () => getSubComponentQueryOptions(),\n\t\t\t_styleguidist: {},\n\t\t} as any,\n\t\texampleMarkdown\n\t);\n\n\texpect(result).toBeTruthy();\n\texpect(() => new Function(result)).not.toThrowError(SyntaxError);\n\texpect(result).toMatch(\n\t\t`const FooComponentSubComponent$0 = require('../fooSub.js');\\\\nconst FooComponentSubComponent = FooComponentSubComponent$0.default || (FooComponentSubComponent$0['FooComponentSubComponent'] || FooComponentSubComponent$0);`\n\t);\n});\n\nit('should allow explicit import of React and component module', () => {\n\tconst exampleMarkdown = `\n    import React from 'react';\n    import FooComponent from '../foo.js';\n    <FooComponent/>`;\n\tconst result = examplesLoader.call(\n\t\t{\n\t\t\tgetOptions: () => getQueryOptions(),\n\t\t\t_styleguidist: {},\n\t\t} as any,\n\t\texampleMarkdown\n\t);\n\n\texpect(result).toBeTruthy();\n\texpect(() => new Function(result)).not.toThrowError(SyntaxError);\n\texpect(result).toMatch(\n\t\t`const React$0 = require('react');\\\\nconst React = React$0.default || (React$0['React'] || React$0);`\n\t);\n\texpect(result).toMatch(\n\t\t`const FooComponent$0 = require('../foo.js');\\\\nconst FooComponent = FooComponent$0.default || (FooComponent$0['FooComponent'] || FooComponent$0);`\n\t);\n});\n\nit('should works for any Markdown file, without a current component', () => {\n\tconst exampleMarkdown = `\n    import React from 'react';\n    import FooComponent from '../foo.js';\n    <FooComponent/>`;\n\tconst result = examplesLoader.call(\n\t\t{\n\t\t\tgetOptions: () => ({}),\n\t\t\t_styleguidist: {},\n\t\t} as any,\n\t\texampleMarkdown\n\t);\n\n\texpect(result).toBeTruthy();\n\texpect(() => new Function(result)).not.toThrowError(SyntaxError);\n\texpect(result).toMatch(\n\t\t`const React$0 = require('react');\\\\nconst React = React$0.default || (React$0['React'] || React$0);`\n\t);\n\texpect(result).not.toMatch('undefined');\n});\n"
  },
  {
    "path": "src/loaders/__tests__/props-loader.spec.ts",
    "content": "import vm from 'vm';\nimport { readFileSync } from 'fs';\nimport glogg from 'glogg';\nimport { PropDescriptor } from 'react-docgen';\n\nimport sortBy from 'lodash/sortBy';\nimport config from '../../scripts/schemas/config';\nimport propsLoader from '../props-loader';\n\nconst logger = glogg('rsg');\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst _styleguidist = {\n\thandlers: config.handlers.default,\n\tgetExampleFilename: config.getExampleFilename.default,\n\tresolver: config.resolver.default,\n};\n\nit('should return valid, parsable JS', () => {\n\tconst file = './test/components/Button/Button.js';\n\tconst result = propsLoader.call(\n\t\t{\n\t\t\trequest: file,\n\t\t\t_styleguidist,\n\t\t} as any,\n\t\treadFileSync(file, 'utf8')\n\t);\n\texpect(result).toBeTruthy();\n\texpect(() => new vm.Script(result)).not.toThrow();\n});\n\nit('should extract doclets', () => {\n\tconst file = './test/components/Placeholder/Placeholder.js';\n\tconst result = propsLoader.call(\n\t\t{\n\t\t\trequest: file,\n\t\t\t_styleguidist,\n\t\t} as any,\n\t\treadFileSync(file, 'utf8')\n\t);\n\texpect(result).toBeTruthy();\n\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(result.includes('makeABarrelRoll')).toBe(false);\n\texpect(result).toMatch('getImageUrl');\n\texpect(result).toMatch(/'see': '\\{@link link\\}'/);\n\texpect(result).toMatch(/'link': 'link'/);\n\texpect(result).toMatch(/require\\('!!.*?\\/loaders\\/examples-loader\\.js!\\.\\/examples.md'\\)/);\n});\n\ndescribe('property sorting', () => {\n\tit('should sort properties by default', () => {\n\t\tconst file = './test/components/Price/Price.js';\n\t\tconst result = propsLoader.call(\n\t\t\t{\n\t\t\t\trequest: file,\n\t\t\t\t_styleguidist,\n\t\t\t} as any,\n\t\t\treadFileSync(file, 'utf8')\n\t\t);\n\t\texpect(result).toBeTruthy();\n\n\t\texpect(() => new vm.Script(result)).not.toThrow();\n\t\texpect(result.includes('makeABarrelRoll')).toBe(false);\n\t\texpect(result).toMatch(\n\t\t\t/props[\\s\\S]*?name': 'symbol'[\\s\\S]*?name': 'value'[\\s\\S]*?name': 'emphasize'[\\s\\S]*?name': 'unit'/m\n\t\t);\n\t});\n\n\tit('should be possible to disable sorting', () => {\n\t\tconst file = './test/components/Price/Price.js';\n\t\tconst result = propsLoader.call(\n\t\t\t{\n\t\t\t\trequest: file,\n\t\t\t\t_styleguidist: { ..._styleguidist, sortProps: (props: any) => props },\n\t\t\t} as any,\n\t\t\treadFileSync(file, 'utf8')\n\t\t);\n\t\texpect(result).toBeTruthy();\n\n\t\texpect(() => new vm.Script(result)).not.toThrow();\n\t\texpect(result.includes('makeABarrelRoll')).toBe(false);\n\t\texpect(result).toMatch(\n\t\t\t/props[\\s\\S]*?name': 'value'[\\s\\S]*?name': 'unit'[\\s\\S]*?name': 'emphasize'[\\s\\S]*?name': 'symbol'/m\n\t\t);\n\t});\n\n\tit('should be possible to write custom sort function', () => {\n\t\tconst sortFn = (props: any) => {\n\t\t\tconst requiredProps = sortBy(\n\t\t\t\tprops.filter((prop: PropDescriptor) => prop.required),\n\t\t\t\t'name'\n\t\t\t).reverse();\n\t\t\tconst optionalProps = sortBy(\n\t\t\t\tprops.filter((prop: PropDescriptor) => !prop.required),\n\t\t\t\t'name'\n\t\t\t).reverse();\n\t\t\treturn optionalProps.concat(requiredProps);\n\t\t};\n\t\tconst file = './test/components/Price/Price.js';\n\t\tconst result = propsLoader.call(\n\t\t\t{\n\t\t\t\trequest: file,\n\t\t\t\t_styleguidist: { ..._styleguidist, sortProps: sortFn },\n\t\t\t} as any,\n\t\t\treadFileSync(file, 'utf8')\n\t\t);\n\t\texpect(result).toBeTruthy();\n\n\t\texpect(() => new vm.Script(result)).not.toThrow();\n\t\texpect(result.includes('makeABarrelRoll')).toBe(false);\n\t\texpect(result).toMatch(\n\t\t\t/props[\\s\\S]*?name': 'unit'[\\s\\S]*?name': 'emphasize'[\\s\\S]*?name': 'value'[\\s\\S]*?name': 'symbol'/m\n\t\t);\n\t});\n});\n\nit('should work with JSDoc annnotated components', () => {\n\tconst file = './test/components/Annotation/Annotation.js';\n\tconst result = propsLoader.call(\n\t\t{\n\t\t\trequest: file,\n\t\t\t_styleguidist,\n\t\t} as any,\n\t\treadFileSync(file, 'utf8')\n\t);\n\texpect(result).toBeTruthy();\n\texpect(() => new vm.Script(result)).not.toThrow();\n\t// eslint-disable-next-line no-eval\n\texpect(eval(result)).toEqual(\n\t\texpect.objectContaining({\n\t\t\tdisplayName: 'Annotation',\n\t\t\tdescription: 'Styled-component test\\n',\n\t\t\tdoclets: {\n\t\t\t\tcomponent: true,\n\t\t\t},\n\t\t})\n\t);\n});\n\nit('should not render ignored props', () => {\n\tconst file = './test/components/Button/Button.js';\n\tconst result = propsLoader.call(\n\t\t{\n\t\t\trequest: file,\n\t\t\t_styleguidist,\n\t\t} as any,\n\t\treadFileSync(file, 'utf8')\n\t);\n\texpect(result).toBeTruthy();\n\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(result.includes('ignoredProp')).toBe(false);\n});\n\nit('should attach examples from Markdown file', () => {\n\tconst file = './test/components/Button/Button.js';\n\tconst result = propsLoader.call(\n\t\t{\n\t\t\trequest: file,\n\t\t\t_styleguidist,\n\t\t} as any,\n\t\treadFileSync(file, 'utf8')\n\t);\n\texpect(result).toBeTruthy();\n\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(result).toMatch(\n\t\t/require\\('!!.*?\\/loaders\\/examples-loader\\.js\\?displayName=Button&file=\\.%2FButton\\.js&shouldShowDefaultExample=false!test\\/components\\/Button\\/Readme\\.md'\\)/\n\t);\n});\n\nit('should warn if no componets are exported', () => {\n\tconst warn = jest.fn();\n\tlogger.once('warn', warn);\n\n\tconst file = __filename;\n\tconst result = propsLoader.call(\n\t\t{\n\t\t\trequest: file,\n\t\t\t_styleguidist,\n\t\t} as any,\n\t\treadFileSync(file, 'utf8')\n\t);\n\texpect(result).toBeTruthy();\n\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(warn).toBeCalledWith(expect.stringMatching('doesn’t export a component'));\n});\n\nit('should warn if a file cannot be parsed', () => {\n\tconst warn = jest.fn();\n\tlogger.once('warn', warn);\n\n\tconst file = './test/components/Button/Readme.md';\n\tconst result = propsLoader.call(\n\t\t{\n\t\t\trequest: file,\n\t\t\t_styleguidist,\n\t\t} as any,\n\t\treadFileSync(file, 'utf8')\n\t);\n\texpect(result).toBeTruthy();\n\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(warn).toBeCalledWith(expect.stringMatching('Cannot parse'));\n});\n\nit('should add context dependencies to webpack from contextDependencies config option', () => {\n\tconst contextDependencies = ['foo', 'bar'];\n\tconst addContextDependency = jest.fn();\n\tconst file = './test/components/Button/Button.js';\n\tconst result = propsLoader.call(\n\t\t{\n\t\t\trequest: file,\n\t\t\t_styleguidist: { ..._styleguidist, contextDependencies },\n\t\t\taddContextDependency,\n\t\t} as any,\n\t\treadFileSync(file, 'utf8')\n\t);\n\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(addContextDependency).toHaveBeenCalledTimes(2);\n\texpect(addContextDependency).toBeCalledWith(contextDependencies[0]);\n\texpect(addContextDependency).toBeCalledWith(contextDependencies[1]);\n});\n\nit('should update the returned props object after enhancing from the updateDocs config option', () => {\n\tconst updateDocs = jest.fn();\n\tconst file = './test/components/Button/Button.js';\n\tconst result = propsLoader.call(\n\t\t{\n\t\t\trequest: file,\n\t\t\t_styleguidist: { ..._styleguidist, updateDocs },\n\t\t} as any,\n\t\treadFileSync(file, 'utf8')\n\t);\n\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(updateDocs).toHaveBeenCalledWith(\n\t\texpect.objectContaining({ displayName: 'Button' }),\n\t\t'./test/components/Button/Button.js'\n\t);\n});\n"
  },
  {
    "path": "src/loaders/__tests__/styleguide-loader.spec.ts",
    "content": "import vm from 'vm';\nimport path from 'path';\nimport * as styleguideLoader from '../styleguide-loader';\nimport getConfig from '../../scripts/config';\n\n/* eslint-disable quotes */\n\nconst file = path.resolve(__dirname, '../../../test/components/Button/Button.js');\nconst configDir = path.resolve(__dirname, '../../../test');\n\nit('should return valid, parsable JS', () => {\n\tconst result = styleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\tsections: [{ components: 'components/**/*.js' }],\n\t\t\tconfigDir,\n\t\t\tgetExampleFilename: () => 'Readme.md',\n\t\t\tgetComponentPathLine: (filepath: string) => filepath,\n\t\t},\n\t\taddContextDependency: () => {},\n\t} as any);\n\texpect(result).toBeTruthy();\n\texpect(() => new vm.Script(result)).not.toThrow();\n});\n\nit('should return correct component paths: default glob pattern', () => {\n\tconst result = styleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\t...getConfig(path.resolve(__dirname, '../../../test/apps/defaults/styleguide.config.js')),\n\t\t},\n\t\taddContextDependency: () => {},\n\t} as any);\n\texpect(result).toBeTruthy();\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(result).toMatch(`'filepath': 'src/components/Button.js'`);\n\texpect(result).toMatch(`'filepath': 'src/components/Placeholder.js'`);\n});\n\nit('should return correct component paths: glob', () => {\n\tconst result = styleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\tsections: [{ components: 'components/**/*.js' }],\n\t\t\tconfigDir,\n\t\t\tgetExampleFilename: () => 'Readme.md',\n\t\t\tgetComponentPathLine: (filepath: string) => filepath,\n\t\t},\n\t\taddContextDependency: () => {},\n\t} as any);\n\texpect(result).toBeTruthy();\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(result).toMatch(`'filepath': 'components/Button/Button.js'`);\n\texpect(result).toMatch(`'filepath': 'components/Placeholder/Placeholder.js'`);\n\texpect(result).toMatch(`'filepath': 'components/RandomButton/RandomButton.js'`);\n});\n\nit('should return correct component paths: function returning absolute paths', () => {\n\tconst result = styleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\tsections: [\n\t\t\t\t{\n\t\t\t\t\tcomponents: () => [\n\t\t\t\t\t\t`${configDir}/components/Button/Button.js`,\n\t\t\t\t\t\t`${configDir}/components/Placeholder/Placeholder.js`,\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t\tconfigDir,\n\t\t\tgetExampleFilename: () => 'Readme.md',\n\t\t\tgetComponentPathLine: (filepath: string) => filepath,\n\t\t},\n\t\taddContextDependency: () => {},\n\t} as any);\n\texpect(result).toBeTruthy();\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(result).toMatch(`'filepath': 'components/Button/Button.js'`);\n\texpect(result).toMatch(`'filepath': 'components/Placeholder/Placeholder.js'`);\n\texpect(result).not.toMatch(`'filepath': 'components/RandomButton/RandomButton.js'`);\n});\n\nit('should return correct component paths: function returning relative paths', () => {\n\tconst result = styleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\tsections: [\n\t\t\t\t{\n\t\t\t\t\tcomponents: () => [\n\t\t\t\t\t\t'components/Button/Button.js',\n\t\t\t\t\t\t'components/Placeholder/Placeholder.js',\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t\tconfigDir,\n\t\t\tgetExampleFilename: () => 'Readme.md',\n\t\t\tgetComponentPathLine: (filepath: string) => filepath,\n\t\t},\n\t\taddContextDependency: () => {},\n\t} as any);\n\texpect(result).toBeTruthy();\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(result).toMatch(`'filepath': 'components/Button/Button.js'`);\n\texpect(result).toMatch(`'filepath': 'components/Placeholder/Placeholder.js'`);\n\texpect(result).not.toMatch(`'filepath': 'components/RandomButton/RandomButton.js'`);\n});\n\nit('should return correct component paths: array of of relative paths', () => {\n\tconst result = styleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\tsections: [\n\t\t\t\t{\n\t\t\t\t\tcomponents: ['components/Button/Button.js', 'components/Placeholder/Placeholder.js'],\n\t\t\t\t},\n\t\t\t],\n\t\t\tconfigDir,\n\t\t\tgetExampleFilename: () => 'Readme.md',\n\t\t\tgetComponentPathLine: (filepath: string) => filepath,\n\t\t},\n\t\taddContextDependency: () => {},\n\t} as any);\n\texpect(result).toBeTruthy();\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(result).toMatch(`'filepath': 'components/Button/Button.js'`);\n\texpect(result).toMatch(`'filepath': 'components/Placeholder/Placeholder.js'`);\n});\n\nit('should filter out components without examples if skipComponentsWithoutExample=true', () => {\n\tconst result = styleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\tsections: [\n\t\t\t\t{\n\t\t\t\t\tcomponents: () => [\n\t\t\t\t\t\t'components/Button/Button.js',\n\t\t\t\t\t\t'components/RandomButton/RandomButton.js',\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t\tconfigDir,\n\t\t\tskipComponentsWithoutExample: true,\n\t\t\tgetExampleFilename: (componentPath: string) =>\n\t\t\t\tpath.join(path.dirname(componentPath), 'Readme.md'),\n\t\t\tgetComponentPathLine: (filepath: string) => filepath,\n\t\t},\n\t\taddContextDependency: () => {},\n\t} as any);\n\texpect(result).toBeTruthy();\n\texpect(() => new vm.Script(result)).not.toThrow();\n\texpect(result).toMatch(`'filepath': 'components/Button/Button.js'`);\n\texpect(result).not.toMatch(`'filepath': 'components/RandomButton/RandomButton.js'`);\n});\n\nit('should add context dependencies to webpack from contextDependencies config option', () => {\n\tconst contextDependencies = ['foo', 'bar'];\n\tconst addContextDependency = jest.fn();\n\tstyleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\tsections: [{ components: 'components/**/*.js' }],\n\t\t\tconfigDir,\n\t\t\tgetExampleFilename: () => 'Readme.md',\n\t\t\tgetComponentPathLine: (filepath: string) => filepath,\n\t\t\tcontextDependencies,\n\t\t},\n\t\taddContextDependency,\n\t} as any);\n\texpect(addContextDependency).toHaveBeenCalledTimes(2);\n\texpect(addContextDependency).toBeCalledWith(contextDependencies[0]);\n\texpect(addContextDependency).toBeCalledWith(contextDependencies[1]);\n});\n\nit('should add common parent folder of all components to context dependencies', () => {\n\tconst addContextDependency = jest.fn();\n\tstyleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\tsections: [{ components: 'components/**/*.js' }],\n\t\t\tconfigDir,\n\t\t\tgetExampleFilename: () => 'Readme.md',\n\t\t\tgetComponentPathLine: (filepath: string) => filepath,\n\t\t},\n\t\taddContextDependency,\n\t} as any);\n\texpect(addContextDependency).toHaveBeenCalledTimes(1);\n\texpect(addContextDependency).toBeCalledWith(expect.stringMatching(/test[\\\\/]components[\\\\//]$/));\n});\n\nit('should convert styles and themes as string into requireIt objects', () => {\n\tconst result = styleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\tsections: [],\n\t\t\tstyles: 'path/to/styles',\n\t\t\ttheme: 'path/to/theme',\n\t\t},\n\t\taddDependency: jest.fn(),\n\t} as any);\n\texpect(result).toMatch(/require\\('path\\/to\\/styles'\\)/);\n\texpect(result).toMatch(/require\\('path\\/to\\/theme'\\)/);\n});\n\nit('should flag both styles and theme as dependencies', () => {\n\tconst addDependency = jest.fn();\n\tstyleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\tsections: [],\n\t\t\tstyles: 'path/to/styles',\n\t\t\ttheme: 'path/to/theme',\n\t\t},\n\t\taddDependency,\n\t} as any);\n\texpect(addDependency).toHaveBeenCalledWith('path/to/styles');\n\texpect(addDependency).toHaveBeenCalledWith('path/to/theme');\n});\n\nit('should transform styles into ES module compatible imports', () => {\n\tconst result = styleguideLoader.pitch.call({\n\t\trequest: file,\n\t\t_styleguidist: {\n\t\t\tsections: [],\n\t\t\tstyles: 'path/to/styles',\n\t\t},\n\t\taddDependency: jest.fn(),\n\t} as any);\n\texpect(result).toMatchInlineSnapshot(`\n\t\t\"const __rsgStyles$0 = require('path/to/styles');\n\t\tconst __rsgStyles = __rsgStyles$0.default || (__rsgStyles$0['__rsgStyles'] || __rsgStyles$0);\n\t\tif (module.hot) {\n\t\t\tmodule.hot.accept([])\n\t\t}\n\t\tmodule.exports = {\n\t\t    'config': { 'styles': __rsgStyles },\n\t\t    'welcomeScreen': true,\n\t\t    'patterns': [],\n\t\t    'sections': []\n\t\t}\n\t\t\"\n\t`);\n});\n"
  },
  {
    "path": "src/loaders/examples-loader.ts",
    "content": "import path from 'path';\nimport filter from 'lodash/filter';\nimport map from 'lodash/map';\nimport values from 'lodash/values';\nimport flatten from 'lodash/flatten';\nimport { generate } from 'escodegen';\nimport toAst from 'to-ast';\nimport { builders as b } from 'ast-types';\nimport chunkify from './utils/chunkify';\nimport expandDefaultComponent from './utils/expandDefaultComponent';\nimport getImports from './utils/getImports';\nimport requireIt from './utils/requireIt';\nimport resolveESModule from './utils/resolveESModule';\nimport * as Rsg from '../typings';\n\nconst absolutize = (filepath: string) => path.resolve(__dirname, filepath);\n\nconst REQUIRE_IN_RUNTIME_PATH = absolutize('utils/client/requireInRuntime');\nconst EVAL_IN_CONTEXT_PATH = absolutize('utils/client/evalInContext');\n\nexport default function examplesLoader(this: Rsg.StyleguidistLoaderContext, source: string) {\n\tconst config = this._styleguidist;\n\tconst { file, displayName, shouldShowDefaultExample, customLangs } = this.getOptions();\n\n\t// Replace placeholders (__COMPONENT__) with the passed-in component name\n\tif (shouldShowDefaultExample) {\n\t\tsource = expandDefaultComponent(source, displayName);\n\t}\n\n\tconst updateExample = config.updateExample\n\t\t? (props: Omit<Rsg.CodeExample, 'type'>) => config.updateExample(props, this.resourcePath)\n\t\t: undefined;\n\n\t// Load examples\n\tconst examples = chunkify(source, updateExample, customLangs);\n\n\t// Find all import statements and require() calls in examples to make them\n\t// available in webpack context at runtime.\n\t// Note that we can't just use require() directly at runtime,\n\t// because webpack changes its name to something like __webpack__require__().\n\tconst allCodeExamples = filter(examples, { type: 'code' });\n\tconst requiresFromExamples = allCodeExamples.reduce((requires: string[], example) => {\n\t\treturn requires.concat(getImports(example.content));\n\t}, []);\n\n\t// Auto imported modules.\n\t// We don't need to do anything here to support explicit imports: they will\n\t// work because both imports (generated below and by rewrite-imports) will\n\t// be eventually transpiled to `var x = require('x')`, so we'll just have two\n\t// of them in the same scope, which is fine in non-strict mode\n\tconst fullContext = {\n\t\t// Modules, provied by the user\n\t\t...config.context,\n\t\t// Append React, because it’s required for JSX\n\t\tReact: 'react',\n\t\t// Append the current component module to make it accessible in examples\n\t\t// without an explicit import\n\t\t// TODO: Do not leak absolute path\n\t\t...(displayName ? { [displayName]: file } : {}),\n\t};\n\n\t// All required or imported modules, either explicitly in examples code\n\t// or implicitly (React, current component and context config option)\n\tconst allModules = [...requiresFromExamples, ...values(fullContext)];\n\n\t// “Prerequire” modules required in Markdown examples and context so they\n\t// end up in a bundle and be available at runtime\n\tconst allModulesCode = allModules.reduce(\n\t\t(requires: Record<string, Rsg.RequireItResult>, requireRequest) => {\n\t\t\trequires[requireRequest] = requireIt(requireRequest);\n\t\t\treturn requires;\n\t\t},\n\t\t{}\n\t);\n\n\t// Require context modules so they are available in an example\n\tconst requireContextCode = b.program(flatten(map(fullContext, resolveESModule)));\n\n\t// Stringify examples object except the evalInContext function\n\tconst examplesWithEval: (Rsg.RuntimeCodeExample | Rsg.MarkdownExample)[] = examples.map(\n\t\t(example) => {\n\t\t\tif (example.type === 'code') {\n\t\t\t\treturn { ...example, evalInContext: { toAST: () => b.identifier('evalInContext') } as any };\n\t\t\t} else {\n\t\t\t\treturn example;\n\t\t\t}\n\t\t}\n\t);\n\n\treturn `\nif (module.hot) {\n\tmodule.hot.accept([])\n}\n\nvar requireMap = ${generate(toAst(allModulesCode))};\nvar requireInRuntimeBase = require(${JSON.stringify(REQUIRE_IN_RUNTIME_PATH)}).default;\nvar requireInRuntime = requireInRuntimeBase.bind(null, requireMap);\nvar evalInContextBase = require(${JSON.stringify(absolutize(EVAL_IN_CONTEXT_PATH))}).default;\nvar evalInContext = evalInContextBase.bind(null, ${JSON.stringify(\n\t\tgenerate(requireContextCode)\n\t)}, requireInRuntime);\n\nmodule.exports = ${generate(toAst(examplesWithEval))}\n\t`;\n}\n"
  },
  {
    "path": "src/loaders/props-loader.ts",
    "content": "import path from 'path';\nimport isArray from 'lodash/isArray';\nimport { Handler, parse, DocumentationObject, PropDescriptor } from 'react-docgen';\nimport { ASTNode } from 'ast-types';\nimport { NodePath } from 'ast-types/lib/node-path';\nimport { generate } from 'escodegen';\nimport toAst from 'to-ast';\nimport createLogger from 'glogg';\nimport getExamples from './utils/getExamples';\nimport getProps from './utils/getProps';\nimport defaultSortProps from './utils/sortProps';\nimport * as consts from '../scripts/consts';\nimport * as Rsg from '../typings';\n\nconst logger = createLogger('rsg');\n\nconst ERROR_MISSING_DEFINITION = 'No suitable component definition found.';\n\nexport default function (this: Rsg.StyleguidistLoaderContext, source: string) {\n\tconst file: string = this.request.split('!').pop() || '';\n\tconst config = this._styleguidist;\n\n\t// Setup Webpack context dependencies to enable hot reload when adding new files or updating any of component dependencies\n\tif (config.contextDependencies) {\n\t\tconfig.contextDependencies.forEach((dir) => this.addContextDependency(dir));\n\t}\n\n\tconst defaultParser = (\n\t\tfilePath: string,\n\t\tcode: string,\n\t\tresolver: (\n\t\t\tast: ASTNode,\n\t\t\tparser: { parse: (input: string) => ASTNode }\n\t\t) => NodePath<any, any> | NodePath[],\n\t\thandlers: Handler[]\n\t) => parse(code, resolver, handlers, { filename: filePath });\n\tconst propsParser = config.propsParser || defaultParser;\n\n\tlet docs: DocumentationObject = {};\n\ttry {\n\t\tdocs = propsParser(file, source, config.resolver, config.handlers(file));\n\n\t\t// Support only one component\n\t\tif (isArray(docs)) {\n\t\t\tif (docs.length === 0) {\n\t\t\t\tthrow new Error(ERROR_MISSING_DEFINITION);\n\t\t\t}\n\t\t\tdocs = docs[0];\n\t\t}\n\t} catch (err) {\n\t\tif (err instanceof Error) {\n\t\t\tconst errorMessage = err.toString();\n\t\t\tconst componentPath = path.relative(process.cwd(), file);\n\t\t\tconst message =\n\t\t\t\terrorMessage === `Error: ${ERROR_MISSING_DEFINITION}`\n\t\t\t\t\t? `${componentPath} matches a pattern defined in “components” or “sections” options in your ` +\n\t\t\t\t\t  'style guide config but doesn’t export a component.\\n\\n' +\n\t\t\t\t\t  'It usually happens when using third-party libraries, see possible solutions here:\\n' +\n\t\t\t\t\t  `${consts.DOCS_THIRDPARTIES}`\n\t\t\t\t\t: `Cannot parse ${componentPath}: ${err}\\n\\n` +\n\t\t\t\t\t  'It usually means that react-docgen does not understand your source code, try to file an issue here:\\n' +\n\t\t\t\t\t  'https://github.com/reactjs/react-docgen/issues';\n\t\t\tlogger.warn(message);\n\t\t}\n\t}\n\n\tconst tempDocs = getProps(docs, file);\n\tlet finalDocs: Rsg.PropsObject = { ...tempDocs, props: [] };\n\n\tconst componentProps = tempDocs.props;\n\tif (componentProps) {\n\t\t// Transform the properties to an array. This will allow sorting\n\t\t// TODO: Extract to a module\n\t\tconst propsAsArray = Object.keys(componentProps).reduce((acc: PropDescriptor[], name) => {\n\t\t\tcomponentProps[name].name = name;\n\t\t\tacc.push(componentProps[name]);\n\t\t\treturn acc;\n\t\t}, []);\n\n\t\tconst sortProps = config.sortProps || defaultSortProps;\n\t\tfinalDocs.props = sortProps(propsAsArray);\n\t}\n\n\t// Examples from Markdown file\n\tconst examplesFile = config.getExampleFilename(file);\n\tfinalDocs.examples = getExamples(\n\t\tfile,\n\t\tfinalDocs.displayName,\n\t\texamplesFile,\n\t\tconfig.defaultExample\n\t);\n\n\tif (config.updateDocs) {\n\t\tfinalDocs = config.updateDocs(finalDocs, file);\n\t}\n\n\treturn `\nif (module.hot) {\n\tmodule.hot.accept([])\n}\n\nmodule.exports = ${generate(toAst(finalDocs))}\n\t`;\n}\n"
  },
  {
    "path": "src/loaders/styleguide-loader.ts",
    "content": "import pick from 'lodash/pick';\nimport flatten from 'lodash/flatten';\nimport { namedTypes as t, builders as b } from 'ast-types';\nimport commonDir from 'common-dir';\nimport { generate } from 'escodegen';\nimport toAst from 'to-ast';\nimport createLogger from 'glogg';\nimport * as fileExistsCaseInsensitive from '../scripts/utils/findFileCaseInsensitive';\nimport getAllContentPages from './utils/getAllContentPages';\nimport getComponentFilesFromSections from './utils/getComponentFilesFromSections';\nimport getComponentPatternsFromSections from './utils/getComponentPatternsFromSections';\nimport getSections from './utils/getSections';\nimport filterComponentsWithExample from './utils/filterComponentsWithExample';\nimport slugger from './utils/slugger';\nimport resolveESModule from './utils/resolveESModule';\nimport * as Rsg from '../typings';\n\nconst logger = createLogger('rsg');\n\n// Config options that should be passed to the client\nconst CLIENT_CONFIG_OPTIONS = [\n\t'compilerConfig',\n\t'tocMode',\n\t'mountPointId',\n\t'pagePerSection',\n\t'previewDelay',\n\t'ribbon',\n\t'showSidebar',\n\t'styles',\n\t'theme',\n\t'title',\n\t'version',\n];\n\nconst STYLE_VARIABLE_NAME = '__rsgStyles';\nconst THEME_VARIABLE_NAME = '__rsgTheme';\n\nexport default function() {}\nexport function pitch(this: Rsg.StyleguidistLoaderContext) {\n\t// Clear cache so it would detect new or renamed files\n\tfileExistsCaseInsensitive.clearCache();\n\n\t// Reset slugger for each code reload to be deterministic\n\tslugger.reset();\n\n\tconst config = this._styleguidist;\n\n\tlet sections = getSections(config.sections, config);\n\tif (config.skipComponentsWithoutExample) {\n\t\tsections = filterComponentsWithExample(sections);\n\t}\n\n\tconst allComponentFiles = getComponentFilesFromSections(\n\t\tconfig.sections,\n\t\tconfig.configDir,\n\t\tconfig.ignore\n\t);\n\tconst allContentPages = getAllContentPages(sections);\n\n\t// Nothing to show in the style guide\n\tconst welcomeScreen = allContentPages.length === 0 && allComponentFiles.length === 0;\n\tconst patterns = welcomeScreen ? getComponentPatternsFromSections(config.sections) : undefined;\n\n\tlogger.debug('Loading components:\\n' + allComponentFiles.join('\\n'));\n\n\t// Setup Webpack context dependencies to enable hot reload when adding new files\n\tif (config.contextDependencies) {\n\t\tconfig.contextDependencies.forEach((dir: string) => this.addContextDependency(dir));\n\t} else if (allComponentFiles.length > 0) {\n\t\t// Use common parent directory of all components as a context\n\t\tthis.addContextDependency(commonDir(allComponentFiles));\n\t}\n\n\tconst configClone = { ...config };\n\tconst styleContext: t.VariableDeclaration[][] = [];\n\n\t/**\n\t * Transforms a string variable member of config\n\t * it transforms this code\n\t * ```\n\t * {\n\t *  param: 'test/path'\n\t * }\n\t * ```\n\t * into this code\n\t * ```\n\t * {\n\t *  param: require('test/path')\n\t * }\n\t * ```\n\t *\n\t * because we have to account for ES module exports,\n\t * we add an extra step and transform it into aa statement\n\t * that can import es5 `module.exports` and ES modules `export default`\n\t *\n\t * so the code will ultimtely look like this\n\t *\n\t * ```\n\t * // es5 - es modules compatibility code\n\t * var obj$0 = require('test/path')\n\t * var obj = obj$0.default || obj$0\n\t *\n\t * {\n\t *  param: obj\n\t * }\n\t * ```\n\t *\n\t * @param memberName the name of the member of the object (\"param\" in the examples)\n\t * @param varName the name of the variable to use (\"obj\" in the last example)\n\t */\n\tconst setVariableValueToObjectInFile = (\n\t\tmemberName: keyof Rsg.ProcessedStyleguidistCSSConfig,\n\t\tvarName: string\n\t) => {\n\t\tconst configMember = config[memberName];\n\t\tif (typeof configMember === 'string') {\n\t\t\t// first attach the file as a dependency\n\t\t\tthis.addDependency(configMember);\n\n\t\t\t// then create a variable to contain the value of the theme/style\n\t\t\tstyleContext.push(resolveESModule(configMember, varName));\n\n\t\t\t// Finally assign the calculted value to the member of the clone\n\t\t\t// NOTE: if we are mutating the config object without cloning it,\n\t\t\t// it changes the value for all hmr iteration\n\t\t\t// until the process is stopped.\n\t\t\tconst variableAst = {};\n\n\t\t\t// Then override the `toAST()` function, because we know\n\t\t\t// what the output of it should be, an identifier\n\t\t\tObject.defineProperty(variableAst, 'toAST', {\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue(): t.ASTNode {\n\t\t\t\t\treturn b.identifier(varName);\n\t\t\t\t},\n\t\t\t});\n\t\t\tconfigClone[memberName] = variableAst;\n\t\t}\n\t};\n\n\tsetVariableValueToObjectInFile('styles', STYLE_VARIABLE_NAME);\n\tsetVariableValueToObjectInFile('theme', THEME_VARIABLE_NAME);\n\n\tconst styleguide = {\n\t\tconfig: pick(configClone, CLIENT_CONFIG_OPTIONS),\n\t\twelcomeScreen,\n\t\tpatterns,\n\t\tsections,\n\t};\n\n\treturn `${generate(b.program(flatten(styleContext)))}\nif (module.hot) {\n\tmodule.hot.accept([])\n}\nmodule.exports = ${generate(toAst(styleguide))}\n`;\n}\n"
  },
  {
    "path": "src/loaders/utils/__tests__/.eslintrc",
    "content": "{\n\t\"extends\": \"tamia/typescript\"\n}\n"
  },
  {
    "path": "src/loaders/utils/__tests__/__snapshots__/chunkify.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should even parse examples with custom extensions 1`] = `\nArray [\n  Object {\n    \"content\": \"Custom extensions\",\n    \"type\": \"markdown\",\n  },\n  Object {\n    \"content\": \"<AppButton>Example in vue</AppButton>\",\n    \"settings\": Object {},\n    \"type\": \"code\",\n  },\n]\n`;\n\nexports[`should parse examples settings correctly 1`] = `\nArray [\n  Object {\n    \"content\": \"Pass props to CodeRenderer\",\n    \"type\": \"markdown\",\n  },\n  Object {\n    \"content\": \"<h1>Hello Markdown!</h1>\",\n    \"settings\": Object {\n      \"showcode\": true,\n    },\n    \"type\": \"code\",\n  },\n  Object {\n    \"content\": \"<h1>Example in frame and Without editor</h1>\",\n    \"settings\": Object {\n      \"frame\": Object {\n        \"width\": \"400px\",\n      },\n    },\n    \"type\": \"code\",\n  },\n  Object {\n    \"content\": \"Pass props to PreviewRenderer\",\n    \"type\": \"markdown\",\n  },\n  Object {\n    \"content\": \"<h2>Hello Markdown!</h2>\",\n    \"settings\": Object {\n      \"noeditor\": true,\n    },\n    \"type\": \"code\",\n  },\n  Object {\n    \"content\": \"\\`\\`\\`jsx\n<span class=\\\\\"token tag\\\\\"><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token punctuation\\\\\">&lt;</span>h2</span><span class=\\\\\"token punctuation\\\\\">></span></span><span class=\\\\\"token plain-text\\\\\">This is Highlighted!</span><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token punctuation\\\\\">&lt;/</span>h2</span><span class=\\\\\"token punctuation\\\\\">></span></span>\n\\`\\`\\`\",\n    \"type\": \"markdown\",\n  },\n]\n`;\n\nexports[`should parse undefined custom extensions without throwing 1`] = `\nArray [\n  Object {\n    \"content\": \"Undefined extensions (default)\",\n    \"type\": \"markdown\",\n  },\n  Object {\n    \"content\": \"<AppButton>Example in jsx with undefined extensions</AppButton>\",\n    \"settings\": Object {},\n    \"type\": \"code\",\n  },\n  Object {\n    \"content\": \"\\`\\`\\`pizza\n<AppButton>Example in pizza with undefined extensions (test double)</AppButton>\n\\`\\`\\`\",\n    \"type\": \"markdown\",\n  },\n]\n`;\n\nexports[`should separate Markdown and component examples 1`] = `\nArray [\n  Object {\n    \"content\": \"# Header\n\nText with *some* **formatting** and a [link](/foo).\n\n<div>And some HTML.</div>\n\n![Image](/bar.png)\n\nThis code example should be rendered as a playground:\",\n    \"type\": \"markdown\",\n  },\n  Object {\n    \"content\": \"<h1>Hello Markdown!</h1>\",\n    \"settings\": Object {},\n    \"type\": \"code\",\n  },\n  Object {\n    \"content\": \"Text with some \\`code\\` (playground too).\",\n    \"type\": \"markdown\",\n  },\n  Object {\n    \"content\": \"<h2>Hello Markdown!</h2>\",\n    \"settings\": Object {},\n    \"type\": \"code\",\n  },\n  Object {\n    \"content\": \"And some language and modifier (playground again):\",\n    \"type\": \"markdown\",\n  },\n  Object {\n    \"content\": \"<h3>Hello Markdown!</h3>\",\n    \"settings\": Object {\n      \"noeditor\": true,\n    },\n    \"type\": \"code\",\n  },\n  Object {\n    \"content\": \"This should be just highlighted:\n\n\\`\\`\\`jsx\n<span class=\\\\\"token tag\\\\\"><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token punctuation\\\\\">&lt;</span>h4</span><span class=\\\\\"token punctuation\\\\\">></span></span><span class=\\\\\"token plain-text\\\\\">Hello Markdown!</span><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token punctuation\\\\\">&lt;/</span>h4</span><span class=\\\\\"token punctuation\\\\\">></span></span>\n\\`\\`\\`\n\nThis should be highlighted too:\n\n\\`\\`\\`html\n<span class=\\\\\"token tag\\\\\"><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token punctuation\\\\\">&lt;</span>h5</span><span class=\\\\\"token punctuation\\\\\">></span></span>Hello Markdown!<span class=\\\\\"token tag\\\\\"><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token punctuation\\\\\">&lt;/</span>h5</span><span class=\\\\\"token punctuation\\\\\">></span></span>\n\\`\\`\\`\",\n    \"type\": \"markdown\",\n  },\n]\n`;\n"
  },
  {
    "path": "src/loaders/utils/__tests__/__snapshots__/filterComponentsWithExample.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should skip components without example file 1`] = `\nArray [\n  Object {\n    \"components\": Array [],\n    \"content\": \"Readme.md\",\n    \"name\": \"Readme\",\n    \"sections\": Array [],\n  },\n  Object {\n    \"components\": Array [\n      Object {\n        \"filepath\": \"components/Button/Button.js\",\n        \"hasExamples\": \"require()\",\n      },\n    ],\n    \"name\": \"Components\",\n    \"sections\": Array [],\n  },\n  Object {\n    \"components\": Array [],\n    \"name\": \"Nesting\",\n    \"sections\": Array [\n      Object {\n        \"components\": Array [\n          Object {\n            \"filepath\": \"components/Modal/Modal.js\",\n            \"hasExamples\": \"require()\",\n          },\n        ],\n        \"name\": \"Nested\",\n        \"sections\": Array [],\n      },\n    ],\n  },\n]\n`;\n"
  },
  {
    "path": "src/loaders/utils/__tests__/__snapshots__/getAst.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`getAst accept Acorn plugins 1`] = `\nNode {\n  \"body\": Array [\n    Node {\n      \"end\": 5,\n      \"expression\": Node {\n        \"children\": Array [],\n        \"closingElement\": null,\n        \"end\": 5,\n        \"openingElement\": Node {\n          \"attributes\": Array [],\n          \"end\": 5,\n          \"name\": Node {\n            \"end\": 2,\n            \"name\": \"X\",\n            \"start\": 1,\n            \"type\": \"JSXIdentifier\",\n          },\n          \"selfClosing\": true,\n          \"start\": 0,\n          \"type\": \"JSXOpeningElement\",\n        },\n        \"start\": 0,\n        \"type\": \"JSXElement\",\n      },\n      \"start\": 0,\n      \"type\": \"ExpressionStatement\",\n    },\n  ],\n  \"end\": 5,\n  \"sourceType\": \"module\",\n  \"start\": 0,\n  \"type\": \"Program\",\n}\n`;\n\nexports[`getAst return AST 1`] = `\nNode {\n  \"body\": Array [\n    Node {\n      \"end\": 2,\n      \"expression\": Node {\n        \"end\": 2,\n        \"raw\": \"42\",\n        \"start\": 0,\n        \"type\": \"Literal\",\n        \"value\": 42,\n      },\n      \"start\": 0,\n      \"type\": \"ExpressionStatement\",\n    },\n  ],\n  \"end\": 2,\n  \"sourceType\": \"module\",\n  \"start\": 0,\n  \"type\": \"Program\",\n}\n`;\n"
  },
  {
    "path": "src/loaders/utils/__tests__/__snapshots__/getComponents.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`getComponents() should return an object for components 1`] = `\nArray [\n  Object {\n    \"filepath\": \"../../Foo.js\",\n    \"hasExamples\": false,\n    \"metadata\": Object {},\n    \"module\": Object {\n      \"require\": \"Foo.js\",\n    },\n    \"pathLine\": \"../../Foo.js\",\n    \"props\": Object {\n      \"require\": \"!!~/src/loaders/props-loader.js!Foo.js\",\n    },\n    \"slug\": \"foo\",\n  },\n  Object {\n    \"filepath\": \"../../Bar.js\",\n    \"hasExamples\": false,\n    \"metadata\": Object {},\n    \"module\": Object {\n      \"require\": \"Bar.js\",\n    },\n    \"pathLine\": \"../../Bar.js\",\n    \"props\": Object {\n      \"require\": \"!!~/src/loaders/props-loader.js!Bar.js\",\n    },\n    \"slug\": \"bar\",\n  },\n]\n`;\n"
  },
  {
    "path": "src/loaders/utils/__tests__/__snapshots__/getProps.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should accept @return as a synonym of @returns 1`] = `\nArray [\n  Object {\n    \"docblock\": \"\nBaz method with foo param\n\n@public\n@return {string} test\n\",\n    \"returns\": Object {\n      \"description\": \"test\",\n      \"title\": \"return\",\n      \"type\": Object {\n        \"name\": \"string\",\n        \"type\": \"NameExpression\",\n      },\n    },\n    \"tags\": Object {\n      \"public\": Array [\n        Object {\n          \"description\": null,\n          \"title\": \"public\",\n          \"type\": null,\n        },\n      ],\n    },\n  },\n]\n`;\n\nexports[`should get method info from docblock and merge it 1`] = `\nArray [\n  Object {\n    \"docblock\": \"\nBaz method with foo param\n\n@public\n@returns {string} test\n\",\n    \"returns\": Object {\n      \"description\": \"test\",\n      \"title\": \"returns\",\n      \"type\": Object {\n        \"name\": \"string\",\n        \"type\": \"NameExpression\",\n      },\n    },\n    \"tags\": Object {\n      \"public\": Array [\n        Object {\n          \"description\": null,\n          \"title\": \"public\",\n          \"type\": null,\n        },\n      ],\n    },\n  },\n]\n`;\n\nexports[`should get method params info from docblock and merge it with passed method info 1`] = `\nArray [\n  Object {\n    \"docblock\": \"\nFoo method with baz param\n\n@public\n@param {string} [baz=bar]\n@arg {string} foo param described with @arg tag\n@argument {string} test param described with @argument tag\n@returns {string} test\n\",\n    \"params\": Array [\n      Object {\n        \"default\": \"bar\",\n        \"description\": null,\n        \"name\": \"baz\",\n        \"title\": \"param\",\n        \"type\": Object {\n          \"expression\": Object {\n            \"name\": \"string\",\n            \"type\": \"NameExpression\",\n          },\n          \"type\": \"OptionalType\",\n        },\n      },\n      Object {\n        \"description\": \"param described with @arg tag\",\n        \"name\": \"foo\",\n        \"title\": \"arg\",\n        \"type\": Object {\n          \"name\": \"string\",\n          \"type\": \"NameExpression\",\n        },\n      },\n      Object {\n        \"description\": \"param described with @argument tag\",\n        \"name\": \"test\",\n        \"title\": \"argument\",\n        \"type\": Object {\n          \"name\": \"string\",\n          \"type\": \"NameExpression\",\n        },\n      },\n    ],\n    \"returns\": Object {\n      \"description\": \"test\",\n      \"title\": \"returns\",\n      \"type\": Object {\n        \"name\": \"string\",\n        \"type\": \"NameExpression\",\n      },\n    },\n    \"tags\": Object {\n      \"public\": Array [\n        Object {\n          \"description\": null,\n          \"title\": \"public\",\n          \"type\": null,\n        },\n      ],\n    },\n  },\n]\n`;\n\nexports[`should highlight code in description (fenced code block) 1`] = `\nObject {\n  \"description\": \"The only true button.\n\n\\`\\`\\`js\n<span class=\\\\\"token function\\\\\">alert</span><span class=\\\\\"token punctuation\\\\\">(</span><span class=\\\\\"token string\\\\\">'Hello world'</span><span class=\\\\\"token punctuation\\\\\">)</span><span class=\\\\\"token punctuation\\\\\">;</span>\n\\`\\`\\`\n\",\n  \"displayName\": \"\",\n  \"doclets\": Object {},\n  \"methods\": Array [],\n  \"tags\": Object {},\n}\n`;\n\nexports[`should not crash when using doctrine to parse a default prop that isn't in the props list 1`] = `\nObject {\n  \"description\": \"The only true button.\n\",\n  \"displayName\": \"\",\n  \"doclets\": Object {},\n  \"methods\": Array [],\n  \"props\": Object {\n    \"crash\": Object {\n      \"description\": \"\",\n      \"tags\": Object {},\n    },\n  },\n  \"tags\": Object {},\n}\n`;\n\nexports[`should remove non-public methods 1`] = `\nObject {\n  \"displayName\": \"Button\",\n  \"doclets\": Object {},\n  \"methods\": Array [\n    Object {\n      \"docblock\": \"Public method.\n@public\",\n      \"tags\": Object {\n        \"public\": Array [\n          Object {\n            \"description\": null,\n            \"title\": \"public\",\n          },\n        ],\n      },\n    },\n  ],\n}\n`;\n\nexports[`should return an object for props 1`] = `\nObject {\n  \"description\": \"The only true button.\n\",\n  \"displayName\": \"Button\",\n  \"doclets\": Object {},\n  \"methods\": Array [],\n  \"props\": Object {\n    \"children\": Object {\n      \"description\": \"Button label.\",\n      \"name\": \"children\",\n      \"required\": true,\n      \"tags\": Object {},\n      \"type\": Object {\n        \"name\": \"object\",\n      },\n    },\n    \"color\": Object {\n      \"description\": \"\",\n      \"name\": \"color\",\n      \"required\": false,\n      \"tags\": Object {},\n      \"type\": Object {\n        \"name\": \"string\",\n      },\n    },\n  },\n  \"tags\": Object {},\n}\n`;\n\nexports[`should return an object for props with doclets 1`] = `\nObject {\n  \"description\": \"The only true button.\n\",\n  \"displayName\": \"Button\",\n  \"doclets\": Object {\n    \"bar\": \"Bar\n\",\n    \"foo\": \"Foo\",\n  },\n  \"methods\": Array [],\n  \"tags\": Object {\n    \"bar\": Array [\n      Object {\n        \"description\": \"Bar\",\n        \"title\": \"bar\",\n      },\n    ],\n    \"foo\": Array [\n      Object {\n        \"description\": \"Foo\",\n        \"title\": \"foo\",\n      },\n    ],\n  },\n}\n`;\n\nexports[`should return an object for props without description 1`] = `\nObject {\n  \"displayName\": \"Button\",\n  \"doclets\": Object {},\n  \"methods\": Array [],\n  \"props\": Object {\n    \"children\": Object {\n      \"description\": \"Button label.\",\n      \"name\": \"children\",\n      \"required\": true,\n      \"tags\": Object {},\n      \"type\": Object {\n        \"name\": \"object\",\n      },\n    },\n  },\n}\n`;\n\nexports[`should return require statement for @example doclet 1`] = `\nObject {\n  \"description\": \"The only true button.\n\",\n  \"displayName\": \"Button\",\n  \"doclets\": Object {\n    \"example\": \"../../../test/components/Placeholder/examples.md\n\",\n  },\n  \"methods\": Array [],\n  \"tags\": Object {\n    \"example\": Array [\n      Object {\n        \"description\": \"../../../test/components/Placeholder/examples.md\",\n        \"title\": \"example\",\n      },\n    ],\n  },\n}\n`;\n\nexports[`should return require statement for @example doclet only when the file exists 1`] = `\nObject {\n  \"description\": \"The only true button.\n\",\n  \"displayName\": \"Button\",\n  \"doclets\": Object {\n    \"example\": \"example.md\n\",\n  },\n  \"methods\": Array [],\n  \"tags\": Object {\n    \"example\": Array [\n      Object {\n        \"description\": \"example.md\",\n        \"title\": \"example\",\n      },\n    ],\n  },\n}\n`;\n"
  },
  {
    "path": "src/loaders/utils/__tests__/__snapshots__/getSections.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`getSections() should return an array 1`] = `\nArray [\n  Object {\n    \"components\": Array [],\n    \"content\": Object {\n      \"require\": \"!!~/src/loaders/examples-loader.js!~/test/components/Button/Readme.md\",\n    },\n    \"exampleMode\": \"collapse\",\n    \"href\": undefined,\n    \"name\": \"Readme\",\n    \"sectionDepth\": 0,\n    \"sections\": Array [],\n    \"slug\": \"section-readme-1\",\n    \"usageMode\": \"collapse\",\n  },\n  Object {\n    \"components\": Array [\n      Object {\n        \"filepath\": \"components/Annotation/Annotation.js\",\n        \"hasExamples\": true,\n        \"metadata\": Object {},\n        \"module\": Object {\n          \"require\": \"~/test/components/Annotation/Annotation.js\",\n        },\n        \"pathLine\": \"components/Annotation/Annotation.js\",\n        \"props\": Object {\n          \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Annotation/Annotation.js\",\n        },\n        \"slug\": \"annotation-1\",\n      },\n      Object {\n        \"filepath\": \"components/Button/Button.js\",\n        \"hasExamples\": true,\n        \"metadata\": Object {},\n        \"module\": Object {\n          \"require\": \"~/test/components/Button/Button.js\",\n        },\n        \"pathLine\": \"components/Button/Button.js\",\n        \"props\": Object {\n          \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Button/Button.js\",\n        },\n        \"slug\": \"button-2\",\n      },\n      Object {\n        \"filepath\": \"components/Placeholder/Placeholder.js\",\n        \"hasExamples\": true,\n        \"metadata\": Object {\n          \"require\": \"~/test/components/Placeholder/Placeholder.json\",\n        },\n        \"module\": Object {\n          \"require\": \"~/test/components/Placeholder/Placeholder.js\",\n        },\n        \"pathLine\": \"components/Placeholder/Placeholder.js\",\n        \"props\": Object {\n          \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Placeholder/Placeholder.js\",\n        },\n        \"slug\": \"placeholder-2\",\n      },\n      Object {\n        \"filepath\": \"components/Price/Price.js\",\n        \"hasExamples\": true,\n        \"metadata\": Object {},\n        \"module\": Object {\n          \"require\": \"~/test/components/Price/Price.js\",\n        },\n        \"pathLine\": \"components/Price/Price.js\",\n        \"props\": Object {\n          \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Price/Price.js\",\n        },\n        \"slug\": \"price-2\",\n      },\n      Object {\n        \"filepath\": \"components/RandomButton/RandomButton.js\",\n        \"hasExamples\": true,\n        \"metadata\": Object {},\n        \"module\": Object {\n          \"require\": \"~/test/components/RandomButton/RandomButton.js\",\n        },\n        \"pathLine\": \"components/RandomButton/RandomButton.js\",\n        \"props\": Object {\n          \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/RandomButton/RandomButton.js\",\n        },\n        \"slug\": \"randombutton-2\",\n      },\n    ],\n    \"content\": undefined,\n    \"exampleMode\": \"collapse\",\n    \"href\": undefined,\n    \"name\": \"Components\",\n    \"sectionDepth\": 0,\n    \"sections\": Array [],\n    \"slug\": \"section-components-1\",\n    \"usageMode\": \"collapse\",\n  },\n  Object {\n    \"components\": Array [\n      Object {\n        \"filepath\": \"components/Button/Button.js\",\n        \"hasExamples\": true,\n        \"metadata\": Object {},\n        \"module\": Object {\n          \"require\": \"~/test/components/Button/Button.js\",\n        },\n        \"pathLine\": \"components/Button/Button.js\",\n        \"props\": Object {\n          \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Button/Button.js\",\n        },\n        \"slug\": \"button-3\",\n      },\n      Object {\n        \"filepath\": \"components/Label/index.js\",\n        \"hasExamples\": true,\n        \"metadata\": Object {},\n        \"module\": Object {\n          \"require\": \"~/test/components/Label/index.js\",\n        },\n        \"pathLine\": \"components/Label/index.js\",\n        \"props\": Object {\n          \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Label/index.js\",\n        },\n        \"slug\": \"label-1\",\n      },\n      Object {\n        \"filepath\": \"components/Placeholder/Placeholder.js\",\n        \"hasExamples\": true,\n        \"metadata\": Object {\n          \"require\": \"~/test/components/Placeholder/Placeholder.json\",\n        },\n        \"module\": Object {\n          \"require\": \"~/test/components/Placeholder/Placeholder.js\",\n        },\n        \"pathLine\": \"components/Placeholder/Placeholder.js\",\n        \"props\": Object {\n          \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Placeholder/Placeholder.js\",\n        },\n        \"slug\": \"placeholder-3\",\n      },\n      Object {\n        \"filepath\": \"components/Price/Price.js\",\n        \"hasExamples\": true,\n        \"metadata\": Object {},\n        \"module\": Object {\n          \"require\": \"~/test/components/Price/Price.js\",\n        },\n        \"pathLine\": \"components/Price/Price.js\",\n        \"props\": Object {\n          \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Price/Price.js\",\n        },\n        \"slug\": \"price-3\",\n      },\n      Object {\n        \"filepath\": \"components/RandomButton/RandomButton.js\",\n        \"hasExamples\": true,\n        \"metadata\": Object {},\n        \"module\": Object {\n          \"require\": \"~/test/components/RandomButton/RandomButton.js\",\n        },\n        \"pathLine\": \"components/RandomButton/RandomButton.js\",\n        \"props\": Object {\n          \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/RandomButton/RandomButton.js\",\n        },\n        \"slug\": \"randombutton-3\",\n      },\n    ],\n    \"content\": undefined,\n    \"exampleMode\": \"collapse\",\n    \"href\": undefined,\n    \"ignore\": \"**/components/Annotation/*\",\n    \"name\": \"Ignore\",\n    \"sectionDepth\": 0,\n    \"sections\": Array [],\n    \"slug\": \"section-ignore-2\",\n    \"usageMode\": \"collapse\",\n  },\n  Object {\n    \"components\": Array [],\n    \"content\": Object {\n      \"content\": \"Hello World\",\n      \"type\": \"markdown\",\n    },\n    \"exampleMode\": \"collapse\",\n    \"href\": undefined,\n    \"name\": \"Ignore\",\n    \"sectionDepth\": 0,\n    \"sections\": Array [],\n    \"slug\": \"section-ignore-3\",\n    \"usageMode\": \"collapse\",\n  },\n]\n`;\n\nexports[`processSection() should return an object for section with components 1`] = `\nObject {\n  \"components\": Array [\n    Object {\n      \"filepath\": \"components/Annotation/Annotation.js\",\n      \"hasExamples\": true,\n      \"metadata\": Object {},\n      \"module\": Object {\n        \"require\": \"~/test/components/Annotation/Annotation.js\",\n      },\n      \"pathLine\": \"components/Annotation/Annotation.js\",\n      \"props\": Object {\n        \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Annotation/Annotation.js\",\n      },\n      \"slug\": \"annotation\",\n    },\n    Object {\n      \"filepath\": \"components/Button/Button.js\",\n      \"hasExamples\": true,\n      \"metadata\": Object {},\n      \"module\": Object {\n        \"require\": \"~/test/components/Button/Button.js\",\n      },\n      \"pathLine\": \"components/Button/Button.js\",\n      \"props\": Object {\n        \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Button/Button.js\",\n      },\n      \"slug\": \"button\",\n    },\n    Object {\n      \"filepath\": \"components/Placeholder/Placeholder.js\",\n      \"hasExamples\": true,\n      \"metadata\": Object {\n        \"require\": \"~/test/components/Placeholder/Placeholder.json\",\n      },\n      \"module\": Object {\n        \"require\": \"~/test/components/Placeholder/Placeholder.js\",\n      },\n      \"pathLine\": \"components/Placeholder/Placeholder.js\",\n      \"props\": Object {\n        \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Placeholder/Placeholder.js\",\n      },\n      \"slug\": \"placeholder\",\n    },\n    Object {\n      \"filepath\": \"components/Price/Price.js\",\n      \"hasExamples\": true,\n      \"metadata\": Object {},\n      \"module\": Object {\n        \"require\": \"~/test/components/Price/Price.js\",\n      },\n      \"pathLine\": \"components/Price/Price.js\",\n      \"props\": Object {\n        \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Price/Price.js\",\n      },\n      \"slug\": \"price\",\n    },\n    Object {\n      \"filepath\": \"components/RandomButton/RandomButton.js\",\n      \"hasExamples\": true,\n      \"metadata\": Object {},\n      \"module\": Object {\n        \"require\": \"~/test/components/RandomButton/RandomButton.js\",\n      },\n      \"pathLine\": \"components/RandomButton/RandomButton.js\",\n      \"props\": Object {\n        \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/RandomButton/RandomButton.js\",\n      },\n      \"slug\": \"randombutton\",\n    },\n  ],\n  \"content\": undefined,\n  \"exampleMode\": \"collapse\",\n  \"href\": undefined,\n  \"name\": \"Components\",\n  \"sectionDepth\": 0,\n  \"sections\": Array [],\n  \"slug\": \"section-components\",\n  \"usageMode\": \"collapse\",\n}\n`;\n\nexports[`processSection() should return an object for section with content 1`] = `\nObject {\n  \"components\": Array [],\n  \"content\": Object {\n    \"require\": \"!!~/src/loaders/examples-loader.js!~/test/components/Button/Readme.md\",\n  },\n  \"exampleMode\": \"collapse\",\n  \"href\": undefined,\n  \"name\": \"Readme\",\n  \"sectionDepth\": 0,\n  \"sections\": Array [],\n  \"slug\": \"section-readme\",\n  \"usageMode\": \"collapse\",\n}\n`;\n\nexports[`processSection() should return an object for section with content as function 1`] = `\nObject {\n  \"components\": Array [],\n  \"content\": Object {\n    \"content\": \"Hello World\",\n    \"type\": \"markdown\",\n  },\n  \"exampleMode\": \"collapse\",\n  \"href\": undefined,\n  \"name\": \"Ignore\",\n  \"sectionDepth\": 0,\n  \"sections\": Array [],\n  \"slug\": \"section-ignore-1\",\n  \"usageMode\": \"collapse\",\n}\n`;\n\nexports[`processSection() should return an object for section without ignored components 1`] = `\nObject {\n  \"components\": Array [\n    Object {\n      \"filepath\": \"components/Button/Button.js\",\n      \"hasExamples\": true,\n      \"metadata\": Object {},\n      \"module\": Object {\n        \"require\": \"~/test/components/Button/Button.js\",\n      },\n      \"pathLine\": \"components/Button/Button.js\",\n      \"props\": Object {\n        \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Button/Button.js\",\n      },\n      \"slug\": \"button-1\",\n    },\n    Object {\n      \"filepath\": \"components/Label/index.js\",\n      \"hasExamples\": true,\n      \"metadata\": Object {},\n      \"module\": Object {\n        \"require\": \"~/test/components/Label/index.js\",\n      },\n      \"pathLine\": \"components/Label/index.js\",\n      \"props\": Object {\n        \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Label/index.js\",\n      },\n      \"slug\": \"label\",\n    },\n    Object {\n      \"filepath\": \"components/Placeholder/Placeholder.js\",\n      \"hasExamples\": true,\n      \"metadata\": Object {\n        \"require\": \"~/test/components/Placeholder/Placeholder.json\",\n      },\n      \"module\": Object {\n        \"require\": \"~/test/components/Placeholder/Placeholder.js\",\n      },\n      \"pathLine\": \"components/Placeholder/Placeholder.js\",\n      \"props\": Object {\n        \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Placeholder/Placeholder.js\",\n      },\n      \"slug\": \"placeholder-1\",\n    },\n    Object {\n      \"filepath\": \"components/Price/Price.js\",\n      \"hasExamples\": true,\n      \"metadata\": Object {},\n      \"module\": Object {\n        \"require\": \"~/test/components/Price/Price.js\",\n      },\n      \"pathLine\": \"components/Price/Price.js\",\n      \"props\": Object {\n        \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/Price/Price.js\",\n      },\n      \"slug\": \"price-1\",\n    },\n    Object {\n      \"filepath\": \"components/RandomButton/RandomButton.js\",\n      \"hasExamples\": true,\n      \"metadata\": Object {},\n      \"module\": Object {\n        \"require\": \"~/test/components/RandomButton/RandomButton.js\",\n      },\n      \"pathLine\": \"components/RandomButton/RandomButton.js\",\n      \"props\": Object {\n        \"require\": \"!!~/src/loaders/props-loader.js!~/test/components/RandomButton/RandomButton.js\",\n      },\n      \"slug\": \"randombutton-1\",\n    },\n  ],\n  \"content\": undefined,\n  \"exampleMode\": \"collapse\",\n  \"href\": undefined,\n  \"ignore\": \"**/components/Annotation/*\",\n  \"name\": \"Ignore\",\n  \"sectionDepth\": 0,\n  \"sections\": Array [],\n  \"slug\": \"section-ignore\",\n  \"usageMode\": \"collapse\",\n}\n`;\n"
  },
  {
    "path": "src/loaders/utils/__tests__/__snapshots__/highlightCode.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should highlight code with specified language 1`] = `\"<span class=\\\\\"token tag\\\\\"><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token punctuation\\\\\">&lt;</span>p</span><span class=\\\\\"token punctuation\\\\\">></span></span>Hello React<span class=\\\\\"token tag\\\\\"><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token punctuation\\\\\">&lt;/</span>p</span><span class=\\\\\"token punctuation\\\\\">></span></span>\"`;\n"
  },
  {
    "path": "src/loaders/utils/__tests__/__snapshots__/highlightCodeInMarkdown.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should highlight code with specified language 1`] = `\n\"The only true button.\n\n\\`\\`\\`html\n<span class=\\\\\"token tag\\\\\"><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token punctuation\\\\\">&lt;</span>p</span><span class=\\\\\"token punctuation\\\\\">></span></span>Hello React<span class=\\\\\"token tag\\\\\"><span class=\\\\\"token tag\\\\\"><span class=\\\\\"token punctuation\\\\\">&lt;/</span>p</span><span class=\\\\\"token punctuation\\\\\">></span></span>\n\\`\\`\\`\n\"\n`;\n\nexports[`should not highlight code without language 1`] = `\n\"The only \\`true\\` button.\n\n    <p>Hello React</p>\n\"\n`;\n"
  },
  {
    "path": "src/loaders/utils/__tests__/__snapshots__/processComponent.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`processComponent() should return an object for section with content 1`] = `\nObject {\n  \"filepath\": \"../../../../pizza.js\",\n  \"hasExamples\": true,\n  \"metadata\": Object {},\n  \"module\": Object {\n    \"require\": \"pizza.js\",\n  },\n  \"pathLine\": \"../../../../pizza.js\",\n  \"props\": Object {\n    \"require\": \"!!~/src/loaders/props-loader.js!pizza.js\",\n  },\n  \"slug\": \"pizza\",\n}\n`;\n"
  },
  {
    "path": "src/loaders/utils/__tests__/chunkify.spec.ts",
    "content": "import chunkify from '../chunkify';\nimport * as Rsg from '../../../typings';\n\n/* eslint-disable max-len */\n\nit('should separate Markdown and component examples', () => {\n\tconst markdown = `\n# Header\n\nText with *some* **formatting** and a [link](/foo).\n\n<div>And some HTML.</div>\n\n![Image](/bar.png)\n\nThis code example should be rendered as a playground:\n\n\t<h1>Hello Markdown!</h1>\n\nText with some \\`code\\` (playground too).\n\n\\`\\`\\`\n<h2>Hello Markdown!</h2>\n\\`\\`\\`\n\nAnd some language and modifier (playground again):\n\n\\`\\`\\`jsx noeditor\n<h3>Hello Markdown!</h3>\n\\`\\`\\`\n\nThis should be just highlighted:\n\n\\`\\`\\`jsx static\n<h4>Hello Markdown!</h4>\n\\`\\`\\`\n\nThis should be highlighted too:\n\n\\`\\`\\`html\n<h5>Hello Markdown!</h5>\n\\`\\`\\`\n`;\n\n\tconst actual = chunkify(markdown);\n\texpect(actual).toMatchSnapshot();\n});\n\nit('should render some extensions as a playground', () => {\n\tconst markdown = `\nThis below extensions should be rendered as a playground:\n\n\\`\\`\\`javascript\n<h3>Hello javascript playground!</h3>\n\\`\\`\\`\n\n\\`\\`\\`js\n<h3>Hello js playground!</h3>\n\\`\\`\\`\n\n\\`\\`\\`jsx\n<h3>Hello jsx playground!</h3>\n\\`\\`\\`\n\n\\`\\`\\`typescript\n<h3>Hello typescript playground!</h3>\n\\`\\`\\`\n\n\\`\\`\\`ts\n<h3>Hello ts playground!</h3>\n\\`\\`\\`\n\n\\`\\`\\`tsx\n<h3>Hello tsx playground!</h3>\n\\`\\`\\`\n`;\n\n\tconst actual = chunkify(markdown);\n\texpect(actual.slice(1).every((chunk) => chunk.type === 'code')).toBe(true);\n});\n\nit('should not add empty Markdown chunks', () => {\n\tconst markdown = `\nFoo:\n\n\t<h1>Hello Markdown!</h1>\n`;\n\tconst expected = [\n\t\t{\n\t\t\ttype: 'markdown',\n\t\t\tcontent: 'Foo:',\n\t\t},\n\t\t{\n\t\t\ttype: 'code',\n\t\t\tcontent: '<h1>Hello Markdown!</h1>',\n\t\t\tsettings: {},\n\t\t},\n\t];\n\n\tconst actual = chunkify(markdown);\n\texpect(actual).toEqual(expected);\n});\n\nit('should parse examples settings correctly', () => {\n\tconst markdown = `\nPass props to CodeRenderer\n\n\\`\\`\\`js { \"showCode\": true }\n<h1>Hello Markdown!</h1>\n\\`\\`\\`\n\n\\`\\`\\`js { \"frame\": {\"width\": \"400px\"} }\n<h1>Example in frame and Without editor</h1>\n\\`\\`\\`\n\nPass props to PreviewRenderer\n\n\\`\\`\\`jsx { \"noEditor\": true }\n<h2>Hello Markdown!</h2>\n\\`\\`\\`\n\n\\`\\`\\`jsx static\n<h2>This is Highlighted!</h2>\n\\`\\`\\`\n`;\n\tconst actual = chunkify(markdown);\n\texpect(actual).toMatchSnapshot();\n});\n\nit('should call updateExample function for example', () => {\n\tconst markdown = `\n\\`\\`\\`jsx {\"file\": \"./src/button/example.jsx\"}\n\\`\\`\\`\n`;\n\tconst expected = [\n\t\t{\n\t\t\ttype: 'code',\n\t\t\tcontent: '<h1>Hello Markdown!</h1>',\n\t\t\tsettings: {},\n\t\t},\n\t];\n\tconst updateExample = (props: Omit<Rsg.CodeExample, 'type'>): Omit<Rsg.CodeExample, 'type'> => {\n\t\tconst content = props.content;\n\t\tconst lang = props.lang;\n\t\tconst settings = props.settings;\n\t\tif (settings && typeof settings.file === 'string') {\n\t\t\tdelete settings.file;\n\t\t\treturn {\n\t\t\t\tcontent: '<h1>Hello Markdown!</h1>',\n\t\t\t\tsettings,\n\t\t\t\tlang,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tcontent,\n\t\t\tsettings,\n\t\t\tlang,\n\t\t};\n\t};\n\tconst actual = chunkify(markdown, updateExample);\n\texpect(actual).toEqual(expected);\n});\n\nit('should even parse examples with custom extensions', () => {\n\tconst markdown = `\nCustom extensions\n\n\\`\\`\\`vue\n<AppButton>Example in vue</AppButton>\n\\`\\`\\`\n`;\n\tconst actual = chunkify(markdown, undefined, ['vue']);\n\texpect(actual).toMatchSnapshot();\n});\n\nit('should parse undefined custom extensions without throwing', () => {\n\tconst markdown = `\nUndefined extensions (default)\n\n\\`\\`\\`jsx\n<AppButton>Example in jsx with undefined extensions</AppButton>\n\\`\\`\\`\n\n\\`\\`\\`pizza\n<AppButton>Example in pizza with undefined extensions (test double)</AppButton>\n\\`\\`\\`\n`;\n\tconst actual = chunkify(markdown, undefined, undefined);\n\texpect(actual).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/expandDefaultComponent.spec.ts",
    "content": "import expandDefaultComponent from '../expandDefaultComponent';\n\nit('expandDefaultComponent() replace placeholders with component name', () => {\n\tconst exampleMarkdown = `\n<div>\n\t<__COMPONENT__>\n\t\t<span>text</span>\n\t\t<span>Name of component: __COMPONENT__</span>\n\t</__COMPONENT__>\n\t<__COMPONENT__ />\n</div>\n`;\n\tconst result = expandDefaultComponent(exampleMarkdown, 'FooComponent');\n\texpect(result).not.toMatch(/__COMPONENT__/);\n\texpect(result).toMatch(/FooComponent/);\n\texpect((result.match(/FooComponent/g) || '').length).toBe(4);\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/filterComponentsWithExample.spec.ts",
    "content": "import filterComponentsWithExample from '../filterComponentsWithExample';\n\nconst sections = [\n\t{\n\t\tname: 'Readme',\n\t\tcontent: 'Readme.md',\n\t\tcomponents: [],\n\t\tsections: [],\n\t},\n\t{\n\t\tname: 'Components',\n\t\tcomponents: [\n\t\t\t{\n\t\t\t\tfilepath: 'components/Button/Button.js',\n\t\t\t\thasExamples: 'require()',\n\t\t\t},\n\t\t\t{\n\t\t\t\tfilepath: 'components/Icon/Icon.js',\n\t\t\t},\n\t\t],\n\t\tsections: [],\n\t},\n\t{\n\t\tname: 'Nesting',\n\t\tcomponents: [],\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Nested',\n\t\t\t\tcomponents: [\n\t\t\t\t\t{\n\t\t\t\t\t\tfilepath: 'components/Image/Image.js',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tfilepath: 'components/Modal/Modal.js',\n\t\t\t\t\t\thasExamples: 'require()',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tsections: [],\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'Nested 2',\n\t\t\t\tcomponents: [\n\t\t\t\t\t{\n\t\t\t\t\t\tfilepath: 'components/Avatar/Avatar.js',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tsections: [],\n\t\t\t},\n\t\t],\n\t},\n] as any;\n\nit('should skip components without example file', () => {\n\tconst result = filterComponentsWithExample(sections);\n\texpect(result).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/getAllContentPages.spec.ts",
    "content": "import getAllContentPages from '../getAllContentPages';\nimport * as Rsg from '../../../typings';\n\nconst readmeContent: Rsg.MarkdownExample = {\n\ttype: 'markdown',\n\tcontent: '# Readme',\n};\n\nconst nestedContent: Rsg.MarkdownExample = {\n\ttype: 'markdown',\n\tcontent: '# Nested',\n};\n\nconst sections: Rsg.LoaderSection[] = [\n\t{\n\t\tname: 'Readme',\n\t\tcontent: readmeContent,\n\t\tcomponents: [],\n\t\tsections: [],\n\t},\n\t{\n\t\tname: 'Components',\n\t\tcomponents: [],\n\t\tsections: [],\n\t},\n\t{\n\t\tname: 'Nesting',\n\t\tcomponents: [],\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Nested',\n\t\t\t\tcomponents: [],\n\t\t\t\tsections: [],\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'Nested 2',\n\t\t\t\tcontent: nestedContent,\n\t\t\t\tcomponents: [],\n\t\t\t\tsections: [],\n\t\t\t},\n\t\t],\n\t},\n];\n\nit('should return all content pages', () => {\n\tconst result = getAllContentPages(sections);\n\texpect(result).toEqual([readmeContent, nestedContent]);\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/getAst.spec.ts",
    "content": "import acornJsx from 'acorn-jsx';\nimport getAst from '../getAst';\n\ndescribe('getAst', () => {\n\ttest('return AST', () => {\n\t\tconst result = getAst(`42`);\n\t\texpect(result).toMatchSnapshot();\n\t});\n\n\ttest('accept Acorn plugins', () => {\n\t\tconst result = getAst(`<X />`, [acornJsx()]);\n\t\texpect(result).toMatchSnapshot();\n\t});\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/getComponentFiles.spec.ts",
    "content": "import path from 'path';\nimport deabsDeep from 'deabsdeep';\nimport getComponentFiles from '../getComponentFiles';\n\nconst configDir = path.resolve(__dirname, '../../../../test');\nconst components = ['components/Annotation/Annotation.js', 'components/Button/Button.js'];\nconst processedComponents = components.map(c => `~/${c}`);\nconst glob = 'components/**/[A-Z]*.js';\nconst globArray = ['components/Annotation/[A-Z]*.js', 'components/Button/[A-Z]*.js'];\n\nconst deabs = (x: string[]) => deabsDeep(x, { root: configDir });\n\nit('getComponentFiles() should return an empty array if components is null', () => {\n\tconst result = getComponentFiles();\n\texpect(result).toEqual([]);\n});\n\nit('getComponentFiles() should accept components as a function that returns file names', () => {\n\tconst result = getComponentFiles(() => components, configDir);\n\texpect(deabs(result)).toEqual(processedComponents);\n});\n\nit('getComponentFiles() should accept components as a function that returns absolute paths', () => {\n\tconst absolutize = (files: string[]) => files.map(file => path.join(configDir, file));\n\tconst result = getComponentFiles(() => absolutize(components), configDir);\n\texpect(deabs(result)).toEqual(processedComponents);\n});\n\nit('getComponentFiles() should accept components as a function that returns globs', () => {\n\tconst result = getComponentFiles(() => globArray, configDir);\n\texpect(deabs(result)).toEqual([\n\t\t'~/components/Annotation/Annotation.js',\n\t\t'~/components/Button/Button.js',\n\t]);\n});\n\nit('getComponentFiles() should accept components as an array of file names', () => {\n\tconst result = getComponentFiles(components, configDir);\n\texpect(deabs(result)).toEqual(processedComponents);\n});\n\nit('getComponentFiles() should accept components as an array of absolute paths', () => {\n\tconst absolutize = (files: string[]) => files.map(file => path.join(configDir, file));\n\tconst result = getComponentFiles(absolutize(components), configDir);\n\texpect(deabs(result)).toEqual(processedComponents);\n});\n\nit('getComponentFiles() should accept components as an array of globs', () => {\n\tconst result = getComponentFiles(globArray, configDir);\n\texpect(deabs(result)).toEqual([\n\t\t'~/components/Annotation/Annotation.js',\n\t\t'~/components/Button/Button.js',\n\t]);\n});\n\nit('getComponentFiles() should accept components as a glob', () => {\n\tconst result = getComponentFiles(glob, configDir);\n\texpect(deabs(result)).toEqual([\n\t\t'~/components/Annotation/Annotation.js',\n\t\t'~/components/Button/Button.js',\n\t\t'~/components/Placeholder/Placeholder.js',\n\t\t'~/components/Price/Price.js',\n\t\t'~/components/RandomButton/RandomButton.js',\n\t]);\n});\n\nit('getComponentFiles() should ignore specified patterns for globs', () => {\n\tconst result = getComponentFiles(glob, configDir, ['**/*Button*']);\n\texpect(deabs(result)).toEqual([\n\t\t'~/components/Annotation/Annotation.js',\n\t\t'~/components/Placeholder/Placeholder.js',\n\t\t'~/components/Price/Price.js',\n\t]);\n});\n\nit('getComponentFiles() should ignore specified patterns for globs in arrays', () => {\n\tconst result = getComponentFiles(globArray, configDir, ['**/*Button*']);\n\texpect(deabs(result)).toEqual(['~/components/Annotation/Annotation.js']);\n});\n\nit('getComponentFiles() should ignore specified patterns for globs from functions', () => {\n\tconst result = getComponentFiles(() => globArray, configDir, ['**/*Button*']);\n\texpect(deabs(result)).toEqual(['~/components/Annotation/Annotation.js']);\n});\n\nit('getComponentFiles() should throw if components is not a function, array or a string', () => {\n\tconst fn = () => getComponentFiles(42 as any, configDir);\n\texpect(fn).toThrowError('should be string, function or array');\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/getComponentFilesFromSections.spec.ts",
    "content": "import path from 'path';\nimport deabsDeep from 'deabsdeep';\nimport getComponentFilesFromSections from '../getComponentFilesFromSections';\n\nconst configDir = path.resolve(__dirname, '../../../../test');\nconst sections = [\n\t{\n\t\tname: 'Readme',\n\t\tcontent: 'Readme.md',\n\t},\n\t{\n\t\tname: 'Components',\n\t\tcomponents: 'components/**/B*.js',\n\t},\n\t{\n\t\tname: 'Nesting',\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Nested',\n\t\t\t\tcomponents: 'components/**/P*.js',\n\t\t\t},\n\t\t],\n\t},\n];\n\nconst deabs = (x: string[]) => deabsDeep(x, { root: configDir });\n\nit('getComponentFilesFromSections() should return a list of files', () => {\n\tconst result = getComponentFilesFromSections(sections, configDir);\n\texpect(deabs(result)).toEqual([\n\t\t'~/components/Button/Button.js',\n\t\t'~/components/Placeholder/Placeholder.js',\n\t\t'~/components/Price/Price.js',\n\t]);\n});\n\nit('getComponentFilesFromSections() should ignore specified patterns', () => {\n\tconst result = getComponentFilesFromSections(sections, configDir, ['**/*Button*']);\n\texpect(deabs(result)).toEqual([\n\t\t'~/components/Placeholder/Placeholder.js',\n\t\t'~/components/Price/Price.js',\n\t]);\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/getComponentPatternsFromSections.spec.ts",
    "content": "import getComponentPatternsFromSections from '../getComponentPatternsFromSections';\n\nconst sections = [\n\t{\n\t\tname: 'Readme',\n\t\tcontent: 'Readme.md',\n\t},\n\t{\n\t\tname: 'Components',\n\t\tcomponents: ['components/**/B*.js'],\n\t},\n\t{\n\t\tname: 'Nesting',\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Nested',\n\t\t\t\tcomponents: ['components/**/P*.js'],\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: 'Nesting With Components',\n\t\tcomponents: ['components/**/T*.js'],\n\t\t// is this on purpose or a bug ?\n\t\t// a section cannot conatin `components` and nested `sections`\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Ignored Nested',\n\t\t\t\tcomponents: ['components/**/O*.js'],\n\t\t\t},\n\t\t],\n\t},\n];\n\nit('should return a list of patterns', () => {\n\tconst result = getComponentPatternsFromSections(sections);\n\texpect(result).toEqual(['components/**/B*.js', 'components/**/P*.js', 'components/**/T*.js']);\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/getComponents.spec.ts",
    "content": "import path from 'path';\nimport identity from 'lodash/identity';\nimport getComponents from '../getComponents';\n\nit('getComponents() should return an object for components', () => {\n\tconst result = getComponents(['Foo.js', 'Bar.js'], {\n\t\tconfigDir: path.resolve(__dirname, '../../../test'),\n\t\tgetExampleFilename: identity,\n\t\tgetComponentPathLine: identity,\n\t} as any);\n\n\texpect(result).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/getExamples.spec.ts",
    "content": "import deabsDeep from 'deabsdeep';\nimport { vol } from 'memfs';\nimport getExamples from '../getExamples';\n\njest.mock('fs', () => {\n\t// eslint-disable-next-line @typescript-eslint/no-var-requires\n\treturn require('memfs').fs;\n});\n\nconst file = '../pizza.js';\nconst displayName = 'Pizza';\nconst examplesFile = './Pizza.md';\nconst defaultExample = './Default.md';\n\nafterEach(() => {\n\tvol.reset();\n});\n\ntest('require an example file if component has example file', () => {\n\tvol.fromJSON({ [examplesFile]: 'pizza' });\n\n\tconst result = getExamples(file, displayName, examplesFile);\n\texpect(result && deabsDeep(result).require).toMatchInlineSnapshot(\n\t\t`\"!!~/src/loaders/examples-loader.js?displayName=Pizza&file=.%2F..%2Fpizza.js&shouldShowDefaultExample=false!./Pizza.md\"`\n\t);\n});\n\ntest('require default example file if component has no example in the file system', () => {\n\tconst result = getExamples(file, displayName, examplesFile, defaultExample);\n\texpect(result && deabsDeep(result).require).toMatchInlineSnapshot(\n\t\t`\"!!~/src/loaders/examples-loader.js?displayName=Pizza&file=.%2F..%2Fpizza.js&shouldShowDefaultExample=false!./Default.md\"`\n\t);\n});\n\ntest('require default example has no example file', () => {\n\tconst result = getExamples(file, displayName, false, defaultExample);\n\texpect(result && deabsDeep(result).require).toMatchInlineSnapshot(\n\t\t`\"!!~/src/loaders/examples-loader.js?displayName=Pizza&file=.%2F..%2Fpizza.js&shouldShowDefaultExample=true!./Default.md\"`\n\t);\n});\n\ntest('return null if component has no example file or default example', () => {\n\tconst result = getExamples(file, displayName);\n\texpect(result).toEqual(null);\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/getImports.spec.ts",
    "content": "import getImports from '../getImports';\n\ntest('find calls to require() in code', () => {\n\texpect(getImports(`require('foo')`)).toEqual(['foo']);\n\texpect(getImports(`require('./foo')`)).toEqual(['./foo']);\n\texpect(getImports(`require('foo');require('bar')`)).toEqual(['foo', 'bar']);\n});\n\ntest('find import statements in code', () => {\n\texpect(getImports(`import A from 'pizza';`)).toEqual(['pizza']);\n\texpect(getImports(`import A from './pizza';`)).toEqual(['./pizza']);\n\texpect(getImports(`import { A as X, B } from 'lunch';`)).toEqual(['lunch']);\n\texpect(getImports(`import A, { B as X, C } from 'lunch';`)).toEqual(['lunch']);\n\texpect(getImports(`import A from 'foo';import B from 'bar';`)).toEqual(['foo', 'bar']);\n});\n\ntest('work with JSX', () => {\n\texpect(getImports(`const A = require('pizza');<Button/>`)).toEqual(['pizza']);\n\texpect(getImports(`import A from 'pizza';<Button>foo</Button>`)).toEqual(['pizza']);\n});\n\ntest('allow comments', () => {\n\texpect(\n\t\tgetImports(`\n/**\n * Some important comment\n */\nimport A from 'dog'\n/* Less important comments */\nimport B from 'cat'\n// Absolutely not important comment\nimport C from 'capybara'\nimport D from 'hamster' // One more comment\nimport E from 'snake'\n`)\n\t).toEqual(['dog', 'cat', 'capybara', 'hamster', 'snake']);\n});\n\ntest('ignore dynamic requires', () => {\n\texpect(getImports(`require('foo' + 'bar')`)).toEqual([]);\n});\n\ntest('ignore imports in comments', () => {\n\texpect(\n\t\tgetImports(`\nimport A from 'pizza'\n// import one from 'one';\n/** import two from 'two' */\n/* import three from 'three' */\n/*\nimport four from 'four';\nimport five from 'five';\n*/\n`)\n\t).toEqual(['pizza']);\n});\n\ntest('ignore imports in strings', () => {\n\texpect(\n\t\tgetImports(`\nimport A from 'pizza'\nconst foo = \"import foo from 'foo'\"\nconst bar = 'import bar from \"bar\"'\nconst baz = \\`import baz from 'baz'\\`\n`)\n\t).toEqual(['pizza']);\n});\n\ntest('ignore imports in JSX', () => {\n\texpect(\n\t\tgetImports(`\nimport A from 'pizza';\n<p>import foo from 'foo'</p>\n`)\n\t).toEqual(['pizza']);\n});\n\ntest('ignore multiple root JSX elements', () => {\n\texpect(getImports(`<A /><B />`)).toEqual([]);\n});\n\ntest('ignore syntax errors', () => {\n\texpect(getImports(`*`)).toEqual([]);\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/getNameFromFilePath.spec.ts",
    "content": "import path from 'path';\nimport getNameFromFilePath from '../getNameFromFilePath';\n\nit('should return the file name without extension', () => {\n\texpect(\n\t\tgetNameFromFilePath(path.join('an', 'absolute', 'path', 'to', 'YourComponent.js'))\n\t).toEqual('YourComponent');\n});\n\nit('should use the directory name if the file name is index.js', () => {\n\texpect(\n\t\tgetNameFromFilePath(path.join('an', 'absolute', 'path', 'to', 'YourComponent', 'index.js'))\n\t).toEqual('YourComponent');\n});\n\nit('should capitalize the display name', () => {\n\texpect(\n\t\tgetNameFromFilePath(path.join('an', 'absolute', 'path', 'to', 'yourComponent.js'))\n\t).toEqual('YourComponent');\n\n\texpect(\n\t\tgetNameFromFilePath(path.join('an', 'absolute', 'path', 'to', 'your-component', 'index.js'))\n\t).toEqual('YourComponent');\n\n\texpect(\n\t\tgetNameFromFilePath(path.join('an', 'absolute', 'path', 'to', 'yourButtonTS.tsx'))\n\t).toEqual('YourButtonTS');\n\n\texpect(\n\t\tgetNameFromFilePath(path.join('an', 'absolute', 'path', 'to', 'your-buttonTS', 'index.tsx'))\n\t).toEqual('YourButtonTS');\n\n\texpect(\n\t\tgetNameFromFilePath(path.join('an', 'absolute', 'path', 'to', 'your_button--TS', 'index.tsx'))\n\t).toEqual('YourButtonTS');\n\n\texpect(\n\t\tgetNameFromFilePath(path.join('an', 'absolute', 'path', 'to', 'ButtonTS', 'index.tsx'))\n\t).toEqual('ButtonTS');\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/getProps.spec.ts",
    "content": "import path from 'path';\nimport getProps from '../getProps';\n\nit('should return an object for props', () => {\n\tconst result = getProps({\n\t\tdisplayName: 'Button',\n\t\tdescription: 'The only true button.',\n\t\tmethods: [],\n\t\tprops: {\n\t\t\tchildren: {\n\t\t\t\tname: 'children',\n\t\t\t\ttype: {\n\t\t\t\t\tname: 'object',\n\t\t\t\t},\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'Button label.',\n\t\t\t},\n\t\t\tcolor: {\n\t\t\t\tname: 'color',\n\t\t\t\ttype: {\n\t\t\t\t\tname: 'string',\n\t\t\t\t},\n\t\t\t\trequired: false,\n\t\t\t\tdescription: '',\n\t\t\t},\n\t\t},\n\t});\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('should return an object for props without description', () => {\n\tconst result = getProps({\n\t\tdisplayName: 'Button',\n\t\tprops: {\n\t\t\tchildren: {\n\t\t\t\tname: 'children',\n\t\t\t\ttype: {\n\t\t\t\t\tname: 'object',\n\t\t\t\t},\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'Button label.',\n\t\t\t},\n\t\t},\n\t});\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('should remove non-public methods', () => {\n\tconst result = getProps(\n\t\t{\n\t\t\tdisplayName: 'Button',\n\t\t\tmethods: [\n\t\t\t\t{\n\t\t\t\t\tdocblock: `Public method.\n@public`,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdocblock: `Private method.\n@private`,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdocblock: 'Private method by default.',\n\t\t\t\t},\n\t\t\t] as any,\n\t\t},\n\t\t__filename\n\t);\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('should get method info from docblock and merge it', () => {\n\tconst result = getProps(\n\t\t{\n\t\t\tdisplayName: 'Button',\n\t\t\tmethods: [\n\t\t\t\t{\n\t\t\t\t\tdocblock: `\nBaz method with foo param\n\n@public\n@returns {string} test\n`,\n\t\t\t\t},\n\t\t\t] as any,\n\t\t},\n\t\t__filename\n\t);\n\n\texpect(result.methods).toMatchSnapshot();\n});\n\nit('should accept @return as a synonym of @returns', () => {\n\tconst result = getProps(\n\t\t{\n\t\t\tdisplayName: 'Button',\n\t\t\tmethods: [\n\t\t\t\t{\n\t\t\t\t\tdocblock: `\nBaz method with foo param\n\n@public\n@return {string} test\n`,\n\t\t\t\t},\n\t\t\t] as any,\n\t\t},\n\t\t__filename\n\t);\n\n\texpect(result.methods).toMatchSnapshot();\n});\n\nit('should get method params info from docblock and merge it with passed method info', () => {\n\tconst result = getProps(\n\t\t{\n\t\t\tdisplayName: 'Button',\n\t\t\tmethods: [\n\t\t\t\t{\n\t\t\t\t\tdocblock: `\nFoo method with baz param\n\n@public\n@param {string} [baz=bar]\n@arg {string} foo param described with @arg tag\n@argument {string} test param described with @argument tag\n@returns {string} test\n`,\n\t\t\t\t\tparams: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'baz',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'foo',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'test',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t] as any,\n\t\t},\n\t\t__filename\n\t);\n\n\texpect(result.methods).toMatchSnapshot();\n});\n\nit('should return an object for props with doclets', () => {\n\tconst result = getProps(\n\t\t{\n\t\t\tdisplayName: 'Button',\n\t\t\tdescription: `\nThe only true button.\n\n@foo Foo\n@bar Bar\n`,\n\t\t},\n\t\t__filename\n\t);\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('should return require statement for @example doclet', () => {\n\tconst result = getProps(\n\t\t{\n\t\t\tdisplayName: 'Button',\n\t\t\tdescription: `\nThe only true button.\n\n@example ../../../test/components/Placeholder/examples.md\n`,\n\t\t},\n\t\t__filename\n\t);\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('should return require statement for @example doclet only when the file exists', () => {\n\tconst result = getProps(\n\t\t{\n\t\t\tdisplayName: 'Button',\n\t\t\tdescription: `\nThe only true button.\n\n@example example.md\n`,\n\t\t},\n\t\t__filename\n\t);\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('should highlight code in description (fenced code block)', () => {\n\tconst result = getProps({\n\t\tdescription: `\nThe only true button.\n\n\\`\\`\\`js\nalert('Hello world');\n\\`\\`\\`\n`,\n\t});\n\n\texpect(result).toMatchSnapshot();\n});\n\nit(\"should not crash when using doctrine to parse a default prop that isn't in the props list\", () => {\n\tconst result = getProps({\n\t\tdescription: 'The only true button.',\n\t\tmethods: [],\n\t\tprops: {\n\t\t\tcrash: {\n\t\t\t\tdescription: undefined,\n\t\t\t},\n\t\t} as any,\n\t});\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('should not crash when using doctrine to parse a return method that does not have type in it', () => {\n\tconst result = getProps(\n\t\t{\n\t\t\tdisplayName: 'Button',\n\t\t\tmethods: [\n\t\t\t\t{\n\t\t\t\t\tdocblock: `\nPublic Method\n\n@public\n@returns {Boolean} return a Boolean Value\n`,\n\t\t\t\t\treturns: {\n\t\t\t\t\t\tdescription: 'return a Boolean Value',\n\t\t\t\t\t\ttype: { name: 'boolean' },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t] as any,\n\t\t},\n\t\t__filename\n\t);\n\n\t// @ts-ignore\n\texpect(result.methods[0].returns).toEqual(\n\t\texpect.objectContaining({\n\t\t\tdescription: 'return a Boolean Value',\n\t\t\ttype: {\n\t\t\t\tname: 'boolean',\n\t\t\t\ttype: 'NameExpression',\n\t\t\t},\n\t\t})\n\t);\n});\n\nit('should guess a displayName for components that react-docgen was not able to recognize', () => {\n\tconst result = getProps(\n\t\t{\n\t\t\tmethods: [],\n\t\t\tprops: {},\n\t\t},\n\t\tpath.join('an', 'absolute', 'path', 'to', 'YourComponent.js')\n\t);\n\texpect(result).toHaveProperty('displayName', 'YourComponent');\n});\n\ndescribe('with @visibleName tag present in the description', () => {\n\tconst result = getProps({\n\t\tdescription: 'bar\\n@visibleName foo',\n\t});\n\tit('should set visibleName property on the docs object', () => {\n\t\texpect(result).toHaveProperty('visibleName', 'foo');\n\t});\n\n\tit('should delete visibleName from doclets on the docs object', () => {\n\t\texpect(result.doclets).not.toHaveProperty('visibleName');\n\t});\n\n\tit('should delete visibleName from tags on the docs object', () => {\n\t\texpect(result.tags).not.toHaveProperty('visibleName');\n\t});\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/getSections.spec.ts",
    "content": "import path from 'path';\nimport getSections, { processSection } from '../getSections';\nimport * as Rsg from '../../../typings';\n\nconst configDir = path.resolve(__dirname, '../../../../test');\nconst config = {\n\tconfigDir,\n\texampleMode: 'collapse',\n\tusageMode: 'collapse',\n\tgetExampleFilename: (a: string) => a,\n\tgetComponentPathLine: (a: string) => a,\n} as Rsg.SanitizedStyleguidistConfig;\n\nconst sections: Rsg.ConfigSection[] = [\n\t{\n\t\tname: 'Readme',\n\t\tcontent: 'components/Button/Readme.md',\n\t},\n\t{\n\t\tname: 'Components',\n\t\tcomponents: 'components/**/[A-Z]*.js',\n\t},\n\t{\n\t\tname: 'Ignore',\n\t\tcomponents: 'components/**/*.js',\n\t\tignore: '**/components/Annotation/*',\n\t},\n\t{\n\t\tname: 'Ignore',\n\t\tcontent: () => 'Hello World',\n\t} as any,\n];\nconst sectionsWithDepth = [\n\t{\n\t\tname: 'Documentation',\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Files',\n\t\t\t\tsections: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'First File',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t\tsectionDepth: 2,\n\t},\n\t{\n\t\tname: 'Components',\n\t\texpand: true,\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Buttons',\n\t\t\t},\n\t\t],\n\t\tsectionDepth: 0,\n\t},\n];\nconst sectionsWithBadDepth = [\n\t{\n\t\tname: 'Documentation',\n\t\tsections: [\n\t\t\t{\n\t\t\t\tname: 'Files',\n\t\t\t\tsections: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'First File',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tsectionDepth: 2,\n\t\t\t},\n\t\t],\n\t},\n];\n\nfunction filterSectionDepth(section: Rsg.LoaderSection): Rsg.ConfigSection {\n\tif (section.sections && section.sections.length) {\n\t\treturn {\n\t\t\tsectionDepth: section.sectionDepth,\n\t\t\tsections: section.sections.map(filterSectionDepth),\n\t\t};\n\t}\n\treturn {\n\t\tsectionDepth: section.sectionDepth,\n\t};\n}\n\nit('processSection() should return an object for section with content', () => {\n\tconst result = processSection(sections[0], config);\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('processSection() should throw when content file not found', () => {\n\tconst fn = () => processSection({ content: 'pizza' }, config);\n\n\texpect(fn).toThrowError('Section content file not found');\n});\n\nit('processSection() should return an object for section with components', () => {\n\tconst result = processSection(sections[1], config);\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('processSection() should return an object for section without ignored components', () => {\n\tconst result = processSection(sections[2], config);\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('processSection() should return an object for section with content as function', () => {\n\tconst result = processSection(sections[3], config);\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('getSections() should return an array', () => {\n\tconst result = getSections(sections, config);\n\n\texpect(result).toMatchSnapshot();\n});\n\nit('getSections() should return an array of sectionsWithDepth with sectionDepth decreasing', () => {\n\tconst result = getSections(sectionsWithDepth, config);\n\n\texpect(result.map(filterSectionDepth)).toEqual([\n\t\t{\n\t\t\tsectionDepth: 2,\n\t\t\tsections: [\n\t\t\t\t{\n\t\t\t\t\tsectionDepth: 1,\n\t\t\t\t\tsections: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsectionDepth: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tsectionDepth: 0,\n\t\t\tsections: [\n\t\t\t\t{\n\t\t\t\t\tsectionDepth: 0,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t]);\n});\n\nit('getSections() should make custom options by user available', () => {\n\tconst result = getSections(sectionsWithDepth, config);\n\tconst expandSection = result.find(section => section.name === 'Components');\n\texpect(expandSection).toHaveProperty('expand');\n});\n\nit('getSections() should return an array of sectionsWithBadDepth taking the sectionDepth of the first depth of the sections', () => {\n\tconst result = getSections(sectionsWithBadDepth, config);\n\n\texpect(result.map(filterSectionDepth)).toEqual([\n\t\t{\n\t\t\tsectionDepth: 0,\n\t\t\tsections: [\n\t\t\t\t{\n\t\t\t\t\tsectionDepth: 0,\n\t\t\t\t\tsections: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsectionDepth: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t]);\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/highlightCode.spec.ts",
    "content": "import glogg from 'glogg';\nimport highlightCode from '../highlightCode';\n\nconst logger = glogg('rsg');\n\nconst code = '<p>Hello React</p>';\n\nit('should highlight code with specified language', () => {\n\tconst actual = highlightCode(code, 'html');\n\texpect(actual).toMatchSnapshot();\n});\n\nit('should warn when language not found', () => {\n\tconst warn = jest.fn();\n\tlogger.once('warn', warn);\n\n\tconst actual = highlightCode(code, 'pizza');\n\texpect(actual).toBe(code);\n\texpect(warn).toBeCalledWith(\n\t\t'Syntax highlighting for “pizza” isn’t supported. Supported languages are: markup, html, mathml, svg, xml, ssml, atom, rss, css, clike, javascript, js, markdown, md, scss, less, flow, typescript, ts, jsx, tsx, graphql, json, webmanifest, bash, shell, diff.'\n\t);\n});\n\nit('should not highlight code without language', () => {\n\tconst actual = highlightCode(code);\n\texpect(actual).toBe(code);\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/highlightCodeInMarkdown.spec.ts",
    "content": "import highlightCodeInMarkdown from '../highlightCodeInMarkdown';\n\nit('should highlight code with specified language', () => {\n\tconst text = `\nThe only true button.\n\n\\`\\`\\`html\n<p>Hello React</p>\n\\`\\`\\`\n`;\n\tconst actual = highlightCodeInMarkdown(text);\n\texpect(actual).toMatchSnapshot();\n});\n\nit('should not highlight code without language', () => {\n\tconst text = `\nThe only \\`true\\` button.\n\n\\`\\`\\`\n<p>Hello React</p>\n\\`\\`\\`\n`;\n\tconst actual = highlightCodeInMarkdown(text);\n\texpect(actual).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/parseExample.spec.ts",
    "content": "import parseExample from '../parseExample';\n\nconst content = '<h1>Hello Markdown!</h1>';\n\nit('should parse modifiers as JSON', () => {\n\tconst actual = parseExample(content, 'js', '{ \"showcode\": true }');\n\texpect(actual).toEqual({\n\t\tlang: 'js',\n\t\tsettings: { showcode: true },\n\t\tcontent,\n\t});\n});\n\nit('should lowercase JSON keys', () => {\n\tconst actual = parseExample(content, 'js', '{ \"showCode\": true }');\n\texpect(actual).toEqual({\n\t\tlang: 'js',\n\t\tsettings: { showcode: true },\n\t\tcontent,\n\t});\n});\n\nit('should parse modifiers as a space-separated string', () => {\n\tconst actual = parseExample(content, 'jsx', 'showcode static');\n\texpect(actual).toEqual({\n\t\tlang: 'jsx',\n\t\tsettings: { showcode: true, static: true },\n\t\tcontent,\n\t});\n});\n\nit('should lowercase modifiers', () => {\n\tconst actual = parseExample(content, 'jsx', 'showCode Static');\n\texpect(actual).toEqual({\n\t\tlang: 'jsx',\n\t\tsettings: { showcode: true, static: true },\n\t\tcontent,\n\t});\n});\n\nit('should return settings as an empty object', () => {\n\tconst actual = parseExample(content, 'js');\n\texpect(actual).toEqual({\n\t\tlang: 'js',\n\t\tsettings: {},\n\t\tcontent,\n\t});\n});\nit('should accept language as null', () => {\n\tconst actual = parseExample(content, null);\n\texpect(actual).toEqual({\n\t\tlang: null,\n\t\tsettings: {},\n\t\tcontent,\n\t});\n});\n\nit('should apply an update function', () => {\n\tconst actual = parseExample(content, 'js', 'coffee', a => ({ ...a, lang: 'pizza' }));\n\texpect(actual).toEqual({\n\t\tlang: 'pizza',\n\t\tsettings: { coffee: true },\n\t\tcontent,\n\t});\n});\n\nit('should return an error when JSON is invalid', () => {\n\tconst actual = parseExample(content, 'js', '{ nope }');\n\texpect(actual).toEqual({\n\t\terror: expect.stringMatching('Cannot parse modifiers'),\n\t});\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/processComponent.spec.ts",
    "content": "import path from 'path';\nimport processComponent from '../processComponent';\n\nconst config = {\n\tconfigDir: __dirname,\n\tgetExampleFilename: (componentpath: string) =>\n\t\tpath.join(path.dirname(componentpath), 'Readme.md'),\n\tgetComponentPathLine: (componentpath: string) => componentpath,\n};\n\nit('processComponent() should return an object for section with content', () => {\n\tconst result = processComponent('pizza.js', config as any);\n\n\texpect(result).toMatchSnapshot();\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/removeDoclets.spec.ts",
    "content": "import removeDoclets from '../removeDoclets';\n\n/* eslint-disable quotes */\n\nit('should find calls to require in code', () => {\n\tconst text = `\nComponent is described here.\n\n@example ./extra.examples.md\n@foo bar\n`;\n\tconst expected = `\nComponent is described here.\n\n\n`;\n\tconst actual = removeDoclets(text);\n\texpect(actual).toBe(expected);\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/requireIt.spec.ts",
    "content": "import { generate } from 'escodegen';\nimport requireIt from '../requireIt';\n\nit('requireIt() should return an AST for require statement', () => {\n\tconst result = requireIt('foo');\n\n\texpect(result).toBeTruthy();\n\texpect(typeof result.toAST).toBe('function');\n\texpect(generate(result.toAST())).toBe(\"require('foo')\");\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/resolveESModule.spec.ts",
    "content": "import { generate } from 'escodegen';\nimport { builders as b } from 'ast-types';\nimport resolveESModule from '../resolveESModule';\n\nit('should return an array of AST', () => {\n\tconst result = resolveESModule('path/to/module', 'NameOfVar');\n\n\texpect(generate(b.program(result))).toMatchInlineSnapshot(`\n\t\t\"const NameOfVar$0 = require('path/to/module');\n\t\tconst NameOfVar = NameOfVar$0.default || (NameOfVar$0['NameOfVar'] || NameOfVar$0);\"\n\t`);\n});\n"
  },
  {
    "path": "src/loaders/utils/__tests__/sortProps.spec.ts",
    "content": "import { PropDescriptor, PropTypeDescriptor } from 'react-docgen';\nimport sortProps from '../sortProps';\n\nfunction makeProp(\n\tname: string,\n\trequired = false,\n\tdefaultValue: any = undefined,\n\ttype: PropTypeDescriptor = { name: 'string' }\n): PropDescriptor {\n\treturn {\n\t\tname,\n\t\trequired,\n\t\tdefaultValue,\n\t\ttype,\n\t};\n}\n\nit('should sort required props', () => {\n\tconst props = [makeProp('prop2', true), makeProp('prop1', true)];\n\tconst result = sortProps(props);\n\texpect(result.map(prop => prop.name)).toEqual(['prop1', 'prop2']);\n});\n\nit('should sort optional props', () => {\n\tconst props = [makeProp('prop2', false), makeProp('prop1', false)];\n\tconst result = sortProps(props);\n\texpect(result.map(prop => prop.name)).toEqual(['prop1', 'prop2']);\n});\n\nit('should sort mixed props (required props should come first)', () => {\n\tconst props = [\n\t\tmakeProp('prop2', false),\n\t\tmakeProp('prop1', true),\n\t\tmakeProp('prop3', true),\n\t\tmakeProp('prop4', false),\n\t];\n\tconst result = sortProps(props);\n\texpect(result.map(prop => prop.name)).toEqual(['prop1', 'prop3', 'prop2', 'prop4']);\n});\n"
  },
  {
    "path": "src/loaders/utils/chunkify.ts",
    "content": "import remark from 'remark';\nimport visit from 'unist-util-visit';\nimport highlightCode from './highlightCode';\nimport parseExample, { ExampleError } from './parseExample';\nimport * as Rsg from '../../typings';\n\nconst PLAYGROUND_LANGS = ['javascript', 'js', 'jsx', 'typescript', 'ts', 'tsx'];\nconst CODE_PLACEHOLDER = '<%{#code#}%>';\n\nfunction isErrorExample(example: any): example is ExampleError {\n\treturn !!example.error;\n}\n\n/**\n * Separate Markdown and code examples that should be rendered as a playground in a style guide.\n *\n * @param {string} markdown\n * @param {Function} updateExample\n * @param {Array<string>} playgroundLangs\n * @returns {Array}\n */\nexport default function chunkify(\n\tmarkdown: string,\n\tupdateExample?: (example: Omit<Rsg.CodeExample, 'type'>) => Omit<Rsg.CodeExample, 'type'>,\n\tplaygroundLangs = PLAYGROUND_LANGS\n): (Rsg.CodeExample | Rsg.MarkdownExample)[] {\n\tconst codeChunks: Rsg.CodeExample[] = [];\n\n\t/*\n\t * - Highlight code in fenced code blocks with defined language (```html).\n\t * - Extract indented and fenced code blocks with lang javascript|js|jsx or if lang is not defined.\n\t * - Leave all other Markdown or HTML as is.\n\t */\n\tfunction processCode() {\n\t\treturn (ast: any) => {\n\t\t\tvisit(ast, 'code', (node: any) => {\n\t\t\t\tconst example = parseExample(node.value, node.lang, node.meta, updateExample);\n\n\t\t\t\tif (isErrorExample(example)) {\n\t\t\t\t\tnode.lang = undefined;\n\t\t\t\t\tnode.value = example.error;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst lang = example.lang;\n\t\t\t\tnode.lang = lang;\n\t\t\t\tif (\n\t\t\t\t\t!lang ||\n\t\t\t\t\t(playgroundLangs.indexOf(lang) !== -1 && !(example.settings && example.settings.static))\n\t\t\t\t) {\n\t\t\t\t\tcodeChunks.push({\n\t\t\t\t\t\ttype: 'code',\n\t\t\t\t\t\tcontent: example.content,\n\t\t\t\t\t\tsettings: example.settings,\n\t\t\t\t\t});\n\t\t\t\t\tnode.type = 'html';\n\t\t\t\t\tnode.value = CODE_PLACEHOLDER;\n\t\t\t\t} else {\n\t\t\t\t\tnode.meta = null;\n\t\t\t\t\tnode.value = highlightCode(example.content, lang);\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\t}\n\n\tconst rendered = remark().use(processCode).processSync(markdown).toString();\n\n\tconst chunks: (Rsg.CodeExample | Rsg.MarkdownExample)[] = [];\n\tconst textChunks = rendered.split(CODE_PLACEHOLDER);\n\ttextChunks.forEach((chunk) => {\n\t\tchunk = chunk.trim();\n\t\tif (chunk) {\n\t\t\tchunks.push({\n\t\t\t\ttype: 'markdown',\n\t\t\t\tcontent: chunk,\n\t\t\t});\n\t\t}\n\t\tconst code = codeChunks.shift();\n\t\tif (code) {\n\t\t\tchunks.push(code);\n\t\t}\n\t});\n\n\treturn chunks;\n}\n"
  },
  {
    "path": "src/loaders/utils/client/__tests__/.eslintrc",
    "content": "{\n\t\"root\": true,\n\t\"parser\": \"babel-eslint\",\n\t\"extends\": \"tamia\"\n}\n"
  },
  {
    "path": "src/loaders/utils/client/__tests__/evalInContext.spec.js",
    "content": "import evalInContext from '../evalInContext';\n\ndescribe('evalInContext', () => {\n\ttest('return a function', () => {\n\t\tconst result = evalInContext(`alert('header')`, (a) => a, `alert('code')`);\n\t\texpect(typeof result).toBe('function');\n\t});\n\n\ttest('create a separate scope for the body', () => {\n\t\tconst fn = () =>\n\t\t\tevalInContext(\n\t\t\t\t`const react = require('react')`,\n\t\t\t\t(a) => a,\n\t\t\t\t`const react = require('react')\nconst x = 42\n`\n\t\t\t);\n\t\texpect(fn).not.toThrow();\n\t});\n});\n"
  },
  {
    "path": "src/loaders/utils/client/__tests__/requireInRuntime.spec.js",
    "content": "import requireInRuntime from '../requireInRuntime';\n\nconst map = {\n\ta: () => 'a',\n};\n\ntest('return a module from the map', () => {\n\tconst result = requireInRuntime(map, 'a');\n\texpect(result).toBeDefined();\n\texpect(result()).toBe('a');\n});\n\ntest('throw if module is not in the map', () => {\n\tconst fn = () => requireInRuntime(map, 'pizza');\n\texpect(fn).toThrowError('require() statements can be added');\n});\n"
  },
  {
    "path": "src/loaders/utils/client/evalInContext.ts",
    "content": "/**\n * Eval example code in a custom context:\n * - `require()` that allows you to require modules from Markdown examples\n *   (won’t work dinamically becasue we need to know all required modules in\n *   advance to be able to bundle them with the code).\n * - `state` variable, `setState` function that will be binded to a React\n *   component that manages example’s state on the frontend.\n *\n * Also prepends a given `code` with a `header` (maps required context modules\n * to local variables: React, current component and modules defined via the\n * `context` config option).\n */\nexport default function evalInContext(\n\theader: string,\n\trequire: (module: string) => any,\n\tcode: string\n): (state: Record<string, unknown>, setState: any) => any {\n\t// 1. Prepend code with the header\n\t// 2. Wrap code in a block (`{}`) to create a new scope, so you could\n\t//    explicitly import context modules in your examples)\n\tconst body = `${header}\n{${code}}`;\n\n\t// eslint-disable-next-line no-new-func\n\tconst func = new Function('require', 'state', 'setState', body);\n\n\t// Bind the `require` function, other context arguments will be passed from\n\t// the frontend\n\treturn func.bind(null, require);\n}\n"
  },
  {
    "path": "src/loaders/utils/client/requireInRuntime.ts",
    "content": "type Module = { [name: string]: any } | (() => any);\ntype RequireMap = { [filepath: string]: Module };\n\n/**\n * Return module from a given map (like {react: require('react')}) or throw.\n * We allow to require modules only from Markdown examples (won’t work dynamically because we need to know all required\n * modules in advance to be able to bundle them with the code).\n */\nexport default function requireInRuntime(requireMap: RequireMap, filepath: string): Module {\n\tif (!(filepath in requireMap)) {\n\t\tthrow new Error(\n\t\t\t`import or require() statements can be added only by editing a Markdown example file: ${filepath}`\n\t\t);\n\t}\n\n\treturn requireMap[filepath];\n}\n"
  },
  {
    "path": "src/loaders/utils/expandDefaultComponent.ts",
    "content": "const COMPONENT_PLACEHOLDER = '__COMPONENT__';\nconst COMPONENT_PLACEHOLDER_REGEXP = new RegExp(COMPONENT_PLACEHOLDER, 'g');\n\n/**\n * Wrap a string with require() statement.\n *\n * @param {string} source Source code.\n * @param {string} componentName Name that will be used instead of a placeholder.\n * @returns {string}\n */\nexport default function expandDefaultComponent(source: string, componentName: string): string {\n\treturn source.replace(COMPONENT_PLACEHOLDER_REGEXP, componentName);\n}\n"
  },
  {
    "path": "src/loaders/utils/filterComponentsWithExample.ts",
    "content": "import * as Rsg from '../../typings';\n\n/**\n * Filter out components without an example file.\n *\n * @param {Array} sections\n * @returns {Array}\n */\nexport default function filterComponentsWithExample(\n\tsections: Rsg.LoaderSection[]\n): Rsg.LoaderSection[] {\n\treturn sections\n\t\t.map(section => ({\n\t\t\t...section,\n\t\t\tsections: filterComponentsWithExample(section.sections),\n\t\t\tcomponents: section.components.filter(component => component.hasExamples),\n\t\t}))\n\t\t.filter(\n\t\t\tsection => section.components.length > 0 || section.sections.length > 0 || section.content\n\t\t);\n}\n"
  },
  {
    "path": "src/loaders/utils/getAllContentPages.ts",
    "content": "import * as Rsg from '../../typings';\n\n/**\n * Get all section content pages.\n *\n * @param {Array} sections\n * @returns {Array}\n */\nexport default function getAllContentPages(\n\tsections: Rsg.LoaderSection[]\n): (Rsg.MarkdownExample | Rsg.RequireItResult)[] {\n\treturn sections.reduce((pages: (Rsg.MarkdownExample | Rsg.RequireItResult)[], section) => {\n\t\tif (section.content) {\n\t\t\tpages = pages.concat([section.content]);\n\t\t}\n\n\t\tif (section.sections) {\n\t\t\tpages = pages.concat(getAllContentPages(section.sections));\n\t\t}\n\n\t\treturn pages;\n\t}, []);\n}\n"
  },
  {
    "path": "src/loaders/utils/getAst.ts",
    "content": "import { Parser, Node as AcornNode, Options } from 'acorn';\nimport Logger from 'glogg';\n\nconst logger = Logger('rsg');\n\nexport const ACORN_OPTIONS: Options = {\n\tecmaVersion: 2019,\n\tsourceType: 'module',\n};\n\n/**\n * Parse source code with Acorn and return AST, returns undefined in case of errors\n */\nexport default function getAst(\n\tcode: string,\n\tplugins: ((BaseParser: typeof Parser) => typeof Parser)[] = []\n): AcornNode | undefined {\n\tconst parser = Parser.extend(...plugins);\n\n\ttry {\n\t\treturn parser.parse(code, ACORN_OPTIONS);\n\t} catch (err) {\n\t\tif (err instanceof Error) {\n\t\t\tlogger.debug(`Acorn cannot parse example code: ${err.message}\\n\\nCode:\\n${code}`);\n\t\t\treturn undefined;\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"
  },
  {
    "path": "src/loaders/utils/getComponentFiles.ts",
    "content": "import glob from 'glob';\nimport path from 'path';\nimport isFunction from 'lodash/isFunction';\nimport isString from 'lodash/isString';\n\nconst getComponentGlobs = (components: string | string[] | (() => string[])): string[] => {\n\tif (isFunction(components)) {\n\t\treturn components();\n\t} else if (Array.isArray(components)) {\n\t\treturn components;\n\t} else if (isString(components)) {\n\t\treturn [components];\n\t}\n\tthrow new Error(\n\t\t`Styleguidist: components should be string, function or array, received ${typeof components}.`\n\t);\n};\n\nconst getFilesMatchingGlobs = (components: string[], rootDir?: string, ignore?: string[]) => {\n\tignore = ignore || [];\n\treturn components\n\t\t.map(listItem =>\n\t\t\tglob.sync(listItem, {\n\t\t\t\tcwd: rootDir,\n\t\t\t\tignore,\n\t\t\t\tabsolute: true,\n\t\t\t})\n\t\t)\n\t\t.reduce((accumulator, current) => accumulator.concat(current), []);\n};\n\n/**\n * Return absolute paths of components that should be rendered in the style guide.\n *\n * @param {string|Function|Array} components Function, Array or glob pattern.\n * @param {string} rootDir\n * @param {Array} [ignore] Glob patterns to ignore.\n * @returns {Array}\n */\nexport default function getComponentFiles(\n\tcomponents?: string | string[] | (() => string[]) | undefined,\n\trootDir?: string,\n\tignore?: string[]\n): string[] {\n\tif (!components) {\n\t\treturn [];\n\t}\n\n\t// Normalize components option into an Array\n\tconst componentGlobs = getComponentGlobs(components);\n\n\t// Resolve list of components from globs\n\tconst componentFiles = getFilesMatchingGlobs(componentGlobs, rootDir, ignore);\n\n\t// Get absolute component file paths with correct slash separator format\n\tconst resolvedComponentFiles = componentFiles.map(file => path.resolve(file));\n\n\treturn resolvedComponentFiles;\n}\n"
  },
  {
    "path": "src/loaders/utils/getComponentFilesFromSections.ts",
    "content": "import getComponentFiles from './getComponentFiles';\nimport * as Rsg from '../../typings';\n\n/**\n * Return absolute paths of all components in sections.\n *\n * @param {Array} sections\n * @param {string} rootDir\n * @param {Array} [ignore] Glob patterns to ignore.\n * @returns {Array}\n */\nexport default function getComponentFilesFromSections(\n\tsections: Rsg.ConfigSection[],\n\trootDir?: string,\n\tignore?: string[]\n): string[] {\n\treturn sections.reduce((components: string[], section) => {\n\t\tif (section.components) {\n\t\t\treturn components.concat(getComponentFiles(section.components, rootDir, ignore));\n\t\t}\n\n\t\tif (section.sections) {\n\t\t\treturn components.concat(getComponentFilesFromSections(section.sections, rootDir, ignore));\n\t\t}\n\n\t\treturn components;\n\t}, []);\n}\n"
  },
  {
    "path": "src/loaders/utils/getComponentPatternsFromSections.ts",
    "content": "import * as Rsg from '../../typings';\n\n/**\n * Return all glob patterns from all sections.\n *\n * NOTE: a section cannot have components & subsections\n * @param {Array} sections\n * @returns {Array}\n */\nexport default function getComponentPatternsFromSections(sections: Rsg.ConfigSection[]): string[] {\n\treturn sections.reduce((patterns: string[], section) => {\n\t\tif (Array.isArray(section.components)) {\n\t\t\treturn patterns.concat(section.components);\n\t\t}\n\n\t\tif (section.sections) {\n\t\t\treturn patterns.concat(getComponentPatternsFromSections(section.sections));\n\t\t}\n\n\t\treturn patterns;\n\t}, []);\n}\n"
  },
  {
    "path": "src/loaders/utils/getComponents.ts",
    "content": "import processComponent from './processComponent';\nimport * as Rsg from '../../typings';\n\n/**\n * Process each component in a list.\n *\n * @param {Array} components File names of components.\n * @param {object} config\n * @returns {object|null}\n */\nexport default function getComponents(\n\tcomponents: string[],\n\tconfig: Rsg.SanitizedStyleguidistConfig\n) {\n\treturn components.map(filepath => processComponent(filepath, config));\n}\n"
  },
  {
    "path": "src/loaders/utils/getExamples.ts",
    "content": "import path from 'path';\nimport fs from 'fs';\nimport { encode } from 'qss';\nimport requireIt from './requireIt';\nimport * as Rsg from '../../typings';\n\nconst examplesLoader = path.resolve(__dirname, '../examples-loader.js');\n\n/**\n * Get require statement for examples file if it exists, or for default examples if it was defined.\n */\nexport default function getExamples(\n\tfile: string,\n\tdisplayName: string,\n\texamplesFile?: string | false,\n\tdefaultExample?: string | false\n): Rsg.RequireItResult | null {\n\tconst examplesFileToLoad =\n\t\t(examplesFile && fs.existsSync(examplesFile) ? examplesFile : false) || defaultExample;\n\tif (!examplesFileToLoad) {\n\t\treturn null;\n\t}\n\n\tconst relativePath = `./${path.relative(path.dirname(examplesFileToLoad), file)}`;\n\n\tconst query = {\n\t\tdisplayName,\n\t\tfile: relativePath,\n\t\tshouldShowDefaultExample: !examplesFile && !!defaultExample,\n\t};\n\treturn requireIt(`!!${examplesLoader}?${encode(query)}!${examplesFileToLoad}`);\n}\n"
  },
  {
    "path": "src/loaders/utils/getImports.ts",
    "content": "import acornJsx from 'acorn-jsx';\nimport { walk } from 'estree-walker';\nimport getAst from './getAst';\n\n/**\n * Returns a list of all strings used in import statements or require() calls\n */\nexport default function getImports(code: string): string[] {\n\t// Parse example source code, but ignore errors:\n\t// 1. Adjacent JSX elements must be wrapped in an enclosing tag (<X/><Y/>) -\n\t//    imports/requires are not allowed in this case, and we'll wrap the code\n\t//    in React.Fragment on the frontend\n\t// 2. All other errors - we'll deal with them on the frontend\n\tconst ast = getAst(code, [acornJsx()]);\n\tif (!ast) {\n\t\treturn [];\n\t}\n\n\tconst imports: string[] = [];\n\twalk(ast as any, {\n\t\tenter: (node: any) => {\n\t\t\t// import foo from 'foo'\n\t\t\t// import 'foo'\n\t\t\tif (node.type === 'ImportDeclaration') {\n\t\t\t\tif (node.source) {\n\t\t\t\t\timports.push(node.source.value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// require('foo')\n\t\t\telse if (node.type === 'CallExpression') {\n\t\t\t\tif (\n\t\t\t\t\tnode.callee &&\n\t\t\t\t\tnode.callee.name === 'require' &&\n\t\t\t\t\tnode.arguments &&\n\t\t\t\t\tnode.arguments[0].value\n\t\t\t\t) {\n\t\t\t\t\timports.push(node.arguments[0].value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t});\n\treturn imports;\n}\n"
  },
  {
    "path": "src/loaders/utils/getNameFromFilePath.ts",
    "content": "import path from 'path';\nimport startCase from 'lodash/startCase';\n\n/**\n * your-buttonTS -> YourButtonTS\n * your_button--TS -> YourButtonTS\n */\nfunction transformFileNameToDisplayName(displayName: string): string {\n\treturn startCase(displayName).replace(/\\s/g, '');\n}\n\nexport default function getNameFromFilePath(filePath: string): string {\n\tlet fileName = path.basename(filePath, path.extname(filePath));\n\tif (fileName === 'index') {\n\t\tfileName = path.basename(path.dirname(filePath));\n\t}\n\n\treturn transformFileNameToDisplayName(fileName);\n}\n"
  },
  {
    "path": "src/loaders/utils/getProps.ts",
    "content": "import path from 'path';\nimport fs from 'fs';\nimport { TagProps, TagParamObject, DocumentationObject, utils, TagObject } from 'react-docgen';\nimport _ from 'lodash';\nimport doctrine, { Annotation } from 'doctrine';\nimport createLogger from 'glogg';\nimport highlightCodeInMarkdown from './highlightCodeInMarkdown';\nimport removeDoclets from './removeDoclets';\nimport requireIt from './requireIt';\nimport getNameFromFilePath from './getNameFromFilePath';\nimport * as Rsg from '../../typings';\n\nconst logger = createLogger('rsg');\n\nconst examplesLoader = path.resolve(__dirname, '../examples-loader.js');\n\nconst JS_DOC_METHOD_PARAM_TAG_SYNONYMS: (keyof TagProps)[] = ['param', 'arg', 'argument'];\nconst JS_DOC_METHOD_RETURN_TAG_SYNONYMS: (keyof TagProps)[] = ['return', 'returns'];\nconst JS_DOC_ALL_SYNONYMS: (keyof TagProps)[] = [\n\t...JS_DOC_METHOD_PARAM_TAG_SYNONYMS,\n\t...JS_DOC_METHOD_RETURN_TAG_SYNONYMS,\n];\n\n// HACK: We have to make sure that doclets is a proper object with correct prototype to\n// work around an issue in react-docgen that breaks the build if a component has JSDoc tags\n// like @see in its description, see https://github.com/reactjs/react-docgen/issues/155\n// and https://github.com/styleguidist/react-styleguidist/issues/298\nconst getDocletsObject = (str?: string) => ({ ...utils.docblock.getDoclets(str) });\n\nconst getDoctrineTags = (documentation: Annotation) => {\n\treturn _.groupBy(documentation.tags, 'title');\n};\n\nconst doesExternalExampleFileExist = (componentPath: string, exampleFile: string) => {\n\tconst exampleFilepath = path.resolve(path.dirname(componentPath), exampleFile);\n\tconst doesFileExist = fs.existsSync(exampleFilepath);\n\n\tif (!doesFileExist) {\n\t\tlogger.warn(`An example file ${exampleFile} defined in ${componentPath} component not found.`);\n\t}\n\treturn doesFileExist;\n};\n\nconst getMergedTag = (tags: TagProps, names: (keyof TagProps)[]): TagObject[] => {\n\treturn names.reduce((params: TagObject[], name) => [...params, ...(tags[name] || [])], []);\n};\n\n/**\n * 1. Remove non-public methods.\n * 2. Extract doclets.\n * 3. Highlight code in descriptions.\n * 4. Extract @example doclet (load linked file with examples-loader).\n *\n * @param {object} doc\n * @param {string} filepath\n * @returns {object}\n */\nexport default function getProps(doc: DocumentationObject, filepath?: string): Rsg.TempPropsObject {\n\tconst outDocs: Rsg.TempPropsObject = { doclets: {}, displayName: '', ...doc, methods: undefined };\n\n\t// Keep only public methods\n\toutDocs.methods = (doc.methods || []).filter(method => {\n\t\tconst doclets = method.docblock && utils.docblock.getDoclets(method.docblock);\n\t\treturn doclets && doclets.public;\n\t}) as Rsg.MethodWithDocblock[];\n\n\t// Parse the docblock of the remaining methods with doctrine to retrieve\n\t// the JSDoc tags\n\t// if a method is visible it must have a docblock\n\toutDocs.methods = outDocs.methods.map(method => {\n\t\tconst allTags = getDoctrineTags(\n\t\t\tdoctrine.parse(method.docblock, { sloppy: true, unwrap: true })\n\t\t);\n\n\t\t// Merge with react-docgen information about arguments and return value\n\t\t// with information from JSDoc\n\n\t\tconst paramTags = getMergedTag(\n\t\t\tallTags as TagProps,\n\t\t\tJS_DOC_METHOD_PARAM_TAG_SYNONYMS\n\t\t) as TagParamObject[];\n\t\tconst params =\n\t\t\tmethod.params &&\n\t\t\tmethod.params.map(param => ({\n\t\t\t\t...param,\n\t\t\t\t...paramTags.find(tagParam => tagParam.name === param.name),\n\t\t\t}));\n\n\t\tif (params) {\n\t\t\tmethod.params = params;\n\t\t}\n\n\t\tconst returnTags = getMergedTag(\n\t\t\tallTags as TagProps,\n\t\t\tJS_DOC_METHOD_RETURN_TAG_SYNONYMS\n\t\t) as TagParamObject[];\n\t\tconst returns = method.returns\n\t\t\t? {\n\t\t\t\t\t...method.returns,\n\t\t\t\t\ttype: {\n\t\t\t\t\t\ttype: 'NameExpression',\n\t\t\t\t\t\t...method.returns.type,\n\t\t\t\t\t},\n\t\t\t  }\n\t\t\t: returnTags[0];\n\n\t\tif (returns) {\n\t\t\tmethod.returns = returns;\n\t\t}\n\n\t\t// Remove tag synonyms\n\t\tmethod.tags = _.omit(allTags, JS_DOC_ALL_SYNONYMS);\n\n\t\treturn method;\n\t});\n\n\tif (doc.description) {\n\t\t// Read doclets from the description and remove them\n\t\toutDocs.doclets = getDocletsObject(doc.description);\n\n\t\tconst documentation = doctrine.parse(doc.description);\n\t\toutDocs.tags = getDoctrineTags(documentation) as TagProps;\n\n\t\toutDocs.description = highlightCodeInMarkdown(removeDoclets(doc.description));\n\n\t\tlet exampleFileExists = false;\n\t\tlet exampleFile = outDocs.doclets.example;\n\n\t\t// doc.doclets.example might be a boolean or undefined\n\t\tif (typeof outDocs.doclets.example === 'string' && filepath) {\n\t\t\texampleFile = outDocs.doclets.example.trim();\n\t\t\texampleFileExists = doesExternalExampleFileExist(filepath, exampleFile);\n\t\t}\n\n\t\tif (exampleFileExists) {\n\t\t\toutDocs.example = requireIt(`!!${examplesLoader}!${exampleFile}`);\n\t\t\tdelete outDocs.doclets.example;\n\t\t}\n\t} else {\n\t\toutDocs.doclets = {};\n\t}\n\n\tif (doc.props) {\n\t\t// Read doclets of props\n\t\tObject.keys(doc.props).forEach(propName => {\n\t\t\tif (!doc.props) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst prop = doc.props[propName];\n\t\t\tconst doclets = getDocletsObject(prop.description);\n\n\t\t\t// When a prop is listed in defaultProps but not in props the prop.description is undefined\n\t\t\tconst documentation = doctrine.parse(prop.description || '');\n\n\t\t\t// documentation.description is the description without tags\n\t\t\tprop.description = documentation.description;\n\t\t\tprop.tags = getDoctrineTags(documentation) as TagProps;\n\n\t\t\t// Remove ignored props\n\t\t\tif (doclets && doclets.ignore && outDocs.props) {\n\t\t\t\tdelete outDocs.props[propName];\n\t\t\t} else if (outDocs.props) {\n\t\t\t\toutDocs.props[propName] = prop;\n\t\t\t}\n\t\t});\n\t}\n\n\tif (!doc.displayName && filepath) {\n\t\t// Guess the exported component's display name based on the file path\n\t\toutDocs.displayName = getNameFromFilePath(filepath);\n\t}\n\n\tif (outDocs.doclets && outDocs.doclets.visibleName) {\n\t\toutDocs.visibleName = outDocs.doclets.visibleName;\n\n\t\t// Custom tag is added both to doclets and tags\n\t\t// Removing from both locations\n\t\tdelete outDocs.doclets.visibleName;\n\t\tif (outDocs.tags) {\n\t\t\tdelete outDocs.tags.visibleName;\n\t\t}\n\t}\n\n\treturn outDocs;\n}\n"
  },
  {
    "path": "src/loaders/utils/getSections.ts",
    "content": "// This two functions should be in the same file because of cyclic imports\n\nimport fs from 'fs';\nimport path from 'path';\nimport _ from 'lodash';\nimport requireIt from './requireIt';\nimport getComponentFiles from './getComponentFiles';\nimport getComponents from './getComponents';\nimport slugger from './slugger';\nimport * as Rsg from '../../typings';\n\nconst examplesLoader = path.resolve(__dirname, '../examples-loader.js');\n\nfunction processSectionContent(\n\tsection: Rsg.ConfigSection,\n\tconfig: Rsg.SanitizedStyleguidistConfig\n): Rsg.RequireItResult | Rsg.MarkdownExample | undefined {\n\tif (!section.content) {\n\t\treturn undefined;\n\t}\n\n\tconst contentRelativePath = section.content;\n\n\tif (_.isFunction(section.content)) {\n\t\treturn {\n\t\t\ttype: 'markdown',\n\t\t\tcontent: section.content(),\n\t\t};\n\t}\n\n\t// Try to load section content file\n\tconst contentAbsolutePath = path.resolve(config.configDir, contentRelativePath);\n\tif (!fs.existsSync(contentAbsolutePath)) {\n\t\tthrow new Error(`Styleguidist: Section content file not found: ${contentAbsolutePath}`);\n\t}\n\treturn requireIt(`!!${examplesLoader}!${contentAbsolutePath}`);\n}\n\nconst getSectionComponents = (\n\tsection: Rsg.ConfigSection,\n\tconfig: Rsg.SanitizedStyleguidistConfig\n) => {\n\tlet ignore = config.ignore ? _.castArray(config.ignore) : [];\n\tif (section.ignore) {\n\t\tignore = ignore.concat(_.castArray(section.ignore));\n\t}\n\n\treturn getComponents(getComponentFiles(section.components, config.configDir, ignore), config);\n};\n\n/**\n * Return object for one level of sections.\n *\n * @param {Array} sections\n * @param {object} config\n * @param {number} parentDepth\n * @returns {Array}\n */\nexport default function getSections(\n\tsections: Rsg.ConfigSection[],\n\tconfig: Rsg.SanitizedStyleguidistConfig,\n\tparentDepth?: number\n): Rsg.LoaderSection[] {\n\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\treturn sections.map(section => processSection(section, config, parentDepth));\n}\n\n/**\n * Return an object for a given section with all components and subsections.\n * @param {object} section\n * @param {object} config\n * @param {number} parentDepth\n * @returns {object}\n */\nexport function processSection(\n\tsection: Rsg.ConfigSection,\n\tconfig: Rsg.SanitizedStyleguidistConfig,\n\tparentDepth?: number\n): Rsg.LoaderSection {\n\tconst content = processSectionContent(section, config);\n\n\tlet sectionDepth;\n\n\tif (parentDepth === undefined) {\n\t\tsectionDepth = section.sectionDepth !== undefined ? section.sectionDepth : 0;\n\t} else {\n\t\tsectionDepth = parentDepth === 0 ? 0 : parentDepth - 1;\n\t}\n\n\treturn {\n\t\t...section,\n\t\texampleMode: section.exampleMode || config.exampleMode,\n\t\tusageMode: section.usageMode || config.usageMode,\n\t\tsectionDepth,\n\t\tslug: `section-${slugger.slug(section.name || 'untitled')}`,\n\t\tsections: getSections(section.sections || [], config, sectionDepth),\n\t\thref: section.href,\n\t\tcomponents: getSectionComponents(section, config),\n\t\tcontent,\n\t};\n}\n"
  },
  {
    "path": "src/loaders/utils/highlightCode.ts",
    "content": "import createLogger from 'glogg';\nimport * as Prism from 'prismjs';\n\nimport 'prismjs/components/prism-clike';\nimport 'prismjs/components/prism-markup';\nimport 'prismjs/components/prism-markdown';\nimport 'prismjs/components/prism-css';\nimport 'prismjs/components/prism-css-extras';\nimport 'prismjs/components/prism-scss';\nimport 'prismjs/components/prism-less';\nimport 'prismjs/components/prism-javascript';\nimport 'prismjs/components/prism-flow';\nimport 'prismjs/components/prism-typescript';\nimport 'prismjs/components/prism-jsx';\nimport 'prismjs/components/prism-tsx';\nimport 'prismjs/components/prism-graphql';\nimport 'prismjs/components/prism-json';\nimport 'prismjs/components/prism-bash';\nimport 'prismjs/components/prism-diff';\n\nconst logger = createLogger('rsg');\n\nconst IGNORED_LANGUAGES = ['extend', 'insertBefore', 'DFS'];\nconst getLanguages = () => Object.keys(Prism.languages).filter(x => !IGNORED_LANGUAGES.includes(x));\n\n/**\n * Highlight code.\n *\n * @param {string} code\n * @param {string} lang\n * @returns {string}\n */\nexport default function highlightCode(code: string, lang?: string): string {\n\tif (!lang) {\n\t\treturn code;\n\t}\n\n\tconst grammar = Prism.languages[lang];\n\tif (!grammar) {\n\t\tlogger.warn(\n\t\t\t`Syntax highlighting for “${lang}” isn’t supported. Supported languages are: ${getLanguages().join(\n\t\t\t\t', '\n\t\t\t)}.`\n\t\t);\n\t\treturn code;\n\t}\n\n\treturn Prism.highlight(code, grammar, lang);\n}\n"
  },
  {
    "path": "src/loaders/utils/highlightCodeInMarkdown.ts",
    "content": "import remark from 'remark';\nimport visit from 'unist-util-visit';\nimport highlightCode from './highlightCode';\n\nfunction highlight() {\n\treturn (ast: any) => {\n\t\tvisit(ast, 'code', (node: any) => {\n\t\t\tnode.value = highlightCode(node.value, node.lang);\n\t\t});\n\t};\n}\n\n/**\n * Highlight code in code snippets in Markdown.\n *\n * @param {string} markdown\n * @returns {string}\n */\nexport default function highlightCodeInMarkdown(markdown: string): string {\n\treturn remark().use(highlight).processSync(markdown).toString();\n}\n"
  },
  {
    "path": "src/loaders/utils/parseExample.ts",
    "content": "import lowercaseKeys from 'lowercase-keys';\nimport { DOCS_DOCUMENTING } from '../../scripts/consts';\nimport * as Rsg from '../../typings';\n\nconst hasStringModifiers = (modifiers: string): boolean => !!modifiers.match(/^[ \\w]+$/);\n\nexport interface ExampleError {\n\terror: string;\n}\n/**\n * Split fenced code block header to lang and modifiers, parse modifiers, lowercase modifier keys, etc.\n */\nexport default function parseExample(\n\tcontent: string,\n\tlang?: string | null,\n\tmodifiers?: string,\n\tupdateExample: (example: Omit<Rsg.CodeExample, 'type'>) => Omit<Rsg.CodeExample, 'type'> = x => x\n): Omit<Rsg.CodeExample, 'type'> | ExampleError {\n\tconst example: Omit<Rsg.CodeExample, 'type'> = {\n\t\tcontent,\n\t\tlang,\n\t};\n\n\tif (modifiers) {\n\t\tif (hasStringModifiers(modifiers)) {\n\t\t\texample.settings = modifiers.split(' ').reduce((obj: Record<string, any>, modifier) => {\n\t\t\t\tobj[modifier] = true;\n\t\t\t\treturn obj;\n\t\t\t}, {});\n\t\t} else {\n\t\t\ttry {\n\t\t\t\texample.settings = JSON.parse(modifiers);\n\t\t\t} catch (err) {\n\t\t\t\treturn {\n\t\t\t\t\terror: `Cannot parse modifiers for \"${modifiers}\". Use space-separated strings or JSON:\\n\\n${DOCS_DOCUMENTING}`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\tconst updatedExample = updateExample(example);\n\treturn {\n\t\t...updatedExample,\n\t\tsettings: lowercaseKeys(updatedExample.settings || {}),\n\t};\n}\n"
  },
  {
    "path": "src/loaders/utils/processComponent.ts",
    "content": "import fs from 'fs';\nimport path from 'path';\nimport getNameFromFilePath from './getNameFromFilePath';\nimport requireIt from './requireIt';\nimport slugger from './slugger';\nimport * as Rsg from '../../typings';\n\nconst propsLoader = path.resolve(__dirname, '../props-loader.js');\n\n/**\n * References the filepath of the metadata file.\n *\n * @param {string} filepath\n * @returns {string}\n */\nfunction getComponentMetadataPath(filepath: string): string {\n\tconst extname = path.extname(filepath);\n\treturn filepath.substring(0, filepath.length - extname.length) + '.json';\n}\n\n/**\n * Return an object with all required for style guide information for a given component.\n *\n * @param {string} filepath\n * @param {object} config\n * @returns {object}\n */\nexport default function processComponent(\n\tfilepath: string,\n\tconfig: Rsg.SanitizedStyleguidistConfig\n): Rsg.LoaderComponent {\n\tconst componentPath = path.relative(config.configDir, filepath);\n\tconst componentName = getNameFromFilePath(filepath);\n\tconst examplesFile = config.getExampleFilename(filepath);\n\tconst componentMetadataPath = getComponentMetadataPath(filepath);\n\treturn {\n\t\tfilepath: componentPath,\n\t\tslug: slugger.slug(componentName),\n\t\tpathLine: config.getComponentPathLine(componentPath),\n\t\tmodule: requireIt(filepath),\n\t\tprops: requireIt(`!!${propsLoader}!${filepath}`),\n\t\thasExamples: !!(examplesFile && fs.existsSync(examplesFile)),\n\t\tmetadata: fs.existsSync(componentMetadataPath) ? requireIt(componentMetadataPath) : {},\n\t};\n}\n"
  },
  {
    "path": "src/loaders/utils/removeDoclets.ts",
    "content": "// Doclet regexp from react-docgen\nconst DOCLET_REGEXP = /^@(\\w+)(?:$|\\s((?:[^](?!^@\\w))*))/gim;\n\n/**\n * Remove all doclets (e.g. `@example Foo.js`) from text.\n * @param {string} text\n * @returns {string}\n */\nexport default function removeDoclets(text: string) {\n\treturn text.replace(DOCLET_REGEXP, '');\n}\n"
  },
  {
    "path": "src/loaders/utils/requireIt.ts",
    "content": "import { builders as b, ASTNode } from 'ast-types';\nimport * as Rsg from '../../typings';\n\n/**\n * Return a require() statement AST.\n *\n * @param {string} filepath Module name.\n * @returns {object}\n */\nexport default function requireIt(filepath: string): Rsg.RequireItResult {\n\tconst obj = { require: filepath };\n\tObject.defineProperty(obj, 'toAST', {\n\t\tenumerable: false,\n\t\tvalue(): ASTNode {\n\t\t\treturn b.callExpression(b.identifier('require'), [b.literal(filepath)]);\n\t\t},\n\t});\n\treturn obj as Rsg.RequireItResult;\n}\n"
  },
  {
    "path": "src/loaders/utils/resolveESModule.ts",
    "content": "import { builders as b } from 'ast-types';\nimport requireIt from './requireIt';\n\n/**\n * Resolve ES5 requires for export default, named export and module.exports\n *\n * @param requireRequest the argument of the `require` function\n * @param name the name of the resulting variable\n * @returns AST\n */\nexport default (requireRequest: string, name: string) => {\n\t// The name could possibly contain invalid characters for a JS variable name\n\t// such as \".\" or \"-\". \n\tconst safeName = name ? name.replace(/\\W/, '') : name;\n\n\treturn [\n\t\t// const safeName$0 = require(path);\n\t\tb.variableDeclaration('const', [\n\t\t\tb.variableDeclarator(b.identifier(`${safeName}$0`), requireIt(requireRequest).toAST() as any),\n\t\t]),\n\t\t// const safeName = safeName$0.default || safeName$0[safeName] || safeName$0;\n\t\tb.variableDeclaration('const', [\n\t\t\tb.variableDeclarator(\n\t\t\t\tb.identifier(safeName),\n\t\t\t\tb.logicalExpression(\n\t\t\t\t\t'||',\n\t\t\t\t\tb.identifier(`${safeName}$0.default`),\n\t\t\t\t\tb.logicalExpression('||', b.identifier(`${safeName}$0['${safeName}']`), b.identifier(`${safeName}$0`))\n\t\t\t\t)\n\t\t\t),\n\t\t]),\n\t]\n};\n"
  },
  {
    "path": "src/loaders/utils/slugger.ts",
    "content": "import GithubSlugger from 'github-slugger';\n\n// Export the singleton instance of GithubSlugger\nexport default new GithubSlugger();\n"
  },
  {
    "path": "src/loaders/utils/sortProps.ts",
    "content": "import sortBy from 'lodash/sortBy';\nimport { PropDescriptor } from 'react-docgen';\n\n/**\n * Sorts an array of properties by their 'required' property first and 'name'\n * property second.\n *\n * @param {array} props\n * @return {array} Sorted properties\n */\nfunction sortProps(props: PropDescriptor[]) {\n\tconst requiredPropNames = sortBy(props.filter(prop => prop.required), 'name');\n\tconst optionalPropNames = sortBy(props.filter(prop => !prop.required), 'name');\n\tconst sortedProps = requiredPropNames.concat(optionalPropNames);\n\treturn sortedProps;\n}\n\nexport default sortProps;\n"
  },
  {
    "path": "src/scripts/__mocks__/build.ts",
    "content": "import * as Rsg from '../../typings';\n\nexport default function build(\n\tconfig: Rsg.SanitizedStyleguidistConfig,\n\tcallback: (err: Error | null, stats: any) => void\n) {\n\tcallback(null, { stats: true });\n\treturn {};\n}\n"
  },
  {
    "path": "src/scripts/__mocks__/server.ts",
    "content": "import * as Rsg from '../../typings';\n\nexport default function server(\n\tconfig: Rsg.SanitizedStyleguidistConfig,\n\tcallback: (err: Error | null) => void\n) {\n\tcallback(null);\n\treturn {};\n}\n"
  },
  {
    "path": "src/scripts/__tests__/__snapshots__/make-webpack-config.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should merge user webpack config 1`] = `\nObject {\n  \"foo\": \"bar\",\n  \"rsg-components\": \"~/src/client/rsg-components\",\n}\n`;\n\nexports[`should not owerwrite user DefinePlugin 1`] = `\nArray [\n  DefinePlugin {\n    \"definitions\": Object {\n      \"process.env.NODE_ENV\": \"\\\\\"test\\\\\"\",\n      \"process.env.STYLEGUIDIST_ENV\": \"\\\\\"development\\\\\"\",\n    },\n  },\n  DefinePlugin {\n    \"definitions\": Object {\n      \"process.env.PIZZA\": \"\\\\\"salami\\\\\"\",\n    },\n  },\n]\n`;\n\nexports[`should prepend requires as webpack entries 1`] = `\nArray [\n  \"a/b.js\",\n  \"c/d.css\",\n  \"~/src/client/index\",\n]\n`;\n\nexports[`should set aliases 1`] = `\nObject {\n  \"rsg-components\": \"~/src/client/rsg-components\",\n}\n`;\n\nexports[`should set aliases from moduleAliases option 1`] = `\nObject {\n  \"foo\": \"bar\",\n  \"rsg-components\": \"~/src/client/rsg-components\",\n}\n`;\n\nexports[`should set aliases from styleguideComponents option 1`] = `\nObject {\n  \"rsg-components\": \"~/src/client/rsg-components\",\n  \"rsg-components/foo\": \"bar\",\n}\n`;\n"
  },
  {
    "path": "src/scripts/__tests__/config.spec.ts",
    "content": "import fs from 'fs';\nimport path from 'path';\nimport { Configuration } from 'webpack';\nimport getConfig from '../config';\n\nconst testComponent = (name: string) => path.resolve(__dirname, '../../../test/components', name);\n\nconst cwd = process.cwd();\nconst configDir = path.resolve(__dirname, '../../../test/apps/defaults');\n\nbeforeEach(() => {\n\tprocess.chdir(configDir);\n});\nafterAll(() => {\n\tprocess.chdir(cwd);\n});\n\nit('should read a config file', () => {\n\tconst result = getConfig('../basic/styleguide.config.js');\n\texpect(result).toMatchObject({ title: 'React Style Guide Example' });\n});\n\nit('should accept absolute path', () => {\n\tconst result = getConfig(path.join(__dirname, '../../../test/apps/basic/styleguide.config.js'));\n\texpect(result).toMatchObject({ title: 'React Style Guide Example' });\n});\n\nit('should throw when passed config file not found', () => {\n\tconst fn = () => getConfig('pizza');\n\texpect(fn).toThrow();\n});\n\nit('should find config file automatically', () => {\n\tprocess.chdir('../basic');\n\tconst result = getConfig();\n\texpect(result).toMatchObject({ title: 'React Style Guide Example' });\n});\n\nit('should accept config as an object', () => {\n\tconst result = getConfig({\n\t\ttitle: 'Style guide',\n\t});\n\texpect(result).toMatchObject({ title: 'Style guide' });\n});\n\nit('should throw if config has errors', () => {\n\texpect.assertions(1);\n\ttry {\n\t\tgetConfig({\n\t\t\tcomponents: 42,\n\t\t} as any);\n\t} catch (err) {\n\t\tif (err instanceof Error) {\n\t\t\texpect(err.message).toMatch('should be string, function, or array');\n\t\t}\n\t}\n});\n\nit('should change the config using the update callback', () => {\n\tconst result = getConfig(\n\t\t{\n\t\t\ttitle: 'Style guide',\n\t\t},\n\t\t(config) => {\n\t\t\tconfig.title = 'Pizza';\n\t\t\treturn config;\n\t\t}\n\t);\n\texpect(result).toMatchObject({ title: 'Pizza' });\n});\n\nit('should have default getExampleFilename implementation', () => {\n\tconst result = getConfig();\n\texpect(typeof result.getExampleFilename).toEqual('function');\n});\n\nit('default getExampleFilename should return Readme.md path if it exists', () => {\n\tprocess.chdir('../..');\n\tconst result = getConfig();\n\texpect(result.getExampleFilename(testComponent('Button/Button.js'))).toEqual(\n\t\ttestComponent('Button/Readme.md')\n\t);\n});\n\nit('default getExampleFilename should return Component.md path if it exists', () => {\n\tprocess.chdir('../..');\n\tconst result = getConfig();\n\texpect(result.getExampleFilename(testComponent('Placeholder/Placeholder.js'))).toEqual(\n\t\ttestComponent('Placeholder/Placeholder.md')\n\t);\n});\n\nit('default getExampleFilename should return Component.md path if it exists with index.js', () => {\n\tprocess.chdir('../..');\n\tconst result = getConfig();\n\tresult.components = './components/**/*.js';\n\texpect(result.getExampleFilename(testComponent('Label/Label.js'))).toEqual(\n\t\ttestComponent('Label/Label.md')\n\t);\n});\n\nit('default getExampleFilename should return false if no examples file found', () => {\n\tprocess.chdir('../..');\n\tconst result = getConfig();\n\texpect(result.getExampleFilename(testComponent('RandomButton/RandomButton.js'))).toBeFalsy();\n});\n\nit('should have default getComponentPathLine implementation', () => {\n\tconst result = getConfig();\n\texpect(typeof result.getComponentPathLine).toEqual('function');\n\texpect(result.getComponentPathLine('components/Button.js')).toEqual('components/Button.js');\n});\n\nit('should have default title based on package.json name', () => {\n\tconst result = getConfig();\n\texpect(result.title).toEqual('Pizza Style Guide');\n});\n\nit('configDir option should be a directory of a passed config', () => {\n\tconst result = getConfig(path.join(configDir, 'styleguide.config.js'));\n\texpect(result).toMatchObject({ configDir });\n});\n\nit('configDir option should be a current directory if the config was passed as an object', () => {\n\tconst result = getConfig();\n\texpect(result).toMatchObject({ configDir: process.cwd() });\n});\n\nit('should absolutize assetsDir if it exists', () => {\n\tconst assetsDir = 'src/components';\n\tconst result = getConfig({\n\t\tassetsDir,\n\t});\n\texpect(result.assetsDir).toEqual(path.join(configDir, assetsDir));\n});\n\nit('should throw if assetsDir does not exist', () => {\n\tconst fn = () =>\n\t\tgetConfig({\n\t\t\tassetsDir: 'pizza',\n\t\t});\n\texpect(fn).toThrow();\n});\n\nit('should use embedded default example template if defaultExample=true', (done) => {\n\tconst result = getConfig({\n\t\tdefaultExample: true,\n\t});\n\texpect(typeof result.defaultExample).toEqual('string');\n\tif (typeof result.defaultExample === 'string') {\n\t\texpect(fs.existsSync(result.defaultExample)).toBeTruthy();\n\t} else {\n\t\tdone.fail();\n\t}\n\tdone();\n});\n\nit('should absolutize defaultExample if it is a string', () => {\n\tconst result = getConfig({\n\t\tdefaultExample: 'src/components/Button.md',\n\t});\n\texpect(result.defaultExample).toMatch(/^\\//);\n});\n\nit('should throw if defaultExample does not exist', () => {\n\texpect.assertions(1);\n\ttry {\n\t\tgetConfig({\n\t\t\tdefaultExample: 'pizza',\n\t\t});\n\t} catch (err) {\n\t\tif (err instanceof Error) {\n\t\t\texpect(err.message).toMatch('does not exist');\n\t\t}\n\t}\n});\n\nit('should use components option as the first sections if there’s no sections option', () => {\n\tconst components = 'components/*/*.js';\n\tconst result = getConfig({\n\t\tcomponents,\n\t});\n\texpect(result.sections).toHaveLength(1);\n\texpect(result.sections[0].components).toEqual(components);\n});\n\nit('should use default components option both components and sections options weren’t specified', () => {\n\tconst result = getConfig();\n\texpect(result.sections).toHaveLength(1);\n\texpect(result.sections[0].components).toMatch('**');\n});\n\nit('should ignore components option there’s sections options', () => {\n\tconst components = 'components/*/*.js';\n\tconst result = getConfig({\n\t\tcomponents: 'components/Button/*.js',\n\t\tsections: [\n\t\t\t{\n\t\t\t\tcomponents,\n\t\t\t},\n\t\t],\n\t});\n\texpect(result.sections).toHaveLength(1);\n\texpect(result.sections[0].components).toEqual(components);\n});\n\nit('should return webpackConfig option as is', () => {\n\tconst webpackConfig = { mode: 'development' } as Configuration;\n\tconst result = getConfig({\n\t\twebpackConfig,\n\t});\n\texpect(result.webpackConfig).toEqual(webpackConfig);\n});\n\nit('should return webpackConfig with user webpack config', () => {\n\tprocess.chdir('../basic');\n\tconst result = getConfig();\n\texpect(result.webpackConfig).toEqual(\n\t\texpect.objectContaining({\n\t\t\tmodule: {\n\t\t\t\trules: expect.any(Array),\n\t\t\t},\n\t\t})\n\t);\n});\n\nit('should allow no webpack config', () => {\n\tprocess.chdir('../no-webpack');\n\tconst fn = () => getConfig();\n\texpect(fn).not.toThrow();\n});\n\nit('should throw when old template as a string option passed', () => {\n\texpect.assertions(1);\n\ttry {\n\t\tgetConfig({\n\t\t\ttemplate: 'pizza',\n\t\t});\n\t} catch (err) {\n\t\tif (err instanceof Error) {\n\t\t\texpect(err.message).toMatch('format has been changed');\n\t\t}\n\t}\n});\n\nit('should throw when editorConfig option passed', () => {\n\texpect.assertions(1);\n\ttry {\n\t\tgetConfig({\n\t\t\teditorConfig: { theme: 'foo' },\n\t\t});\n\t} catch (err) {\n\t\tif (err instanceof Error) {\n\t\t\texpect(err.message).toMatch('config option was removed');\n\t\t}\n\t}\n});\n\nit('mountPointId should have default value', () => {\n\tconst result = getConfig();\n\texpect(result.mountPointId).toEqual('rsg-root');\n});\n\nit('mountPointId should have default value', () => {\n\tconst result = getConfig();\n\texpect(result.mountPointId).toEqual('rsg-root');\n});\n\nit('should set the exampleMode to expand if the flag showCode is on', () => {\n\tconst result = getConfig({\n\t\tshowCode: true,\n\t});\n\texpect(result.exampleMode).toBe('expand');\n});\n\nit('should set the exampleMode to collapse if the flag showCode is off', () => {\n\tconst result = getConfig({\n\t\tshowCode: false,\n\t});\n\texpect(result.exampleMode).toBe('collapse');\n});\n\nit('should set the usageMode to expand if the flag showUsage is on', () => {\n\tconst result = getConfig({\n\t\tshowUsage: true,\n\t});\n\texpect(result.usageMode).toBe('expand');\n});\n\nit('should set the usageMode to collapse if the flag showUsage is off', () => {\n\tconst result = getConfig({\n\t\tshowUsage: false,\n\t});\n\texpect(result.usageMode).toBe('collapse');\n});\n"
  },
  {
    "path": "src/scripts/__tests__/create-server.spec.ts",
    "content": "import { WebpackOptionsNormalized } from 'webpack';\nimport createServer from '../create-server';\nimport getConfig from '../config';\n\nconst cwd = process.cwd();\nafterEach(() => {\n\tprocess.chdir(cwd);\n});\n\ntest('createServer should return an object containing a server instance', () => {\n\tprocess.chdir('test/apps/basic');\n\tconst config = getConfig();\n\tconst result = createServer(config, 'production');\n\texpect(result).toBeTruthy();\n\texpect(result.app).toBeTruthy();\n});\n\ntest('createServer should support an array-valued assetsDir', (done) => {\n\tprocess.chdir('test/apps/basic');\n\tconst config = getConfig({\n\t\tassetsDir: ['src/components', 'src/components2'],\n\t});\n\tconst result = createServer(config, 'production');\n\texpect(result).toBeTruthy();\n\texpect(result.app).toBeTruthy();\n\tdone();\n});\n\ntest('createServer should return an object containing a production Webpack compiler', (done) => {\n\tprocess.chdir('test/apps/basic');\n\tconst config = getConfig();\n\tconst result = createServer(config, 'production');\n\texpect(result).toBeTruthy();\n\texpect(result.compiler).toBeTruthy();\n\tlet output: WebpackOptionsNormalized['output'];\n\tif (result.compiler && result.compiler.options && result.compiler.options.output) {\n\t\toutput = result.compiler.options.output;\n\t} else {\n\t\tdone.fail('no output');\n\t\treturn;\n\t}\n\texpect(output.filename).toBe('build/bundle.[chunkhash:8].js');\n\texpect(output.chunkFilename).toBe('build/[name].[chunkhash:8].js');\n\tdone();\n});\n\ntest('createServer should return an object containing a development Webpack compiler', (done) => {\n\tprocess.chdir('test/apps/basic');\n\tconst config = getConfig();\n\tconst result = createServer(config, 'development');\n\texpect(result).toBeTruthy();\n\texpect(result.compiler).toBeTruthy();\n\tlet output: WebpackOptionsNormalized['output'];\n\tif (result.compiler && result.compiler.options && result.compiler.options.output) {\n\t\toutput = result.compiler.options.output;\n\t} else {\n\t\tdone.fail('no output');\n\t\treturn;\n\t}\n\texpect(output.filename).toBe('build/[name].bundle.js');\n\texpect(output.chunkFilename).toBe('build/[name].js');\n\tdone();\n});\n\ntest('createServer should apply some base config options', () => {\n\tprocess.chdir('test/apps/basic');\n\tconst config = {\n\t\t...getConfig(),\n\t\tserverHost: 'localhost',\n\t\tserverPort: 6000,\n\t};\n\tconst result = createServer(config, 'development');\n\texpect(result).toBeTruthy();\n\texpect(result.compiler).toBeTruthy();\n\texpect(result.compiler.options.devServer).toMatchObject({\n\t\thost: 'localhost',\n\t\tport: 6000,\n\t\tcompress: true,\n\t\thot: true,\n\t\tclient: { logging: 'none' },\n\t\twebSocketServer: 'ws',\n\t});\n});\n\ntest('createServer should allow overriding default devServer options', () => {\n\tprocess.chdir('test/apps/basic');\n\tconst config = {\n\t\t...getConfig(),\n\t\twebpackConfig: {\n\t\t\tdevServer: {\n\t\t\t\tclient: {\n\t\t\t\t\toverlay: false,\n\t\t\t\t\tprogress: true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n\tconst result = createServer(config, 'development');\n\texpect(result).toBeTruthy();\n\texpect(result.compiler).toBeTruthy();\n\texpect(result.compiler.options.devServer).toMatchObject({\n\t\tclient: {\n\t\t\toverlay: false,\n\t\t\tprogress: true,\n\t\t},\n\t});\n});\n"
  },
  {
    "path": "src/scripts/__tests__/index.esm.spec.ts",
    "content": "/* eslint-disable @typescript-eslint/no-var-requires */\nimport { Configuration } from 'webpack';\nimport last from 'lodash/last';\nimport styleguidist from '../index.esm';\n\njest.mock('../build');\njest.mock('../server');\n\nconst getDefaultWebpackConfig = () => styleguidist().makeWebpackConfig();\n\nconst cwd = process.cwd();\nafterEach(() => {\n\tprocess.chdir(cwd);\n});\n\nit('should return API methods', () => {\n\tconst api = styleguidist(require('../../../test/data/styleguide.config.js'));\n\texpect(api).toBeTruthy();\n\texpect(typeof api.build).toBe('function');\n\texpect(typeof api.server).toBe('function');\n\texpect(typeof api.makeWebpackConfig).toBe('function');\n});\n\ndescribe('makeWebpackConfig', () => {\n\tit('should return development Webpack config', () => {\n\t\tconst api = styleguidist();\n\t\tconst result = api.makeWebpackConfig('development');\n\t\texpect(result).toBeTruthy();\n\t\texpect(result.output && result.output.filename).toBe('build/[name].bundle.js');\n\t\texpect(result.output && result.output.chunkFilename).toBe('build/[name].js');\n\t});\n\n\tit('should return production Webpack config', () => {\n\t\tconst api = styleguidist();\n\t\tconst result = api.makeWebpackConfig('production');\n\t\texpect(result).toBeTruthy();\n\t\texpect(result.output && result.output.filename).toBe('build/bundle.[chunkhash:8].js');\n\t\texpect(result.output && result.output.chunkFilename).toBe('build/[name].[chunkhash:8].js');\n\t});\n\n\tit('should merge webpackConfig config option', () => {\n\t\tconst defaultWebpackConfig = getDefaultWebpackConfig();\n\t\tconst api = styleguidist({\n\t\t\twebpackConfig: {\n\t\t\t\tresolve: {\n\t\t\t\t\textensions: ['.scss'],\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t\tconst result = api.makeWebpackConfig();\n\n\t\texpect(result).toBeTruthy();\n\t\texpect(result?.resolve?.extensions).toHaveLength(\n\t\t\t(defaultWebpackConfig?.resolve?.extensions?.length || 0) + 1\n\t\t);\n\t\texpect(last(result?.resolve?.extensions)).toEqual('.scss');\n\t});\n\n\tit('should merge webpackConfig but ignore output section', () => {\n\t\tconst defaultWebpackConfig = getDefaultWebpackConfig();\n\t\tconst api = styleguidist({\n\t\t\twebpackConfig: {\n\t\t\t\tresolve: {\n\t\t\t\t\textensions: ['.scss'],\n\t\t\t\t},\n\t\t\t\toutput: {\n\t\t\t\t\tfilename: 'broken.js',\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t\tconst result = api.makeWebpackConfig();\n\n\t\texpect(result.output && result.output.filename).toEqual(\n\t\t\tdefaultWebpackConfig.output && defaultWebpackConfig.output.filename\n\t\t);\n\t});\n\n\tit('should merge webpackConfig config option as a function', () => {\n\t\tconst api = styleguidist({\n\t\t\twebpackConfig: (env) =>\n\t\t\t\t({\n\t\t\t\t\tmode: env,\n\t\t\t\t} as Configuration),\n\t\t});\n\t\tconst result = api.makeWebpackConfig();\n\n\t\texpect(result).toBeTruthy();\n\t\texpect(result.mode).toEqual('production');\n\t});\n\n\tit('should apply updateWebpackConfig config option', () => {\n\t\tconst defaultWebpackConfig = getDefaultWebpackConfig();\n\t\tconst api = styleguidist({\n\t\t\tdangerouslyUpdateWebpackConfig: (webpackConfig, env) => {\n\t\t\t\tif (webpackConfig.resolve && webpackConfig.resolve.extensions) {\n\t\t\t\t\twebpackConfig.resolve.extensions.push(env);\n\t\t\t\t}\n\t\t\t\treturn webpackConfig;\n\t\t\t},\n\t\t});\n\t\tconst result = api.makeWebpackConfig();\n\n\t\texpect(result).toBeTruthy();\n\t\texpect(result?.resolve?.extensions).toHaveLength(\n\t\t\t(defaultWebpackConfig?.resolve?.extensions?.length || 0) + 1\n\t\t);\n\t\texpect(last(result?.resolve?.extensions)).toEqual('production');\n\t});\n\n\tit('should merge Create React App Webpack config', () => {\n\t\tprocess.chdir('test/apps/basic');\n\t\tconst api = styleguidist();\n\t\tconst result = api.makeWebpackConfig();\n\n\t\texpect(result).toBeTruthy();\n\t\texpect(result.module).toBeTruthy();\n\t});\n\n\tit('should add webpack entry for each require config option item', () => {\n\t\tconst modules = ['babel-polyfill', 'path/to/styles.css'];\n\t\tconst api = styleguidist({\n\t\t\trequire: modules,\n\t\t});\n\t\tconst result = api.makeWebpackConfig();\n\n\t\texpect(result.entry).toEqual(expect.arrayContaining(modules));\n\t});\n\n\tit('should add webpack alias for each styleguideComponents config option item', () => {\n\t\tconst api = styleguidist({\n\t\t\tstyleguideComponents: {\n\t\t\t\tWrapper: 'styleguide/components/Wrapper',\n\t\t\t\tStyleGuideRenderer: 'styleguide/components/StyleGuide',\n\t\t\t},\n\t\t});\n\t\tconst result = api.makeWebpackConfig();\n\n\t\texpect(result?.resolve?.alias).toMatchObject({\n\t\t\t'rsg-components/Wrapper': 'styleguide/components/Wrapper',\n\t\t\t'rsg-components/StyleGuide/StyleGuideRenderer': 'styleguide/components/StyleGuide',\n\t\t});\n\t});\n});\n\ndescribe('build', () => {\n\tit('should pass style guide config and stats to callback', () => {\n\t\tconst config = {\n\t\t\tcomponents: '*.js',\n\t\t};\n\t\tconst callback = jest.fn();\n\t\tconst api = styleguidist(config);\n\t\tapi.build(callback);\n\n\t\texpect(callback).toBeCalled();\n\t\texpect(callback.mock.calls[0][1].components).toBe(config.components);\n\t\texpect(callback.mock.calls[0][2]).toEqual({ stats: true });\n\t});\n});\n\ndescribe('server', () => {\n\tit('should pass style guide config to callback', () => {\n\t\tconst config = {\n\t\t\tcomponents: '*.js',\n\t\t};\n\t\tconst callback = jest.fn();\n\t\tconst api = styleguidist(config);\n\t\tapi.server(callback);\n\n\t\texpect(callback).toBeCalled();\n\t\texpect(callback.mock.calls[0][1].components).toBe(config.components);\n\t});\n});\n"
  },
  {
    "path": "src/scripts/__tests__/logger.spec.ts",
    "content": "import glogg from 'glogg';\nimport setupLogger from '../logger';\n\nconst logger = glogg('rsg');\nafterEach(() => {\n\tlogger.removeAllListeners();\n});\n\ntest('should setup custom logger function', () => {\n\tconst info = jest.fn();\n\tconst message = 'pizza';\n\tsetupLogger({ info }, false);\n\tlogger.info(message);\n\texpect(info).toBeCalledWith(message);\n});\n\ntest('should setup debug logger in verbose mode', () => {\n\tconst debug = jest.fn();\n\tconst message = 'pizza';\n\tsetupLogger({ debug }, true);\n\tlogger.debug(message);\n\texpect(debug).toBeCalledWith(message);\n});\n\ntest('should not setup debug logger in non-verbose mode', () => {\n\tconst debug = jest.fn();\n\tconst message = 'pizza';\n\tsetupLogger({ debug }, false);\n\tlogger.debug(message);\n\texpect(debug).toHaveBeenCalledTimes(0);\n});\n\ntest('should accept default loggers', () => {\n\tconst info = jest.fn();\n\tconst message = 'pizza';\n\tsetupLogger(undefined, false, { info });\n\tlogger.info(message);\n\texpect(info).toBeCalledWith(message);\n});\n"
  },
  {
    "path": "src/scripts/__tests__/make-webpack-config.spec.ts",
    "content": "import webpack, {\n\tCompiler,\n\tConfiguration,\n\tvalidate,\n\tValidationError,\n\tWebpackPluginInstance,\n} from 'webpack';\nimport CopyWebpackPlugin from 'copy-webpack-plugin';\nimport makeWebpackConfig from '../make-webpack-config';\nimport * as Rsg from '../../typings';\n\njest.mock('copy-webpack-plugin');\n\ntype WebpackPlugin = WebpackPluginInstance | ((this: Compiler, compiler: Compiler) => void) | '...';\n\nconst styleguideConfig = ({\n\tstyleguideDir: __dirname,\n\trequire: [],\n\ttitle: 'Style Guide',\n} as unknown) as Rsg.SanitizedStyleguidistConfig;\n\nconst getClasses = (plugins: WebpackPlugin[] = [], name: string): WebpackPlugin[] =>\n\tplugins.filter((x) => x.constructor.name === name);\n\nconst getClassNames = (plugins: WebpackPlugin[] = []): string[] =>\n\tplugins.map((x) => x.constructor.name);\n\nconst process$env$nodeEnv = process.env.NODE_ENV;\n\nbeforeEach(() => {\n\t((CopyWebpackPlugin as unknown) as jest.Mock).mockClear();\n});\n\nafterEach(() => {\n\tprocess.env.NODE_ENV = process$env$nodeEnv;\n});\n\nit('should return a development config', () => {\n\tconst env = 'development';\n\tconst config = makeWebpackConfig(styleguideConfig, env);\n\n\texpect(() => validate(config)).not.toThrow(ValidationError);\n\texpect(config).toMatchObject({\n\t\tmode: env,\n\t});\n\texpect(config).not.toHaveProperty('optimization');\n});\n\nit('should return a production config', () => {\n\tconst env = 'production';\n\tconst config = makeWebpackConfig(styleguideConfig, env);\n\texpect(() => validate(config)).not.toThrow(ValidationError);\n\n\tconst plugins = getClassNames(config.plugins);\n\texpect(plugins).toContain('CleanWebpackPlugin');\n\texpect(plugins).not.toContain('HotModuleReplacementPlugin');\n\n\texpect(config).toMatchObject({\n\t\toutput: {\n\t\t\tfilename: expect.stringContaining('[chunkhash'),\n\t\t\tchunkFilename: expect.stringContaining('[chunkhash'),\n\t\t},\n\t});\n\n\texpect(config).toMatchObject({\n\t\tmode: env,\n\t});\n\tconst result = getClasses(config.optimization && config.optimization.minimizer, 'TerserPlugin');\n\texpect(result).toHaveLength(1);\n});\n\nit('should set aliases', () => {\n\tconst result = makeWebpackConfig(styleguideConfig, 'development');\n\texpect(result.resolve && result.resolve.alias).toMatchSnapshot();\n});\n\nit('should set aliases from moduleAliases option', () => {\n\tconst result = makeWebpackConfig(\n\t\t{\n\t\t\t...styleguideConfig,\n\t\t\tmoduleAliases: {\n\t\t\t\tfoo: 'bar',\n\t\t\t},\n\t\t},\n\t\t'development'\n\t);\n\texpect(result.resolve && result.resolve.alias).toMatchSnapshot();\n});\n\nit('should set aliases from styleguideComponents option', () => {\n\tconst result = makeWebpackConfig(\n\t\t{\n\t\t\t...styleguideConfig,\n\t\t\tstyleguideComponents: {\n\t\t\t\tfoo: 'bar',\n\t\t\t},\n\t\t},\n\t\t'development'\n\t);\n\texpect(result.resolve && result.resolve.alias).toMatchSnapshot();\n});\n\nit('should prepend requires as webpack entries', () => {\n\tconst result = makeWebpackConfig(\n\t\t{ ...styleguideConfig, require: ['a/b.js', 'c/d.css'] },\n\t\t'development'\n\t);\n\texpect(result.entry).toMatchSnapshot();\n});\n\nit('should enable verbose mode in CleanWebpackPlugin', () => {\n\tconst result = makeWebpackConfig({ ...styleguideConfig, verbose: true }, 'production');\n\texpect((getClasses(result.plugins, 'CleanWebpackPlugin')[0] as any).verbose).toBe(true);\n});\n\nit('should set from with assetsDir in CopyWebpackPlugin', () => {\n\tmakeWebpackConfig({ ...styleguideConfig, assetsDir: '/assets/' }, 'production');\n\texpect(CopyWebpackPlugin).toHaveBeenCalledWith({\n\t\tpatterns: [{ from: '/assets/' }],\n\t});\n});\n\nit('should set array of from with assetsDir array in CopyWebpackPlugin', () => {\n\tmakeWebpackConfig({ ...styleguideConfig, assetsDir: ['/assets1/', '/assets2/'] }, 'production');\n\texpect(CopyWebpackPlugin).toHaveBeenCalledWith({\n\t\tpatterns: [{ from: '/assets1/' }, { from: '/assets2/' }],\n\t});\n});\n\nit('should merge user webpack config', () => {\n\tconst result = makeWebpackConfig(\n\t\t{ ...styleguideConfig, webpackConfig: { resolve: { alias: { foo: 'bar' } } } },\n\t\t'development'\n\t);\n\texpect(result.resolve && result.resolve.alias).toMatchSnapshot();\n});\n\nit('should not owerwrite user DefinePlugin', () => {\n\tconst result = makeWebpackConfig(\n\t\t{\n\t\t\t...styleguideConfig,\n\t\t\twebpackConfig: {\n\t\t\t\tplugins: [\n\t\t\t\t\tnew webpack.DefinePlugin({\n\t\t\t\t\t\t'process.env.PIZZA': JSON.stringify('salami'),\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t'development'\n\t);\n\n\t// Doesn’t really test that values won’t be overwritten, just that\n\t// DefinePlugin is applied twice. To write a real test we’d have to run\n\t// webpack\n\texpect(getClasses(result.plugins, 'DefinePlugin')).toMatchSnapshot();\n});\n\nit('should update webpack config', () => {\n\tconst extensions = ['.web.js', '.js'];\n\tconst result = makeWebpackConfig(\n\t\t{\n\t\t\t...styleguideConfig,\n\t\t\tdangerouslyUpdateWebpackConfig: (c: Configuration) => {\n\t\t\t\tif (c.resolve) {\n\t\t\t\t\tc.resolve.extensions = extensions;\n\t\t\t\t}\n\t\t\t\treturn c;\n\t\t\t},\n\t\t},\n\t\t'development'\n\t);\n\texpect(result.resolve && result.resolve.extensions).toEqual(extensions);\n});\n\nit('should pass template context to HTML plugin', () => {\n\tconst template = {\n\t\tpizza: 'salami',\n\t};\n\tconst result = makeWebpackConfig(\n\t\t{\n\t\t\t...styleguideConfig,\n\t\t\ttemplate,\n\t\t},\n\t\t'development'\n\t);\n\texpect(getClasses(result.plugins, 'MiniHtmlWebpackPlugin')[0]).toMatchObject({\n\t\toptions: {\n\t\t\tcontext: template,\n\t\t\ttemplate: expect.any(Function),\n\t\t},\n\t});\n});\n\nit('should pass template function to HTML plugin', () => {\n\tconst template = () => '<html />';\n\tconst result = makeWebpackConfig(\n\t\t{\n\t\t\t...styleguideConfig,\n\t\t\ttemplate,\n\t\t},\n\t\t'development'\n\t);\n\texpect(getClasses(result.plugins, 'MiniHtmlWebpackPlugin')[0]).toMatchObject({\n\t\toptions: {\n\t\t\tcontext: expect.any(Object),\n\t\t\ttemplate,\n\t\t},\n\t});\n});\n\nit('should update NODE_ENV', () => {\n\tprocess.env.NODE_ENV = '';\n\tmakeWebpackConfig(styleguideConfig, 'production');\n\texpect(process.env.NODE_ENV).toBe('production');\n});\n\nit('should not overwrite NODE_ENV', () => {\n\tmakeWebpackConfig(styleguideConfig, 'production');\n\texpect(process.env.NODE_ENV).toBe(process$env$nodeEnv);\n});\n\nit('should pass specified mountPointId to HTML plugin', () => {\n\tconst result = makeWebpackConfig(\n\t\t{\n\t\t\t...styleguideConfig,\n\t\t\tmountPointId: 'foo-bar',\n\t\t},\n\t\t'development'\n\t);\n\texpect(\n\t\t(getClasses(result.plugins, 'MiniHtmlWebpackPlugin')[0] as any).options.context.container\n\t).toEqual('foo-bar');\n});\n"
  },
  {
    "path": "src/scripts/__tests__/server.spec.ts",
    "content": "import server from '../server';\nimport getConfig from '../config';\n\njest.mock('../create-server', () => () => {\n\treturn {\n\t\tapp: {\n\t\t\tstartCallback: (cb: () => void) => cb(),\n\t\t\tclose: (cb: () => void) => cb(),\n\t\t},\n\t\tcompiler: {},\n\t};\n});\n\ntest('server should return an object containing a server instance', () => {\n\tconst config = getConfig();\n\tconst callback = jest.fn();\n\tconst serverInfo = server(config, callback);\n\n\texpect(callback).toBeCalled();\n\texpect(serverInfo.app).toBeTruthy();\n\texpect(serverInfo.compiler).toBeTruthy();\n\texpect(typeof serverInfo.app.startCallback).toBe('function');\n\texpect(typeof serverInfo.app.close).toBe('function');\n});\n"
  },
  {
    "path": "src/scripts/build.ts",
    "content": "import webpack from 'webpack';\nimport makeWebpackConfig from './make-webpack-config';\nimport * as Rsg from '../typings';\n\nexport default function build(\n\tconfig: Rsg.SanitizedStyleguidistConfig,\n\tcallback: (err: Error, stats: webpack.Stats) => void\n) {\n\treturn webpack(makeWebpackConfig(config, 'production'), (err, stats) => {\n\t\t// require('fs').writeFileSync('stats.json', JSON.stringify(stats.toJson()));\n\t\tcallback(err as Error, stats as webpack.Stats);\n\t});\n}\n"
  },
  {
    "path": "src/scripts/config.ts",
    "content": "import fs from 'fs';\nimport path from 'path';\nimport findup from 'findup';\nimport isString from 'lodash/isString';\nimport isPlainObject from 'lodash/isPlainObject';\nimport schema from './schemas/config';\nimport StyleguidistError from './utils/error';\nimport sanitizeConfig from './utils/sanitizeConfig';\nimport * as Rsg from '../typings';\n\nconst CONFIG_FILENAME = 'styleguide.config.js';\n\n/**\n * Try to find config file up the file tree.\n *\n * @return {string|boolean} Config absolute file path.\n */\nfunction findConfigFile(): string | false {\n\tlet configDir;\n\ttry {\n\t\tconfigDir = findup.sync(process.cwd(), CONFIG_FILENAME);\n\t} catch (exception) {\n\t\treturn false;\n\t}\n\n\treturn path.join(configDir, CONFIG_FILENAME);\n}\n\n/**\n * Read, parse and validate config file or passed config.\n *\n * @param {object|string} [config] All config options or config file name or nothing.\n * @param {function} [update] Change config object before running validation on it.\n * @returns {object}\n */\nfunction getConfig(\n\tconfig?: string | Rsg.StyleguidistConfig,\n\tupdate?: (conf: Rsg.StyleguidistConfig) => Rsg.StyleguidistConfig\n): Rsg.SanitizedStyleguidistConfig {\n\tlet configFilepath: string | false = false;\n\tif (isString(config)) {\n\t\t// Load config from a given file\n\t\tconfigFilepath = path.resolve(process.cwd(), config);\n\t\tif (!fs.existsSync(configFilepath)) {\n\t\t\tthrow new StyleguidistError('Styleguidist config not found: ' + configFilepath + '.');\n\t\t}\n\t\tconfig = {};\n\t} else if (!isPlainObject(config)) {\n\t\t// Try to read config options from a file\n\t\tconfigFilepath = findConfigFile();\n\t\tconfig = {};\n\t}\n\n\tif (configFilepath) {\n\t\tconfig = require(configFilepath);\n\t}\n\n\tif (!config || isString(config)) {\n\t\treturn {} as any;\n\t}\n\n\tif (update) {\n\t\tconfig = update(config);\n\t}\n\n\tconst configDir = configFilepath ? path.dirname(configFilepath) : process.cwd();\n\n\ttry {\n\t\treturn sanitizeConfig(config, schema, configDir) as any;\n\t} catch (exception) {\n\t\tif (exception instanceof StyleguidistError) {\n\t\t\tthrow new StyleguidistError(\n\t\t\t\t`Something is wrong with your style guide config\\n\\n${exception.message}`,\n\t\t\t\texception.extra\n\t\t\t);\n\t\t} else {\n\t\t\tthrow exception;\n\t\t}\n\t}\n}\n\nexport default getConfig;\n"
  },
  {
    "path": "src/scripts/consts.ts",
    "content": "export const HOMEPAGE = 'https://react-styleguidist.js.org/';\nexport const BUGS = 'https://github.com/styleguidist/react-styleguidist/issues';\nexport const DOCS_CONFIG = 'https://react-styleguidist.js.org/docs/configuration';\nexport const DOCS_COMPONENTS = 'https://react-styleguidist.js.org/docs/components';\nexport const DOCS_WEBPACK = 'https://react-styleguidist.js.org/docs/webpack';\nexport const DOCS_DOCUMENTING = 'https://react-styleguidist.js.org/docs/documenting';\nexport const DOCS_THIRDPARTIES = 'https://react-styleguidist.js.org/docs/thirdparties';\n"
  },
  {
    "path": "src/scripts/create-server.ts",
    "content": "import webpack from 'webpack';\nimport WebpackDevServer, { Configuration } from 'webpack-dev-server';\nimport makeWebpackConfig from './make-webpack-config';\nimport * as Rsg from '../typings';\n\nexport default function createServer(\n\tconfig: Rsg.SanitizedStyleguidistConfig,\n\tenv: 'development' | 'production' | 'none'\n): { app: WebpackDevServer; compiler: webpack.Compiler } {\n\tconst webpackConfig = makeWebpackConfig(config, env);\n\n\tconst baseConfig: Partial<Configuration> = {\n\t\thost: config.serverHost,\n\t\tport: config.serverPort,\n\t\tcompress: true,\n\t\thot: true,\n\t\tclient: {\n\t\t\tlogging: 'none',\n\t\t},\n\t\tstatic: Array.isArray(config.assetsDir)\n\t\t\t? config.assetsDir.map((assetsDir) => ({\n\t\t\t\t\tdirectory: assetsDir,\n\t\t\t\t\twatch: true,\n\t\t\t\t\tpublicPath: '/',\n\t\t\t  }))\n\t\t\t: {\n\t\t\t\t\tdirectory: config.assetsDir,\n\t\t\t\t\twatch: true,\n\t\t\t\t\tpublicPath: '/',\n\t\t\t  },\n\t\tdevMiddleware: {\n\t\t\tstats: webpackConfig.stats || {},\n\t\t},\n\t};\n\n\t// Allow custom devServer options to override base config.\n\twebpackConfig.devServer = {\n\t\t...baseConfig,\n\t\t...webpackConfig.devServer,\n\t};\n\n\tconst compiler = webpack(webpackConfig);\n\tconst devServer = new WebpackDevServer(webpackConfig.devServer, compiler);\n\n\t// User defined customizations\n\tif (config.configureServer) {\n\t\tconfig.configureServer((devServer as any).app, env);\n\t}\n\n\treturn { app: devServer, compiler };\n}\n"
  },
  {
    "path": "src/scripts/index.esm.ts",
    "content": "import webpack from 'webpack';\n// Make sure user has webpack installed\nimport './utils/ensureWebpack';\n\nimport makeWebpackConfig from './make-webpack-config';\nimport build from './build';\nimport server from './server';\nimport getConfig from './config';\nimport setupLogger from './logger';\nimport * as Rsg from '../typings';\n\n/**\n * Initialize Styleguide API.\n *\n * @param {object} [config] Styleguidist config.\n * @returns {object} API.\n */\nexport default function (configArg?: Rsg.StyleguidistConfig | string) {\n\tconst config = getConfig(configArg, (conf) => {\n\t\tsetupLogger(conf.logger as Record<string, (msg: string) => void>, conf.verbose, {});\n\t\treturn conf;\n\t});\n\n\treturn {\n\t\t/**\n\t\t * Build style guide.\n\t\t *\n\t\t * @param {Function} callback callback(err, config, stats).\n\t\t * @return {Compiler} Webpack Compiler instance.\n\t\t */\n\t\tbuild(\n\t\t\tcallback: (\n\t\t\t\terr: Error,\n\t\t\t\tstyleguidistConfig: Rsg.SanitizedStyleguidistConfig,\n\t\t\t\tstats: webpack.Stats\n\t\t\t) => void\n\t\t) {\n\t\t\treturn build(config, (err: Error, stats: webpack.Stats) => callback(err, config, stats));\n\t\t},\n\n\t\t/**\n\t\t * Start style guide dev server.\n\t\t *\n\t\t * @param {Function} callback callback(err, config).\n\t\t * @return {ServerInfo.App} Webpack-Dev-Server.\n\t\t * @return {ServerInfo.Compiler} Webpack Compiler instance.\n\t\t */\n\t\tserver(\n\t\t\tcallback: (\n\t\t\t\terr: Error | undefined,\n\t\t\t\tstyleguidistConfig: Rsg.SanitizedStyleguidistConfig\n\t\t\t) => void\n\t\t) {\n\t\t\treturn server(config, (err) => callback(err, config));\n\t\t},\n\n\t\t/**\n\t\t * Return Styleguidist Webpack config.\n\t\t *\n\t\t * @param {string} [env=production] 'production' or 'development'.\n\t\t * @return {object}\n\t\t */\n\t\tmakeWebpackConfig(env?: 'development' | 'production' | 'none') {\n\t\t\treturn makeWebpackConfig(config, env || 'production');\n\t\t},\n\t};\n}\n"
  },
  {
    "path": "src/scripts/index.ts",
    "content": "// eslint-disable-next-line @typescript-eslint/no-var-requires\nmodule.exports = require('./index.esm').default;\n\nexport * from '../typings';\n"
  },
  {
    "path": "src/scripts/logger.ts",
    "content": "/* eslint-disable no-console */\n\nimport _ from 'lodash/fp';\nimport kleur from 'kleur';\nimport loggerMaker from 'glogg';\n\nconst logger = loggerMaker('rsg');\n\nconst format = (message: string) => message.trim() + '\\n';\n\nconst printers: Record<string, (message: string) => void> = {\n\tinfo: (message: string) => console.log(format(message)),\n\twarn: (message: string) => console.warn(kleur.yellow(`Warning: ${format(message)}`)),\n\tdebug: (message: string) => console.log(format(message)),\n};\n\n/**\n * Setup up logger:\n * const logger = require('glogg')('rsg')\n * logger.info('Drinking coffee...')\n *\n * @param {Object} methods Custom methods\n * @param {bool} verbose Print debug messages\n * @param {Object} [defaults] Default methods\n */\nexport default function setupLogger(\n\tmethods?: Record<string, (message: string) => void>,\n\tverbose?: boolean,\n\tdefaults?: Record<string, (message: string) => void>\n) {\n\t_.flow(\n\t\t_.defaults(defaults || printers),\n\t\t_.omit(verbose ? [] : ['debug']),\n\t\t_.toPairs,\n\t\t_.forEach((printer: any[]) => logger.on(printer[0], printer[1]))\n\t)(methods);\n}\n"
  },
  {
    "path": "src/scripts/make-webpack-config.ts",
    "content": "import path from 'path';\nimport castArray from 'lodash/castArray';\nimport webpack, { Configuration, Resolver } from 'webpack';\nimport TerserPlugin from 'terser-webpack-plugin';\nimport { MiniHtmlWebpackPlugin } from 'mini-html-webpack-plugin';\nimport MiniHtmlWebpackTemplate from '@vxna/mini-html-webpack-template';\nimport { CleanWebpackPlugin } from 'clean-webpack-plugin';\nimport CopyWebpackPlugin from 'copy-webpack-plugin';\nimport merge from 'webpack-merge';\nimport forEach from 'lodash/forEach';\nimport isFunction from 'lodash/isFunction';\n\nimport StyleguidistOptionsPlugin from './utils/StyleguidistOptionsPlugin';\nimport mergeWebpackConfig from './utils/mergeWebpackConfig';\nimport * as Rsg from '../typings';\n\nconst RENDERER_REGEXP = /Renderer$/;\n\nconst sourceDir = path.resolve(__dirname, '../client');\n\ninterface AliasedConfiguration extends Configuration {\n\tresolve: Resolver['resolve'] & { alias: Record<string, string> };\n}\n\nexport default function (\n\tconfig: Rsg.SanitizedStyleguidistConfig,\n\tenv: 'development' | 'production' | 'none'\n): Configuration {\n\tprocess.env.NODE_ENV = process.env.NODE_ENV || env;\n\n\tconst isProd = env === 'production';\n\n\tconst template = isFunction(config.template) ? config.template : MiniHtmlWebpackTemplate;\n\tconst templateContext = isFunction(config.template) ? {} : config.template;\n\tconst htmlPluginOptions = {\n\t\tcontext: {\n\t\t\tlang: 'en',\n\t\t\t...templateContext,\n\t\t\ttitle: config.title,\n\t\t\tcontainer: config.mountPointId,\n\t\t},\n\t\ttemplate,\n\t};\n\n\tlet webpackConfig: Configuration = {\n\t\tentry: config.require.concat([path.resolve(sourceDir, 'index')]),\n\t\tmode: env,\n\t\toutput: {\n\t\t\tpath: config.styleguideDir,\n\t\t\tfilename: 'build/[name].bundle.js',\n\t\t\tchunkFilename: 'build/[name].js',\n\t\t\tpublicPath: '',\n\t\t},\n\t\tresolve: {\n\t\t\textensions: ['.wasm', '.mjs', '.js', '.jsx', '.ts', '.tsx', '.json'],\n\t\t\talias: {},\n\t\t},\n\t\tplugins: [\n\t\t\tnew StyleguidistOptionsPlugin(config),\n\t\t\tnew MiniHtmlWebpackPlugin(htmlPluginOptions),\n\t\t\tnew webpack.DefinePlugin({\n\t\t\t\t'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),\n\t\t\t\t'process.env.STYLEGUIDIST_ENV': JSON.stringify(env),\n\t\t\t}),\n\t\t],\n\t\tperformance: {\n\t\t\thints: false,\n\t\t},\n\t};\n\n\tif (isProd) {\n\t\tconst minimizer = new TerserPlugin({\n\t\t\tterserOptions: {\n\t\t\t\tie8: false,\n\t\t\t\tecma: 5,\n\t\t\t\tcompress: {\n\t\t\t\t\tkeep_fnames: true,\n\t\t\t\t\twarnings: false,\n\t\t\t\t\t/*\n\t\t\t\t\t * Disable reduce_funcs to keep Terser from inlining\n\t\t\t\t\t * Preact's VNode. If enabled, the 'new VNode()' is replaced\n\t\t\t\t\t * with a anonymous 'function(){}', which is problematic for\n\t\t\t\t\t * preact-compat, since it extends the VNode prototype to\n\t\t\t\t\t * accomodate React's API.\n\t\t\t\t\t */\n\t\t\t\t\treduce_funcs: false,\n\t\t\t\t},\n\t\t\t\tmangle: {\n\t\t\t\t\tkeep_fnames: true,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t\twebpackConfig = merge(webpackConfig, {\n\t\t\toutput: {\n\t\t\t\tfilename: 'build/bundle.[chunkhash:8].js',\n\t\t\t\tchunkFilename: 'build/[name].[chunkhash:8].js',\n\t\t\t},\n\t\t\tplugins: [\n\t\t\t\tnew CleanWebpackPlugin({\n\t\t\t\t\tcleanOnceBeforeBuildPatterns: [`${config.styleguideDir}/build/**/*`],\n\t\t\t\t\tverbose: config.verbose === true,\n\t\t\t\t}),\n\t\t\t],\n\t\t\toptimization: {\n\t\t\t\tminimize: config.minimize === true,\n\t\t\t\tminimizer: [minimizer],\n\t\t\t},\n\t\t});\n\t\tif (config.assetsDir && webpackConfig.plugins) {\n\t\t\tconst copyPatterns = {\n\t\t\t\tpatterns: castArray(config.assetsDir).map((dir) => ({ from: dir })),\n\t\t\t};\n\t\t\twebpackConfig.plugins.push(\n\t\t\t\t// FIXME: Since we don't have the type of copy-webpack-plugin@6.0\n\t\t\t\t// we cast the config as any to make it work. Once the new types are\n\t\t\t\t// released we must remove the cast.\n\t\t\t\tnew CopyWebpackPlugin(copyPatterns as any)\n\t\t\t);\n\t\t}\n\t} else {\n\t\twebpackConfig = merge(webpackConfig, {\n\t\t\tdevServer: {\n\t\t\t\twebSocketServer: 'ws',\n\t\t\t},\n\t\t});\n\t}\n\n\tif (config.webpackConfig) {\n\t\twebpackConfig = mergeWebpackConfig(webpackConfig, config.webpackConfig, env);\n\t}\n\n\t// Custom aliases\n\t// NOTE: in a sanitized config, moduleAliases are always an object (never null or undefined)\n\tconst aliasedWebpackConfig = merge(webpackConfig, {\n\t\tresolve: { alias: config.moduleAliases },\n\t}) as AliasedConfiguration;\n\n\tconst alias = aliasedWebpackConfig.resolve.alias;\n\n\t// Custom style guide components\n\tif (config.styleguideComponents) {\n\t\tforEach(config.styleguideComponents, (filepath, name) => {\n\t\t\tconst fullName = name.match(RENDERER_REGEXP)\n\t\t\t\t? `${name.replace(RENDERER_REGEXP, '')}/${name}`\n\t\t\t\t: name;\n\t\t\talias[`rsg-components/${fullName}`] = filepath;\n\t\t});\n\t}\n\n\t// Add components folder alias at the end, so users can override our components\n\t// to customize the style guide (their aliases should be before this one)\n\talias['rsg-components'] = path.resolve(sourceDir, 'rsg-components');\n\n\twebpackConfig = config.dangerouslyUpdateWebpackConfig\n\t\t? config.dangerouslyUpdateWebpackConfig(aliasedWebpackConfig, env)\n\t\t: aliasedWebpackConfig;\n\n\treturn webpackConfig;\n}\n"
  },
  {
    "path": "src/scripts/schemas/config.ts",
    "content": "// If you want to access any of these options in React, don’t forget to update CLIENT_CONFIG_OPTIONS array\n// in loaders/styleguide-loader.js\n\nimport glogg from 'glogg';\nimport path from 'path';\nimport startCase from 'lodash/startCase';\nimport kleur from 'kleur';\nimport * as reactDocgen from 'react-docgen';\nimport { TransformOptions } from 'buble';\nimport { createDisplayNameHandler } from 'react-docgen-displayname-handler';\nimport annotationResolver from 'react-docgen-annotation-resolver';\nimport { ASTNode } from 'ast-types';\nimport { NodePath } from 'ast-types/lib/node-path';\nimport findUserWebpackConfig from '../utils/findUserWebpackConfig';\nimport getUserPackageJson from '../utils/getUserPackageJson';\nimport fileExistsCaseInsensitive from '../utils/findFileCaseInsensitive';\nimport StyleguidistError from '../utils/error';\nimport * as consts from '../consts';\nimport * as Rsg from '../../typings';\n\nconst EXTENSIONS = 'js,jsx,ts,tsx';\nconst DEFAULT_COMPONENTS_PATTERN =\n\t// HACK: on windows, the case insensitivity makes each component appear twice\n\t// to avoid this issue, the case management is removed on win32\n\t// it virtually changes nothing\n\tprocess.platform === 'win32'\n\t\t? /* istanbul ignore next: no windows on our test plan */ `src/components/**/*.{${EXTENSIONS}}`\n\t\t: `src/@(components|Components)/**/*.{${EXTENSIONS}}`;\n\nconst logger = glogg('rsg');\n\ntype NestedThemeValue = Record<string, unknown> | string;\n\nexport type StyleguidistConfigKey = keyof Rsg.SanitizedStyleguidistConfig;\n\nexport interface ConfigSchemaOptions<T> {\n\tprocess?(value: any, config: T, rootDir: string): any;\n\tdefault?: any;\n\trequired?: boolean | ((config?: T) => string | boolean);\n\tdeprecated?: string;\n\tremoved?: string;\n\ttype?: string | string[];\n\texample?: any;\n}\n\nconst configSchema: Record<StyleguidistConfigKey, ConfigSchemaOptions<Rsg.StyleguidistConfig>> = {\n\tassetsDir: {\n\t\ttype: ['array', 'existing directory path'],\n\t\texample: 'assets',\n\t},\n\ttocMode: {\n\t\ttype: 'string',\n\t\tdefault: 'expand',\n\t},\n\tcompilerConfig: {\n\t\ttype: 'object',\n\t\tdefault: {\n\t\t\t// Don't include an Object.assign ponyfill, we have our own\n\t\t\tobjectAssign: 'Object.assign',\n\t\t\t// Transpile only features needed for IE11\n\t\t\ttarget: { ie: 11 },\n\t\t\ttransforms: {\n\t\t\t\t// Don't throw on ESM imports, we transpile them ourselves\n\t\t\t\tmodules: false,\n\t\t\t\t// Enable tagged template literals for styled-components\n\t\t\t\tdangerousTaggedTemplateString: true,\n\t\t\t\t// to make async/await work by default (no transformation)\n\t\t\t\tasyncAwait: false,\n\t\t\t},\n\t\t} as TransformOptions,\n\t},\n\t// `components` is a shortcut for { sections: [{ components }] },\n\t// see `sections` below\n\tcomponents: {\n\t\ttype: ['string', 'function', 'array'],\n\t\texample: 'components/**/[A-Z]*.js',\n\t},\n\tconfigDir: {\n\t\tprocess: (value: string, config: Rsg.StyleguidistConfig, rootDir: string): string => rootDir,\n\t},\n\tcontext: {\n\t\ttype: 'object',\n\t\tdefault: {},\n\t\texample: {\n\t\t\tmap: 'lodash/map',\n\t\t},\n\t},\n\tcontextDependencies: {\n\t\ttype: 'array',\n\t},\n\tconfigureServer: {\n\t\ttype: 'function',\n\t},\n\tdangerouslyUpdateWebpackConfig: {\n\t\ttype: 'function',\n\t},\n\tdefaultExample: {\n\t\ttype: ['boolean', 'existing file path'],\n\t\tdefault: false,\n\t\tprocess: (val: boolean | string): string | boolean =>\n\t\t\tval === true ? path.resolve(__dirname, '../../../templates/DefaultExample.md') : val,\n\t},\n\texampleMode: {\n\t\ttype: 'string',\n\t\tprocess: (value: string, config: Rsg.StyleguidistConfig): string => {\n\t\t\treturn config.showCode === undefined ? value : config.showCode ? 'expand' : 'collapse';\n\t\t},\n\t\tdefault: 'collapse',\n\t},\n\tgetComponentPathLine: {\n\t\ttype: 'function',\n\t\tdefault: (componentPath: string): string => componentPath,\n\t},\n\tgetExampleFilename: {\n\t\ttype: 'function',\n\t\tdefault: (componentPath: string): string | boolean => {\n\t\t\tconst files = [\n\t\t\t\tpath.join(path.dirname(componentPath), 'Readme.md'),\n\t\t\t\t// ComponentName.md\n\t\t\t\tcomponentPath.replace(path.extname(componentPath), '.md'),\n\t\t\t\t// FolderName.md when component definition file is index.js\n\t\t\t\tpath.join(path.dirname(componentPath), path.basename(path.dirname(componentPath)) + '.md'),\n\t\t\t];\n\t\t\tfor (const file of files) {\n\t\t\t\tconst existingFile = fileExistsCaseInsensitive(file);\n\t\t\t\tif (existingFile) {\n\t\t\t\t\treturn existingFile;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t},\n\thandlers: {\n\t\ttype: 'function',\n\t\tdefault: (componentPath: string): reactDocgen.Handler[] =>\n\t\t\treactDocgen.defaultHandlers.concat(createDisplayNameHandler(componentPath)),\n\t},\n\tignore: {\n\t\ttype: 'array',\n\t\tdefault: [\n\t\t\t'**/__tests__/**',\n\t\t\t`**/*.test.{${EXTENSIONS}}`,\n\t\t\t`**/*.spec.{${EXTENSIONS}}`,\n\t\t\t'**/*.d.ts',\n\t\t],\n\t},\n\teditorConfig: {\n\t\tprocess: (value?: unknown): void => {\n\t\t\tif (value) {\n\t\t\t\tthrow new StyleguidistError(\n\t\t\t\t\t`${kleur.bold(\n\t\t\t\t\t\t'editorConfig'\n\t\t\t\t\t)} config option was removed. Use “theme” option to change syntax highlighting.`\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t},\n\tlogger: {\n\t\ttype: 'object',\n\t},\n\tminimize: {\n\t\ttype: 'boolean',\n\t\tdefault: true,\n\t},\n\tmoduleAliases: {\n\t\ttype: 'object',\n\t},\n\tmountPointId: {\n\t\ttype: 'string',\n\t\tdefault: 'rsg-root',\n\t},\n\tpagePerSection: {\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t},\n\tpreviewDelay: {\n\t\ttype: 'number',\n\t\tdefault: 500,\n\t},\n\tprintBuildInstructions: {\n\t\ttype: 'function',\n\t},\n\tprintServerInstructions: {\n\t\ttype: 'function',\n\t},\n\tpropsParser: {\n\t\ttype: 'function',\n\t},\n\trequire: {\n\t\ttype: 'array',\n\t\tdefault: [],\n\t\texample: ['babel-polyfill', 'path/to/styles.css'],\n\t},\n\tresolver: {\n\t\ttype: 'function',\n\t\tdefault: (\n\t\t\tast: ASTNode,\n\t\t\trecast: {\n\t\t\t\tvisit: (\n\t\t\t\t\tnode: NodePath,\n\t\t\t\t\thandlers: { [handlerName: string]: () => boolean | undefined }\n\t\t\t\t) => void;\n\t\t\t}\n\t\t) => {\n\t\t\tconst findAllExportedComponentDefinitions =\n\t\t\t\treactDocgen.resolver.findAllExportedComponentDefinitions;\n\t\t\tconst annotatedComponents = annotationResolver(ast, recast);\n\t\t\tconst exportedComponents = findAllExportedComponentDefinitions(ast, recast);\n\t\t\treturn annotatedComponents.concat(exportedComponents);\n\t\t},\n\t},\n\tribbon: {\n\t\ttype: 'object',\n\t\texample: {\n\t\t\turl: 'http://example.com/',\n\t\t\ttext: 'Fork me on GitHub',\n\t\t},\n\t},\n\tsections: {\n\t\ttype: 'array',\n\t\tdefault: [],\n\t\tprocess: (val: Rsg.ConfigSection[], config: Rsg.StyleguidistConfig): Rsg.ConfigSection[] => {\n\t\t\tif (!val) {\n\t\t\t\t// If root `components` isn't empty, make it a first section\n\t\t\t\t// If `components` and `sections` weren’t specified, use default pattern\n\t\t\t\tconst components = config.components || DEFAULT_COMPONENTS_PATTERN;\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tcomponents,\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn val;\n\t\t},\n\t\texample: [\n\t\t\t{\n\t\t\t\tname: 'Documentation',\n\t\t\t\tcontent: 'Readme.md',\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'Components',\n\t\t\t\tcomponents: './lib/components/**/[A-Z]*.js',\n\t\t\t},\n\t\t],\n\t},\n\tserverHost: {\n\t\ttype: 'string',\n\t\tdefault: '0.0.0.0',\n\t},\n\tserverPort: {\n\t\ttype: 'number',\n\t\tdefault: parseInt(process.env.NODE_PORT as string) || 6060,\n\t},\n\tshowCode: {\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t\tdeprecated: 'Use exampleMode option instead',\n\t},\n\tshowUsage: {\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t\tdeprecated: 'Use usageMode option instead',\n\t},\n\tshowSidebar: {\n\t\ttype: 'boolean',\n\t\tdefault: true,\n\t},\n\tskipComponentsWithoutExample: {\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t},\n\tsortProps: {\n\t\ttype: 'function',\n\t},\n\tstyleguideComponents: {\n\t\ttype: 'object',\n\t},\n\tstyleguideDir: {\n\t\ttype: 'directory path',\n\t\tdefault: 'styleguide',\n\t},\n\tstyles: {\n\t\ttype: ['object', 'existing file path', 'function'],\n\t\tdefault: {},\n\t\texample: {\n\t\t\tLogo: {\n\t\t\t\tlogo: {\n\t\t\t\t\tfontStyle: 'italic',\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tprocess: (val: NestedThemeValue, config: unknown, configDir: string): NestedThemeValue => {\n\t\t\treturn typeof val === 'string' ? path.resolve(configDir, val) : val;\n\t\t},\n\t},\n\ttemplate: {\n\t\ttype: ['object', 'function'],\n\t\tdefault: {},\n\t\tprocess: (val: any) => {\n\t\t\tif (typeof val === 'string') {\n\t\t\t\tthrow new StyleguidistError(\n\t\t\t\t\t`${kleur.bold(\n\t\t\t\t\t\t'template'\n\t\t\t\t\t)} config option format has been changed, you need to update your config.`,\n\t\t\t\t\t'template'\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn val;\n\t\t},\n\t},\n\ttheme: {\n\t\ttype: ['object', 'existing file path'],\n\t\tdefault: {},\n\t\texample: {\n\t\t\tlink: 'firebrick',\n\t\t\tlinkHover: 'salmon',\n\t\t},\n\t\tprocess: (val: NestedThemeValue, config: unknown, configDir: string): NestedThemeValue =>\n\t\t\ttypeof val === 'string' ? path.resolve(configDir, val) : val,\n\t},\n\ttitle: {\n\t\ttype: 'string',\n\t\tprocess: (val?: string): string => {\n\t\t\tif (val) {\n\t\t\t\treturn val;\n\t\t\t}\n\t\t\tconst name = getUserPackageJson().name || '';\n\t\t\treturn `${startCase(name)} Style Guide`;\n\t\t},\n\t\texample: 'My Style Guide',\n\t},\n\tupdateDocs: {\n\t\ttype: 'function',\n\t},\n\tupdateExample: {\n\t\ttype: 'function',\n\t\tdefault: (props: { lang: string }): { lang: string } => {\n\t\t\tif (props.lang === 'example') {\n\t\t\t\tprops.lang = 'js';\n\t\t\t\tlogger.warn(\n\t\t\t\t\t'\"example\" code block language is deprecated. Use \"js\", \"jsx\" or \"javascript\" instead:\\n' +\n\t\t\t\t\t\tconsts.DOCS_DOCUMENTING\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn props;\n\t\t},\n\t},\n\tupdateWebpackConfig: {\n\t\ttype: 'function',\n\t\tremoved: `Use \"webpackConfig\" option instead:\\n${consts.DOCS_WEBPACK}`,\n\t},\n\tusageMode: {\n\t\ttype: 'string',\n\t\tprocess: (value: string, config: Rsg.StyleguidistConfig) => {\n\t\t\treturn config.showUsage === undefined ? value : config.showUsage ? 'expand' : 'collapse';\n\t\t},\n\t\tdefault: 'collapse',\n\t},\n\tverbose: {\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t},\n\tversion: {\n\t\ttype: 'string',\n\t},\n\twebpackConfig: {\n\t\ttype: ['object', 'function'],\n\t\tprocess: (val?: any) => {\n\t\t\tif (val) {\n\t\t\t\treturn val;\n\t\t\t}\n\n\t\t\tconst file = findUserWebpackConfig();\n\t\t\tif (file) {\n\t\t\t\tlogger.info(`Loading webpack config from:\\n${file}`);\n\t\t\t\t// eslint-disable-next-line import/no-dynamic-require\n\t\t\t\treturn require(file);\n\t\t\t}\n\n\t\t\tlogger.warn(\n\t\t\t\t'No webpack config found. ' +\n\t\t\t\t\t'You may need to specify \"webpackConfig\" option in your style guide config:\\n' +\n\t\t\t\t\tconsts.DOCS_WEBPACK\n\t\t\t);\n\n\t\t\treturn undefined;\n\t\t},\n\t\texample: {\n\t\t\tmodule: {\n\t\t\t\trules: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\t\t\texclude: /node_modules/,\n\t\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t},\n};\n\nexport default configSchema;\n"
  },
  {
    "path": "src/scripts/server.ts",
    "content": "import WebpackDevServer from 'webpack-dev-server';\nimport webpack from 'webpack';\nimport createServer from './create-server';\nimport * as Rsg from '../typings';\n\nexport default function server(\n\tconfig: Rsg.SanitizedStyleguidistConfig,\n\tcallback: (error?: Error) => void\n): { app: WebpackDevServer; compiler: webpack.Compiler } {\n\tconst env = 'development';\n\tconst serverInfo = createServer(config, env);\n\n\tserverInfo.app.startCallback(callback);\n\n\treturn serverInfo;\n}\n"
  },
  {
    "path": "src/scripts/utils/StyleguidistOptionsPlugin.ts",
    "content": "import webpack, { Compilation, Compiler, WebpackPluginInstance, LoaderContext } from 'webpack';\n\nimport * as Rsg from '../../typings';\n\n// Webpack plugin that makes Styleguidist config available for Styleguidist webpack loaders.\n// It will be available as `this._styleguidist`.\n//\n// Other working in webpack 2 way is to use LoaderOptionsPlugin, but it has problems.\n// See this issue for details: https://github.com/styleguidist/react-styleguidist/issues/328\n\nexport default class StyleguidistOptionsPlugin implements WebpackPluginInstance {\n\tprivate options: Rsg.SanitizedStyleguidistConfig;\n\n\tpublic constructor(options: Rsg.SanitizedStyleguidistConfig) {\n\t\tthis.options = options;\n\t}\n\n\tprivate pluginFunc = (\n\t\tcontext: Rsg.StyleguidistLoaderContext,\n\t\tmodule: LoaderContext<Rsg.SanitizedStyleguidistConfig>\n\t) => {\n\t\tif (!module.resource) {\n\t\t\treturn;\n\t\t}\n\t\tcontext._styleguidist = this.options;\n\t};\n\n\t/**\n\t *\n\t * @param compil Compilation\n\t */\n\tprivate plugin = (compil: Compilation) => {\n\t\twebpack.NormalModule.getCompilationHooks(compil).loader.tap(\n\t\t\t'StyleguidistOptionsPlugin',\n\t\t\tthis.pluginFunc as any\n\t\t);\n\t};\n\n\tpublic apply(compiler: Compiler) {\n\t\tcompiler.hooks.compilation.tap('StyleguidistOptionsPlugin', this.plugin);\n\t}\n}\n"
  },
  {
    "path": "src/scripts/utils/__tests__/StyleguidistOptionsPlugin.spec.ts",
    "content": "import StyleguidistOptionsPlugin from '../StyleguidistOptionsPlugin';\nimport * as Rsg from '../../../typings';\n\nconst options: any = {\n\tfoo: 42,\n};\nconst mockContext: { _styleguidist?: Rsg.StyleguidistConfig } = {};\n\nlet mockedModule: Record<string, unknown>;\n\njest.mock('webpack', () => {\n\treturn {\n\t\tNormalModule: {\n\t\t\tgetCompilationHooks: () => {\n\t\t\t\treturn {\n\t\t\t\t\tloader: {\n\t\t\t\t\t\ttap: (moduleName: string, compilationCallback: (context: any, opt: any) => void) => {\n\t\t\t\t\t\t\tcompilationCallback(mockContext, mockedModule);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t};\n});\n\nit('should do nothing when module.resource is not present', () => {\n\tmockedModule = {};\n\tconst compiler = {\n\t\thooks: {\n\t\t\tcompilation: {\n\t\t\t\ttap: (name: string, callback: (opt: any) => void) => {\n\t\t\t\t\tcallback({});\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n\tconst plugin = new StyleguidistOptionsPlugin(options);\n\tplugin.apply(compiler as any);\n\texpect(mockContext._styleguidist).toBeFalsy();\n});\n\nit('should attach Styleguidist config options', () => {\n\tmockedModule = { resource: 'test' };\n\tconst compiler = {\n\t\thooks: {\n\t\t\tcompilation: {\n\t\t\t\ttap: (name: string, callback: (opt: any) => void) => {\n\t\t\t\t\tcallback({});\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n\tconst plugin = new StyleguidistOptionsPlugin(options);\n\tplugin.apply(compiler as any);\n\texpect(mockContext._styleguidist).toEqual(options);\n});\n"
  },
  {
    "path": "src/scripts/utils/__tests__/findFileCaseInsensitive.spec.ts",
    "content": "import path from 'path';\nimport findFileCaseInsensitive, { clearCache } from '../findFileCaseInsensitive';\n\nit('should return a file path with the correct case if a file exists', () => {\n\tconst result = findFileCaseInsensitive(path.join(__dirname, 'Findfilecaseinsensitive.Spec.TS'));\n\texpect(result).toMatch(__filename);\n});\n\nit('should return undefined if a file doesn’t exist', () => {\n\tconst result = findFileCaseInsensitive(path.join(__dirname, 'pizza.js'));\n\texpect(result).toBeFalsy();\n});\n\nit('cache clean function shouldn’t throw', () => {\n\tconst fn = () => clearCache();\n\texpect(fn).not.toThrowError();\n});\n"
  },
  {
    "path": "src/scripts/utils/__tests__/findUserWebpackConfig.spec.ts",
    "content": "import findUserWebpackConfig from '../findUserWebpackConfig';\n\nconst cwd = process.cwd();\nafterEach(() => process.chdir(cwd));\n\nit('should return path to Create React App Webpack old config (react-scripts <= 2.1.1)', () => {\n\tconst result = findUserWebpackConfig(a => a);\n\texpect(result).toMatchInlineSnapshot(`\"react-scripts/config/webpack.config.dev\"`);\n});\n\nit('should return path to Create React App Webpack config (react-scripts > 2.1.1)', () => {\n\tconst result = findUserWebpackConfig(a => {\n\t\tif (/webpack\\.config\\.dev/.test(a)) {\n\t\t\t// Simulate an error. For example, if the file doesn't exist.\n\t\t\tthrow new Error();\n\t\t}\n\t\treturn a;\n\t});\n\texpect(result).toMatchInlineSnapshot(`\"react-scripts/config/webpack.config\"`);\n});\n\nit('should return an absolute path to user Webpack config located in project root folder', () => {\n\tprocess.chdir('test/apps/basic');\n\n\tconst result = findUserWebpackConfig();\n\texpect(result).toMatch(/^\\//);\n\texpect(result).toMatch(/webpack.config.js$/);\n});\n\nit('should return false if there is no webpack config', () => {\n\tprocess.chdir('test/apps/no-webpack');\n\n\tconst result = findUserWebpackConfig();\n\texpect(result).toBeFalsy();\n});\n"
  },
  {
    "path": "src/scripts/utils/__tests__/getUserPackageJson.spec.ts",
    "content": "import getUserPackageJson from '../getUserPackageJson';\n\nconst cwd = process.cwd();\nafterEach(() => {\n\tprocess.chdir(cwd);\n});\n\nit('should return object with package.json contents', () => {\n\tprocess.chdir('test/apps/cra');\n\tconst result = getUserPackageJson();\n\texpect(result).toBeTruthy();\n\texpect(result.name).toBe('pizza-cra');\n});\n"
  },
  {
    "path": "src/scripts/utils/__tests__/getWebpackVersion.spec.ts",
    "content": "import getWebpackVersion from '../getWebpackVersion';\n\nit('should return version number', () => {\n\tconst result = getWebpackVersion();\n\texpect(result).toBeGreaterThanOrEqual(1);\n});\n"
  },
  {
    "path": "src/scripts/utils/__tests__/mergeWebpackConfig.spec.ts",
    "content": "import mergeWebpackConfig from '../mergeWebpackConfig';\n\nclass TerserPlugin {\n\tpublic apply() {}\n}\nclass MyPlugin {\n\tpublic apply() {}\n}\nclass MiniHtmlWebpackPlugin {\n\tpublic apply() {}\n}\n\nit('should merge two objects', () => {\n\tconst result = mergeWebpackConfig(\n\t\t{ entry: 'main.js', devtool: 'cheap-source-map' },\n\t\t{ devtool: 'inline-source-map' }\n\t);\n\texpect(result).toEqual({ entry: 'main.js', devtool: 'cheap-source-map' });\n});\n\nit('should merge an object and a function', () => {\n\tconst result = mergeWebpackConfig({ entry: 'main.js', devtool: 'cheap-source-map' }, () => ({\n\t\tdevtool: 'inline-source-map',\n\t}));\n\texpect(result).toEqual({ entry: 'main.js', devtool: 'cheap-source-map' });\n});\n\nit('should pass an environment to a user config', () => {\n\tconst env = 'production';\n\tconst userConfig = jest.fn();\n\tmergeWebpackConfig({}, userConfig, env);\n\texpect(userConfig).toBeCalledWith(env);\n});\n\nit('should ignore certain sections', () => {\n\tconst result = mergeWebpackConfig({ entry: 'main' }, () => ({\n\t\tentry: 'other',\n\t\tmodule: { rules: [] },\n\t}));\n\texpect(result).toEqual({ entry: 'main', module: { rules: [] } });\n});\n\nit('should ignore certain Webpack plugins', done => {\n\tconst baseInstance = new TerserPlugin();\n\tconst userInstance = new TerserPlugin();\n\tconst result = mergeWebpackConfig(\n\t\t{\n\t\t\tplugins: [baseInstance],\n\t\t},\n\t\t{\n\t\t\tplugins: [userInstance, new MyPlugin(), new MiniHtmlWebpackPlugin()],\n\t\t}\n\t);\n\t// this test is necessary as some results can contain no plugins\n\tif (!result || !result.plugins) {\n\t\tdone.fail();\n\t\treturn;\n\t}\n\texpect(result.plugins).toHaveLength(2);\n\texpect(result.plugins[0]).toBe(baseInstance);\n\texpect(result.plugins[0].constructor.name).toBe('TerserPlugin');\n\texpect(result.plugins[1].constructor.name).toBe('MyPlugin');\n\tdone();\n});\n\nit('should pass devtool settings in development', () => {\n\tconst result = mergeWebpackConfig(\n\t\t{ devtool: false },\n\t\t() => ({ devtool: 'source-map' }),\n\t\t'development'\n\t);\n\texpect(result).toEqual({ devtool: 'source-map' });\n});\n\nit('should ignore devtool settings in production', () => {\n\tconst result = mergeWebpackConfig(\n\t\t{ devtool: false },\n\t\t() => ({ devtool: 'source-map' }),\n\t\t'production'\n\t);\n\texpect(result).toEqual({ devtool: false });\n});\n"
  },
  {
    "path": "src/scripts/utils/__tests__/sanitizeConfig.spec.ts",
    "content": "import path from 'path';\nimport glogg from 'glogg';\nimport sanitizeConfig from '../sanitizeConfig';\n\nconst logger = glogg('rsg');\n\nit('should return non-empty required field as is', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: 'pizza',\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(result).toBeTruthy();\n\texpect(result.food).toBe('pizza');\n});\n\nit('should return default value for empty non-required field', () => {\n\tconst result = sanitizeConfig<{ food?: string }>(\n\t\t{},\n\t\t{\n\t\t\tfood: {\n\t\t\t\tdefault: 'pizza',\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(result.food).toBe('pizza');\n});\n\nit('should return actual value for non-empty field with default value', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: 'burger',\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\tdefault: 'pizza',\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(result.food).toBe('burger');\n});\n\nit('should accept required as a function', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: 'pizza',\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\trequired: () => true,\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(result.food).toBe('pizza');\n});\n\nit('should throw if required field is undefined', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\trequired: true,\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('config option is required');\n});\n\nit('should throw with custom message returned by required function', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\trequired: () => 'Not good',\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('Not good');\n});\n\nit('should throw when type in schema is incorrect', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{\n\t\t\t\tfood: 42,\n\t\t\t},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\ttype: 'pizza',\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('Wrong type');\n});\n\nit('should check type for number', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: 42,\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\ttype: 'number',\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(result.food).toBe(42);\n});\n\nit('should throw when field is not a number', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{\n\t\t\t\tfood: 'pizza',\n\t\t\t},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\ttype: 'number',\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('config option should be');\n});\n\nit('should check type for string', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: 'pizza',\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\ttype: 'string',\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(result.food).toBe('pizza');\n});\n\nit('should throw when field is not a string', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{\n\t\t\t\tfood: 42,\n\t\t\t},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\ttype: 'string',\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('config option should be');\n});\n\nit('should check type for boolean', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: true,\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\ttype: 'boolean',\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(result.food).toBe(true);\n});\n\nit('should throw when field is not a boolean', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{\n\t\t\t\tfood: 42,\n\t\t\t},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\ttype: 'boolean',\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('config option should be');\n});\n\nit('should check type for array', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: [1, 2],\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\ttype: 'array',\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(result.food).toEqual([1, 2]);\n});\n\nit('should throw when field is not an array', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{\n\t\t\t\tfood: 42,\n\t\t\t},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\ttype: 'array',\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('config option should be');\n});\n\nit('should check type for function', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: () => true,\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\ttype: 'function',\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(typeof result.food).toBe('function');\n});\n\nit('should throw when field is not a function', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{\n\t\t\t\tfood: 42,\n\t\t\t},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\ttype: 'function',\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('config option should be');\n});\n\nit('should check type for object', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: { a: 42 },\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\ttype: 'object',\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(result.food).toEqual({ a: 42 });\n});\n\nit('should throw when field is not an object', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{\n\t\t\t\tfood: 42,\n\t\t\t},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\ttype: 'object',\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('config option should be');\n});\n\nit('should check type for file path', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: __filename,\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\ttype: 'file path',\n\t\t\t},\n\t\t},\n\t\t__dirname\n\t);\n\texpect(result.food).toEqual(__filename);\n});\n\nit('should check type for relative file path and absolutize it', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: path.basename(__filename),\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\ttype: 'file path',\n\t\t\t},\n\t\t},\n\t\t__dirname\n\t);\n\texpect(result.food).toEqual(__filename);\n});\n\nit('should throw when file does not exist', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{\n\t\t\t\tfood: 'pizza.js',\n\t\t\t},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\ttype: 'existing file path',\n\t\t\t\t},\n\t\t\t},\n\t\t\t__dirname\n\t\t);\n\texpect(fn).toThrowError('does not exist');\n});\n\nit('should check type for directory path', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: __dirname,\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\ttype: 'directory path',\n\t\t\t},\n\t\t},\n\t\t__dirname\n\t);\n\texpect(result.food).toEqual(__dirname);\n});\n\nit('should check type for relative directory path and absolutize it', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: 'data',\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\ttype: 'file path',\n\t\t\t},\n\t\t},\n\t\t__dirname\n\t);\n\texpect(result.food).toEqual(path.join(__dirname, 'data'));\n});\n\nit('should throw with correct type name', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{\n\t\t\t\tfood: null,\n\t\t\t},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\ttype: 'object',\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('config option should be object, received null');\n});\n\nit('should pass value to a custom process function', () => {\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: true,\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\ttype: ['boolean', 'string'],\n\t\t\t\tprocess: val => (val === true ? 'pizza' : val),\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(result.food).toEqual('pizza');\n});\n\nit('should not throw if process function returns value for undefined required field', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\trequired: true,\n\t\t\t\t\tprocess: () => 'pizza',\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).not.toThrowError('config option is required');\n});\n\nit('should throw when directory does not exist', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{\n\t\t\t\tfood: 'pizza.js',\n\t\t\t},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\ttype: 'existing directory path',\n\t\t\t\t},\n\t\t\t},\n\t\t\t__dirname\n\t\t);\n\texpect(fn).toThrowError('does not exist');\n});\n\nit('should throw for unknown options', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig<{ drink?: any; food?: any }>(\n\t\t\t{\n\t\t\t\tbook: 'hobbit',\n\t\t\t} as any,\n\t\t\t{\n\t\t\t\tdrink: {},\n\t\t\t\tfood: {},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('Unknown config option');\n});\n\nit('should throw for unknown options with suggestion', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig<{ drink?: any; food?: any }>(\n\t\t\t{\n\t\t\t\tdring: 'pizza',\n\t\t\t} as any,\n\t\t\t{\n\t\t\t\tdrink: {},\n\t\t\t\tfood: {},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('Did you mean');\n});\n\nit('should warn for deprecated options', () => {\n\tconst warn = jest.fn();\n\tlogger.once('warn', warn);\n\n\tconst result = sanitizeConfig(\n\t\t{\n\t\t\tfood: 'pizza',\n\t\t},\n\t\t{\n\t\t\tfood: {\n\t\t\t\tdeprecated: 'Don’t use!',\n\t\t\t},\n\t\t},\n\t\t''\n\t);\n\texpect(result.food).toBe('pizza');\n\texpect(warn).toBeCalledWith(expect.stringMatching('config option is deprecated. Don’t use!'));\n});\n\nit('should throw for removed options', () => {\n\tconst fn = () =>\n\t\tsanitizeConfig(\n\t\t\t{\n\t\t\t\tfood: 'pizza',\n\t\t\t},\n\t\t\t{\n\t\t\t\tfood: {\n\t\t\t\t\tremoved: 'Don’t use!',\n\t\t\t\t},\n\t\t\t},\n\t\t\t''\n\t\t);\n\texpect(fn).toThrowError('was removed');\n});\n"
  },
  {
    "path": "src/scripts/utils/ensureWebpack.ts",
    "content": "/**\n * Check webpack availability and version at run time instead of using peerDependencies to allow\n * usage of build tools that contains webpack as their own dependency, like Create React App.\n */\n\nimport getWebpackVersion from './getWebpackVersion';\nimport StyleguidistError from './error';\nimport * as consts from '../consts';\n\nconst MIN_WEBPACK_VERSION = 4;\nconst webpackVersion = getWebpackVersion();\n\nif (!webpackVersion) {\n\tthrow new StyleguidistError(\n\t\t'Webpack is required for Styleguidist, please add it to your project:\\n\\n' +\n\t\t\t'    npm install --save-dev webpack\\n\\n' +\n\t\t\t'See how to configure webpack for your style guide:\\n' +\n\t\t\tconsts.DOCS_WEBPACK\n\t);\n} else if (webpackVersion < MIN_WEBPACK_VERSION) {\n\tthrow new StyleguidistError(\n\t\t`Webpack ${webpackVersion} is not supported by Styleguidist, the minimum supported version is ${MIN_WEBPACK_VERSION}`\n\t);\n}\n"
  },
  {
    "path": "src/scripts/utils/error.ts",
    "content": "class StyleguidistError extends Error {\n\tpublic extra: any;\n\tpublic constructor(message: string, extra?: any) {\n\t\tsuper(message);\n\t\tError.captureStackTrace(this, this.constructor);\n\t\tObject.defineProperty(this, 'name', {\n\t\t\tvalue: this.constructor.name,\n\t\t});\n\t\tObject.defineProperty(this, 'extra', {\n\t\t\tvalue: extra,\n\t\t});\n\t}\n}\n\nexport default StyleguidistError;\n"
  },
  {
    "path": "src/scripts/utils/findFileCaseInsensitive.ts",
    "content": "import fs from 'fs';\nimport path from 'path';\nimport memoize from 'lodash/memoize';\n\nconst readdirSync = memoize(fs.readdirSync);\n\n/**\n * Find a file in a directory, case-insensitive\n *\n * @param {string} filepath\n * @return {string|undefined} File path with correct case\n */\nexport default function findFileCaseInsensitive(filepath: string): string | undefined {\n\tconst dir = path.dirname(filepath);\n\tconst fileNameLower = path.basename(filepath).toLowerCase();\n\tconst files = readdirSync(dir);\n\tconst found = files.find(file => file.toLowerCase() === fileNameLower);\n\treturn found && path.join(dir, found);\n}\n\n/**\n * Clear cache.\n */\nexport function clearCache() {\n\t(readdirSync.cache as any).clear();\n}\n"
  },
  {
    "path": "src/scripts/utils/findUserWebpackConfig.ts",
    "content": "import fs from 'fs';\nimport path from 'path';\n\n// react-scripts <= 2.1.1\nconst CREATE_REACT_APP_WEBPACK_CONFIG_OLD = 'react-scripts/config/webpack.config.dev';\n// react-scripts > 2.1.1\nconst CREATE_REACT_APP_WEBPACK_CONFIG = 'react-scripts/config/webpack.config';\nconst USER_WEBPACK_CONFIG_NAMES = ['webpack.config.js', 'webpackfile.js'];\n\nconst absolutize = (filePath: string): string => path.resolve(process.cwd(), filePath);\n\n/**\n * Find user’s Webpack config and return its path.\n * Fixed location for Create React App or webpack.config.js in the root directory.\n * Returns false if config not found.\n *\n * @param {Function} resolve\n * @return {string|boolean}\n */\nexport default function findUserWebpackConfig(resolve?: (input: string) => string) {\n\tresolve = resolve || require.resolve;\n\ttry {\n\t\t// Create React App <= 2.1.1\n\t\treturn resolve(CREATE_REACT_APP_WEBPACK_CONFIG_OLD);\n\t} catch (err) {\n\t\ttry {\n\t\t\t// Create React App > 2.1.1\n\t\t\treturn resolve(CREATE_REACT_APP_WEBPACK_CONFIG);\n\t\t} catch (innerErr) {\n\t\t\t// Check in the root folder\n\t\t\t// FIXME: This looks like a bug in ESLint\n\t\t\t// eslint-disable-next-line no-unused-vars\n\t\t\tfor (const configFile of USER_WEBPACK_CONFIG_NAMES) {\n\t\t\t\tconst absoluteConfigFile = absolutize(configFile);\n\t\t\t\tif (fs.existsSync(absoluteConfigFile)) {\n\t\t\t\t\treturn absoluteConfigFile;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n"
  },
  {
    "path": "src/scripts/utils/getUserPackageJson.ts",
    "content": "import path from 'path';\n\n/**\n * Return user’s package.json.\n *\n * @return {object}\n */\nexport default function getUserPackageJson() {\n\ttry {\n\t\treturn require(path.resolve(process.cwd(), 'package.json'));\n\t} catch (err) {\n\t\treturn {};\n\t}\n}\n"
  },
  {
    "path": "src/scripts/utils/getWebpackVersion.ts",
    "content": "/**\n * Return installed Webpack version.\n *\n * @return {number}\n */\nexport default function getWebpackVersion() {\n\ttry {\n\t\t// eslint-disable-next-line @typescript-eslint/no-var-requires\n\t\treturn parseInt(require('webpack/package.json').version, 10);\n\t} catch (err) {\n\t\treturn undefined;\n\t}\n}\n"
  },
  {
    "path": "src/scripts/utils/mergeWebpackConfig.ts",
    "content": "import mergeBase from 'webpack-merge';\nimport isFunction from 'lodash/isFunction';\nimport omit from 'lodash/omit';\nimport { Configuration, WebpackPluginInstance } from 'webpack';\n\nconst IGNORE_SECTIONS = ['entry', 'externals', 'output', 'watch', 'stats', 'styleguidist'];\nconst IGNORE_SECTIONS_ENV: Record<string, string[]> = {\n\tdevelopment: [],\n\t// For production builds, we'll ignore devtool settings to avoid\n\t// source mapping bloat.\n\tproduction: ['devtool'],\n};\n\nconst IGNORE_PLUGINS = [\n\t'CommonsChunkPlugins',\n\t'MiniHtmlWebpackPlugin',\n\t'HtmlWebpackPlugin',\n\t'OccurrenceOrderPlugin',\n\t'DedupePlugin',\n\t'UglifyJsPlugin',\n\t'TerserPlugin',\n\t'HotModuleReplacementPlugin',\n];\n\nconst merge = mergeBase({\n\t// Ignore user’s plugins to avoid duplicates and issues with our plugins\n\tcustomizeArray: mergeBase.unique(\n\t\t'plugins',\n\t\tIGNORE_PLUGINS,\n\t\t(plugin: WebpackPluginInstance) => plugin.constructor && plugin.constructor.name\n\t),\n});\n\ntype MetaConfig = Configuration | ((env?: string) => Configuration);\n\n/**\n * Merge two Webpack configs.\n *\n * In the user config:\n * - Ignores given sections (options.ignore).\n * - Ignores plugins that shouldn’t be used twice or may cause issues.\n *\n * @param {object} baseConfig\n * @param {object|Function} userConfig\n * @param {string} env\n * @return {object}\n */\nexport default function mergeWebpackConfig(\n\tbaseConfig: MetaConfig,\n\tuserConfig: MetaConfig,\n\tenv = 'production'\n) {\n\tconst userConfigObject = isFunction(userConfig) ? userConfig(env) : userConfig;\n\tconst safeUserConfig = omit(userConfigObject, IGNORE_SECTIONS.concat(IGNORE_SECTIONS_ENV[env]));\n\treturn merge(baseConfig, safeUserConfig);\n}\n"
  },
  {
    "path": "src/scripts/utils/sanitizeConfig.ts",
    "content": "import fs from 'fs';\nimport path from 'path';\nimport castArray from 'lodash/castArray';\nimport isBoolean from 'lodash/isBoolean';\nimport isFunction from 'lodash/isFunction';\nimport isPlainObject from 'lodash/isPlainObject';\nimport isString from 'lodash/isString';\nimport isFinite from 'lodash/isFinite';\nimport map from 'lodash/map';\nimport listify from 'listify';\nimport kleur from 'kleur';\nimport { distance } from 'fastest-levenshtein';\nimport typeDetect from 'type-detect';\nimport loggerMaker from 'glogg';\nimport { stringify } from 'q-i';\nimport StyleguidistError from './error';\nimport { ConfigSchemaOptions } from '../schemas/config';\n\nconst logger = loggerMaker('rsg');\n\nconst typeCheckers: Record<string, (untypedObject: unknown) => boolean> = {\n\tnumber: isFinite,\n\tstring: isString,\n\tboolean: isBoolean,\n\tarray: Array.isArray,\n\tfunction: isFunction,\n\tobject: isPlainObject,\n\t'file path': isString,\n\t'existing file path': isString,\n\t'directory path': isString,\n\t'existing directory path': isString,\n};\n\nconst typesList = (types: string[]) => listify(types, { finalWord: 'or' });\nconst shouldBeFile = (types: string[]) => types.some((type) => type.includes('file'));\nconst shouldBeDirectory = (types: string[]) => types.some((type) => type.includes('directory'));\nconst shouldExist = (types: string[]) => types.some((type) => type.includes('existing'));\n\nfunction isDirectory(pathString: string): boolean {\n\ttry {\n\t\treturn fs.lstatSync(pathString).isDirectory();\n\t} catch (e: any) {\n\t\tif (e.code !== 'ENOENT') {\n\t\t\tthrow e;\n\t\t}\n\t\treturn false;\n\t}\n}\n\n/**\n * Validates and normalizes config.\n *\n * @param {object} config\n * @param {object} schema\n * @param {string} rootDir\n * @return {object}\n */\nexport default function sanitizeConfig<T extends Record<string, any>>(\n\tconfig: T,\n\tschema: Record<keyof T, ConfigSchemaOptions<T>>,\n\trootDir: string\n): T {\n\t// Check for unknown fields\n\tmap(config, (value, keyAny: keyof T) => {\n\t\tconst key = keyAny as string;\n\t\tif (!schema[key]) {\n\t\t\t// Try to guess\n\t\t\tconst possibleOptions = Object.keys(schema);\n\t\t\tconst suggestedOption = possibleOptions.reduce((suggestion: string, option: string) => {\n\t\t\t\tconst steps = distance(option, key);\n\t\t\t\tif (steps < 2) {\n\t\t\t\t\treturn option;\n\t\t\t\t}\n\t\t\t\treturn suggestion;\n\t\t\t}, '');\n\n\t\t\tthrow new StyleguidistError(\n\t\t\t\t`Unknown config option ${kleur.bold(key)} was found, the value is:\\n` +\n\t\t\t\t\tstringify(value) +\n\t\t\t\t\t(suggestedOption ? `\\n\\nDid you mean ${kleur.bold(suggestedOption)}?` : ''),\n\t\t\t\tsuggestedOption\n\t\t\t);\n\t\t}\n\t});\n\n\t// Check all fields\n\tconst safeConfig: Partial<T> = {};\n\tmap(schema, (props, keyAny: keyof T) => {\n\t\tconst key = keyAny as string;\n\t\tlet value = config[key];\n\n\t\t// Custom processing\n\t\tif (props.process) {\n\t\t\tvalue = props.process(value, config, rootDir);\n\t\t}\n\n\t\tif (value === undefined) {\n\t\t\t// Default value\n\t\t\tvalue = props.default;\n\n\t\t\t// Check if the field is required\n\t\t\tconst isRequired = isFunction(props.required) ? props.required(config) : props.required;\n\t\t\tif (isRequired) {\n\t\t\t\tconst message = isString(isRequired)\n\t\t\t\t\t? isRequired\n\t\t\t\t\t: `${kleur.bold(key)} config option is required.`;\n\t\t\t\tthrow new StyleguidistError(message, key);\n\t\t\t}\n\t\t} else if (props.deprecated) {\n\t\t\tlogger.warn(`${key} config option is deprecated. ${props.deprecated}`);\n\t\t} else if (props.removed) {\n\t\t\tthrow new StyleguidistError(`${kleur.bold(key)} config option was removed. ${props.removed}`);\n\t\t}\n\n\t\tif (value !== undefined && props.type) {\n\t\t\tconst types = castArray(props.type);\n\n\t\t\t// Check type\n\t\t\tconst hasRightType = types.some((type) => {\n\t\t\t\tif (!typeCheckers[type]) {\n\t\t\t\t\tthrow new StyleguidistError(\n\t\t\t\t\t\t`Wrong type ${kleur.bold(type)} specified for ${kleur.bold(key)} in schema.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn typeCheckers[type](value);\n\t\t\t});\n\t\t\tif (!hasRightType) {\n\t\t\t\tconst exampleValue = props.example || props.default;\n\t\t\t\tconst example: Record<string, any> = {};\n\t\t\t\tif (exampleValue) {\n\t\t\t\t\texample[key] = exampleValue;\n\t\t\t\t}\n\t\t\t\tconst exampleText = exampleValue\n\t\t\t\t\t? `\nExample:\n\n${stringify(example)}`\n\t\t\t\t\t: '';\n\t\t\t\tthrow new StyleguidistError(\n\t\t\t\t\t`${kleur.bold(key)} config option should be ${typesList(types)}, received ${typeDetect(\n\t\t\t\t\t\tvalue\n\t\t\t\t\t)}.\\n${exampleText}`,\n\t\t\t\t\tkey\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Absolutize paths\n\t\t\tif (isString(value) && (shouldBeFile(types) || shouldBeDirectory(types))) {\n\t\t\t\tvalue = path.resolve(rootDir, value);\n\n\t\t\t\t// Check for existence\n\t\t\t\tif (shouldExist(types)) {\n\t\t\t\t\tif (shouldBeFile(types) && !fs.existsSync(value)) {\n\t\t\t\t\t\tthrow new StyleguidistError(\n\t\t\t\t\t\t\t`A file specified in ${kleur.bold(key)} config option does not exist:\\n${value}`,\n\t\t\t\t\t\t\tkey\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (shouldBeDirectory(types) && !isDirectory(value)) {\n\t\t\t\t\t\tthrow new StyleguidistError(\n\t\t\t\t\t\t\t`A directory specified in ${kleur.bold(key)} config option does not exist:\\n${value}`,\n\t\t\t\t\t\t\tkey\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsafeConfig[keyAny] = value;\n\t});\n\n\treturn safeConfig as T;\n}\n"
  },
  {
    "path": "src/typings/RecursivePartial.ts",
    "content": "/**\n * In a custom config file you might only want to override some parameters\n * This is the usage of the recursive Partial\n * `interface Test{param:string, paramObject:{p1:number, p2:boolean}}`\n * becomes\n * `interface TestPartial{param?:string, paramObject?:{p1?:number, p2?:boolean}}`\n * where everything is optional\n */\nexport type RecursivePartial<T> = {\n\t[P in keyof T]?: T[P] extends (infer U)[]\n\t\t? RecursivePartial<U>[]\n\t\t: T[P] extends (...args: unknown[]) => unknown\n\t\t? T[P]\n\t\t: T[P] extends Record<string, unknown>\n\t\t? RecursivePartial<T[P]>\n\t\t: T[P];\n};\n"
  },
  {
    "path": "src/typings/RsgComponent.ts",
    "content": "import { MethodDescriptor, PropDescriptor, TagProps } from 'react-docgen';\nimport { RequireItResult } from './RsgRequireItResult';\nimport { Example } from './RsgExample';\n\nexport type ExpandMode = 'expand' | 'collapse' | 'hide';\n\nexport interface BaseComponent {\n\thasExamples?: boolean;\n\tname?: string;\n\tslug?: string;\n\thref?: string;\n\tfilepath?: string;\n\tpathLine?: string;\n\tdescription?: string;\n\texampleMode?: ExpandMode;\n\tusageMode?: ExpandMode;\n}\n\nexport interface Component extends BaseComponent {\n\tvisibleName?: string;\n\tprops?: {\n\t\tdisplayName?: string;\n\t\tvisibleName?: string;\n\t\tdescription?: string;\n\t\tmethods?: MethodDescriptor[];\n\t\tprops?: PropDescriptor[];\n\t\ttags?: TagProps;\n\t\texample?: Example[];\n\t\texamples?: Example[];\n\t};\n\tmodule?: number;\n\tmetadata?: {\n\t\ttags?: string[];\n\t};\n}\n\nexport interface LoaderComponent extends BaseComponent {\n\tmodule: RequireItResult;\n\tprops: RequireItResult;\n\tmetadata: RequireItResult | Record<string, unknown>;\n}\n"
  },
  {
    "path": "src/typings/RsgExample.ts",
    "content": "export interface MarkdownExample {\n\ttype: 'markdown';\n\tcontent: string;\n\tsettings?: Record<string, any>;\n}\n\nexport interface CodeExample {\n\ttype: 'code';\n\tcontent: string;\n\tlang?: string | null;\n\tsettings?: Record<string, any>;\n}\n\nexport interface RuntimeCodeExample extends CodeExample {\n\tevalInContext(a: string): () => any;\n}\n\nexport type Example = RuntimeCodeExample | MarkdownExample;\n"
  },
  {
    "path": "src/typings/RsgPropsObject.ts",
    "content": "import { DocumentationObject, MethodDescriptor, PropDescriptor } from 'react-docgen';\nimport { RequireItResult } from './RsgRequireItResult';\n\nexport interface MethodWithDocblock extends MethodDescriptor {\n\tdocblock: string;\n}\n\nexport interface TempPropsObject extends DocumentationObject {\n\tdisplayName: string;\n\tvisibleName?: string;\n\tmethods?: MethodWithDocblock[];\n\tdoclets: Record<string, any>;\n\texample?: RequireItResult | null;\n}\n\nexport interface PropsObject extends Omit<TempPropsObject, 'props'> {\n\tprops?: Record<string, PropDescriptor> | PropDescriptor[];\n\texamples?: RequireItResult | null;\n}\n"
  },
  {
    "path": "src/typings/RsgRequireItResult.ts",
    "content": "import { ASTNode } from 'ast-types';\n\nexport interface RequireItResult {\n\trequire: string;\n\ttoAST(): ASTNode;\n}\n"
  },
  {
    "path": "src/typings/RsgSection.ts",
    "content": "import { RequireItResult } from './RsgRequireItResult';\nimport { MarkdownExample, Example } from './RsgExample';\nimport { LoaderComponent, ExpandMode, Component } from './RsgComponent';\n\nexport interface BaseSection {\n\tname?: string;\n\tslug?: string;\n\tignore?: string | string[];\n\tdescription?: string;\n\texampleMode?: ExpandMode;\n\tusageMode?: ExpandMode;\n\thref?: string;\n\tsectionDepth?: number;\n\texternal?: boolean;\n\texpand?: boolean;\n}\n\nexport interface ProcessedSection extends BaseSection {\n\tvisibleName?: string;\n\tfilepath?: string;\n\texternalLink?: boolean;\n\thref?: string;\n}\n\n/**\n * Section used on the client in javascript\n * It is the output of the function `client/utils/processSection`\n */\nexport interface Section extends ProcessedSection {\n\tcontent?: Example[] | string;\n\tcomponents?: Component[];\n\tsections?: Section[];\n}\n\n/**\n * Item of the Table Of Contents used in\n * ComponentsList\n * TableOfContent\n * filterSectionByName\n */\nexport interface TOCItem extends ProcessedSection {\n\theading?: boolean;\n\tshouldOpenInNewTab?: boolean;\n\tselected?: boolean;\n\tinitialOpen?: boolean;\n\tforcedOpen?: boolean;\n\tcontent?: React.ReactNode;\n\tcomponents?: TOCItem[];\n\tsections?: TOCItem[];\n}\n\n/**\n * Used in the config file and at the early stages of processing\n * in `schema/config.ts` this is the type that is used\n */\nexport interface ConfigSection extends BaseSection {\n\tcomponents?: string | string[] | (() => string[]);\n\tsections?: ConfigSection[];\n\tcontent?: string;\n}\n\n/**\n * Type returned when sections are transformed to their webpack\n * loadable equivalents\n */\nexport interface LoaderSection extends BaseSection {\n\tslug?: string;\n\tcontent?: RequireItResult | MarkdownExample;\n\tcomponents: LoaderComponent[];\n\tsections: LoaderSection[];\n}\n"
  },
  {
    "path": "src/typings/RsgStyleguidistConfig.ts",
    "content": "import WebpackDevServer from 'webpack-dev-server';\nimport { Configuration, LoaderContext } from 'webpack';\nimport { TransformOptions } from 'buble';\nimport { Handler, DocumentationObject, PropDescriptor } from 'react-docgen';\nimport { ASTNode } from 'ast-types';\nimport { NodePath } from 'ast-types/lib/node-path';\nimport { Styles } from 'jss';\nimport { RecursivePartial } from './RecursivePartial';\nimport { ExpandMode } from './RsgComponent';\nimport { PropsObject } from './RsgPropsObject';\nimport { CodeExample } from './RsgExample';\nimport { ConfigSection, Section } from './RsgSection';\nimport { Theme } from './RsgTheme';\n\ntype OptionsType = {\n\tdisplayName: string;\n\tfile: string;\n\tshouldShowDefaultExample: string;\n\tcustomLangs: string[];\n};\nexport interface StyleguidistLoaderContext extends LoaderContext<OptionsType> {\n\t_styleguidist: SanitizedStyleguidistConfig;\n}\n\ninterface BaseStyleguidistConfig {\n\tassetsDir: string | string[];\n\ttocMode: ExpandMode;\n\tcompilerConfig: TransformOptions;\n\tcomponents: (() => string[]) | string | string[];\n\tconfigDir: string;\n\tcontext: Record<string, any>;\n\tcontextDependencies: string[];\n\tconfigureServer(server: WebpackDevServer, env: string): string;\n\tdangerouslyUpdateWebpackConfig: (server: Configuration, env: string) => Configuration;\n\tdefaultExample: string | false;\n\texampleMode: ExpandMode;\n\teditorConfig: {\n\t\ttheme: string;\n\t};\n\tgetComponentPathLine(componentPath: string): string;\n\tgetExampleFilename(componentPath: string): string;\n\thandlers: (componentPath: string) => Handler[];\n\tignore: string[];\n\tlogger: {\n\t\tinfo(message: string): void;\n\t\twarn(message: string): void;\n\t\tdebug(message: string): void;\n\t};\n\tminimize: boolean;\n\tmountPointId: string;\n\tmoduleAliases: Record<string, string>;\n\tpagePerSection: boolean;\n\tpreviewDelay: number;\n\tprintBuildInstructions(config: SanitizedStyleguidistConfig): void;\n\tprintServerInstructions(config: SanitizedStyleguidistConfig, options: { isHttps: boolean }): void;\n\tpropsParser(\n\t\tfilePath: string,\n\t\tcode: string,\n\t\tresolver: (\n\t\t\tast: ASTNode,\n\t\t\tparser: { parse: (input: string) => ASTNode }\n\t\t) => NodePath<any, any> | NodePath[],\n\t\thandlers: Handler[]\n\t): DocumentationObject;\n\trequire: string[];\n\tresolver(\n\t\tast: ASTNode,\n\t\tparser: { parse: (code: string) => ASTNode }\n\t): NodePath<any, any> | NodePath[];\n\tribbon?: {\n\t\ttext?: string;\n\t\turl: string;\n\t};\n\tserverHost: string;\n\tserverPort: number;\n\tshowCode: boolean;\n\tshowUsage: boolean;\n\tshowSidebar: boolean;\n\tskipComponentsWithoutExample: boolean;\n\tsortProps(props: PropDescriptor[]): PropDescriptor[];\n\tstyleguideComponents: Record<string, string>;\n\tstyleguideDir: string;\n\tstyles: Styles | string | ((theme: Theme) => Styles);\n\ttemplate: any;\n\ttheme: RecursivePartial<Theme> | string;\n\ttitle: string;\n\tupdateDocs(doc: PropsObject, file: string): PropsObject;\n\tupdateExample(props: Omit<CodeExample, 'type'>, ressourcePath: string): Omit<CodeExample, 'type'>;\n\tupdateWebpackConfig(config: Configuration): Configuration;\n\tusageMode: ExpandMode;\n\tverbose: boolean;\n\tversion: string;\n\twebpackConfig: Configuration | ((env?: string) => Configuration);\n}\n\nexport interface ProcessedStyleguidistConfig extends BaseStyleguidistConfig {\n\tsections: Section[];\n\ttheme: RecursivePartial<Theme>;\n\tstyles: ((th: Theme) => Styles) | Styles;\n}\n\nexport type ProcessedStyleguidistCSSConfig = Pick<ProcessedStyleguidistConfig, 'theme'> &\n\tPick<ProcessedStyleguidistConfig, 'styles'>;\n\nexport interface SanitizedStyleguidistConfig extends BaseStyleguidistConfig {\n\tsections: ConfigSection[];\n}\n\n/**\n * definition of the config object where everything is optional\n * note that teh default example can be both a string and a boolean but ends\n * up only being a string after sanitizing\n */\nexport interface StyleguidistConfig\n\textends RecursivePartial<Omit<SanitizedStyleguidistConfig, 'defaultExample'>> {\n\tdefaultExample?: string | boolean;\n}\n"
  },
  {
    "path": "src/typings/RsgTheme.ts",
    "content": "/**\n * When the theme is to be used in a component,\n * it will have all it's values set.\n * None of those declarations should be optional\n */\nexport interface Theme {\n\tspaceFactor: number;\n\tspace: number[];\n\tcolor: {\n\t\tbase: string;\n\t\tlight: string;\n\t\tlightest: string;\n\t\tlink: string;\n\t\tlinkHover: string;\n\t\tfocus: string;\n\t\tborder: string;\n\t\tname: string;\n\t\ttype: string;\n\t\terror: string;\n\t\tbaseBackground: string;\n\t\tcodeBackground: string;\n\t\tsidebarBackground: string;\n\t\tribbonBackground: string;\n\t\tribbonText: string;\n\t\t// Based on default Prism theme\n\t\tcodeBase: string;\n\t\tcodeComment: string;\n\t\tcodePunctuation: string;\n\t\tcodeProperty: string;\n\t\tcodeDeleted: string;\n\t\tcodeString: string;\n\t\tcodeInserted: string;\n\t\tcodeOperator: string;\n\t\tcodeKeyword: string;\n\t\tcodeFunction: string;\n\t\tcodeVariable: string;\n\t};\n\tfontFamily: {\n\t\tbase: string[];\n\t\tmonospace: string[];\n\t};\n\tfontSize: {\n\t\tbase: number;\n\t\ttext: number;\n\t\tsmall: number;\n\t\th1: number;\n\t\th2: number;\n\t\th3: number;\n\t\th4: number;\n\t\th5: number;\n\t\th6: number;\n\t};\n\tmq: {\n\t\tsmall: string;\n\t};\n\tborderRadius: number;\n\tmaxWidth: number;\n\tsidebarWidth: number;\n\tbuttonTextTransform: string;\n}\n"
  },
  {
    "path": "src/typings/dependencies/acorn-jsx.ts",
    "content": "declare module 'acorn-jsx' {\n\timport { Parser } from 'acorn';\n\n\tfunction acornJsx(): (BaseParser: typeof Parser) => typeof Parser;\n\texport = acornJsx;\n}\n"
  },
  {
    "path": "src/typings/dependencies/common-dir.ts",
    "content": "declare module 'common-dir' {\n\tfunction commonDir(list: string[]): string;\n\texport = commonDir;\n}\n"
  },
  {
    "path": "src/typings/dependencies/deabsdeep.ts",
    "content": "declare module 'deabsdeep' {\n\tinterface Options {\n\t\troot?: string;\n\t\tmask?: string;\n\t}\n\tfunction deabsdeep<T>(objectToFreze: T, opt?: Options): T;\n\texport = deabsdeep;\n}\n"
  },
  {
    "path": "src/typings/dependencies/deepfreeze.ts",
    "content": "declare module 'deepfreeze' {\n\tfunction deepfreeze<T>(objectToFreze: T): T;\n\texport = deepfreeze;\n}\n"
  },
  {
    "path": "src/typings/dependencies/findup.ts",
    "content": "declare module 'findup' {\n\tconst findup: {\n\t\tsync(cwd: string, path: string): string;\n\t};\n\texport = findup;\n}\n"
  },
  {
    "path": "src/typings/dependencies/github-slugger.ts",
    "content": "declare module 'github-slugger' {\n\tclass Slugger {\n\t\treset(): void;\n\t\tslug(input: string): string;\n\t}\n\texport = Slugger;\n}\n"
  },
  {
    "path": "src/typings/dependencies/glogg.ts",
    "content": "declare module 'glogg' {\n\tinterface GloggLogger {\n\t\tdebug(msg: string): void;\n\t\tinfo(msg: string): void;\n\t\twarn(msg: string): void;\n\t\terror(msg: string): void;\n\t\ton(event: string | symbol, listener: (...args: any[]) => void): void;\n\t\tonce(actionName: string, action: (msg: string) => void): void;\n\t\tremoveAllListeners(): void;\n\t}\n\tfunction getLogger(namespace: string): GloggLogger;\n\texport = getLogger;\n}\n"
  },
  {
    "path": "src/typings/dependencies/listify.ts",
    "content": "declare module 'listify' {\n\tinterface ListifyOptions {\n\t\tfinalWord: string;\n\t}\n\tfunction listify(list: any[], opt?: ListifyOptions): string;\n\texport = listify;\n}\n"
  },
  {
    "path": "src/typings/dependencies/mini-html-webpack-template.ts",
    "content": "declare module '@vxna/mini-html-webpack-template' {\n\tfunction template(...args: any[]): string;\n\texport = template;\n}\n"
  },
  {
    "path": "src/typings/dependencies/q-i.ts",
    "content": "declare module 'q-i' {\n\texport const stringify: (obj: any) => string;\n}\n"
  },
  {
    "path": "src/typings/dependencies/react-docgen.ts",
    "content": "declare module 'react-docgen' {\n\timport { Tag, Type } from 'doctrine';\n\timport { ASTNode } from 'ast-types';\n\timport { NodePath } from 'ast-types/lib/node-path';\n\n\texport type Handler = (documentation: Documentation, path: NodePath) => void;\n\n\tinterface Documentation {\n\t\taddComposes(moduleName: string): void;\n\t\tset(key: string, value: any): void;\n\t\tget(key: string): any;\n\t\tgetPropDescriptor(propName: string): PropDescriptor;\n\t\tgetContextDescriptor(propName: string): PropDescriptor;\n\t\tgetChildContextDescriptor(propName: string): PropDescriptor;\n\t\ttoObject(): DocumentationObject;\n\t}\n\n\texport interface TagObject extends Omit<Tag, 'description'> {\n\t\tdescription?: string;\n\t}\n\n\texport interface TagParamObject extends TagObject {\n\t\tname: string;\n\t\ttype?: Type | null;\n\t\tdefault?: string;\n\t}\n\n\texport interface TagProps {\n\t\tdeprecated?: TagObject[];\n\t\tsee?: TagObject[];\n\t\tlink?: TagObject[];\n\t\tauthor?: TagObject[];\n\t\tversion?: TagObject[];\n\t\tsince?: TagObject[];\n\t\treturns?: TagParamObject[];\n\t\treturn?: TagParamObject[];\n\t\targ?: TagParamObject[];\n\t\targument?: TagParamObject[];\n\t\tparam?: TagParamObject[];\n\t\t[title: string]: TagObject[] | undefined;\n\t}\n\n\texport interface PropTypeDescriptor {\n\t\tname:\n\t\t\t| 'arrayOf'\n\t\t\t| 'custom'\n\t\t\t| 'enum'\n\t\t\t| 'array'\n\t\t\t| 'bool'\n\t\t\t| 'func'\n\t\t\t| 'number'\n\t\t\t| 'object'\n\t\t\t| 'string'\n\t\t\t| 'any'\n\t\t\t| 'element'\n\t\t\t| 'node'\n\t\t\t| 'symbol'\n\t\t\t| 'objectOf'\n\t\t\t| 'shape'\n\t\t\t| 'exact'\n\t\t\t| 'instanceOf'\n\t\t\t| 'elementType';\n\t\tvalue?: any;\n\t\traw?: string;\n\t\tcomputed?: boolean;\n\t\t// These are only needed for shape/exact types.\n\t\t// Consider consolidating PropTypeDescriptor and PropDescriptor\n\t\tdescription?: string;\n\t\trequired?: boolean;\n\t}\n\n\texport interface PropDescriptor {\n\t\tname: string;\n\t\ttype?: PropTypeDescriptor;\n\t\trequired?: boolean;\n\t\tdefaultValue?: any;\n\t\tdescription?: string;\n\t\ttags?: TagProps;\n\t}\n\n\texport interface MethodDescriptor {\n\t\tname: string;\n\t\tdescription?: string;\n\t\tdocblock?: string;\n\t\treturns?: { name: string; [key: string]: any } | null;\n\t\tparams?: any[];\n\t\tmodifiers?: string[];\n\t\ttags?: TagProps;\n\t}\n\n\texport interface DocumentationObject {\n\t\tdisplayName?: string;\n\t\tdescription?: string;\n\t\ttags?: TagProps;\n\t\tprops?: { [propName: string]: PropDescriptor };\n\t\tmethods?: MethodDescriptor[];\n\t\tcontext?: { [constextName: string]: PropDescriptor };\n\t\tchildContext?: { [chilCOntextName: string]: PropDescriptor };\n\t\tcomposes?: string[];\n\t}\n\n\tinterface Options {\n\t\tfilename?: string;\n\t\tcwd?: string;\n\t\tbabelrc?: string;\n\t\tbabelrcRoots?: boolean | string | string[];\n\t\troot?: string;\n\t\trootMode?: 'root' | 'upward' | 'upward-optional';\n\t\tconfigFile?: string;\n\t\tenvName?: string;\n\t}\n\n\texport const defaultHandlers: Handler[];\n\n\t/**\n\t * Parse the components at filePath and return props, public methods, events and slots\n\t * @param filePath absolute path of the parsed file\n\t * @param opts\n\t */\n\texport function parse(\n\t\tsource: string | Buffer,\n\t\tresolver?: (\n\t\t\tast: ASTNode,\n\t\t\tparser: { parse: (code: string) => ASTNode }\n\t\t) => NodePath<any, any> | NodePath[],\n\t\thandlers?: Handler[],\n\t\toptions?: Options\n\t): DocumentationObject | DocumentationObject[];\n\n\texport const utils: {\n\t\tdocblock: {\n\t\t\tgetDoclets: (str?: string) => Record<string, any>;\n\t\t};\n\t};\n\n\texport const resolver: {\n\t\tfindAllComponentDefinitions(ast: ASTNode): NodePath[];\n\t\tfindAllExportedComponentDefinitions(\n\t\t\tast: ASTNode,\n\t\t\trecast: {\n\t\t\t\tvisit: (\n\t\t\t\t\tpath: NodePath,\n\t\t\t\t\thandlers: { [handlerName: string]: () => boolean | undefined }\n\t\t\t\t) => void;\n\t\t\t}\n\t\t): NodePath[];\n\t\tfindExportedComponentDefinition(ast: ASTNode): NodePath | undefined;\n\t};\n}\n\ndeclare module 'react-docgen-displayname-handler' {\n\timport { NodePath as DisplaNameHandlerNodePath } from 'ast-types/lib/node-path';\n\timport { Documentation } from 'react-docgen';\n\n\ttype Handler = (documentation: Documentation, path: DisplaNameHandlerNodePath) => void;\n\texport function createDisplayNameHandler(componentPath: string): Handler;\n}\n\ndeclare module 'react-docgen-annotation-resolver' {\n\timport { ASTNode as AnnoASTNode } from 'ast-types';\n\timport { NodePath as AnnoNodePath } from 'ast-types/lib/node-path';\n\n\tfunction annotationResolver(\n\t\tast: AnnoASTNode,\n\t\trecast: {\n\t\t\tvisit: (\n\t\t\t\tnode: AnnoNodePath,\n\t\t\t\thandlers: { [handlerName: string]: () => boolean | undefined }\n\t\t\t) => void;\n\t\t}\n\t): AnnoNodePath[];\n\texport = annotationResolver;\n}\n"
  },
  {
    "path": "src/typings/dependencies/strip-shebang.ts",
    "content": "declare module 'strip-shebang' {\n\tfunction stripShebang(input: string): string;\n\texport = stripShebang;\n}\n"
  },
  {
    "path": "src/typings/dependencies/stripHtmlComments.ts",
    "content": "declare module 'strip-html-comments' {\n\tfunction stripHtmlComments(text: string): string;\n\texport = stripHtmlComments;\n}\n"
  },
  {
    "path": "src/typings/dependencies/to-ast.ts",
    "content": "declare module 'to-ast' {\n\timport { ASTNode } from 'ast-types';\n\n\tfunction toAST(obj: any): ASTNode;\n\texport = toAST;\n}\n"
  },
  {
    "path": "src/typings/dependencies/webpack-merge.ts",
    "content": "declare module 'webpack-merge' {\n\timport { Configuration, WebpackPluginInstance } from 'webpack';\n\n\ttype MetaConfig = Configuration | ((env?: string) => Configuration);\n\ttype mergeFunction = (...configs: MetaConfig[]) => Configuration;\n\ttype customizeArrayFuntion = () => any[];\n\tinterface WebpackMergeOptions {\n\t\tcustomizeArray: customizeArrayFuntion;\n\t}\n\tconst webpackMerge: {\n\t\t(options: WebpackMergeOptions): mergeFunction;\n\t\t(...configs: MetaConfig[]): Configuration;\n\t\tunique(\n\t\t\tkey: string,\n\t\t\tuniques: string[],\n\t\t\tgetter?: (plugin: WebpackPluginInstance) => string | undefined | false\n\t\t): customizeArrayFuntion;\n\t};\n\texport = webpackMerge;\n}\n"
  },
  {
    "path": "src/typings/index.ts",
    "content": "import './dependencies/acorn-jsx';\nimport './dependencies/findup';\nimport './dependencies/listify';\nimport './dependencies/react-docgen';\nimport './dependencies/webpack-merge';\nimport './dependencies/common-dir';\nimport './dependencies/github-slugger';\nimport './dependencies/strip-shebang';\nimport './dependencies/deabsdeep';\nimport './dependencies/glogg';\nimport './dependencies/mini-html-webpack-template';\nimport './dependencies/stripHtmlComments';\nimport './dependencies/deepfreeze';\nimport './dependencies/q-i';\nimport './dependencies/to-ast';\n\nexport * from './RsgComponent';\nexport * from './RsgExample';\nexport * from './RsgPropsObject';\nexport * from './RsgRequireItResult';\nexport * from './RsgSection';\nexport * from './RsgStyleguidistConfig';\nexport * from './RsgTheme';\n"
  },
  {
    "path": "src/typings/test.Classes.d.ts",
    "content": "import { Theme } from './RsgTheme';\n\ndeclare global {\n\t/**\n\t * function used in react tests to generate\n\t * mocks of JSS Class names\n\t */\n\tconst classes: (styles: (theme: Theme) => Record<string, any>) => Record<string, string>;\n}\n"
  },
  {
    "path": "styleguide.config.js",
    "content": "module.exports = {\n\tcomponents: 'src/client/rsg-components/**/[A-Z]*.js',\n\twebpackConfig: {\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\t\texclude: /node_modules/,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.css$/,\n\t\t\t\t\tuse: ['style-loader', 'css-loader'],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n};\n"
  },
  {
    "path": "templates/DefaultExample.md",
    "content": "    <__COMPONENT__>Default Example Usage</__COMPONENT__>\n"
  },
  {
    "path": "test/apps/basic/package.json",
    "content": "{\n  \"name\": \"pizza-basic\",\n  \"devDependencies\": {\n    \"postcss-loader\": \"^7.0.0\"\n  }\n}\n"
  },
  {
    "path": "test/apps/basic/styleguide.config.js",
    "content": "const path = require('path');\n\nconst dir = path.resolve(__dirname, 'lib');\n\nmodule.exports = {\n\ttitle: 'React Style Guide Example',\n\tdefaultExample: true,\n\tcomponents: './components/**/[A-Z]*.js',\n\twebpackConfig: {\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\t\tinclude: dir,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.css$/,\n\t\t\t\t\tinclude: dir,\n\t\t\t\t\tuse: [\n\t\t\t\t\t\t'style-loader',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tloader: 'css-loader',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tmodules: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n};\n"
  },
  {
    "path": "test/apps/basic/webpack.config.js",
    "content": "module.exports = {\n\toutput: 'nope.js',\n\tresolve: {\n\t\textensions: ['.scss'],\n\t},\n};\n"
  },
  {
    "path": "test/apps/cra/package.json",
    "content": "{\n  \"name\": \"pizza-cra\",\n  \"devDependencies\": {\n    \"postcss-loader\": \"^7.0.0\",\n    \"react-scripts\": \"^5.0.0\"\n  }\n}\n"
  },
  {
    "path": "test/apps/defaults/package.json",
    "content": "{\n  \"name\": \"Pizza\"\n}\n"
  },
  {
    "path": "test/apps/defaults/src/components/Button.js",
    "content": ""
  },
  {
    "path": "test/apps/defaults/src/components/Button.md",
    "content": ""
  },
  {
    "path": "test/apps/defaults/src/components/Placeholder.js",
    "content": ""
  },
  {
    "path": "test/apps/defaults/styleguide.config.js",
    "content": "module.exports = {};\n"
  },
  {
    "path": "test/apps/no-webpack/package.json",
    "content": "{\n  \"name\": \"pizza-no-webpack\",\n  \"devDependencies\": {}\n}\n"
  },
  {
    "path": "test/apps/no-webpack/styleguide.config.js",
    "content": "module.exports = {\n\ttitle: 'React Style Guide Example',\n\tcomponents: './components/**/[A-Z]*.js',\n};\n"
  },
  {
    "path": "test/browser.js",
    "content": "/* eslint-disable no-console */\n/* eslint-disable import/no-extraneous-dependencies */\n\nconst puppeteer = require('puppeteer');\nconst path = require('path');\n\nconst args = process.argv.slice(2);\n\nlet browser;\n\nprocess.on('unhandledRejection', (reason) => {\n\tconsole.log('Unhandled Promise rejection:', reason);\n\tif (browser) {\n\t\tbrowser.close().then(() => process.exit(1));\n\t}\n\tprocess.exit(1);\n});\n\nasync function onerror(err) {\n\tconsole.error(err.stack);\n\tif (browser) {\n\t\tawait browser.close();\n\t}\n\tprocess.exit(1);\n}\n\n(async () => {\n\tbrowser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });\n\tconst page = await browser.newPage();\n\tawait page.setViewport({ width: 1024, height: 768 });\n\tpage.on('error', onerror);\n\tpage.on('pageerror', onerror);\n\n\tpage.on('console', (msg) => {\n\t\tif (msg.type() !== 'clear') {\n\t\t\tconsole.log('PAGE LOG:', msg.text());\n\t\t}\n\t});\n\n\tconst url = /https?/.test(args[0]) ? args[0] : `file://${path.resolve(args[0])}`;\n\tawait page.goto(url);\n\n\tif (args[1]) {\n\t\tawait page.screenshot({ path: args[1] });\n\t}\n\n\tawait browser.close();\n})().catch(onerror);\n"
  },
  {
    "path": "test/classes.js",
    "content": "import keymirror from 'keymirror';\nimport * as theme from '../src/client/styles/theme';\n\nexport default (styles) => keymirror(styles(theme));\n"
  },
  {
    "path": "test/components/.eslintrc",
    "content": "{\n\t\"parser\": \"babel-eslint\",\n\t\"extends\": \"tamia/react\",\n\t\"rules\": {\n\t\t\"valid-jsdoc\": 0\n\t}\n}\n"
  },
  {
    "path": "test/components/Annotation/Annotation.js",
    "content": "/* eslint-disable */\nimport styled from 'styled-components';\n\n/**\n * @component\n * Styled-component test\n * */\nexport default styled('div')`\n\tdisplay: inline;\n`;\n"
  },
  {
    "path": "test/components/Button/Button.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\n/**\n * The only true button.\n */\nexport default function Button({ color, size, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tfontSize: Button.sizes[size],\n\t};\n\n\treturn <button style={styles}>{children}</button>;\n}\nButton.propTypes = {\n\t/**\n\t * Button label.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\tcolor: PropTypes.string,\n\tsize: PropTypes.oneOf(['small', 'normal', 'large']),\n\t/**\n\t * A prop that should not be visible in the doc.\n\t * @ignore\n\t */\n\tignoredProp: PropTypes.bool,\n};\nButton.defaultProps = {\n\tcolor: '#333',\n\tsize: 'normal',\n};\nButton.sizes = {\n\tsmall: '10px',\n\tnormal: '14px',\n\tlarge: '18px',\n};\n"
  },
  {
    "path": "test/components/Button/Readme.md",
    "content": "Basic button:\n\n    <Button>Push Me</Button>\n\nBig pink button:\n\n    <Button size=\"large\" color=\"deeppink\">Click Me</Button>\n\nAnd you _can_ **use** `any` [Markdown](http://daringfireball.net/projects/markdown/) here.\n\nIf you define a fenced code block with a language flag it will be rendered as a regular Markdown code snippet:\n\n```javascript\nimport React from 'react'\n```\n"
  },
  {
    "path": "test/components/Label/Label.md",
    "content": "Basic Label:\n\n    <Label>Hi there !!!</Label>\n\nPink background label:\n\n    <Label background=\"deeppink\" color=\"white\">Click Me</Label>\n"
  },
  {
    "path": "test/components/Label/index.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\n/**\n * The only true label.\n */\nexport default function Label({ color, background, children }) {\n\tconst styles = {\n\t\tcolor,\n\t\tbackground,\n\t\tpadding: '.5em 1em',\n\t\tborderRadius: '0.3em',\n\t\tfontFamily: 'arial',\n\t};\n\n\t// eslint-disable-next-line jsx-a11y/label-has-for\n\treturn <label style={styles}>{children}</label>;\n}\nLabel.propTypes = {\n\t/**\n\t * Label text.\n\t */\n\tchildren: PropTypes.string.isRequired,\n\tcolor: PropTypes.string,\n\tbackground: PropTypes.string,\n};\nLabel.defaultProps = {\n\tcolor: '#333',\n\tbackground: 'white',\n};\n"
  },
  {
    "path": "test/components/Placeholder/Placeholder.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\n/**\n * Image placeholders.\n *\n * @example ./examples.md\n * @see {@link link}\n * @link link\n */\nexport default class Placeholder extends Component {\n\tstatic propTypes = {\n\t\ttype: PropTypes.oneOf([\n\t\t\t'animal',\n\t\t\t'bacon',\n\t\t\t'beard',\n\t\t\t'bear',\n\t\t\t'cat',\n\t\t\t'food',\n\t\t\t'city',\n\t\t\t'nature',\n\t\t\t'people',\n\t\t]),\n\t\twidth: PropTypes.number,\n\t\theight: PropTypes.number,\n\t\talt: PropTypes.string,\n\t};\n\n\tstatic defaultProps = {\n\t\ttype: 'animal',\n\t\twidth: 150,\n\t\theight: 150,\n\t\talt: 'Photo of an animal',\n\t};\n\n\t/**\n\t * A public method.\n\t * @public\n\t */\n\tgetImageUrl() {\n\t\tconst { type, width, height } = this.props;\n\t\tconst types = {\n\t\t\tanimal: `http://placeimg.com/${width}/${height}/animals`,\n\t\t\tbacon: `http://baconmockup.com/${width}/${height}`,\n\t\t\tbear: `http://www.placebear.com/${width}/${height}`,\n\t\t\tbeard: `http://placebeard.it/${width}/${height}`,\n\t\t\tcat: `http://lorempixel.com/${width}/${height}/cats`,\n\t\t\tcity: `http://lorempixel.com/${width}/${height}/city`,\n\t\t\tfood: `http://lorempixel.com/${width}/${height}/food`,\n\t\t\tnature: `http://lorempixel.com/${width}/${height}/nature`,\n\t\t\tpeople: `http://lorempixel.com/${width}/${height}/people`,\n\t\t};\n\t\treturn types[type];\n\t}\n\n\tmakeABarrelRoll() {\n\t\treturn 'This is a private method';\n\t}\n\n\trender() {\n\t\tconst { width, height, alt } = this.props;\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"placeholder\"\n\t\t\t\tsrc={this.getImageUrl()}\n\t\t\t\twidth={width}\n\t\t\t\theight={height}\n\t\t\t\talt={alt}\n\t\t\t/>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "test/components/Placeholder/Placeholder.json",
    "content": "{\n  \"customMetadata\": \"This is some sample custom metadata\",\n  \"anotherCustomMetadata\": \"This is some another custom metadata\",\n  \"foo\": true,\n  \"bar\": false\n}\n"
  },
  {
    "path": "test/components/Placeholder/Placeholder.md",
    "content": "    <Placeholder type=\"beard\"/>\n"
  },
  {
    "path": "test/components/Placeholder/examples.md",
    "content": "Hello world!\n"
  },
  {
    "path": "test/components/Price/Price.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nconst unitSymbols = {\n\tUSD: '$',\n\tEUR: '€',\n};\n\n/**\n * Price component that renders a price and a unit.\n */\nexport default function Price(props) {\n\tlet Host = 'span';\n\tif (props.emphasize) {\n\t\tHost = 'em';\n\t}\n\treturn (\n\t\t<Host>\n\t\t\t{props.value}\n\t\t\t{!props.symbol ? props.unit : unitSymbols[props.unit]}\n\t\t</Host>\n\t);\n}\n\nPrice.propTypes = {\n\t/** Price value. */\n\tvalue: PropTypes.number.isRequired,\n\t/** Price unit */\n\tunit: PropTypes.oneOf(['EUR', 'USD']),\n\t/** Flag that determines if the price should be emphasized or not. */\n\temphasize: PropTypes.bool,\n\t/** Defines if the unit should be shown as a symbol or not. */\n\tsymbol: PropTypes.bool.isRequired,\n};\n"
  },
  {
    "path": "test/components/RandomButton/RandomButton.js",
    "content": "import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport sample from 'lodash/sample';\n\n/**\n * Button that changes label on every click.\n */\nexport default class RandomButton extends Component {\n\tstatic propTypes = {\n\t\t/**\n\t\t * List of possible labels.\n\t\t */\n\t\tvariants: PropTypes.array.isRequired,\n\t};\n\n\tconstructor(props) {\n\t\tsuper();\n\t\tthis.state = {\n\t\t\tlabel: sample(props.variants),\n\t\t};\n\t}\n\n\thandleClick = () => {\n\t\tthis.setState({\n\t\t\tlabel: sample(this.props.variants),\n\t\t});\n\t};\n\n\trender() {\n\t\treturn <button onClick={this.handleClick}>{this.state.label}</button>;\n\t}\n}\n"
  },
  {
    "path": "test/cypress/.eslintrc",
    "content": "{\n  \"env\": {\n    \"mocha\": true\n  }\n}\n"
  },
  {
    "path": "test/cypress/fixtures/example.json",
    "content": "{\n  \"name\": \"Using fixtures to represent data\",\n  \"email\": \"hello@cypress.io\",\n  \"body\": \"Fixtures are a great way to mock data for responses to routes\"\n}"
  },
  {
    "path": "test/cypress/integration/component_spec.js",
    "content": "describe('Single component', () => {\n\tbefore(() => {\n\t\t// Open simple button component in isolation\n\t\tcy.visit('/#!/Button');\n\t});\n\n\tdescribe('props and methods section', () => {\n\t\tbeforeEach(() => {\n\t\t\tcy.get('button').contains('Props & methods').as('propsBtn');\n\n\t\t\tcy.get('@propsBtn').closest('[class^=rsg--tabs]').as('container');\n\t\t});\n\n\t\tit('is present', () => {\n\t\t\tcy.get('@propsBtn').should('exist');\n\t\t});\n\n\t\tit('does not show table initially', () => {\n\t\t\tcy.get('@container').find('table').should('not.exist');\n\t\t});\n\n\t\tit('shows the table on button click', () => {\n\t\t\tcy.get('@propsBtn').click();\n\t\t\tcy.get('@container').find('table').should('contain', 'Prop name');\n\t\t});\n\t});\n\n\tdescribe('preview section', () => {\n\t\tbeforeEach(() => {\n\t\t\tcy.get('[data-testid*=\"-example-\"]')\n\t\t\t\t.as('container')\n\t\t\t\t.find('[class^=rsg--preview]')\n\t\t\t\t.as('preview');\n\n\t\t\tcy.get('@container').find('button').contains('View Code').as('viewCodeBtn');\n\t\t});\n\n\t\tit('renders component preview', () => {\n\t\t\tcy.get('@preview').find('button', { timeout: 10000 }).contains('Push Me').should('exist');\n\t\t});\n\n\t\tit('has view code button', () => {\n\t\t\tcy.get('@viewCodeBtn').should('exist');\n\t\t});\n\n\t\tit('does not show code initially', () => {\n\t\t\tcy.get('@container').find('textarea').should('not.exist');\n\t\t});\n\n\t\tit('shows code on click', () => {\n\t\t\tcy.get('@viewCodeBtn').click();\n\t\t\tcy.get('@container').find('textarea').should('exist');\n\t\t});\n\n\t\tit('changes the render after code change', () => {\n\t\t\tconst codeToSkip = '</Button>';\n\t\t\tcy.get('@container')\n\t\t\t\t.find('textarea')\n\t\t\t\t.type(`${'{leftarrow}'.repeat(codeToSkip.length)} Harder`);\n\n\t\t\tcy.get('@preview').find('button').contains('Push Me Harder').should('exist');\n\t\t});\n\n\t\tit('toggles isolated example mode correctly', () => {\n\t\t\tcy.get('[data-testid$=\"-examples\"]').as('componentExamples');\n\n\t\t\t// Toggle into isolated example mode\n\t\t\tcy.get('@componentExamples').find('[data-testid$=\"-isolate-button\"]').first().click();\n\n\t\t\t// Assert that there is only one example showing\n\t\t\tcy.get('@componentExamples').find('[data-testid*=\"-example-\"]').should('have.length', 1);\n\n\t\t\t// Toggle out of isolated example mode\n\t\t\tcy.get('[data-testid$=\"-isolate-button\"]').click();\n\n\t\t\t// Assert the other examples are showing again\n\t\t\tcy.get('@componentExamples')\n\t\t\t\t.find('[data-testid*=\"-example-\"]')\n\t\t\t\t.should('have.length.above', 1);\n\n\t\t\t// Check that we've returned to isolated component mode instead of normal mode\n\t\t\t// TODO: this is currently bugged (returns to normal mode rather than isolated component mode)\n\t\t\t//cy.get('[id$=container]').should('have.length', 1);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "test/cypress/integration/core_spec.js",
    "content": "describe('Styleguidist core', () => {\n\tbefore(() => cy.visit('/'));\n\n\tit('loads the page', () => {\n\t\tcy.title().should('include', 'React Styleguidist');\n\t});\n\n\tit('shows multiple components in normal mode', () => {\n\t\tcy.get('[data-testid$=-container]').should('have.length.above', 1);\n\t});\n\n\tit('toggles isolated component mode correctly', () => {\n\t\tcy.get('[data-testid=sidebar]').as('sidebar');\n\n\t\t// Toggle into isolated mode\n\t\tcy.get('[data-testid$=\"-isolate-button\"]').first().click();\n\n\t\t// Assert there's only one component showing\n\t\tcy.get('[data-testid$=-container]').should('have.length', 1);\n\n\t\t// Assert the sidebar is no longer showing\n\t\tcy.get('@sidebar').should('not.exist');\n\n\t\t// Toogle out of isolated mode\n\t\tcy.get('[data-testid$=\"-isolate-button\"]').first().click();\n\n\t\t// Assert that more than one component is now showing\n\t\tcy.get('[data-testid$=-container]').should('have.length.above', 1);\n\n\t\t// Asser that the sidebar is now showing again\n\t\tcy.get('@sidebar').should('exist');\n\t});\n});\n"
  },
  {
    "path": "test/cypress/plugins/index.js",
    "content": "// ***********************************************************\n// This example plugins/index.js can be used to load plugins\n//\n// You can change the location of this file or turn off loading\n// the plugins file with the 'pluginsFile' configuration option.\n//\n// You can read more here:\n// https://on.cypress.io/plugins-guide\n// ***********************************************************\n\n// This function is called when a project is opened or re-opened (e.g. due to\n// the project's config changing)\n\nmodule.exports = (/* on, config */) => {\n\t// `on` is used to hook into various events Cypress emits\n\t// `config` is the resolved Cypress config\n};\n"
  },
  {
    "path": "test/cypress/support/commands.js",
    "content": "// ***********************************************\n// This example commands.js shows you how to\n// create various custom commands and overwrite\n// existing commands.\n//\n// For more comprehensive examples of custom\n// commands please read more here:\n// https://on.cypress.io/custom-commands\n// ***********************************************\n//\n//\n// -- This is a parent command --\n// Cypress.Commands.add(\"login\", (email, password) => { ... })\n//\n//\n// -- This is a child command --\n// Cypress.Commands.add(\"drag\", { prevSubject: 'element'}, (subject, options) => { ... })\n//\n//\n// -- This is a dual command --\n// Cypress.Commands.add(\"dismiss\", { prevSubject: 'optional'}, (subject, options) => { ... })\n//\n//\n// -- This is will overwrite an existing command --\n// Cypress.Commands.overwrite(\"visit\", (originalFn, url, options) => { ... })\n"
  },
  {
    "path": "test/cypress/support/index.js",
    "content": "// ***********************************************************\n// This example support/index.js is processed and\n// loaded automatically before your test files.\n//\n// This is a great place to put global configuration and\n// behavior that modifies Cypress.\n//\n// You can change the location of this file or turn off\n// automatically serving support files with the\n// 'supportFile' configuration option.\n//\n// You can read more here:\n// https://on.cypress.io/configuration\n// ***********************************************************\n\n// Import commands.js using ES2015 syntax:\n// import './commands'\n\n// Alternatively you can use CommonJS syntax:\n// require('./commands')\n"
  },
  {
    "path": "test/data/badconfig.config.js",
    "content": "module.exports = {\n\ttitle: 'React Style Guide Example',\n\t// No components or sections: one of these fields is required\n};\n"
  },
  {
    "path": "test/data/styleguide.config.js",
    "content": "const path = require('path');\n\nconst dir = path.resolve(__dirname, 'lib');\n\nmodule.exports = {\n\ttitle: 'React Style Guide Example',\n\tdefaultExample: true,\n\tcomponents: './components/**/[A-Z]*.js',\n\twebpackConfig: {\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\t\tinclude: dir,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.css$/,\n\t\t\t\t\tinclude: dir,\n\t\t\t\t\tuse: [\n\t\t\t\t\t\t'style-loader',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tloader: 'css-loader',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tmodules: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n};\n"
  },
  {
    "path": "test/data/webpack.config.func.js",
    "content": "module.exports = (env) => ({\n\toutput: 'nope.js',\n\tresolve: {\n\t\textensions: [env],\n\t},\n});\n"
  },
  {
    "path": "test/data/webpack.config.js",
    "content": "module.exports = {\n\toutput: 'nope.js',\n\tresolve: {\n\t\textensions: ['.scss'],\n\t},\n};\n"
  },
  {
    "path": "test/deabsdeepSerializer.js",
    "content": "const escape = require('escape-string-regexp');\nconst isObject = require('is-plain-obj');\nconst path = require('path');\n\nconst MASK = '~';\nconst DIRNAME = getRootDir();\n\n/**\n * Recursively replace absolute paths in object keys and values or in array values with a “~”.\n *\n * @param {object} obj\n * @param {object} [options]\n * @param {string} [options.root]\n * @param {string} [options.mask]\n * @return {object}\n */\nfunction deabsDeep(obj, options) {\n\toptions = options || {};\n\tconst root = options.root || DIRNAME;\n\tconst mask = options.mask || MASK;\n\n\tconst regExp = new RegExp(escape(root), 'g');\n\tconst deabs = (s) => (typeof s === 'string' ? s.replace(regExp, mask) : s);\n\n\tif (Array.isArray(obj)) {\n\t\treturn obj.map(deabs);\n\t}\n\n\treturn mapObj(obj, (key, value) => [deabs(key), deabs(value)]);\n}\n\nfunction getRootDir(dir) {\n\tdir = dir || __dirname;\n\tconst m = dir.match(/[\\\\/]node_modules[\\\\/]/);\n\treturn m ? dir.substring(0, m.index) : path.resolve(__dirname, '..');\n}\n\n/* istanbul ignore next */\nfunction mapObj(obj, fn, seen) {\n\tseen = seen || new WeakMap();\n\tif (seen.has(obj)) {\n\t\treturn seen.get(obj);\n\t}\n\n\tconst target = {};\n\n\tseen.set(obj, target);\n\n\tfor (const key of Object.keys(obj)) {\n\t\tconst val = obj[key];\n\t\tconst res = fn(key, val, obj);\n\t\tlet newVal = res[1];\n\n\t\tif (isObject(newVal)) {\n\t\t\tif (Array.isArray(newVal)) {\n\t\t\t\tnewVal = newVal.map((x) => (isObject(x) ? mapObj(x, fn, seen) : x));\n\t\t\t} else {\n\t\t\t\tnewVal = mapObj(newVal, fn, seen);\n\t\t\t}\n\t\t}\n\n\t\ttarget[res[0]] = newVal;\n\t}\n\n\t// The $$typeof property is a React marker that's used for serialization.\n\t// deabsdeep doesn't know about React Elements but since it's registered globally,\n\t// it should keep this property on the object.\n\tif (obj.$$typeof) {\n\t\ttarget.$$typeof = obj.$$typeof;\n\t}\n\n\treturn target;\n}\n\n// Borrowed from https://github.com/eyolas/jest-serializer-supertest\nconst KEY = '__JEST_SERIALIZER_DEABSDEEP__';\n\nmodule.exports = {\n\ttest(val) {\n\t\treturn (Array.isArray(val) || isObject(val)) && !Object.prototype.hasOwnProperty.call(val, KEY);\n\t},\n\tprint(val, serialize) {\n\t\tconst newVal = deabsDeep(val);\n\n\t\t// To skip maximum call stack size exceeded\n\t\tObject.defineProperty(newVal, KEY, {\n\t\t\tenumerable: false,\n\t\t});\n\n\t\treturn serialize(newVal);\n\t},\n};\n"
  },
  {
    "path": "test/empty.js",
    "content": "module.exports = '';\n"
  },
  {
    "path": "test/jestsetup.js",
    "content": "/* eslint-disable no-console */\n\nimport keymirror from 'keymirror';\nimport * as theme from '../src/client/styles/theme';\n\n// Get class names from styles function\nglobal.classes = (styles) => keymirror(styles(theme));\n\njest.mock('react-scripts/config/webpack.config.dev', () => ({ cra: true }), { virtual: true });\njest.mock('webpack-dev-server', function () {\n\treturn function () {\n\t\treturn {\n\t\t\tapp: {},\n\t\t};\n\t};\n});\n"
  },
  {
    "path": "test/raf-polyfill.js",
    "content": "// requestAnimationFrame “polyfill”\nwindow.requestAnimationFrame = (a) => a();\nglobal.requestAnimationFrame = window.requestAnimationFrame;\n"
  },
  {
    "path": "test/run.build.js",
    "content": "/* eslint-disable no-console */\n\nconst styleguidist = require('../lib/scripts');\n\nstyleguidist(require('../examples/basic/styleguide.config.js')).build((err, config) => {\n\tif (err) {\n\t\tconsole.log(err);\n\t} else {\n\t\tconsole.log('Style guide published to', config.styleguideDir);\n\t}\n});\n"
  },
  {
    "path": "test/run.server.js",
    "content": "/* eslint-disable no-console */\n\nconst path = require('path');\nconst styleguidist = require('../lib/scripts');\n\nconst dir = path.resolve(__dirname, '../examples/basic/src');\n\nstyleguidist({\n\tcomponents: path.resolve(dir, 'components/**/[A-Z]*.js'),\n\twebpackConfig: {\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\t\tinclude: dir,\n\t\t\t\t\tloader: 'babel-loader',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.css$/,\n\t\t\t\t\tinclude: dir,\n\t\t\t\t\tuse: [\n\t\t\t\t\t\t'style-loader',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tloader: 'css-loader',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tmodules: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\tmoduleAliases: {\n\t\t'rsg-example': dir,\n\t},\n\tlogger: {\n\t\tinfo: console.log,\n\t\twarn: (message) => console.warn(`Warning: ${message}`),\n\t},\n\tserverPort: 8082,\n\t// Do not require delays in integration tests\n\tpreviewDelay: 0,\n}).server((err, config) => {\n\tif (err) {\n\t\tconsole.log(err);\n\t} else {\n\t\tconsole.log('Listening at http://' + config.serverHost + ':' + config.serverPort);\n\t}\n});\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"esnext\",\n    \"module\": \"es2015\",\n    \"baseUrl\": \".\",\n    \"moduleResolution\": \"node\",\n    \"jsx\": \"react\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"noUnusedLocals\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"outDir\": \"./lib\",\n    \"lib\": [\"dom\"],\n    \"skipLibCheck\": true,\n    \"paths\": {\n      \"rsg-components/*\": [\"src/client/rsg-components/*\"]\n    }\n  },\n  \"files\": [\"dangerfile.ts\"],\n  \"include\": [\"src\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "tsconfig.types.json",
    "content": "{\n\t\"extends\": \"./tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t// only generate typings when using this tsconfig\n\t\t\"declaration\": true\n\t},\n\t// ignore the dangerfile in calculation of the root folder\n\t\"files\": [],\n\t// avoid generating typings for tests and mocks\n\t\"exclude\": [\n\t\t\"dangerfile.ts\",\n\t\t\"node_modules\",\n\t\t\"**/__tests__/*.ts\",\n\t\t\"**/__mocks__/*.ts\",\n\t\t\"**/*.spec.tsx\",\n\t\t\"**/*.spec.ts\"\n\t]\n}\n"
  }
]