{"id":50558109,"url":"https://github.com/interline-io/catenary","last_synced_at":"2026-06-04T09:01:45.358Z","repository":{"id":348697252,"uuid":"1198977214","full_name":"interline-io/catenary","owner":"interline-io","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-01T23:12:16.000Z","size":537,"stargazers_count":0,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-01T23:12:17.124Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/interline-io.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-02T00:16:01.000Z","updated_at":"2026-06-01T22:33:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/interline-io/catenary","commit_stats":null,"previous_names":["interline-io/catenary"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/interline-io/catenary","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interline-io%2Fcatenary","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interline-io%2Fcatenary/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interline-io%2Fcatenary/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interline-io%2Fcatenary/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/interline-io","download_url":"https://codeload.github.com/interline-io/catenary/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interline-io%2Fcatenary/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33897568,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2026-06-04T09:01:44.515Z","updated_at":"2026-06-04T09:01:45.321Z","avatar_url":"https://github.com/interline-io.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cfigure\u003e\n  \u003cimg src=\"./docs/catbus.jpg\" alt=\"still from the film 'My Neighbor Toroto' showing the Catbus in front of a train with a catenary power supply\" /\u003e\n  \u003cfigcaption\u003e\u003ca href=\"https://ghibli.fandom.com/wiki/Catbus?file=Carbus_and_Everyone.jpg\"\u003eFilm still © Studio Ghibli\u003c/a\u003e\u003c/figcaption\u003e\n\u003c/figure\u003e\n\n# Catenary\n\nA Vue 3 UI controls library built on [Bulma](https://bulma.io/) and [Material Design Icons](https://pictogrammers.com/library/mdi/). Catenary provides 30 general-purpose, domain-agnostic components designed to be reusable across any application.\n\nPublished to GitHub Packages as `@interline-io/catenary`.\n\n## Installation\n\nConfigure your project to use the GitHub Packages registry for the `@interline-io` scope. Add to your project's `.npmrc`:\n\n```\n@interline-io:registry=https://npm.pkg.github.com\n```\n\nThen install:\n\n```bash\npnpm add @interline-io/catenary\n```\n\n### Peer dependencies\n\nYour project must provide:\n\n- `vue` 3.5+\n- `bulma` 1.0+ -- CSS framework (configured and loaded by your app)\n- `@mdi/font` 7.4+ -- Material Design Icons (loaded by your app)\n\n`date-fns` 4.x is a direct dependency and installed automatically.\n\n## Usage\n\n### Vue plugin (recommended)\n\nRegister all components globally with the `cat-` prefix:\n\n```ts\nimport { createApp } from 'vue'\nimport CatenaryPlugin from '@interline-io/catenary'\nimport '@interline-io/catenary/style.css'\n\nconst app = createApp(App)\napp.use(CatenaryPlugin)\napp.mount('#app')\n```\n\nComponents are then available everywhere as `\u003ccat-button\u003e`, `\u003ccat-input\u003e`, `\u003ccat-modal\u003e`, etc.\n\n### Individual imports\n\nFor tree-shaking, import only the components you need:\n\n```ts\nimport { CatButton, CatInput, CatField } from '@interline-io/catenary'\nimport '@interline-io/catenary/style.css'\n```\n\n### Nuxt\n\nCreate a plugin file to register the components:\n\n```ts\n// app/plugins/catenary.ts\nimport CatenaryPlugin from '@interline-io/catenary'\nimport '@interline-io/catenary/style.css'\n\nexport default defineNuxtPlugin((nuxtApp) =\u003e {\n  nuxtApp.vueApp.use(CatenaryPlugin)\n})\n```\n\nNo Nuxt module configuration is needed. The plugin handles global registration of all `cat-*` components.\n\n### Bulma and icon CSS\n\nThe `@interline-io/catenary/style.css` export includes the component-scoped styles extracted from the library. It does **not** include the full Bulma stylesheet or Material Design Icons font. You must load those in your app's global styles:\n\n```scss\n// In your app's main stylesheet or entry point\n@use \"bulma/sass\" with (\n  $primary: #9e0e84,  // customize as needed\n);\n\n@use \"@mdi/font/css/materialdesignicons.css\";\n```\n\nOr via CDN/link tags if you prefer.\n\n## Components\n\n### Form controls\n\n| Component | Tag | Description |\n|-----------|-----|-------------|\n| CatButton | `\u003ccat-button\u003e` | Button with variants, sizes, loading state, icons |\n| CatCheckbox | `\u003ccat-checkbox\u003e` | Checkbox with v-model support |\n| CatCheckboxGroup | `\u003ccat-checkbox-group\u003e` | Multiple checkboxes from an options array |\n| CatRadio | `\u003ccat-radio\u003e` | Radio button |\n| CatSwitch | `\u003ccat-switch\u003e` | Toggle switch |\n| CatInput | `\u003ccat-input\u003e` | Text input with icons, types, variants |\n| CatTextarea | `\u003ccat-textarea\u003e` | Multi-line text input |\n| CatSelect | `\u003ccat-select\u003e` | Select dropdown |\n| CatTaginput | `\u003ccat-taginput\u003e` | Tag-based input with autocomplete and custom options |\n| CatDatepicker | `\u003ccat-datepicker\u003e` | Calendar date picker with single/multiple selection |\n| CatField | `\u003ccat-field\u003e` | Form field wrapper (labels, horizontal layout, addons, grouping) |\n| CatSlider | `\u003ccat-slider\u003e` | Range slider |\n| CatSliderTick | `\u003ccat-slider-tick\u003e` | Tick mark for slider |\n\n### Layout and navigation\n\n| Component | Tag | Description |\n|-----------|-----|-------------|\n| CatTabs | `\u003ccat-tabs\u003e` | Tab navigation |\n| CatTabItem | `\u003ccat-tab-item\u003e` | Individual tab panel |\n| CatDropdown | `\u003ccat-dropdown\u003e` | Dropdown menu |\n| CatDropdownItem | `\u003ccat-dropdown-item\u003e` | Item within a dropdown |\n| CatModal | `\u003ccat-modal\u003e` | Modal dialog with sizes, fullscreen, footer slots |\n| CatCard | `\u003ccat-card\u003e` | Card container with optional expand/collapse |\n\n### Data display\n\n| Component | Tag | Description |\n|-----------|-----|-------------|\n| CatTable | `\u003ccat-table\u003e` | Data table with sortable columns |\n| CatTableColumn | `\u003ccat-table-column\u003e` | Column definition for table |\n| CatPagination | `\u003ccat-pagination\u003e` | Page navigation |\n| CatTag | `\u003ccat-tag\u003e` | Badge/label tag |\n| CatNotification | `\u003ccat-notification\u003e` | Notification banner |\n| CatMsg | `\u003ccat-msg\u003e` | Message box with icon, expand/collapse, close |\n\n### Utilities\n\n| Component | Tag | Description |\n|-----------|-----|-------------|\n| CatIcon | `\u003ccat-icon\u003e` | Material Design Icon wrapper |\n| CatLoading | `\u003ccat-loading\u003e` | Loading spinner overlay |\n| CatTooltip | `\u003ccat-tooltip\u003e` | Tooltip overlay |\n| CatSearchBar | `\u003ccat-search-bar\u003e` | Search input with clear button |\n| CatThemeToggle | `\u003ccat-theme-toggle\u003e` | Light/dark theme switcher |\n\n## Variants and sizes\n\nMost components accept `variant` and `size` props. The core set is:\n\n```\nVariants: primary, link, info, success, warning, danger\nSizes:    small, normal, medium, large\n```\n\nSome components extend these (e.g., buttons add `white`, `light`, `dark`, `text`, `ghost`). All variant and size constants are exported as TypeScript types and runtime arrays:\n\n```ts\nimport { CoreVariants, ButtonVariants, type ButtonVariant } from '@interline-io/catenary'\n```\n\n## CSS conventions\n\nComponents follow a consistent class naming pattern:\n\n- Root element gets both the Bulma class and a `cat-` prefixed class: `class=\"card cat-card\"`\n- Bulma helper classes are used directly for spacing, typography, and flexbox\n- Custom classes invented by the library always use the `cat-` prefix\n- Variant styles use SCSS `@each` loops over Bulma CSS variables\n\n## Development\n\nRequires **Node v22.21.1** (see `.nvmrc`) and **pnpm**.\n\n```bash\npnpm install\npnpm dev              # Start Nuxt playground at localhost:3000\npnpm build            # Build library (dist/catenary.js + types)\npnpm test             # Run tests (vitest + jsdom)\npnpm lint             # ESLint (incl. eslint-plugin-vuejs-accessibility)\npnpm typecheck        # vue-tsc + nuxi typecheck\npnpm check            # Lint + typecheck (runs both in sequence)\npnpm changeset        # Record a user-facing change for the next release\n```\n\nThe `playground/` directory is a Nuxt app with interactive demos for every component. It is a devDependency and is not included in the published package.\n\n## Publishing\n\nReleases are managed with [Changesets](https://github.com/changesets/changesets). PRs that ship a user-facing change should include a changeset file (run `pnpm changeset` and commit the generated `.changeset/*.md`). On merge to `main`, the `Release` workflow opens or updates a \"Version Packages\" PR that bumps the version and updates `CHANGELOG.md`; merging that PR publishes a new release to GitHub Packages under the `latest` dist-tag.\n\nPushes to non-`main` branches also publish preview tarballs to GitHub Packages as `0.1.0-branch.\u003cbranch\u003e.\u003csha\u003e`, under the branch name as a dist-tag. These are useful for testing changes in consuming apps before they are released.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finterline-io%2Fcatenary","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finterline-io%2Fcatenary","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finterline-io%2Fcatenary/lists"}