Skip to content

feat(filter)!: move the filter components to @flux-ui/filter - #58

Open
basmilius wants to merge 5 commits into
mainfrom
feat/filter-package
Open

basmilius wants to merge 5 commits into
mainfrom
feat/filter-package

Conversation

@basmilius

@basmilius basmilius commented Sep 23, 2026 •

Copy link
Copy Markdown
Owner

This PR resolves #39. The filter components move out of @flux-ui/components into a new package, @flux-ui/filter.

The reason is the Vite plugin. defineFilter() is a compile-time macro, and its plugin forced a second build entry, @flux-ui/components/vite, into the core package. That entry now ships as @flux-ui/filter/vite, and the core package has one entry again.

What moved

  • The nine FluxFilter* components plus FluxFilterBase and FluxFilterWindow, the four Filter* primitives, three private composables, useFilterInjection, defineFilter and the other filter helpers, the injection key, Filter.module.scss and defineFilterMacro.
  • The filter components import @flux-ui/components through its public barrel, the way ai does. Two internals they needed were private to components. VNodeRenderer and createLabelForDateRange now live in @flux-ui/internals. VNodeRenderer became a functional component because tsdown's isolated declarations want an explicit type. createLabelForDateRange takes the multi-year label as a string instead of a translate function, so internals doesn't need to know a dictionary key.
  • The filter types stay in @flux-ui/types, like the statistics types. I dropped the seven dead ones the issue lists (FluxFilterBase, FluxFilterItem and the five Flux*Entry types), and their section in types.md with them.

Translations

All dictionaries now live in @flux-ui/internals, one file per package under src/data/i18n/, merged into one english. Internals exports a single useTranslate and the FluxTranslate and FluxTranslation types over every key. The per-package useTranslate wrappers are gone.

That has two effects on the filters. The filter bar reuses flux.filter and flux.filterReset from the components file instead of carrying copies. And a defineFilter factory can translate any Flux key, flux.cancel included.

The filter keys keep their flux.* names instead of moving to flux.filter.*. There are two reasons. Existing translations keep working, and flux.filter.* would collide with the flux.filter leaf that FluxActionBar uses in a nested messages file.

The cost is that every app ships all 164 strings, about 2.2 KB gzipped, including those of packages it does not install.

Docs and tooling

  • Filter gets its own docs section at /filter/ with an intro, installation, translations, the component pages, useFilterInjection and a helpers page. The examples moved to docs/code/filter/.
  • upgrading-v4.md has a new section with the import changes. I also corrected the translation key count and rewrote the section on the translate composable, since it now lives in internals.
  • CI, the release workflow, build.sh, transform-dts.mjs, generate-translations.ts and CLAUDE.md all know about the new package.

Checked

  • Every package builds, followed by transform-dts.mjs and the docs build. No type errors in the vue-tsc or dts output.
  • check-contrast.ts, check-palette-refs.ts and generate-translations.ts --check pass.
  • bun install --frozen-lockfile passes. Adding the workspace made bun prune pinia@3.0.4, an orphaned lockfile entry the docs build relied on without declaring it: the bundle of @basmilius/common imports pinia. The first CI run failed on exactly that. Docs now declares pinia@^4 as a dev dependency, the range @basmilius/common asks for.

The review subagent found one regression, and it is fixed. Two filter styles, the badge and the bar button, override a component class at the same specificity. On main they won by sitting later in the same bundle. As separate stylesheets the import order decides. I tried raising their specificity, but that ties them with .secondary-button:active, .is-active and .badge:is(a, button):hover, which win today, so the hover and active states would depend on order instead. The installation page and the upgrade guide now say to import @flux-ui/filter/style.css after the components stylesheet. The ai, flow and application install pages list the sibling stylesheet first. If one of those overrides a component class, it has the same latent problem. I did not check that here.

I did not click through the filter examples in a browser. The docs prerender without errors, but that is all I verified.

Breaking for consumers

  • Filter imports move to @flux-ui/filter, and defineFilterMacro to @flux-ui/filter/vite.
  • FluxTranslate and FluxTranslation move from @flux-ui/components to @flux-ui/internals.
  • Seven dead filter types are removed from @flux-ui/types.

The upgrade guide covers all three.

The filter cluster was the only feature that forced a build-tool entry
(@flux-ui/components/vite) into the core package. It now lives in its own
package, which ships defineFilterMacro at @flux-ui/filter/vite.

- Components, primitives, composables, util, injection key, styles and the
  Vite macro move to packages/filter.
- VNodeRenderer and createLabelForDateRange move to @flux-ui/internals so
  both packages can reach them.
- The filter dictionary keeps the existing flux.* key names, so existing
  translations still apply.
- Drop the dead FluxFilterBase / FluxFilterItem / Flux*Entry types.
- Docs get their own Filter section; the v4 upgrade guide covers the move.

BREAKING CHANGE: the filter components, defineFilter, pickFilterCommon,
useFilterInjection, isFluxFilterOption* and their types are imported from
@flux-ui/filter; defineFilterMacro from @flux-ui/filter/vite.

Closes #39
Adding the filter workspace made bun prune the orphaned pinia@3 lockfile
entry the docs build silently relied on.
The filter badge and bar button override a component class at the same
specificity; as separate stylesheets the components one has to load first.
Also documents VNodeRenderer and createLabelForDateRange in internals and
lists @flux-ui/filter as a sibling package.
@basmilius

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

…nternals

One dictionary per package under internals/src/data/i18n, merged into one
english with a single useTranslate and FluxTranslate over every key. The
filter bar reuses flux.filter from the components file instead of carrying
a copy, and a defineFilter factory can translate any Flux key again.

BREAKING CHANGE: FluxTranslate and FluxTranslation are no longer exported
from @flux-ui/components; import them from @flux-ui/internals.
Also names the filter remove string on the filter translations page and
limits the upgrade note on per-package translate exports to what shipped.
@basmilius

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@basmilius

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review skipped: 216 files exceed the limit of 100.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move the filter components to a @flux-ui/filter package

1 participant