{"id":21701402,"url":"https://github.com/ktsn/birdseye","last_synced_at":"2025-06-26T20:03:28.880Z","repository":{"id":48270922,"uuid":"142963598","full_name":"ktsn/birdseye","owner":"ktsn","description":"Next generation component catalog","archived":false,"fork":false,"pushed_at":"2021-11-08T08:41:04.000Z","size":5521,"stargazers_count":39,"open_issues_count":27,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T08:12:10.361Z","etag":null,"topics":["catalog","component","styleguide","web-components"],"latest_commit_sha":null,"homepage":"","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/ktsn.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":"2018-07-31T04:48:55.000Z","updated_at":"2023-02-16T11:57:22.000Z","dependencies_parsed_at":"2022-08-23T15:01:01.604Z","dependency_job_id":null,"html_url":"https://github.com/ktsn/birdseye","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktsn%2Fbirdseye","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktsn%2Fbirdseye/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktsn%2Fbirdseye/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktsn%2Fbirdseye/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ktsn","download_url":"https://codeload.github.com/ktsn/birdseye/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248574133,"owners_count":21126955,"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":["catalog","component","styleguide","web-components"],"created_at":"2024-11-25T20:19:40.221Z","updated_at":"2025-04-12T13:37:27.807Z","avatar_url":"https://github.com/ktsn.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Birdseye\n\n**This project is under work in progress. Some features may not be implemented or have bugs. APIs would be changed near the future**\n\nNext generation component catalog.\n\n## Concept\n\n- No need to write source code for each component guide.\n- Essentially both build tool and view library agnostic.\n- Use Web Components instead of iframe to encapsulate styles for better dev experience.\n\n## Getting Started\n\nBirdseye currently supports the following view libraries. Please refer the guide for a lib that you are using.\n\n- Vue.js\n\n### Vue.js with Vue CLI v3\n\nInstall `@birdseye/app` and `@birdseye/vue` in your Vue CLI project:\n\n```bash\n$ npm i -D @birdseye/app @birdseye/vue\n```\n\n#### Writing catalog by code\n\nCreate catalog file:\n\n```js\n// birdseye/catalogs/MyButton.catalog.js\nimport { catalogFor } from '@birdseye/vue'\nimport MyButton from '@/components/MyButton.vue'\n\nexport default catalogFor(MyButton, 'MyButton')\n  .add('primary', {\n    props: {\n      primary: true\n    },\n    slots: {\n      default: 'Button Text'\n    }\n  })\n  .add('hovered state', {\n    data: {\n      hover: true\n    },\n    slots: {\n      default: 'Hovered'\n    }\n  })\n```\n\nMake `birdseye/preview.js` and bootstrap component catalog:\n\n```js\n// birdseye/preview.js\nimport birdseye from '@birdseye/app'\n\n// Load all your catalogs\nconst load = ctx =\u003e ctx.keys().map(x =\u003e ctx(x).default)\nconst catalogs = load(require.context('./catalogs/', true, /\\.catalog\\.js$/))\n\n// Mount component catalog\nbirdseye('#app', catalogs)\n```\n\nServe the component catalog by running vue-cli-service:\n\n```bash\n$ npm run serve -- birdseye/preview.js\n```\n\n#### Tweaking preview container style\n\nWhen you want to modify preview container style (such as padding, background-color etc.), specify `containerStyle` option in your catalog:\n\n```js\nimport { catalogFor } from '@birdseye/vue'\nimport MyButton from '@/components/MyButton.vue'\n\nexport default catalogFor(MyButton, 'MyButton').add('white button', {\n  props: {\n    white: true\n  },\n  slots: {\n    default: 'Button Text'\n  },\n\n  // Make background color black\n  containerStyle: {\n    backgroundColor: 'black'\n  }\n})\n```\n\nThe above example makes the preview background color black. You can specify any CSS properties in `containerStyle` option.\n\n#### Injecting slots and scoped slots\n\nYou can inject slots and scoped slots by using `slots` option of `add` function. Pass a template string for a slot:\n\n```js\nimport { catalogFor } from '@birdseye/vue'\nimport MyButton from '@/components/MyButton.vue'\n\nexport default catalogFor(MyButton, 'MyButton')\n  .add('primary', {\n    props: {\n      primary: true\n    },\n    slots: {\n      // Directly pass template string for the slot\n      default: '\u003cspan\u003eButton Text\u003c/span\u003e'\n    }\n  })\n```\n\nPass a function for a scoped slot. The first argument is injected scoped slot props. You can get `$createElement` helper via `this` context:\n\n```js\nimport { catalogFor } from '@birdseye/vue'\nimport MyButton from '@/components/MyButton.vue'\n\nexport default catalogFor(MyButton, 'MyButton')\n  .add('primary', {\n    props: {\n      primary: true\n    },\n    slots: {\n      // Pass scoped slot function\n      default(props) {\n        const h = this.$createElement\n        return h('span', ['Button Text ', props.message])\n      }\n    }\n  })\n```\n\n#### Wrapping catalog component with another element\n\nYou can use `mapRender` option to modify rendered element structure. `mapRender` should be a function that receives [`createElement` function](https://vuejs.org/v2/guide/render-function.html#createElement-Arguments) and original VNode object as arguments respectively.\n\nThe following example maps the catalog component with `VApp` component of [Vuetify](https://vuetifyjs.com).\n\n```js\nimport { catalogFor } from '@birdseye/vue'\nimport { VApp } from 'vuetify/lib'\nimport MyButton from '@/components/MyButton.vue'\n\nexport default catalogFor(MyButton, {\n  name: 'MyButton',\n\n  // Define map function to render\n  mapRender: (h, vnode) =\u003e {\n    return h(VApp, [vnode])\n  }\n}).add('white button', {\n  props: {\n    white: true\n  },\n  slots: {\n    default: 'Button Text'\n  }\n})\n```\n\n#### Writing catalog in SFC\n\nUpdate the webpack config in `vue.config.js`:\n\n```js\nmodule.exports = {\n  chainWebpack: config =\u003e {\n    if (process.env.NODE_ENV !== 'production') {\n      // Process \u003cbirdseye\u003e custom block with @birdseye/vue/webpack-loader\n      // prettier-ignore\n      config.module\n        .rule('birdseye-vue')\n          .resourceQuery(/blockType=birdseye/)\n          .use('birdseye-vue-loader')\n            .loader('@birdseye/vue/webpack-loader')\n    }\n  }\n}\n```\n\nYou write rendering patterns of a component in `\u003cbirdseye\u003e` custom block. In each `patterns` item, you can specify `props` and `data` value which will be passed to the component. For example, in the following code, component guide will have two patterns for this component (named `Test Component`). The first pattern (`Pattern Name 1`) shows the component having `\"First pattern\"` as `foo` value and `123` as `bar` value.\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv\u003e\n    \u003cp\u003eThis is Vue.js component\u003c/p\u003e\n    \u003cp\u003efoo value: {{ foo }}\u003c/p\u003e\n    \u003cp\u003ebar value: {{ bar }}\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nexport default {\n  props: {\n    foo: {\n      type: String,\n      default: ''\n    }\n  },\n\n  data() {\n    return {\n      bar: 0\n    }\n  }\n}\n\u003c/script\u003e\n\n\u003cbirdseye\u003e\n{\n  \"name\": \"Test Component\",\n  \"patterns\": [\n    {\n      \"name\": \"Pattern Name 1\",\n      \"props\": {\n        \"foo\": \"First pattern\"\n      },\n      \"data\": {\n        \"bar\": 123\n      }\n    },\n    {\n      \"name\": \"Pattern Name 2\",\n      \"props\": {\n        \"foo\": \"Second pattern\"\n      },\n      \"data\": {\n        \"bar\": 456\n      }\n    }\n  ]\n}\n\u003c/birdseye\u003e\n```\n\nFinally, make `birdseye/preview.js` and bootstrap component catalog:\n\n```js\nimport birdseye from '@birdseye/app'\nimport { instrument } from '@birdseye/vue'\n\n// Load all your component\nconst load = ctx =\u003e ctx.keys().map(x =\u003e ctx(x).default)\nconst components = load(require.context('../src/components', true, /\\.vue$/))\n\n// Mount component catalog\nbirdseye('#app', instrument(components))\n```\n\nYou can serve the component catalog by running vue-cli-service:\n\n```bash\n$ npm run serve -- birdseye/preview.js\n```\n\n## Visual Regression Testing\n\nIf you want to visual regression test your component catalog, use `@birdseye/snapshot` package. See [docs](packages/@birdseye/snapshot/README.md) of `@birdseye/snapshot`\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fktsn%2Fbirdseye","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fktsn%2Fbirdseye","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fktsn%2Fbirdseye/lists"}