@tower_74/cms-ui
v0.31.0
Published
Shared Vue 3 component & widget library for the Base CMS.
Downloads
6,205
Readme
@tower_74/cms-ui
Shared Vue 3 component & widget library for the Base CMS — developed and documented in Storybook, consumed by every client site as a versioned package. See base-cms ADR-0007 and §10 component inventory.
Status: v0.4.0 — primitives, form/data widgets, content blocks (incl. data-driven
PostList) + page templates. Build whole pages in Storybook under Pages/Landing / Pages/Detail.
Requirements
Node ≥ 18 (repo pins Node 22 via .nvmrc; run nvm use). Vue ^3.4 (peer dependency).
Develop
nvm use
npm install
npm run storybook # http://localhost:6006 — component catalog
npm run lint # ESLint (--fix)
npm test # Vitest
npm run build # build the library into dist/Use in an app
- Install from the private registry:
npm install @tower_74/cms-ui - Import the design tokens once (e.g. in your CSS entry):
@tower_74/cms-ui/tokens.css - Add the Tailwind preset and include the package in
content:// tailwind.config.js module.exports = { presets: [require('@tower_74/cms-ui/tailwind-preset')], content: [ './node_modules/@tower_74/cms-ui/dist/**/*.{js,cjs}', // ...your app paths ], }; - Use components:
<script setup> import { Button, Card } from '@tower_74/cms-ui'; </script> <template> <Card title="Hello"><Button>Click</Button></Card> </template>
Components are theme-only via CSS variables — override the tokens (per site) to re-skin everything with no rebuild.
Local cross-development with a site (yalc)
# in cms-ui
npm run build && yalc publish # then `yalc push` on each change
# in the consuming site
yalc add @tower_74/cms-uiPublish
npm version <patch|minor|major>
npm publish # runs the build via prepublishOnlyComponents
Primitives
| Component | Notes |
|---|---|
| Button | variants: primary / secondary / danger / ghost; sizes sm/md/lg |
| Badge | neutral / success / warning / danger / info |
| Card | title + header / default / footer slots |
| Input | v-model, invalid state |
| Textarea | v-model, rows, invalid |
| Select | v-model, options: {label,value}[], invalid |
| Checkbox | v-model (boolean), label |
Widgets
| Component | Notes |
|---|---|
| FormField | label + required + help/error wrapper around any control |
| FormBuilder | schema-driven form: fields[] + v-model + errors; text/textarea/select/checkbox/number |
| DataTable | columns[] + rows[]; per-column #cell-<key> slots; empty state |
Blocks (data-driven, themeable page sections)
| Component | Notes |
|---|---|
| Section / Container | layout primitives (padding/background; max-width) |
| Hero, PageHeader | page intros |
| RichText | renders editor HTML |
| FeatureGrid, Stats, LogoCloud, Testimonial, FAQ | marketing sections |
| PostList | grid of post cards (data-driven; fed by a server data provider) |
| ImageWithText, Gallery, CallToAction | content sections |
| BlockRenderer | renders a blocks: { type, data }[] array via blockRegistry |
Page templates — LandingPageTemplate, DetailPageTemplate (compose blocks; demoed under
Pages/ in Storybook with the blocks array editable in the Controls panel).
Commerce (Tailwind UI ecommerce patterns, themed via tokens; data-driven, events-out)
| Component | Notes |
|---|---|
| ProductCard / ProductGrid | catalog grid of product cards |
| ProductOverview | product detail with variant picker; emits add-to-cart { variantId, quantity } |
| CartLineItem | cart row; emits update:quantity and remove |
| CartSummary | totals (subtotal/discount/shipping/tax/total) + actions slot |
Conventions
- Vue 3
<script setup>+ typed props/emits; data via props (SSR-safe, Storybook-mockable). - No hard-coded colors — read tokens via the Tailwind preset.
- Every component ships a
*.stories.ts; a11y checked via the Storybook a11y addon.
