Skip to content

Release v2.1.0

Choose a tag to compare

@github-actions github-actions released this 03 Jun 13:45
15979d9

Extracts the filter UI from PivotViewer into a generic, standalone FilterPanel component that can be used independently of any data viewer.

Added

  • Source/Filter/ module: standalone FilterPanel, FilterEditor, RangeHistogramFilter, useFilterState hook, and full TypeScript type definitions (FilterDefinition, FilterEditorProps, FilterEditorSlotProps, FilterValues, RangeValues, CustomFilterValues) (#102)
  • FilterEditor slot component — declares a custom editor for a specific filter group as a declarative child of <FilterPanel>; value tracked separately in customValues (#102)
  • type: 'custom' filter type as an explicit opt-in for fully custom filter editors (#102)
  • 5 Storybook stories for FilterPanel: single-select, multi-select, numeric range/histogram, custom editor, and mixed filter types (#102)
  • ./Filter subpath export in package.json for direct imports via @cratis/components/Filter (#102)
  • Documentation/Filter/index.md — full API reference covering all exported types, FilterPanel props, FilterEditor props, useFilterState hook, and usage examples for every filter type (#102)
  • BDD specs in Source/Filter/for_useFilterState/ covering buildFilterValues and buildRangeValues — 9 tests across 4 spec files (#102)
  • Source/Filter/utils.ts exporting buildFilterValues and buildRangeValues as pure, testable utility functions (#102)

Changed

  • FilterPanel accepts children?: ReactNode — uses React.Children + isValidElement to discover <FilterEditor> slots and render them in the matching filter group (#102)
  • PivotViewer/components/FilterPanel.tsx is now a thin adapter: converts PivotFilter<TItem>[] + computed options into FilterDefinition[], generates <FilterEditor> children from any PivotFilter.renderEditor, and delegates all rendering to the new standalone component — no breaking changes to the public API (#102)
  • PivotFilter<TItem> retains renderEditor? and type: 'custom' so PivotViewer consumers can inject custom filter editors without any workarounds (#102)
  • Source/Filter/useFilterState.ts now imports buildFilterValues and buildRangeValues from ./utils (#102)
  • Documentation/toc.yml updated with Filter entries in both the Storybook section and Common Components section (#102)
  • eslint.config.mjs — added argsIgnorePattern: '^_' to the @typescript-eslint/no-unused-vars rule to honour the _-prefix convention for intentionally unused parameters (#102)

Fixed

  • Storybook static build (storybook build) now completes successfully — fixed a pre-existing [lightningcss minify] Invalid empty selector crash by adding cssMinify: false to the viteFinal config in Source/.storybook/main.ts (#102)
  • CI build failure caused by ESLint flagging _props in FilterEditor.tsx as unused — resolved by adding argsIgnorePattern: '^_' to the ESLint rule config (#102)

Usage — custom editor in standalone context:

import { FilterPanel, FilterEditor, useFilterState } from '@cratis/components/Filter';

const filters: FilterDefinition[] = [
  { key: 'score', label: 'Score', type: 'custom' },
];

function MyView() {
  const state = useFilterState(filters);
  const buttonRef = useRef<HTMLButtonElement>(null);
  return (
    <>
      <button ref={buttonRef}>Filters</button>
      <FilterPanel
        isOpen={open}
        filters={filters}
        anchorRef={buttonRef}
        customValues={state.customValues}
        onCustomValueChange={state.handleCustomValueChange}
        onFilterToggle={state.handleToggleFilter}
        onFilterClear={state.handleClearFilter}
        onRangeChange={state.handleRangeChange}
        onExpandedFilterChange={state.setExpandedFilterKey}
        onClose={() => setOpen(false)}
        {...state}
      >
        <FilterEditor filterKey="score">
          {({ value, onChange }) => (
            <MySlider value={value as number} onChange={onChange} />
          )}
        </FilterEditor>
      </FilterPanel>
    </>
  );
}