diff --git a/.storybook/main.ts b/.storybook/main.ts index 32c42a6..b768007 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -13,6 +13,19 @@ const config: StorybookConfig = { const { default: tailwindcss } = await import('@tailwindcss/vite'); cfg.plugins = cfg.plugins ?? []; cfg.plugins.push(tailwindcss()); + + /* + | Storybook inherits vite.config.ts, so the declaration-file plugin runs + | here too — and this build has no declarations to emit. It is not just + | wasted work: bundling types means API Extractor, which walks the + | stories and dies on Vue's internal template symbols ("Symbol not found + | for identifier: __VLS_1"). Dropping it here is what lets the library + | build bundle its types without the docs build having to cope. + */ + cfg.plugins = cfg.plugins.filter( + (plugin) => !(plugin && 'name' in plugin && String(plugin.name).includes('dts')), + ); + return cfg; }, }; diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..77e98ab --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,164 @@ +# Changelog + +All notable changes to `@codebar-ag/storybook`. + +The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and +this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## v1.7.0 + +### Added + +- **Tokenless installs from this repository.** A `prepare` script builds `dist` + on install, so the package can be consumed straight from the public repo as a + git dependency and no GitHub Packages token is needed: + + ```json + "@codebar-ag/storybook": "github:codebar-ag/storybook.codebar.ch#v1.7.0" + ``` + + `files` is `["dist"]` and `dist` is gitignored, so a git install previously + resolved to a package with no entry point at all. It also means `npm publish` + always ships a freshly built `dist` rather than whatever was last in the + working tree. + +- `CHANGELOG.md` — release notes now live here instead of in the README. + +### Fixed + +- **The dependency tree could not be installed at all.** `npm ci` failed on + `main` — and with it the `release`, `pages` and `test` workflows — because + `@storybook/vue3-vite` was `^10.5.3` while `storybook` stayed `^9.0.0` and both + addons `^9.1.20`, leaving its peer requirement of `storybook@^10` + unsatisfiable. + +- **All five security advisories cleared** (`npm audit`: 0 vulnerabilities, was + 5 high). The half-finished `^10.5.3` bump was reaching for a real fix, so it + was completed rather than reverted: aligning the Storybook family on `^10.5.5` + pulls `vue-component-meta` and `@vue/language-core` to versions whose + `minimatch`/`brace-expansion` are patched, and takes `postcss` to `8.5.25`, + closing the source-map path-traversal advisory. + +- **`main` had lost the published v1.6.0.** That release was tagged and + published from a commit that was never merged, so `main` was missing + `CodeEditor`, `FullscreenPanel`, `Card`'s `sm` size, the `PageHeading` actions + slot and the `CodePreview` changes — 437 lines that consumers on `^1.6.0` + already depended on. Merged back in; anything released from `main` before this + would have silently regressed them. + +- **Types are a single bundled `index.d.ts` again.** `vite-plugin-dts` 5 renamed + `rollupTypes` to `bundleTypes` and *ignores* the old name instead of rejecting + it, so the build had quietly started emitting split per-component + declarations — an 84 KB entry point became 9 KB plus a `components/` tree. + Consumers that parse the declaration file rather than merely importing from it + saw an apparently valid file describing almost nothing. Adds + `@microsoft/api-extractor`, which `bundleTypes` requires. + +- Two implicit-`any` handler parameters in `Pagination.vue`. Pre-existing and + unrelated to the upgrade, but `typecheck` could not run while the tree was + uninstallable, so nothing had reported them. + +### Changed + +- Storybook and its addons: `^9` → `^10.5.5`. No config migration was needed — + the full docs build and all 184 Playwright story tests pass unchanged. +- `publishConfig.access`: `restricted` → `public`. This affects *future* + publishes only. The existing package's visibility is a setting on the package + itself, and GitHub's npm registry requires a token for every read regardless + of visibility — the git dependency above is what actually removes the token. + +## v1.6.0 + +- `CodeEditor` and `FullscreenPanel` promoted to the public API. +- `PageHeading` gained an actions slot. +- `Card` gained the `sm` size. +- `CodePreview` and `useEscapeKey` refinements, plus `codeMirrorTheme` helper. + +> **Note:** published to GitHub Packages but never merged to `main`. If you +> pinned a git dependency to a commit rather than the tag, upgrade to v1.7.0, +> which is the first release where `main` actually contains this work. + +## v1.5.0 + +- `Toaster` gained a `maxWidth` prop. +- `DataTable` row cursor fix. + +## v1.4.3 + +- Maintenance release. + +## v1.4.2 + +- **Placeholder names in story fixtures.** Real client and person names were + replaced with `Mustermann AG` / `Max Mustermann` placeholders (and + `mustermann.*` hosts) throughout the Storybook stories. No component or API + changes. + +## v1.4.1 + +- **All-mono restored.** v1.4.0 switched the UI font to Inter; that is reverted. + The all-mono look (JetBrains Mono everywhere, via `--font-mono`) is the + brand's visual identity and is intentional. Skip v1.4.0 and upgrade straight + to v1.4.1. + +## v1.4.0 + +- Switched the UI font to Inter. **Superseded — do not use;** see v1.4.1. + +## v1.3.1 + +- Restored the package name `@codebar-ag/storybook`. + +## v1.3.0 + +### Added + +- **New components** — atoms `Avatar`, `Divider`, `Kbd`, `Spinner`; molecules + `Accordion`/`AccordionItem`, `Combobox`, `InputNumber`, `PasswordInput`, + `PinInput`, `Popover`, `Tabs`, `Tooltip`; organisms `DataTable` (sortable, + selectable, paginated), `Drawer`, `Navbar`, `Sidebar`/`SidebarGroup`/ + `SidebarItem`; layouts `AppShell`, `AuthLayout`, `ErrorLayout`. +- **Composables are now part of the public API** — overlay/keyboard utilities + (`useFocusTrap`, `useClickOutside`, `useEscapeKey`, `useScrollLock`, + `useListNavigation`), form helpers (`useFieldA11y`, `useFormErrors`, + `usePasswordManagerAttrs`), data-table helpers (`useSort`, `useSelection`, + `usePagination`), plus `useControllable` and `useRootAttrs`. +- **Helpers** — `cx` class combiner and `resolveTone` with the + `Tone`/`LegacyTone` types. +- **Storybook** — Foundations docs (colors, typography, spacing, radii & + shadows, icons), example pages (Auth, Errors, Dashboard), docs + a11y + addons, and per-story play functions that run in CI via Playwright. + +### Migration notes + +Non-breaking, but worth knowing when upgrading: + +- **Tones unified.** `Badge`/`StatusBadge` now use the semantic tones + `neutral | info | success | warning | danger`; `Alert` gained `danger`. + The old values (`gray`/`blue`/`green`/`amber`/`red`, Alert's `error`) keep + rendering identically via `resolveTone()` but log a dev-only deprecation + warning and will be removed in the next major. +- **Dropdown DOM changed.** The root moved from `
/` to + `
`, }), }; + +// `purple` is a deprecated legacy alias (rides `info`) for non-severity +// statuses like "seen this before" — e.g. a duplicate webhook delivery. +export const LegacyPurpleAlias: Story = { + args: { variant: 'purple', label: 'Duplicate', dot: false }, +}; diff --git a/src/components/molecules/Card.stories.ts b/src/components/molecules/Card.stories.ts index 3daf674..47de170 100644 --- a/src/components/molecules/Card.stories.ts +++ b/src/components/molecules/Card.stories.ts @@ -30,3 +30,12 @@ export const WithActionsAndFooter: Story = { `, }), }; + +export const Small: Story = { + render: () => ({ + components: { Card }, + template: ` +

A denser card for rows nested inside a larger container.

+
`, + }), +}; diff --git a/src/components/molecules/Card.vue b/src/components/molecules/Card.vue index b800a0a..cae8127 100644 --- a/src/components/molecules/Card.vue +++ b/src/components/molecules/Card.vue @@ -13,8 +13,10 @@ const props = withDefaults( variant?: 'default' | 'danger'; hoverable?: boolean; // 'lg' is for screens with a single, centered card as the focal point - // (e.g. auth screens) where the default density reads cramped. - size?: 'md' | 'lg'; + // (e.g. auth screens) where the default density reads cramped. 'sm' + // is for cards nested inside another card/list — a denser container, + // not a different component. + size?: 'sm' | 'md' | 'lg'; }>(), { title: null, description: null, padded: true, variant: 'default', hoverable: false, size: 'md' }, ); @@ -25,18 +27,22 @@ const { rootAttrs, classAttr } = useRootAttrs(); const variants: Record = { default: '', danger: 'border-danger-line/60' }; const headerPadding: Record = { + sm: 'px-3 sm:px-4 pt-3 pb-2.5', md: 'px-4 sm:px-5 pt-5 pb-4', lg: 'px-5 sm:px-6 pt-6 pb-5', }; const bodyPadding: Record = { + sm: 'px-3 sm:px-4 py-3', md: 'px-4 sm:px-5 py-5', lg: 'px-5 sm:px-6 py-6', }; const footerPadding: Record = { + sm: 'px-3 sm:px-4 py-2.5', md: 'px-4 sm:px-5 py-4', lg: 'px-5 sm:px-6 py-5', }; const titleSize: Record = { + sm: 'text-sm', md: 'text-lg', lg: 'text-xl', }; diff --git a/src/components/molecules/FullscreenPanel.stories.ts b/src/components/molecules/FullscreenPanel.stories.ts new file mode 100644 index 0000000..fb2fe8e --- /dev/null +++ b/src/components/molecules/FullscreenPanel.stories.ts @@ -0,0 +1,27 @@ +import type { Meta, StoryObj } from '@storybook/vue3-vite'; +import FullscreenPanel from './FullscreenPanel.vue'; +import Button from '../atoms/Button.vue'; + +const meta: Meta = { + title: 'Molecules/FullscreenPanel', + component: FullscreenPanel, + parameters: { layout: 'padded' }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: () => ({ + components: { FullscreenPanel, Button }, + template: ` +
+ {{ isFullscreen ? 'Fullscreen' : 'Inline' }} + +
+

Editor content lives in the default slot.

+
`, + }), +}; diff --git a/src/components/molecules/FullscreenPanel.vue b/src/components/molecules/FullscreenPanel.vue new file mode 100644 index 0000000..11fe9d7 --- /dev/null +++ b/src/components/molecules/FullscreenPanel.vue @@ -0,0 +1,38 @@ + + + diff --git a/src/components/molecules/PageHeading.stories.ts b/src/components/molecules/PageHeading.stories.ts index 49a8f82..3b9358b 100644 --- a/src/components/molecules/PageHeading.stories.ts +++ b/src/components/molecules/PageHeading.stories.ts @@ -1,5 +1,6 @@ import type { Meta, StoryObj } from '@storybook/vue3-vite'; import PageHeading from './PageHeading.vue'; +import Button from '../atoms/Button.vue'; const meta: Meta = { title: 'Molecules/PageHeading', @@ -30,3 +31,19 @@ export const WithDescription: Story = { `, }), }; + +export const WithActions: Story = { + render: () => ({ + components: { PageHeading, Button }, + template: ` + File cabinets + + + `, + }), +}; diff --git a/src/components/molecules/PageHeading.vue b/src/components/molecules/PageHeading.vue index 84e0da7..fc49fca 100644 --- a/src/components/molecules/PageHeading.vue +++ b/src/components/molecules/PageHeading.vue @@ -1,8 +1,9 @@ diff --git a/src/components/organisms/CodeEditor.stories.ts b/src/components/organisms/CodeEditor.stories.ts new file mode 100644 index 0000000..968cb02 --- /dev/null +++ b/src/components/organisms/CodeEditor.stories.ts @@ -0,0 +1,40 @@ +import type { Meta, StoryObj } from '@storybook/vue3-vite'; +import CodeEditor from './CodeEditor.vue'; + +const meta: Meta = { + title: 'Organisms/CodeEditor', + component: CodeEditor, + parameters: { layout: 'padded' }, + args: { + modelValue: '{\n "vendor": "string",\n "invoice_number": "string"\n}', + language: 'json', + }, + render: (args) => ({ + components: { CodeEditor }, + setup: () => ({ args }), + template: '
', + }), +}; + +export default meta; +type Story = StoryObj; + +export const Json: Story = {}; + +export const Markdown: Story = { + args: { + modelValue: '# Extraction prompt\n\nSummarize the invoice fields below.', + language: 'markdown', + }, +}; + +export const ReadOnlyEmpty: Story = { + render: () => ({ + components: { CodeEditor }, + template: '
', + }), +}; + +export const AutoHeight: Story = { + args: { autoHeight: true, maxHeight: '12rem' }, +}; diff --git a/src/components/organisms/CodeEditor.vue b/src/components/organisms/CodeEditor.vue new file mode 100644 index 0000000..7a8fd4e --- /dev/null +++ b/src/components/organisms/CodeEditor.vue @@ -0,0 +1,155 @@ + + + diff --git a/src/components/organisms/CodePreview.vue b/src/components/organisms/CodePreview.vue index 19db003..3506d03 100644 --- a/src/components/organisms/CodePreview.vue +++ b/src/components/organisms/CodePreview.vue @@ -1,6 +1,7 @@