{"id":20983753,"url":"https://github.com/victorgaard/playground","last_synced_at":"2025-06-19T06:33:33.509Z","repository":{"id":215605994,"uuid":"739320801","full_name":"victorgaard/playground","owner":"victorgaard","description":"Playground - Design System Documentation for React ✨","archived":false,"fork":false,"pushed_at":"2024-06-23T12:21:01.000Z","size":758,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-14T16:44:54.816Z","etag":null,"topics":["components-react","design-system","javascript","react","tailwindcss","typescript","vite"],"latest_commit_sha":null,"homepage":"https://playground.victorsantos.work","language":"TypeScript","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/victorgaard.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-05T09:34:16.000Z","updated_at":"2025-02-26T06:01:26.000Z","dependencies_parsed_at":"2024-01-24T17:30:10.774Z","dependency_job_id":"15f7169b-aa4a-4092-b0bd-da6d3455bf3f","html_url":"https://github.com/victorgaard/playground","commit_stats":null,"previous_names":["victorgaard/playground-vite","victorgaard/playground"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/victorgaard/playground","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorgaard%2Fplayground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorgaard%2Fplayground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorgaard%2Fplayground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorgaard%2Fplayground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/victorgaard","download_url":"https://codeload.github.com/victorgaard/playground/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorgaard%2Fplayground/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260702099,"owners_count":23049169,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["components-react","design-system","javascript","react","tailwindcss","typescript","vite"],"created_at":"2024-11-19T05:50:00.742Z","updated_at":"2025-06-19T06:33:28.496Z","avatar_url":"https://github.com/victorgaard.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003cimg src=\"https://github.com/victorgaard/playground/assets/13384559/bdeefd10-bdcf-49bf-b4c0-d282035f3bb6\" /\u003e\n\nPlayground is a design system documentation tool for React components. My motivation to build it is purely educational and aimed towards making a lighter alternative to Storybook. It is also a great opportunity to hone my design \u0026 engineering skills. \n\n🛠️ Built with React, Typescript, TanStack Router, and Tailwind. All baked with Vite. \u003cbr /\u003e\n👉 [Live demo](https://playground.victorsantos.work/) hosted at Netlify.\u003cbr /\u003e \u003cbr /\u003e\n[![Netlify Status](https://api.netlify.com/api/v1/badges/e2567937-271f-4ca2-bdcd-64f341b01b9e/deploy-status)](https://app.netlify.com/sites/glittery-tarsier-f22d47/deploys)\n\n----\n\n## How Playground works\nPlayground relies on playground extension files to do its magic. For every `.playground.ts|tsx` file, a new entry will be added to the routes when the server runs and/or in the build process. You will notice that a small script `generateRoutes` runs before each of these two. This is important to generate the components navigation menu. \n\n## Getting started\nRunning the project is quite simple:\n\n- Clone this project\n- Install the dependencies `npm i`\n- Run the server with `npm run dev`\n\n## Creating playground files\nLet's create a playground file:\n\n- Create a file for your component with the `.playground.ts|tsx` extension\n- Assuming you have a Button component, create a `Button.playground.tsx` file\n- Export a props const and use the `generateProps` helper \n- If you use Typescript, pass your component type to `generateProps` to have out of the box type safety\n\n```typescript\nimport { generateProps } from \"@/utils/generateProps\";\n\nexport const props = generateProps\u003cButtonProps\u003e({\n  Component: Button,\n  defaultProps: {\n    // this is where the Button required props will be defined\n    children: \"👉 click me\",\n    variant: \"primary\",\n    size: \"md\"\n  },\n});\n```\n\n- Now run `npm run routes` or `npm run dev` to propagate your playground file to the routes\n  \nYou probably (🤞) see your component in the navigation menu now, right? \u003cbr /\u003e\nFeel free to refer to the examples inside the folder `./src/components/ui`.\n\n## Enhancing the playground\nYou just added your first component to the playground and you visualize it there. Hoorray! 🎉 \u003cbr /\u003e\nBut let's not stop there. There are more you can enhance your component playground. You can define variant props, as well as examples.\n\n- Variant props are a way to provide shortcuts in the playground UI, i.e.: a Button can have two sizes, like 'sm' and 'md'. If you pass an array of `['sm', 'md']` to the variant props, they will be offered in the props sidebar as radio buttons.\n- Examples are a way to provide component presets, i.e.: you can create a small destructive button by defining these props as an example.\n- Let's jump to another example:\n\n```typescript\nexport const props = generateProps\u003cButtonProps\u003e({\n  Component: Button,\n  defaultProps: {\n    children: \"👉 click me\",\n    variant: \"primary\",\n    size: \"md\"\n  },\n  variantProps: {\n    // these will appear as radio buttons in the playground UI\n    variant: [\"primary\", \"secondary\", \"tertiary\", \"ghost\", \"destructive\"],\n    size: [\"sm\", \"md\"]\n  },\n  examples: {\n    // these will appear as top navigation presets, on the side of the Default option\n    destructive: {\n      children: \"👀 uh-oh danger zone\",\n      size: \"sm\"\n      variant: \"destructive\",\n    },\n  },\n});\n```\n\nThis code will output this playground UI for your button:\n\n|Default:|Destructive example:\n----------|----------\n|\u003cimg width=\"1265\" alt=\"image\" src=\"https://github.com/victorgaard/playground/assets/13384559/3394f517-dd24-47f3-a6aa-25f15402efdd\"\u003e|\u003cimg width=\"1265\" alt=\"image\" src=\"https://github.com/victorgaard/playground/assets/13384559/e3b38965-723c-451b-857c-ab65eae7a1a9\"\u003e\n\n\nDid you notice the radio buttons for the variant props, as well as the new items in the navigation for the examples? You have the power! Harness it and go beyond! 🤘\n\n\n## Current limitations\nPlayground tracks props changes via URL Params. It works well and offers shareable URLs that match a given component state, but the main limitation of this approach is that JSX passed as props or as children is very tricky to parse back to React code. Right now any JSX passed as URL Params will be just transformed to text. \n\nAn interim workaround for this issue is having all JSX props or children set in the `defaultProps` and not changing them in the `examples`. Let's say your Button renders an icon and a text as children. You can add it on `defaultProps`, and since the children are not changed afterward in the `examples`, it will preserve the JSX as children and work as intended.\n\n```typescript\nexport const props = generateProps\u003cButtonProps\u003e({\n  Component: Button,\n  defaultProps: {\n    children: \u003c\u003e\u003cBoltIcon /\u003e click me\u003c/\u003e,\n    variant: \"primary\",\n    size: \"md\",\n  },\n  variantProps: {\n    variant: [\"primary\", \"secondary\", \"tertiary\", \"ghost\", \"destructive\"],\n  },\n  examples: {\n    secondary: {\n      variant: \"secondary\",\n    },\n  },\n});\n```\n\n## Contribute\nAll contributions must be written in English. Feel free to open an issue or submit PRs. \nFor PRS, please do so on the `develop` branch. \n\nCommit messages should follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/), like:\n\n- fix: ...\n- feat: ...\n- chore: ...\n- test: ...\n- refactor: ...\n\nPlayground follows the [Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct/) code of conduct to foster an open, welcoming, diverse, inclusive, and healthy community.\n\n## License\nMIT License\n\nCopyright (c) 2024 Victor F. Santos\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvictorgaard%2Fplayground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvictorgaard%2Fplayground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvictorgaard%2Fplayground/lists"}