{"id":31914950,"url":"https://github.com/apennell/annies-component-lab","last_synced_at":"2026-05-04T18:40:41.214Z","repository":{"id":39496087,"uuid":"98236967","full_name":"apennell/annies-component-lab","owner":"apennell","description":"Component library for building reusable React components and displaying their use in a living style guide","archived":false,"fork":false,"pushed_at":"2023-01-05T06:22:19.000Z","size":2401,"stargazers_count":0,"open_issues_count":21,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-13T19:44:46.050Z","etag":null,"topics":["css-modules","documentation","livingstyleguide","react","styleguide","styleguidist"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apennell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-24T21:35:34.000Z","updated_at":"2020-10-11T23:36:00.000Z","dependencies_parsed_at":"2023-02-03T15:31:52.859Z","dependency_job_id":null,"html_url":"https://github.com/apennell/annies-component-lab","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/apennell/annies-component-lab","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apennell%2Fannies-component-lab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apennell%2Fannies-component-lab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apennell%2Fannies-component-lab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apennell%2Fannies-component-lab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apennell","download_url":"https://codeload.github.com/apennell/annies-component-lab/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apennell%2Fannies-component-lab/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32620511,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-04T10:08:07.713Z","status":"ssl_error","status_checked_at":"2026-05-04T10:08:02.005Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css-modules","documentation","livingstyleguide","react","styleguide","styleguidist"],"created_at":"2025-10-13T19:43:12.046Z","updated_at":"2026-05-04T18:40:41.198Z","avatar_url":"https://github.com/apennell.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Annie's Component Lab :art: :curly_loop: :computer: :curly_loop: :information_desk_person:\n\n### [Annie](http://anniepennell.com/)'s new and improved ✨ example component lab.\n\nThis is a living style guide and component lab that provides a toolbox of UI components for reuse within React apps.\n\n## Contents\n\n- [Implementing the Lab Components](#implementing-the-lab-components)\n- [Lab Component Development](#lab-component-development)\n  - [Code style](#code-style)\n  - [Scripts](#scripts)\n  - [Adding components](#adding-components)\n  - [Documenting components](#documenting-components)\n  - [Styling components](#styling-components)\n  - [Running tests](#running-tests)\n- [Lab Skeleton](#lab-skeleton) (packages and dependencies)\n  - [React Styleguidist](#react-styleguidist)\n  - [styled-components](#styled-components)\n\n## Implementing the Lab Components\n\nTo include the component lab's components into your project, you must manually add this git repository's address into your project's `package.json` dependencies, as follows:\n\n```\n  \"dependencies\": {\n    \"annies-component-lab\": \"git@github.com:apennell/annies-component-lab.git#main\"\n  }\n```\n\nThis will pull from the `main` branch of the `annies-component` repository, although you can replace `main` in the link with a version number, a tag name, or a commit hash.\n\nNote: If you are using a branch name, new commits will **not** be automatically pulled into your project when you perform npm install / updates. Instead, you will need to manually remove the `annies-component-lab` package from your project component(s)'s `node_modules` and then run `npm install` again.\n\nOnce you have the dependency installed, you'll need to import the specific individual components into your project's component. For example, to add the `\u003cButton /\u003e` component from the lab to a React component in the app, add at the top of your `.jsx` file:\n\n```js\nimport { Button } from 'annies-component-lab';\n```\n\nYou will now be able to use `\u003cButton /\u003e` like any other jsx component.\n\n## Lab Component Development\n\n### Code style\n\nFollow the code standards of Airbnb's language style guides, so please consult them as you code and ensure that anything you write adheres to the code style defined there.\n\n- [JavaScript guide](http://airbnb.io/projects/javascript/)\n- [React/JSX guide](https://github.com/airbnb/javascript/tree/master/react)\n- [CSS/Sass guide](https://github.com/airbnb/css)\n\n### Scripts\n\n#### `npm install`\n\nInstall dependencies; run first before getting started!\n\n#### `npm start`\n\nStarts a styleguide dev server then watches for and compiles changes.\n\nOpen [http://localhost:6060](http://localhost:6060) to view the styleguide in the browser.\n\n#### `npm run styleguide:build`\n\nBuilds a static version of the component lab.\n\n#### `npm test`\n\nRuns latest tests since last commit. `npm test -- --coverage` will show overall test coverage.\n\nAlthough being able to see all green passes, \"Chasing 100% coverage is usually a misleading goal, and\" [they don't want](https://github.com/facebookincubator/create-react-app/issues/2507) to give people the feeling that [they] encourage that.\" So, suppress your inner A+ student.\n\n\u003c!-- TODO: update with rollup added --\u003e\n\u003c!-- #### `npm run dist`\n\nBundles components into a library that can be redistributed externallly via npm.\n\nTo [include the component lab's components](#implementing-the-lab-components) into your project, you must manually add this git repository's address into your project's `package.json` dependencies, as follows:\n\n```\n  \"dependencies\": {\n    \"annies-component-lab\": \"https://github.com/apennell/annies-component-lab.git#master\"\n  }\n```\n\nReplace `\u003cVERSION_NUMBER\u003e` with one of the following:\n\n- a branch name\n- a version number\n- a tag name\n- a commit hash\n\nIf you are using a branch name, new commits will **not** be automatically pulled into your project when you perform npm install / updates. Instead, you will need to manually remove the `annies-component-lab` package from your project component(s)'s `node_modules` and then run `npm install` again. [Read more about version numbers](https://stackoverflow.com/a/22345808). --\u003e\n\n### Adding components\n\n1. **Create a directory** for the component within `src/components` in the proper section, e.g. a button component is in the Element section, so `src/components/Elements/Button`.\n\n   - If you're making a new section within `/components` (like if `Elements` didn't already exist in the previous example), add the new section to `styleguide.config.js` to have it included. Give it a `name` and assign the `components` key to the location where the components can be found. You can also direct it to a content path to include a markdown file at the top of the section.\n     ```js\n     module.exports = {\n       title: \"Annie's Component Lab\",\n       sections: [\n         {\n           name: 'Elements',\n           content: './docs/Elements.md',\n           components: './src/components/Elements/**/[A-Z]*.jsx'\n         }\n       ]\n     };\n     ```\n\n2. **Add a `.jsx` file** for your component in that directory, e.g. `/Button/Button.jsx`. You will build your component here.\n\n   - Include `import React from 'react';` and `import PropTypes from 'prop-types';` at the top of your file.\n   - You can add a description (using the syntax noted [below](#documenting*components)) at the top of the component, just below the `import` statements.\n   - Construct your component, making sure to include `propTypes` and `defaultProps`.\n   - Add comments above each propType to give it a [description for the style guide output](#documenting-components).\n\n   Basic structure of `.jsx` component file:\n\n   ```js\n   /** src/components/Elements/Button/Button.jsx */\n   import React from 'react';\n   import PropTypes from 'prop-types';\n\n   /** Construct stateless functional Button component */\n   const Button = ({ children, onClick, buttonStyle, size }) =\u003e {\n     /**\n      * Get buttonStyle and size css CSS Modules styles object\n      * Combine them into one class using classnames package\n      */\n     let className = cx(styles[buttonStyle], styles[`${size}Size`]);\n\n     return (\n       \u003cbutton onClick={onClick} className={className}\u003e\n         {children}\n       \u003c/button\u003e\n     );\n   };\n\n   /** Define all available proptypes with description */\n   Button.propTypes = {\n     /** Button label */\n     children: PropTypes.string.isRequired,\n     /** Function to call when button is clicked */\n     onClick: PropTypes.func,\n     /** Button's style type */\n     buttonStyle: PropTypes.oneOf(['normal', 'primary', 'inverse', 'textLink']),\n     /** Size of the button */\n     size: PropTypes.oneOf(['normal', 'large']),\n     /** Set true if button should be full-width, else leave blank */\n     isFullWidth: PropTypes.bool\n   };\n\n   /** Set all default props for non-required props */\n   Button.defaultProps = {\n     buttonStyle: 'normal',\n     size: 'normal',\n     isFullWidth: false\n   };\n\n   export default Button;\n   ```\n\n3. **Add a component `README.md`** titled after the component in its directory, e.g. `/Button/Button.md`. _This is where you will [document the component](https://github.com/apennell/annies-component-lab#documenting-components) and display examples of it to render in the component lab_. Any code block without a language tag will be rendered as a React component (the examples) with a live preview and its code. The code block in the component lab is editable in the browser!\n\n   - Using markdown, start with any necessary notes or descriptions provided by Design.\n   - Provide code examples showing the use of available props, options and variations.\n   - For example, for `\u003cButton /\u003e`, there is a section with an example of each of the following: options (button style), size, tags, and states. In the size example, there are default, large, and full-width buttons shown.\n   - Add any additional instructions, descriptions, or notes from Design along with each of these examples so their purpose and implementation can be clearly understood without further explanation.\n\n[Styleguidist](https://react-styleguidist.js.org/docs/components.html) searches and parses components following the global structure of `src/components/**/*.{js, jsx}`. It ignores test files (`__tests__` directory and files names containing .`test.js, .test.jsx, .spec.js and .spec.jsx`).\n\nThe general file structure should be as follows:\n\n```\nstyleguide-1.0\n  |__docs // additional md docs that can be included as a component but are necessary for the style guide\n     |__{Identity}.md\n  |__src\n     |__components\n        |__Elements\n           |__Button\n              |__Button.jsx\n              |__Button.md\n           |__Modal\n              |__Modal.jsx\n              |__Modal.md\n         |__Pages\n            |__SomePage\n  |__styleguide // style guide build files--gitignore these\n     |__build\n  |__styleguide.config.js // configuration for styleguidist\n```\n\nThe style guide components build into `styleguide/build`, however the `styleguide` directory should be included in the `.gitignore` file.\n\n### Documenting components\n\nFormat for documentation to be parsed and appear in component lab:\n\n```\n/**\n* Documentation text here. Markdown is *supported*.\n*/\n```\n\n- By default, any methods your components have are considered to be private and are not published. Mark your public methods with JSDoc `@public` tag to get them published in the docs.\n- By default, all props in components are considered public and published in component lab docs. If you need to remove a prop from the documentation but keep in code, mark with JSDoc `@ignore` tag in the comment/description are directly above that prop.\n- Available JSDocs tags for documenting components, props, and methods: [@deprecated](http://usejsdoc.org/tags-deprecated.html), [@see, @link](http://usejsdoc.org/tags-see.html), [@author](http://usejsdoc.org/tags-author.html), [@since](http://usejsdoc.org/tags-since.html), and [@version](http://usejsdoc.org/tags-version.html). You can also use [@param, @arg, @argument](http://usejsdoc.org/tags-param.html) for documenting props.\n- Code examples in Markdown files use ES6+JSX syntax and can access all components in the component lab using global variables (although ES6 `import` syntax isn't supported within these files), e.g.:\n\n  ```\n  \u003cPanel\u003e\n    \u003cp\u003eUsing the Button component in the example of the Panel component:\u003c/p\u003e\n    \u003cButton\u003ePush Me\u003c/Button\u003e\n  \u003c/Panel\u003e\n  ```\n\n- Each example (in the `ComponentName.md` file) has its own state, accessible with the `state` variable and changed with the `setState` function:\n\n  ```\n  initialState = { isOpen: false };\n  \u003cdiv\u003e\n    \u003cbutton onClick={() =\u003e setState({ isOpen: true })}\u003eOpen\u003c/button\u003e\n    \u003cModal isOpen={state.isOpen}\u003e\n      \u003ch1\u003eHallo!\u003c/h1\u003e\n      \u003cbutton onClick={() =\u003e setState({ isOpen: false })}\u003eClose\u003c/button\u003e\n    \u003c/Modal\u003e\n  \u003c/div\u003e\n  ```\n\n**View more documentation in [Styleguidist's Cookbook](https://react-styleguidist.js.org/docs/cookbook.html).**\n\n### Styling components\n\nTo modularize our styles and classes and reduce the risk of global namespacing and clashing, we are using **[styled-components](https://styled-components.com/)**.\n\nTodo :)\n\n#### Configuration\n\nTodo! :)\n\n### Running Tests\n\nWe are using [Jest](https://facebook.github.io/jest/) as the test runner with React Testing Library.\n\n1. Create a file `*.test.js` within the directory of the component to test, i.e. `src/components/Elements/Button/Button.test.js` for a `\u003cButton /\u003e` test.\n2. Start with a simple [smoke test](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#testing-components) to make sure the component simply mounts and doesn't throw during rendering.\n3. Write more tests, focusing on the user's perspective. Example of testing a button's `onClick` event:\n\n```jsx\nimport React from 'react';\nimport userEvent from '@testing-library/user-event';\n\nimport { render, screen } from 'test-utils';\nimport Button from './Button';\n\ndescribe('Button', () =\u003e {\n  test('should render button with text', () =\u003e {\n    render(\u003cButton\u003eClick Me!\u003c/Button\u003e);\n    const button = screen.getByRole('button', { name: /click me/i });\n    expect(button).toBeInTheDocument();\n  });\n\n  test('should handle click event', () =\u003e {\n    const onClickMock = jest.fn();\n    render(\u003cButton onClick={onClickMock}\u003eClick Me\u003c/Button\u003e);\n    const button = screen.getByRole('button', { name: /click me/i });\n    userEvent.click(button);\n    expect(onClickMock).toBeCalled();\n  });\n});\n```\n\n4. Run `npm test` to run the latest tests since the last commit. `npm test -- --coverage` will show overall test coverage. Run `npm run jest --watch` to run the tests in watch mode as you develop.\n\n**Testing Resources and Docs**\n\n- [Jest](http://facebook.github.io/jest/docs/getting-started.html)\n- [Jest Mock Functions API](http://facebook.github.io/jest/docs/mock-function-api.html)\n\u003c!-- TODO! Add mawr resources --\u003e\n\n## Lab Skeleton\n\n### React Styleguidist\n\nThe component lab/style guide was built using **[React Styleguidist](https://react-styleguidist.js.org/)**. Usage of this package in our component lab is pretty well-documented here, but checkout their documents and [cookbook](https://react-styleguidist.js.org/docs/cookbook.html) for more information.\n\n### styled-components\n\nTo modularize our styles and classes and reduce the risk of global namespacing and clashing, we are using **[styled-components](https://styled-components.com/)**. See the section on [styling components](#styling-components) for more on our implementation.\n\n#### Updating to New Releases\n\nTODO :)\n\n\u003c!-- TODO! --\u003e\n\u003c!-- #### Folder Structure\n\nFor the project to build, **these files must exist with exact filenames**:\n\n- `public/index.html` is the page template;\n- `src/index.js` is the JavaScript entry point.\n\nYou can delete or rename the other files.\n\nYou may create subdirectories inside `src`. For faster rebuilds, only files inside `src` are processed by Webpack.\u003cbr\u003e\nYou need to **put any JS and CSS files inside `src`**, or Webpack won’t see them.\n\nOnly files inside `public` can be used from `public/index.html`.\n\nYou can, however, create more top-level directories. They will not be included in the production build so you can use them for things like documentation. --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapennell%2Fannies-component-lab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapennell%2Fannies-component-lab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapennell%2Fannies-component-lab/lists"}