@fuf-stack/megapixels 0.9.1 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, '__esModule', { value: true });
2
- const require_Filter = require('../Filter-Bc0LWCnZ.cjs');
2
+ const require_Filter = require('../Filter-obuSI5QN.cjs');
3
3
 
4
4
  exports.createFilter = require_Filter.createFilter_default;
5
5
  exports.default = require_Filter.Filter_default;
@@ -1,2 +1,2 @@
1
- import { a as FilterProps, c as FilterDefinition, d as FilterFormProps, f as FilterInstance, i as FilterChildRenderFn, l as FilterDisplayProps, n as createFilter, o as FilterValues, p as FiltersConfiguration, r as Filter, s as filterVariants, t as filters, u as FilterFactory } from "../index-C-2_lJp0.cjs";
1
+ import { a as FilterProps, c as FilterDefinition, d as FilterFormProps, f as FilterInstance, i as FilterChildRenderFn, l as FilterDisplayProps, n as createFilter, o as FilterValues, p as FiltersConfiguration, r as Filter, s as filterVariants, t as filters, u as FilterFactory } from "../index-Ck6wyFDZ.cjs";
2
2
  export { FilterChildRenderFn, FilterDefinition, FilterDisplayProps, FilterFactory, FilterFormProps, FilterInstance, FilterProps, FilterValues, FiltersConfiguration, createFilter, Filter as default, filterVariants, filters };
@@ -1,2 +1,2 @@
1
- import { a as FilterProps, c as FilterDefinition, d as FilterFormProps, f as FilterInstance, i as FilterChildRenderFn, l as FilterDisplayProps, n as createFilter, o as FilterValues, p as FiltersConfiguration, r as Filter, s as filterVariants, t as filters, u as FilterFactory } from "../index-OWKeKysC.js";
1
+ import { a as FilterProps, c as FilterDefinition, d as FilterFormProps, f as FilterInstance, i as FilterChildRenderFn, l as FilterDisplayProps, n as createFilter, o as FilterValues, p as FiltersConfiguration, r as Filter, s as filterVariants, t as filters, u as FilterFactory } from "../index-BIQQB435.js";
2
2
  export { FilterChildRenderFn, FilterDefinition, FilterDisplayProps, FilterFactory, FilterFormProps, FilterInstance, FilterProps, FilterValues, FiltersConfiguration, createFilter, Filter as default, filterVariants, filters };
@@ -1,3 +1,3 @@
1
- import { i as filterVariants, n as filters, r as createFilter_default, t as Filter_default } from "../Filter-nSuQco2t.js";
1
+ import { i as filterVariants, n as filters, r as createFilter_default, t as Filter_default } from "../Filter-D_PSnttT.js";
2
2
 
3
3
  export { createFilter_default as createFilter, Filter_default as default, filterVariants, filters };
@@ -527,7 +527,7 @@ const Filter = ({ children = void 0, className = void 0, config: config$2, formN
527
527
  }), children?.(valuesValidated ?? {})]
528
528
  });
529
529
  };
530
- var Filter_default = Filter;
530
+ var Filter_default$1 = Filter;
531
531
 
532
532
  //#endregion
533
533
  //#region src/Filter/filters/createFilter.ts
@@ -744,8 +744,8 @@ const filters = {
744
744
  boolean: boolean$1,
745
745
  checkboxes
746
746
  };
747
- var Filter_default$1 = Filter_default;
747
+ var Filter_default = Filter_default$1;
748
748
 
749
749
  //#endregion
750
- export { filterVariants as i, filters as n, createFilter_default as r, Filter_default$1 as t };
751
- //# sourceMappingURL=Filter-nSuQco2t.js.map
750
+ export { filterVariants as i, filters as n, createFilter_default as r, Filter_default as t };
751
+ //# sourceMappingURL=Filter-D_PSnttT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Filter-D_PSnttT.js","names":["filters","config","config","config","config","SearchInput","ActiveFilters","AddFilterMenu","FilterModal","config","Display","Form","config","validate","boolean","createFilter","validate","Form","config","createFilter","Filter"],"sources":["../src/Filter/hooks/useFilterValidation.ts","../src/Filter/Subcomponents/FiltersContext.tsx","../src/Filter/Subcomponents/ActiveFilters.tsx","../src/Filter/Subcomponents/AddFilterMenu.tsx","../src/Filter/Subcomponents/FilterModal.tsx","../src/Filter/Subcomponents/SearchInput.tsx","../src/Filter/Filter.tsx","../src/Filter/filters/createFilter.ts","../src/Filter/filters/boolean/Display.tsx","../src/Filter/filters/boolean/Form.tsx","../src/Filter/filters/boolean/schema.ts","../src/Filter/filters/boolean/boolean.ts","../src/Filter/filters/checkboxes/Display.tsx","../src/Filter/filters/checkboxes/Form.tsx","../src/Filter/filters/checkboxes/schema.ts","../src/Filter/filters/checkboxes/checkboxes.ts","../src/Filter/index.ts"],"sourcesContent":["import type { VetoInstance, VetoRawShape, VetoTypeAny } from '@fuf-stack/veto';\nimport type { FilterInstance } from '../filters/types';\n\nimport { useMemo } from 'react';\n\nimport { object, string, stringToJSON, veto } from '@fuf-stack/veto';\n\n/**\n * useFilterValidation\n *\n * Builds a composite validation schema from all provided filter definitions\n * under \"filter\" and optionally includes a \"search\" string field.\n * Memoized by inputs.\n */\nexport const useFilterValidation = (\n filters: FilterInstance<unknown, unknown>[],\n withSearch?: boolean,\n) => {\n return useMemo<VetoInstance>(() => {\n // build filter validation\n let filterSchema: Record<string, VetoTypeAny> = {};\n filters.forEach((f) => {\n filterSchema = {\n ...filterSchema,\n [f.name]: f.validation(f.config) as VetoTypeAny,\n };\n });\n\n const validationSchema: VetoRawShape = {\n // filter validation\n filter: stringToJSON()\n .pipe(object(filterSchema))\n .or(object(filterSchema))\n .optional()\n .nullable()\n // transform null to undefined\n .transform((val) => {\n return val ?? undefined;\n }),\n // optional search validation\n ...(withSearch\n ? { search: string({ min: 0 }).nullable().optional() }\n : {}),\n };\n\n return veto(validationSchema);\n }, [filters, withSearch]);\n};\n\nexport default useFilterValidation;\n","import type { ReactNode } from 'react';\nimport type { FilterInstance, FiltersConfiguration } from '../filters/types';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useFormContext } from '@fuf-stack/uniform/hooks/useFormContext';\n\ninterface FiltersContextValue {\n /** Active filters (names only) */\n activeFilters: string[];\n /** Seed default value and open modal for a filter usage. */\n addFilter: (name: string) => void;\n /** Close the modal. */\n closeFilterModal: () => void;\n /** Build fully-qualified form field path for a filter name */\n getFilterFormFieldName: (name: string) => string;\n /** Get current form value for a given filter name */\n getFilterValueByName: (name: string) => unknown;\n /** Get filter instance by name */\n getFilterInstanceByName: (name: string) => FilterInstance<unknown, unknown>;\n /** Validation helper for a specific filter field. */\n hasError: (name: string) => boolean;\n /** Name of the current filter that has its modal open */\n modalFilterName: string | undefined;\n /** Remove a filter from the form. */\n removeFilter: (name: string) => void;\n /** Open the modal for a given filter name. */\n showFilterModal: (name: string) => void;\n /** Filters that are not active (names only) */\n unusedFilters: string[];\n}\n\n/**\n * FiltersContext\n *\n * Central state for the filter UI with a clear boundary:\n * - The parent component controls committed filter values (via value/onChange)\n * - The form acts as an edit buffer (used by the modal)\n *\n * Design:\n * - activeFilters/unusedFilters are names-only and derived from the controlled\n * form state\n * - getFilterInstanceByName gives access to the concrete registry entry to\n * retrieve the correct Form/Display components\n * - add seeds defaults in the form and opens the modal\n * - remove un-registers the form field; if the removed filter is currently\n * open in the modal, the modal is closed without rollback\n * - on a new successful form submit (Apply), the modal closes without rollback\n * by subscribing to ex-forms submit state\n */\nconst FiltersContext = createContext<FiltersContextValue | undefined>(\n undefined,\n);\n\nexport const FiltersContextProvider = ({\n children,\n config,\n}: {\n children: ReactNode;\n config: FiltersConfiguration;\n}) => {\n // ex-forms integration:\n // - setValue/unregister/getFieldState: core helpers to manipulate and validate fields\n // - formState: we subscribe to submit-success to auto-close the modal after Apply\n const {\n formState,\n getFieldState,\n setValue,\n triggerSubmit,\n unregister,\n watch,\n } = useFormContext();\n\n /**\n * currentModalFilter\n *\n * Single source of truth for the filter edit modal and its rollback snapshot.\n * - name: which filter's modal is currently open (null when closed)\n * - hadValue/previousValue: snapshot of the controlled value taken when the\n * modal is opened; used to restore state if the user cancels/closes without\n * applying.\n *\n * Lifecycle semantics:\n * - showFilterModal(name): capture snapshot (current controlled value) and open\n * the modal for that filter.\n * - closeFilterModal(): if a snapshot exists, roll back un-applied edits by\n * restoring the previous value (setValue) or removing the field (unregister)\n * when it did not exist before; then clear currentModalFilter.\n * - On successful submit (Apply): close and clear currentModalFilter WITHOUT rollback\n * so edits remain committed.\n * - removeFilter(name): unregisters the field; when removing the filter that is\n * currently open, close the modal WITHOUT rollback (since removal is explicit).\n */\n const [currentModalFilter, setCurrentModalFilter] = useState<{\n name: string;\n hadValue: boolean;\n previousValue: unknown;\n } | null>(null);\n\n // Read current filter values from the form as the live edit buffer\n const filterValue = watch('filter', {});\n\n /**\n * getFilterFormFieldName\n *\n * Returns the fully-qualified field path for a given filter name,\n * e.g., `${filterUrlParam}.status`.\n */\n const getFilterFormFieldName = useCallback((name: string) => {\n return `filter.${name}`;\n }, []);\n\n /**\n * getFilterValueByName\n *\n * Returns the committed value for a filter from the controlled state.\n */\n const getFilterValueByName = useCallback(\n (name: string) => {\n return (filterValue as Record<string, unknown>)[name];\n },\n [filterValue],\n );\n\n /** Open the filter edit modal for the given filter name. */\n const showFilterModal = useCallback(\n (name: string) => {\n const prev = getFilterValueByName(name);\n setCurrentModalFilter({\n name,\n hadValue: typeof prev !== 'undefined',\n previousValue: prev,\n });\n },\n [getFilterValueByName],\n );\n\n /** Close the filter edit modal. Rollback un-applied edits to controlled state. */\n const closeFilterModal = useCallback(() => {\n if (currentModalFilter?.name) {\n const fieldName = getFilterFormFieldName(currentModalFilter.name);\n // if the filter had a value, set it back to the previous value,\n // otherwise unregister the field\n if (currentModalFilter.hadValue) {\n setValue(fieldName, currentModalFilter.previousValue);\n } else {\n unregister(fieldName);\n }\n }\n setCurrentModalFilter(null);\n }, [getFilterFormFieldName, currentModalFilter, setValue, unregister]);\n\n /**\n * Auto-close on submit success\n *\n * Close the modal only on new successful submissions. We track the last\n * submitCount and only react when it changes AND the form reports a\n * successful submit. This prevents closing when `isSubmitSuccessful` remains\n * true without a new submit event.\n */\n const lastSubmitCountRef = useRef<number>(0);\n useEffect(() => {\n if (\n formState.submitCount !== lastSubmitCountRef.current &&\n formState.isSubmitSuccessful\n ) {\n // On successful submit, close without rollback\n setCurrentModalFilter(null);\n }\n lastSubmitCountRef.current = formState.submitCount;\n }, [\n formState.submitCount,\n formState.isSubmitSuccessful,\n setCurrentModalFilter,\n ]);\n\n /**\n * activeFilters\n *\n * Filter names derived from the controlled form state. A filter is considered\n * active when a field exists at `filter.<name>`. Newly added filters become\n * active immediately (seeded default), and will be rolled back on cancel.\n */\n const activeFilters = useMemo(() => {\n return config\n .filter((f) => {\n return Object.hasOwn(filterValue ?? {}, f.name);\n })\n .map((f) => {\n return f.name;\n });\n }, [config, filterValue]);\n\n /**\n * unusedFilters\n *\n * Complement of activeFilters (names without a corresponding `filter.<name>`\n * field in the controlled form state).\n */\n const unusedFilters = useMemo(() => {\n return config\n .filter((f) => {\n return !Object.hasOwn(filterValue ?? {}, f.name);\n })\n .map((f) => {\n return f.name;\n });\n }, [config, filterValue]);\n\n /**\n * getRegistryFilterByName\n *\n * Looks up the concrete registry entry for a filter by name, enabling access\n * to typed Form/Display components and other registry-level metadata.\n */\n const getFilterInstanceByName = useCallback(\n (name: string) => {\n return config.find((f) => {\n return f.name === name;\n }) as FilterInstance<unknown, unknown>;\n },\n [config],\n );\n\n /**\n * addFilter\n *\n * Seeds the filter with its registry default value inside the form and opens\n * the modal for immediate editing. No URL writes happen here.\n */\n const addFilter = useCallback(\n (name: string) => {\n const inst = getFilterInstanceByName(name);\n showFilterModal(name);\n setValue(getFilterFormFieldName(name), inst.defaultValue);\n },\n [\n getFilterFormFieldName,\n getFilterInstanceByName,\n setValue,\n showFilterModal,\n ],\n );\n\n /**\n * removeFilter\n *\n * Unregisters the filter field from the form. This immediately removes the\n * filter from the active list since derived state watches the form. It\n * closes the modal without rollback if the removed filter is currently open.\n */\n const removeFilter = useCallback(\n (name: string) => {\n // unregister form field\n unregister(getFilterFormFieldName(name));\n // close filter modal if open\n if (currentModalFilter?.name === name) {\n // Explicit removal: close without rollback\n setCurrentModalFilter(null);\n }\n // trigger form submit (to update filter state)\n triggerSubmit();\n },\n [\n getFilterFormFieldName,\n currentModalFilter,\n setCurrentModalFilter,\n triggerSubmit,\n unregister,\n ],\n );\n\n /**\n * hasError\n *\n * Helper that checks the ex-forms field state for a specific filter and\n * reports whether the field is currently invalid.\n */\n const hasError = useCallback(\n (name: string) => {\n return getFieldState(getFilterFormFieldName(name)).invalid;\n },\n [getFieldState, getFilterFormFieldName],\n );\n\n const contextValue: FiltersContextValue = useMemo(() => {\n return {\n activeFilters,\n addFilter,\n closeFilterModal,\n getFilterFormFieldName,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n modalFilterName: currentModalFilter?.name,\n removeFilter,\n showFilterModal,\n unusedFilters,\n };\n }, [\n activeFilters,\n addFilter,\n closeFilterModal,\n getFilterFormFieldName,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n currentModalFilter,\n removeFilter,\n showFilterModal,\n unusedFilters,\n ]);\n\n return (\n <FiltersContext.Provider value={contextValue}>\n {children}\n </FiltersContext.Provider>\n );\n};\n\n/**\n * useFilters\n *\n * Convenience hook to consume the FiltersContext. Throws a descriptive error\n * when used outside of a FiltersContextProvider to make integration mistakes\n * obvious during development.\n */\nexport const useFilters = (): FiltersContextValue => {\n const ctx = useContext(FiltersContext);\n if (!ctx) {\n throw new Error('useFilters must be used within FiltersContextProvider');\n }\n return ctx;\n};\n\nexport default FiltersContext;\n","import Label from '@fuf-stack/pixels/Label';\n\nimport { useFilters } from './FiltersContext';\n\n/**\n * ActiveFilters\n *\n * Shows the list of currently applied filters as clickable chips that open\n * the edit modal. Each chip can be removed via its close action.\n */\ninterface ActiveFiltersProps {\n /** CSS class name to apply to each label */\n className?: string;\n}\n\nconst ActiveFilters = ({ className = undefined }: ActiveFiltersProps) => {\n const {\n activeFilters,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n removeFilter,\n showFilterModal,\n } = useFilters();\n return (\n <>\n {activeFilters.map((name) => {\n const instance = getFilterInstanceByName(name);\n const value = getFilterValueByName(name);\n\n // get the display component from the instance\n const DisplayComponent = instance.components.Display;\n\n return (\n <button\n key={name}\n aria-label={`Open ${name} filter`}\n type=\"button\"\n onClick={() => {\n showFilterModal(name);\n }}\n >\n <Label\n className={className}\n color={hasError(name) ? 'danger' : 'primary'}\n variant=\"flat\"\n onClose={() => {\n removeFilter(name);\n }}\n >\n {instance.icon}\n <DisplayComponent config={instance.config} value={value} />\n </Label>\n </button>\n );\n })}\n </>\n );\n};\n\nexport default ActiveFilters;\n","import { FaSliders } from 'react-icons/fa6';\n\nimport Menu from '@fuf-stack/pixels/Menu';\n\nimport { useFilters } from './FiltersContext';\n\ninterface AddFilterMenuProps {\n /** CSS class name map for slots */\n classNames?: Partial<{\n addFilterMenuItem: string;\n addFilterMenuButton: string;\n }>;\n}\n\n/**\n * AddFilterMenu\n *\n * Renders a menu trigger that opens a list of addable filters. Selecting an\n * item triggers the parent to seed a default value and open the modal.\n */\nconst AddFilterMenu = ({ classNames = {} }: AddFilterMenuProps) => {\n const { unusedFilters, addFilter, getFilterInstanceByName } = useFilters();\n\n const menuItems = unusedFilters.map((name) => {\n const instance = getFilterInstanceByName(name);\n const config = instance.config as { text?: string };\n const label = config?.text ?? name;\n return {\n key: name,\n icon: instance.icon,\n label,\n onClick: () => {\n addFilter(name);\n },\n };\n });\n\n return (\n <Menu\n isDisabled={!menuItems.length}\n items={menuItems}\n placement=\"bottom-start\"\n className={{\n item: classNames.addFilterMenuItem,\n trigger: classNames.addFilterMenuButton,\n }}\n triggerButtonProps={{\n 'aria-label': 'Add Filter',\n 'data-testid': 'add_filter_button',\n disableRipple: true,\n size: 'sm',\n variant: 'bordered',\n }}\n >\n <FaSliders />\n Filter\n </Menu>\n );\n};\n\nexport default AddFilterMenu;\n","import { Suspense } from 'react';\nimport { PiSlidersHorizontalBold } from 'react-icons/pi';\n\nimport Button from '@fuf-stack/pixels/Button';\nimport Modal from '@fuf-stack/pixels/Modal';\nimport SubmitButton from '@fuf-stack/uniform/SubmitButton';\n\nimport { useFilters } from './FiltersContext';\n\ninterface FilterModalProps {\n classNames?: Partial<{\n header: string;\n footer: string;\n body: string;\n }>;\n}\n\nconst FilterModal = ({ classNames = {} }: FilterModalProps) => {\n const {\n closeFilterModal,\n getFilterFormFieldName,\n getFilterInstanceByName,\n modalFilterName,\n removeFilter,\n } = useFilters();\n\n // don't render if no filter is open\n if (!modalFilterName) {\n return null;\n }\n\n const instance = getFilterInstanceByName(modalFilterName);\n const config = instance.config as { text?: string };\n\n // get the form component from the instance\n const FormComponent = instance.components.Form;\n\n return (\n <Modal\n isOpen\n onClose={closeFilterModal}\n className={{\n body: classNames.body,\n footer: classNames.footer,\n header: classNames.header,\n }}\n footer={\n <>\n <Button\n ariaLabel=\"Remove filter\"\n color=\"danger\"\n testId=\"remove_filter_button\"\n variant=\"flat\"\n onClick={() => {\n removeFilter(modalFilterName);\n }}\n >\n Remove\n </Button>\n <SubmitButton ariaLabel=\"Apply filter\" testId=\"apply_filter_button\">\n Apply Filter\n </SubmitButton>\n </>\n }\n header={\n <>\n {instance.icon ?? <PiSlidersHorizontalBold />}\n <div>{`${config?.text ?? modalFilterName} Filter`}</div>\n </>\n }\n >\n <Suspense>\n <FormComponent\n config={config}\n fieldName={getFilterFormFieldName(modalFilterName)}\n />\n </Suspense>\n </Modal>\n );\n};\n\nexport default FilterModal;\n","import { useState } from 'react';\nimport { FaSearch } from 'react-icons/fa';\n\nimport { motion } from '@fuf-stack/pixel-motion';\nimport Button from '@fuf-stack/pixels/Button';\nimport { useFormContext } from '@fuf-stack/uniform/hooks/useFormContext';\nimport Input from '@fuf-stack/uniform/Input';\nimport SubmitButton from '@fuf-stack/uniform/SubmitButton';\n\nexport type SearchConfiguration =\n | boolean\n | {\n /** Placeholder shown in the search input */\n placeholder?: string;\n };\n\ninterface SearchInputProps {\n /** Slots class names passed from parent variants */\n classNames?: Partial<{\n searchWrapper: string;\n searchShowButton: string;\n searchMotionDiv: string;\n searchInput: string;\n searchInputWrapper: string;\n searchSubmitButton: string;\n }>;\n /** Search configuration */\n config: SearchConfiguration;\n}\n\n/**\n * SearchInput\n *\n * By default renders only a search button. When clicked, the text input animates in\n * and a trailing submit button is shown.\n */\nconst SearchInput = ({ classNames = {}, config }: SearchInputProps) => {\n const { formState, setFocus, triggerSubmit } = useFormContext();\n\n // Auto-open if there is an initial or externally set search value\n const isInitiallyVisible = !!formState?.defaultValues?.search;\n const [isVisible, setIsVisible] = useState(isInitiallyVisible);\n\n const placeholder =\n typeof config === 'object' ? config.placeholder : undefined;\n\n return (\n <div className={classNames.searchWrapper}>\n {!isVisible && (\n <Button\n ariaLabel=\"Show search input\"\n className={classNames.searchShowButton}\n icon={<FaSearch />}\n size=\"sm\"\n testId=\"show_search_input_button\"\n variant=\"bordered\"\n onClick={() => {\n setIsVisible(true);\n }}\n />\n )}\n {isVisible ? (\n <motion.div\n key=\"search-input\"\n animate={{ opacity: 1 }}\n className={classNames.searchMotionDiv}\n // if the input was not initially visible, animate in\n initial={!isInitiallyVisible ? { opacity: 0.5 } : false}\n onAnimationComplete={() => {\n // if the input was not initially visible, focus it\n if (!isInitiallyVisible) {\n setFocus('search');\n }\n }}\n transition={{\n duration: 0.3,\n ease: 'circOut',\n }}\n >\n <Input\n clearable\n debounceDelay={0}\n name=\"search\"\n placeholder={placeholder}\n size=\"sm\"\n className={{\n input: classNames.searchInput,\n inputWrapper: classNames.searchInputWrapper,\n }}\n // submit on clear\n onClear={() => {\n triggerSubmit();\n }}\n />\n <SubmitButton\n ariaLabel=\"Submit search\"\n // eslint-disable-next-line react/no-children-prop\n children={null}\n className={classNames.searchSubmitButton}\n color=\"primary\"\n icon={<FaSearch />}\n size=\"sm\"\n testId=\"submit_search_button\"\n />\n </motion.div>\n ) : null}\n </div>\n );\n};\n\nexport default SearchInput;\n","import type { TVClassName } from '@fuf-stack/pixel-utils';\nimport type { VetoInput } from '@fuf-stack/veto';\nimport type { ReactNode } from 'react';\nimport type { FiltersConfiguration } from './filters/types';\nimport type { SearchConfiguration } from './Subcomponents/SearchInput';\n\nimport createDebug from 'debug';\n\nimport { tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\nimport Form from '@fuf-stack/uniform/Form';\n\nimport { useFilterValidation } from './hooks/useFilterValidation';\nimport ActiveFilters from './Subcomponents/ActiveFilters';\nimport AddFilterMenu from './Subcomponents/AddFilterMenu';\nimport FilterModal from './Subcomponents/FilterModal';\nimport { FiltersContextProvider } from './Subcomponents/FiltersContext';\nimport SearchInput from './Subcomponents/SearchInput';\n\nconst debug = createDebug('megapixels:Filter');\n\n// filter styling variants\nexport const filterVariants = tv({\n slots: {\n // outer wrapper\n base: 'flex flex-auto flex-col',\n // add filter menu trigger button\n addFilterMenuButton: '',\n // add filter menu item\n addFilterMenuItem: '',\n // active filter label\n activeFilterLabel: 'h-8 cursor-pointer rounded-md dark:text-foreground',\n // filter modal body\n filterModalBody: '',\n // filter modal header\n filterModalHeader: 'flex items-center gap-3 text-default-700',\n // filter modal footer\n filterModalFooter: 'justify-between',\n // form element\n form: 'mb-3 flex flex-wrap gap-3',\n // search input field\n searchInput: '',\n // search input wrapper (inner control)\n searchInputWrapper: '',\n // search motion container\n searchMotionDiv: 'flex w-72 gap-2',\n // search show button\n searchShowButton: '',\n // search submit button\n searchSubmitButton: '',\n // search wrapper\n searchWrapper: 'flex items-center',\n },\n});\n\ntype ClassName = TVClassName<typeof filterVariants>;\n\nexport interface FilterValues {\n search?: string;\n filter?: string | Record<string, unknown> | null;\n}\n\nexport type FilterChildRenderFn = (values: {\n search?: string;\n filter?: Record<string, unknown>;\n}) => ReactNode;\n\n/**\n * Filter\n *\n * Controlled, form-driven filter UI.\n *\n * Responsibilities\n * - Derives initial form values from the controlled `values` prop\n * - Builds a composite validation schema from the filter registry (and optional search)\n * - Exposes ergonomic UI: active filters list, add/remove actions, and per-filter modal\n * - Commits changes by invoking the controlled `onChange` callback on submit\n *\n * Structure\n * - Owns an ex-forms `Form` that wraps the entire filter experience\n * - Optionally renders a search input bound to the `search` field\n * - Renders ActiveFilters, AddFilterMenu, and FilterModal inside a shared context\n * - Optionally renders children as a render-prop with the resolved `values`\n */\nexport interface FilterProps {\n /** Optional render-prop that receives the resolved, controlled values */\n children?: FilterChildRenderFn;\n /** CSS class name */\n className?: ClassName;\n /** Configuration of the filter */\n config: {\n /**\n * Declarative filter configuration. Each entry ties a logical name to a\n * registry filter type and (optionally) per-usage config overrides.\n */\n filters: FiltersConfiguration;\n /** Optional configuration for search field */\n search?: SearchConfiguration;\n };\n /** ex-forms form instance name. Defaults to \"filterComponentForm\". */\n formName?: string;\n /** Controlled setter invoked on submit with the next canonical values */\n onChange: (nextValues: FilterValues) => void;\n /** Controlled committed state: the canonical `search` and `filter` values */\n values: FilterValues;\n}\n\n/**\n * Renders the filter UI bound to a single ex-forms `Form`.\n * The form is the source of truth during user interaction; the committed\n * state is controlled by the parent via `values`/`onChange`.\n */\nconst Filter = ({\n children = undefined,\n className = undefined,\n config,\n formName = 'filterComponentForm',\n onChange,\n values,\n}: FilterProps) => {\n // Submit handler: map form state back into the controlled `values` shape\n const handleSubmit = (nextValues: Record<string, unknown>) => {\n debug('handleSubmit', { nextValues });\n onChange(nextValues as FilterValues);\n };\n\n // Build validation schema for all configured filters (and optional search)\n const validation = useFilterValidation(\n config.filters,\n Boolean(config.search),\n );\n\n // validate controlled values are valid\n const {\n data: valuesValidated,\n errors,\n success,\n } = validation.validate(values as VetoInput);\n\n // classNames from slots\n const variants = filterVariants();\n const classNames = variantsToClassNames(variants, className, 'base');\n\n debug('render', {\n props: { config, values },\n validation: { errors, success, valuesValidated },\n });\n\n return (\n <div className={classNames.base}>\n {/*\n Uniform Form wrapper\n - initialValues derive from controlled props (with optional defaults)\n - validation is built from the registry for all configured filters\n - onSubmit maps form values back into values/onChange\n */}\n <Form\n className={classNames.form}\n // disable debug mode for now\n debug={{ disable: true }}\n initialValues={valuesValidated ?? {}}\n name={formName}\n onSubmit={handleSubmit}\n validation={validation}\n >\n {/* Render search if search config is provided */}\n {config.search ? (\n <SearchInput\n config={config.search}\n classNames={{\n searchInput: classNames.searchInput,\n searchInputWrapper: classNames.searchInputWrapper,\n searchMotionDiv: classNames.searchMotionDiv,\n searchShowButton: classNames.searchShowButton,\n searchSubmitButton: classNames.searchSubmitButton,\n searchWrapper: classNames.searchWrapper,\n }}\n />\n ) : null}\n {/*\n FiltersContextProvider exposes a minimal API for the UI layer:\n - activeFilters/unusedFilters by name\n - helpers to get merged config, value, components, and field names\n - methods to add/remove filters and show/close the modal\n */}\n <FiltersContextProvider config={config.filters}>\n <ActiveFilters className={classNames.activeFilterLabel} />\n <AddFilterMenu\n classNames={{\n addFilterMenuButton: classNames.addFilterMenuButton,\n addFilterMenuItem: classNames.addFilterMenuItem,\n }}\n />\n <FilterModal\n classNames={{\n body: classNames.filterModalBody,\n footer: classNames.filterModalFooter,\n header: classNames.filterModalHeader,\n }}\n />\n </FiltersContextProvider>\n </Form>\n {/* Children can consume derived search string and parsed filter object */}\n {children?.(valuesValidated ?? {})}\n </div>\n );\n};\n\nexport default Filter;\n","import type { FilterDefinition, FilterFactory } from './types';\n\n/**\n * createFilter\n *\n * Builds a filter factory from a static FilterDefinition. The returned factory\n * accepts a usage descriptor (name/icon and optional partial config) and\n * produces a concrete FilterInstance with:\n * - merged config (shallow: definition.defaults.config overlaid by overrides)\n * - Form/Display components\n * - validate function (forwarded from the definition)\n * - defaultValue (forwarded from the definition)\n * - name and icon for UI integration\n *\n * @typeParam Config - Configuration object shape for the filter\n * @typeParam Value - Runtime value type for the filter\n * @param definition - Static description of the filter (components, defaults, validate)\n * @returns FilterFactory that creates FilterInstance<Config, Value>\n */\nconst createFilter = <Config, Value>(\n definition: FilterDefinition<Config, Value>,\n): FilterFactory<Config, Value> => {\n return ({ name, icon, config }) => {\n return {\n components: definition.components,\n config: { ...definition.defaults.config, ...(config ?? {}) } as Config,\n defaultValue: definition.defaults.value,\n icon,\n name,\n validation: definition.validation,\n };\n };\n};\n\nexport default createFilter;\n","import type { FilterDisplayProps } from '../types';\nimport type { Config, Value } from './schema';\n\n/**\n * Read-only presentation for the boolean filter.\n * Displays human-readable text based on the current boolean `value`\n * and the provided `config` strings.\n */\nconst Display = ({\n value,\n config: { text, textPrefix, textNoWord },\n}: FilterDisplayProps<Config, Value>) => {\n if (typeof value === 'boolean') {\n return (\n <>\n {`${value ? textPrefix : `${textPrefix} ${textNoWord ?? 'no'}`} ${text}`}\n </>\n );\n }\n return <>{`${text}...`}</>;\n};\n\nexport default Display;\n","import type { FilterFormProps } from '../types';\nimport type { Config } from './schema';\n\nimport Switch from '@fuf-stack/uniform/Switch';\n\n/**\n * Renders the form control for the boolean filter.\n * Uses a `Switch` to toggle the boolean value and composes\n * the label from the provided `config` and `fieldName`.\n */\nconst Form = ({\n fieldName,\n config: { text, textPrefix },\n}: FilterFormProps<Config>) => {\n return <Switch label={`${textPrefix} ${text}`} name={fieldName} />;\n};\n\nexport default Form;\n","import type { vInfer } from '@fuf-stack/veto';\n\nimport { boolean, object, string } from '@fuf-stack/veto';\n\n/** configuration of the filter */\nexport const config = object({\n /**\n * Human‑readable label used in the UI (e.g. in the chip and modal header).\n * Examples: \"Magical\", \"Haunted\"\n */\n text: string(),\n /**\n * Optional word shown before the label when building sentence‑like chips.\n * Examples: \"is\" → \"is Magical\"\n */\n textPrefix: string().optional(),\n /**\n * Optional negation word used when a boolean value is false.\n * Examples: \"not\" → \"is not Magical\"\n */\n textNoWord: string().optional(),\n});\n\n/** validate the filter value */\nexport const validate = (_config?: Config) => {\n return boolean().optional();\n};\n\nexport type Config = vInfer<typeof config>;\nexport type Value = vInfer<ReturnType<typeof validate>>;\n","/* eslint-disable import-x/prefer-default-export */\n\nimport type { Config, Value } from './schema';\n\nimport createFilter from '../createFilter';\nimport Display from './Display';\nimport Form from './Form';\nimport { validate } from './schema';\n\n/**\n * Boolean filter definition for the Filter system.\n * Provides Display and Form components, default value/config, and validation.\n *\n * Defaults:\n * - value: true\n * - config: { text: 'Active', textPrefix: 'is', textNoWord: 'no' }\n *\n * @see Display\n * @see Form\n * @see validate\n */\nexport const boolean = createFilter<Config, Value>({\n components: { Display, Form },\n defaults: {\n value: true,\n config: { text: 'Active', textPrefix: 'is', textNoWord: 'no' },\n },\n validation: validate,\n});\n","import type { FilterDisplayProps } from '../types';\nimport type { Config, Value } from './schema';\n\n/**\n * Read-only presentation for the checkboxes filter.\n * Resolves and displays selected option labels based on `value` and `config`.\n * Supports string, ReactNode, and function labels (mode: 'display').\n */\nconst Display = ({\n value,\n config: { text, options },\n}: FilterDisplayProps<Config, Value>) => {\n if (value && value.length > 0) {\n return (\n <span className=\"flex items-center gap-1\">\n {text} is\n {value.map((val) => {\n const option = options.find((op) => {\n return op.value === val;\n });\n const label = option?.label ?? val;\n const resolvedLabel =\n typeof label === 'function' ? label('display') : label;\n return <span key={val}>{resolvedLabel}</span>;\n })}\n </span>\n );\n }\n return `${text} is ...`;\n};\n\nexport default Display;\n","import type { FilterFormProps } from '../types';\nimport type { Config } from './schema';\n\nimport Checkboxes from '@fuf-stack/uniform/Checkboxes';\n\n/**\n * Renders the form control for the checkboxes filter.\n * Uses a `Checkboxes` to select multiple options.\n * Resolves function labels with 'form' mode.\n */\nconst Form = ({ fieldName, config }: FilterFormProps<Config>) => {\n const resolvedOptions = config.options.map((option) => {\n return {\n ...option,\n label:\n typeof option.label === 'function'\n ? option.label('form')\n : option.label,\n };\n });\n\n return <Checkboxes name={fieldName} options={resolvedOptions} />;\n};\n\nexport default Form;\n","import type { vInfer } from '@fuf-stack/veto';\nimport type { ReactNode } from 'react';\n\nimport { any, array, object, refineArray, string } from '@fuf-stack/veto';\n\n/** configuration of the filter */\nexport const config = object({\n /**\n * Human‑readable label used in the UI (e.g. label and modal header).\n * Example: \"Snacks\", \"Mood\"\n */\n text: string(),\n /**\n * Options rendered as multiple checkboxes. Each option needs a `label`\n * (what the user sees) and a `value` (what is written into the form state).\n * Label can be a string, React node, or a function that receives mode\n * ('form' or 'display') and returns a React node.\n */\n options: array(object({ label: any(), value: string() })),\n});\n\n/** Type-safe Config that overrides label to support ReactNode or function */\nexport type Config = Omit<vInfer<typeof config>, 'options'> & {\n options: {\n label: ReactNode | ((mode: 'form' | 'display') => ReactNode);\n value: string;\n }[];\n};\n\n/** validate the filter value */\nexport const validate = (cfg?: Config) => {\n return refineArray(array(string()).optional())({\n unique: true,\n custom: (values, ctx) => {\n if (!cfg) {\n return;\n }\n values.forEach((value) => {\n if (\n !cfg.options.find((option) => {\n return option?.value === value;\n })\n ) {\n ctx.addIssue({\n code: 'custom',\n message: `Invalid value: ${value}`,\n });\n }\n });\n },\n });\n};\n\nexport type Value = vInfer<ReturnType<typeof validate>>;\n","/* eslint-disable import-x/prefer-default-export */\n\nimport type { Config, Value } from './schema';\n\nimport createFilter from '../createFilter';\nimport Display from './Display';\nimport Form from './Form';\nimport { validate } from './schema';\n\n/**\n * Checkboxes filter definition for the Filter system.\n * Provides Display and Form components, default value/config, and validation.\n *\n * Defaults:\n * - value: []\n * - config: { text: 'Options', options: [] }\n *\n * @see Display\n * @see Form\n * @see validate\n */\nexport const checkboxes = createFilter<Config, Value>({\n components: { Display, Form },\n defaults: { value: [], config: { text: 'Options', options: [] } },\n validation: validate,\n});\n","import Filter from './Filter';\nimport { boolean } from './filters/boolean/boolean';\nimport { checkboxes } from './filters/checkboxes/checkboxes';\n\n// export types\nexport type * from './filters/types';\n\n// export helpers\nexport { default as createFilter } from './filters/createFilter';\n\n// export all filters\nexport const filters = {\n boolean,\n checkboxes,\n};\n\n// export everything from the Filter component (types and filterVariants)\nexport * from './Filter';\n\n// export the Filter component as default\nexport default Filter;\n"],"mappings":"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"}
@@ -27,33 +27,33 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  //#endregion
28
28
  let debug = require("debug");
29
29
  debug = __toESM(debug);
30
- let __fuf_stack_pixel_utils = require("@fuf-stack/pixel-utils");
31
- let __fuf_stack_uniform_Form = require("@fuf-stack/uniform/Form");
32
- __fuf_stack_uniform_Form = __toESM(__fuf_stack_uniform_Form);
30
+ let _fuf_stack_pixel_utils = require("@fuf-stack/pixel-utils");
31
+ let _fuf_stack_uniform_Form = require("@fuf-stack/uniform/Form");
32
+ _fuf_stack_uniform_Form = __toESM(_fuf_stack_uniform_Form);
33
33
  let react = require("react");
34
- let __fuf_stack_veto = require("@fuf-stack/veto");
35
- let __fuf_stack_pixels_Label = require("@fuf-stack/pixels/Label");
36
- __fuf_stack_pixels_Label = __toESM(__fuf_stack_pixels_Label);
37
- let __fuf_stack_uniform_hooks_useFormContext = require("@fuf-stack/uniform/hooks/useFormContext");
34
+ let _fuf_stack_veto = require("@fuf-stack/veto");
35
+ let _fuf_stack_pixels_Label = require("@fuf-stack/pixels/Label");
36
+ _fuf_stack_pixels_Label = __toESM(_fuf_stack_pixels_Label);
37
+ let _fuf_stack_uniform_hooks_useFormContext = require("@fuf-stack/uniform/hooks/useFormContext");
38
38
  let react_jsx_runtime = require("react/jsx-runtime");
39
39
  let react_icons_fa6 = require("react-icons/fa6");
40
- let __fuf_stack_pixels_Menu = require("@fuf-stack/pixels/Menu");
41
- __fuf_stack_pixels_Menu = __toESM(__fuf_stack_pixels_Menu);
40
+ let _fuf_stack_pixels_Menu = require("@fuf-stack/pixels/Menu");
41
+ _fuf_stack_pixels_Menu = __toESM(_fuf_stack_pixels_Menu);
42
42
  let react_icons_pi = require("react-icons/pi");
43
- let __fuf_stack_pixels_Button = require("@fuf-stack/pixels/Button");
44
- __fuf_stack_pixels_Button = __toESM(__fuf_stack_pixels_Button);
45
- let __fuf_stack_pixels_Modal = require("@fuf-stack/pixels/Modal");
46
- __fuf_stack_pixels_Modal = __toESM(__fuf_stack_pixels_Modal);
47
- let __fuf_stack_uniform_SubmitButton = require("@fuf-stack/uniform/SubmitButton");
48
- __fuf_stack_uniform_SubmitButton = __toESM(__fuf_stack_uniform_SubmitButton);
43
+ let _fuf_stack_pixels_Button = require("@fuf-stack/pixels/Button");
44
+ _fuf_stack_pixels_Button = __toESM(_fuf_stack_pixels_Button);
45
+ let _fuf_stack_pixels_Modal = require("@fuf-stack/pixels/Modal");
46
+ _fuf_stack_pixels_Modal = __toESM(_fuf_stack_pixels_Modal);
47
+ let _fuf_stack_uniform_SubmitButton = require("@fuf-stack/uniform/SubmitButton");
48
+ _fuf_stack_uniform_SubmitButton = __toESM(_fuf_stack_uniform_SubmitButton);
49
49
  let react_icons_fa = require("react-icons/fa");
50
- let __fuf_stack_pixel_motion = require("@fuf-stack/pixel-motion");
51
- let __fuf_stack_uniform_Input = require("@fuf-stack/uniform/Input");
52
- __fuf_stack_uniform_Input = __toESM(__fuf_stack_uniform_Input);
53
- let __fuf_stack_uniform_Switch = require("@fuf-stack/uniform/Switch");
54
- __fuf_stack_uniform_Switch = __toESM(__fuf_stack_uniform_Switch);
55
- let __fuf_stack_uniform_Checkboxes = require("@fuf-stack/uniform/Checkboxes");
56
- __fuf_stack_uniform_Checkboxes = __toESM(__fuf_stack_uniform_Checkboxes);
50
+ let _fuf_stack_pixel_motion = require("@fuf-stack/pixel-motion");
51
+ let _fuf_stack_uniform_Input = require("@fuf-stack/uniform/Input");
52
+ _fuf_stack_uniform_Input = __toESM(_fuf_stack_uniform_Input);
53
+ let _fuf_stack_uniform_Switch = require("@fuf-stack/uniform/Switch");
54
+ _fuf_stack_uniform_Switch = __toESM(_fuf_stack_uniform_Switch);
55
+ let _fuf_stack_uniform_Checkboxes = require("@fuf-stack/uniform/Checkboxes");
56
+ _fuf_stack_uniform_Checkboxes = __toESM(_fuf_stack_uniform_Checkboxes);
57
57
 
58
58
  //#region src/Filter/hooks/useFilterValidation.ts
59
59
  /**
@@ -72,11 +72,11 @@ const useFilterValidation = (filters$1, withSearch) => {
72
72
  [f.name]: f.validation(f.config)
73
73
  };
74
74
  });
75
- return (0, __fuf_stack_veto.veto)({
76
- filter: (0, __fuf_stack_veto.stringToJSON)().pipe((0, __fuf_stack_veto.object)(filterSchema)).or((0, __fuf_stack_veto.object)(filterSchema)).optional().nullable().transform((val) => {
75
+ return (0, _fuf_stack_veto.veto)({
76
+ filter: (0, _fuf_stack_veto.stringToJSON)().pipe((0, _fuf_stack_veto.object)(filterSchema)).or((0, _fuf_stack_veto.object)(filterSchema)).optional().nullable().transform((val) => {
77
77
  return val ?? void 0;
78
78
  }),
79
- ...withSearch ? { search: (0, __fuf_stack_veto.string)({ min: 0 }).nullable().optional() } : {}
79
+ ...withSearch ? { search: (0, _fuf_stack_veto.string)({ min: 0 }).nullable().optional() } : {}
80
80
  });
81
81
  }, [filters$1, withSearch]);
82
82
  };
@@ -103,7 +103,7 @@ const useFilterValidation = (filters$1, withSearch) => {
103
103
  */
104
104
  const FiltersContext = (0, react.createContext)(void 0);
105
105
  const FiltersContextProvider = ({ children, config: config$2 }) => {
106
- const { formState, getFieldState, setValue, triggerSubmit, unregister, watch } = (0, __fuf_stack_uniform_hooks_useFormContext.useFormContext)();
106
+ const { formState, getFieldState, setValue, triggerSubmit, unregister, watch } = (0, _fuf_stack_uniform_hooks_useFormContext.useFormContext)();
107
107
  /**
108
108
  * currentModalFilter
109
109
  *
@@ -323,7 +323,7 @@ const ActiveFilters = ({ className = void 0 }) => {
323
323
  onClick: () => {
324
324
  showFilterModal(name);
325
325
  },
326
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__fuf_stack_pixels_Label.default, {
326
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_fuf_stack_pixels_Label.default, {
327
327
  className,
328
328
  color: hasError(name) ? "danger" : "primary",
329
329
  variant: "flat",
@@ -362,7 +362,7 @@ const AddFilterMenu = ({ classNames = {} }) => {
362
362
  }
363
363
  };
364
364
  });
365
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__fuf_stack_pixels_Menu.default, {
365
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_fuf_stack_pixels_Menu.default, {
366
366
  isDisabled: !menuItems.length,
367
367
  items: menuItems,
368
368
  placement: "bottom-start",
@@ -390,7 +390,7 @@ const FilterModal = ({ classNames = {} }) => {
390
390
  const instance = getFilterInstanceByName(modalFilterName);
391
391
  const config$2 = instance.config;
392
392
  const FormComponent = instance.components.Form;
393
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__fuf_stack_pixels_Modal.default, {
393
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_pixels_Modal.default, {
394
394
  isOpen: true,
395
395
  onClose: closeFilterModal,
396
396
  className: {
@@ -398,7 +398,7 @@ const FilterModal = ({ classNames = {} }) => {
398
398
  footer: classNames.footer,
399
399
  header: classNames.header
400
400
  },
401
- footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__fuf_stack_pixels_Button.default, {
401
+ footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_pixels_Button.default, {
402
402
  ariaLabel: "Remove filter",
403
403
  color: "danger",
404
404
  testId: "remove_filter_button",
@@ -407,7 +407,7 @@ const FilterModal = ({ classNames = {} }) => {
407
407
  removeFilter(modalFilterName);
408
408
  },
409
409
  children: "Remove"
410
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__fuf_stack_uniform_SubmitButton.default, {
410
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_uniform_SubmitButton.default, {
411
411
  ariaLabel: "Apply filter",
412
412
  testId: "apply_filter_button",
413
413
  children: "Apply Filter"
@@ -430,13 +430,13 @@ var FilterModal_default = FilterModal;
430
430
  * and a trailing submit button is shown.
431
431
  */
432
432
  const SearchInput = ({ classNames = {}, config: config$2 }) => {
433
- const { formState, setFocus, triggerSubmit } = (0, __fuf_stack_uniform_hooks_useFormContext.useFormContext)();
433
+ const { formState, setFocus, triggerSubmit } = (0, _fuf_stack_uniform_hooks_useFormContext.useFormContext)();
434
434
  const isInitiallyVisible = !!formState?.defaultValues?.search;
435
435
  const [isVisible, setIsVisible] = (0, react.useState)(isInitiallyVisible);
436
436
  const placeholder = typeof config$2 === "object" ? config$2.placeholder : void 0;
437
437
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
438
438
  className: classNames.searchWrapper,
439
- children: [!isVisible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__fuf_stack_pixels_Button.default, {
439
+ children: [!isVisible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_pixels_Button.default, {
440
440
  ariaLabel: "Show search input",
441
441
  className: classNames.searchShowButton,
442
442
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_fa.FaSearch, {}),
@@ -446,7 +446,7 @@ const SearchInput = ({ classNames = {}, config: config$2 }) => {
446
446
  onClick: () => {
447
447
  setIsVisible(true);
448
448
  }
449
- }), isVisible ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__fuf_stack_pixel_motion.motion.div, {
449
+ }), isVisible ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_fuf_stack_pixel_motion.motion.div, {
450
450
  animate: { opacity: 1 },
451
451
  className: classNames.searchMotionDiv,
452
452
  initial: !isInitiallyVisible ? { opacity: .5 } : false,
@@ -457,7 +457,7 @@ const SearchInput = ({ classNames = {}, config: config$2 }) => {
457
457
  duration: .3,
458
458
  ease: "circOut"
459
459
  },
460
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__fuf_stack_uniform_Input.default, {
460
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_uniform_Input.default, {
461
461
  clearable: true,
462
462
  debounceDelay: 0,
463
463
  name: "search",
@@ -470,7 +470,7 @@ const SearchInput = ({ classNames = {}, config: config$2 }) => {
470
470
  onClear: () => {
471
471
  triggerSubmit();
472
472
  }
473
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__fuf_stack_uniform_SubmitButton.default, {
473
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_uniform_SubmitButton.default, {
474
474
  ariaLabel: "Submit search",
475
475
  children: null,
476
476
  className: classNames.searchSubmitButton,
@@ -487,7 +487,7 @@ var SearchInput_default = SearchInput;
487
487
  //#endregion
488
488
  //#region src/Filter/Filter.tsx
489
489
  const debug$1 = (0, debug.default)("megapixels:Filter");
490
- const filterVariants = (0, __fuf_stack_pixel_utils.tv)({ slots: {
490
+ const filterVariants = (0, _fuf_stack_pixel_utils.tv)({ slots: {
491
491
  base: "flex flex-auto flex-col",
492
492
  addFilterMenuButton: "",
493
493
  addFilterMenuItem: "",
@@ -515,7 +515,7 @@ const Filter = ({ children = void 0, className = void 0, config: config$2, formN
515
515
  };
516
516
  const validation = useFilterValidation(config$2.filters, Boolean(config$2.search));
517
517
  const { data: valuesValidated, errors, success } = validation.validate(values);
518
- const classNames = (0, __fuf_stack_pixel_utils.variantsToClassNames)(filterVariants(), className, "base");
518
+ const classNames = (0, _fuf_stack_pixel_utils.variantsToClassNames)(filterVariants(), className, "base");
519
519
  debug$1("render", {
520
520
  props: {
521
521
  config: config$2,
@@ -529,7 +529,7 @@ const Filter = ({ children = void 0, className = void 0, config: config$2, formN
529
529
  });
530
530
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
531
531
  className: classNames.base,
532
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__fuf_stack_uniform_Form.default, {
532
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_fuf_stack_uniform_Form.default, {
533
533
  className: classNames.form,
534
534
  debug: { disable: true },
535
535
  initialValues: valuesValidated ?? {},
@@ -564,7 +564,7 @@ const Filter = ({ children = void 0, className = void 0, config: config$2, formN
564
564
  }), children?.(valuesValidated ?? {})]
565
565
  });
566
566
  };
567
- var Filter_default = Filter;
567
+ var Filter_default$1 = Filter;
568
568
 
569
569
  //#endregion
570
570
  //#region src/Filter/filters/createFilter.ts
@@ -623,7 +623,7 @@ var Display_default$1 = Display$1;
623
623
  * the label from the provided `config` and `fieldName`.
624
624
  */
625
625
  const Form$1 = ({ fieldName, config: { text, textPrefix } }) => {
626
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__fuf_stack_uniform_Switch.default, {
626
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_uniform_Switch.default, {
627
627
  label: `${textPrefix} ${text}`,
628
628
  name: fieldName
629
629
  });
@@ -633,14 +633,14 @@ var Form_default$1 = Form$1;
633
633
  //#endregion
634
634
  //#region src/Filter/filters/boolean/schema.ts
635
635
  /** configuration of the filter */
636
- const config$1 = (0, __fuf_stack_veto.object)({
637
- text: (0, __fuf_stack_veto.string)(),
638
- textPrefix: (0, __fuf_stack_veto.string)().optional(),
639
- textNoWord: (0, __fuf_stack_veto.string)().optional()
636
+ const config$1 = (0, _fuf_stack_veto.object)({
637
+ text: (0, _fuf_stack_veto.string)(),
638
+ textPrefix: (0, _fuf_stack_veto.string)().optional(),
639
+ textNoWord: (0, _fuf_stack_veto.string)().optional()
640
640
  });
641
641
  /** validate the filter value */
642
642
  const validate$1 = (_config) => {
643
- return (0, __fuf_stack_veto.boolean)().optional();
643
+ return (0, _fuf_stack_veto.boolean)().optional();
644
644
  };
645
645
 
646
646
  //#endregion
@@ -706,7 +706,7 @@ var Display_default = Display;
706
706
  * Resolves function labels with 'form' mode.
707
707
  */
708
708
  const Form = ({ fieldName, config: config$2 }) => {
709
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__fuf_stack_uniform_Checkboxes.default, {
709
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_uniform_Checkboxes.default, {
710
710
  name: fieldName,
711
711
  options: config$2.options.map((option) => {
712
712
  return {
@@ -721,16 +721,16 @@ var Form_default = Form;
721
721
  //#endregion
722
722
  //#region src/Filter/filters/checkboxes/schema.ts
723
723
  /** configuration of the filter */
724
- const config = (0, __fuf_stack_veto.object)({
725
- text: (0, __fuf_stack_veto.string)(),
726
- options: (0, __fuf_stack_veto.array)((0, __fuf_stack_veto.object)({
727
- label: (0, __fuf_stack_veto.any)(),
728
- value: (0, __fuf_stack_veto.string)()
724
+ const config = (0, _fuf_stack_veto.object)({
725
+ text: (0, _fuf_stack_veto.string)(),
726
+ options: (0, _fuf_stack_veto.array)((0, _fuf_stack_veto.object)({
727
+ label: (0, _fuf_stack_veto.any)(),
728
+ value: (0, _fuf_stack_veto.string)()
729
729
  }))
730
730
  });
731
731
  /** validate the filter value */
732
732
  const validate = (cfg) => {
733
- return (0, __fuf_stack_veto.refineArray)((0, __fuf_stack_veto.array)((0, __fuf_stack_veto.string)()).optional())({
733
+ return (0, _fuf_stack_veto.refineArray)((0, _fuf_stack_veto.array)((0, _fuf_stack_veto.string)()).optional())({
734
734
  unique: true,
735
735
  custom: (values, ctx) => {
736
736
  if (!cfg) return;
@@ -781,13 +781,13 @@ const filters = {
781
781
  boolean,
782
782
  checkboxes
783
783
  };
784
- var Filter_default$1 = Filter_default;
784
+ var Filter_default = Filter_default$1;
785
785
 
786
786
  //#endregion
787
787
  Object.defineProperty(exports, 'Filter_default', {
788
788
  enumerable: true,
789
789
  get: function () {
790
- return Filter_default$1;
790
+ return Filter_default;
791
791
  }
792
792
  });
793
793
  Object.defineProperty(exports, 'createFilter_default', {
@@ -808,4 +808,4 @@ Object.defineProperty(exports, 'filters', {
808
808
  return filters;
809
809
  }
810
810
  });
811
- //# sourceMappingURL=Filter-Bc0LWCnZ.cjs.map
811
+ //# sourceMappingURL=Filter-obuSI5QN.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Filter-obuSI5QN.cjs","names":["filters","config","Label","Menu","FaSliders","config","Modal","Button","SubmitButton","PiSlidersHorizontalBold","Suspense","config","Button","FaSearch","motion","Input","SubmitButton","debug","config","Form","SearchInput","ActiveFilters","AddFilterMenu","FilterModal","config","Display","Form","Switch","config","validate","createFilter","validate","Checkboxes","config","createFilter","Filter"],"sources":["../src/Filter/hooks/useFilterValidation.ts","../src/Filter/Subcomponents/FiltersContext.tsx","../src/Filter/Subcomponents/ActiveFilters.tsx","../src/Filter/Subcomponents/AddFilterMenu.tsx","../src/Filter/Subcomponents/FilterModal.tsx","../src/Filter/Subcomponents/SearchInput.tsx","../src/Filter/Filter.tsx","../src/Filter/filters/createFilter.ts","../src/Filter/filters/boolean/Display.tsx","../src/Filter/filters/boolean/Form.tsx","../src/Filter/filters/boolean/schema.ts","../src/Filter/filters/boolean/boolean.ts","../src/Filter/filters/checkboxes/Display.tsx","../src/Filter/filters/checkboxes/Form.tsx","../src/Filter/filters/checkboxes/schema.ts","../src/Filter/filters/checkboxes/checkboxes.ts","../src/Filter/index.ts"],"sourcesContent":["import type { VetoInstance, VetoRawShape, VetoTypeAny } from '@fuf-stack/veto';\nimport type { FilterInstance } from '../filters/types';\n\nimport { useMemo } from 'react';\n\nimport { object, string, stringToJSON, veto } from '@fuf-stack/veto';\n\n/**\n * useFilterValidation\n *\n * Builds a composite validation schema from all provided filter definitions\n * under \"filter\" and optionally includes a \"search\" string field.\n * Memoized by inputs.\n */\nexport const useFilterValidation = (\n filters: FilterInstance<unknown, unknown>[],\n withSearch?: boolean,\n) => {\n return useMemo<VetoInstance>(() => {\n // build filter validation\n let filterSchema: Record<string, VetoTypeAny> = {};\n filters.forEach((f) => {\n filterSchema = {\n ...filterSchema,\n [f.name]: f.validation(f.config) as VetoTypeAny,\n };\n });\n\n const validationSchema: VetoRawShape = {\n // filter validation\n filter: stringToJSON()\n .pipe(object(filterSchema))\n .or(object(filterSchema))\n .optional()\n .nullable()\n // transform null to undefined\n .transform((val) => {\n return val ?? undefined;\n }),\n // optional search validation\n ...(withSearch\n ? { search: string({ min: 0 }).nullable().optional() }\n : {}),\n };\n\n return veto(validationSchema);\n }, [filters, withSearch]);\n};\n\nexport default useFilterValidation;\n","import type { ReactNode } from 'react';\nimport type { FilterInstance, FiltersConfiguration } from '../filters/types';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useFormContext } from '@fuf-stack/uniform/hooks/useFormContext';\n\ninterface FiltersContextValue {\n /** Active filters (names only) */\n activeFilters: string[];\n /** Seed default value and open modal for a filter usage. */\n addFilter: (name: string) => void;\n /** Close the modal. */\n closeFilterModal: () => void;\n /** Build fully-qualified form field path for a filter name */\n getFilterFormFieldName: (name: string) => string;\n /** Get current form value for a given filter name */\n getFilterValueByName: (name: string) => unknown;\n /** Get filter instance by name */\n getFilterInstanceByName: (name: string) => FilterInstance<unknown, unknown>;\n /** Validation helper for a specific filter field. */\n hasError: (name: string) => boolean;\n /** Name of the current filter that has its modal open */\n modalFilterName: string | undefined;\n /** Remove a filter from the form. */\n removeFilter: (name: string) => void;\n /** Open the modal for a given filter name. */\n showFilterModal: (name: string) => void;\n /** Filters that are not active (names only) */\n unusedFilters: string[];\n}\n\n/**\n * FiltersContext\n *\n * Central state for the filter UI with a clear boundary:\n * - The parent component controls committed filter values (via value/onChange)\n * - The form acts as an edit buffer (used by the modal)\n *\n * Design:\n * - activeFilters/unusedFilters are names-only and derived from the controlled\n * form state\n * - getFilterInstanceByName gives access to the concrete registry entry to\n * retrieve the correct Form/Display components\n * - add seeds defaults in the form and opens the modal\n * - remove un-registers the form field; if the removed filter is currently\n * open in the modal, the modal is closed without rollback\n * - on a new successful form submit (Apply), the modal closes without rollback\n * by subscribing to ex-forms submit state\n */\nconst FiltersContext = createContext<FiltersContextValue | undefined>(\n undefined,\n);\n\nexport const FiltersContextProvider = ({\n children,\n config,\n}: {\n children: ReactNode;\n config: FiltersConfiguration;\n}) => {\n // ex-forms integration:\n // - setValue/unregister/getFieldState: core helpers to manipulate and validate fields\n // - formState: we subscribe to submit-success to auto-close the modal after Apply\n const {\n formState,\n getFieldState,\n setValue,\n triggerSubmit,\n unregister,\n watch,\n } = useFormContext();\n\n /**\n * currentModalFilter\n *\n * Single source of truth for the filter edit modal and its rollback snapshot.\n * - name: which filter's modal is currently open (null when closed)\n * - hadValue/previousValue: snapshot of the controlled value taken when the\n * modal is opened; used to restore state if the user cancels/closes without\n * applying.\n *\n * Lifecycle semantics:\n * - showFilterModal(name): capture snapshot (current controlled value) and open\n * the modal for that filter.\n * - closeFilterModal(): if a snapshot exists, roll back un-applied edits by\n * restoring the previous value (setValue) or removing the field (unregister)\n * when it did not exist before; then clear currentModalFilter.\n * - On successful submit (Apply): close and clear currentModalFilter WITHOUT rollback\n * so edits remain committed.\n * - removeFilter(name): unregisters the field; when removing the filter that is\n * currently open, close the modal WITHOUT rollback (since removal is explicit).\n */\n const [currentModalFilter, setCurrentModalFilter] = useState<{\n name: string;\n hadValue: boolean;\n previousValue: unknown;\n } | null>(null);\n\n // Read current filter values from the form as the live edit buffer\n const filterValue = watch('filter', {});\n\n /**\n * getFilterFormFieldName\n *\n * Returns the fully-qualified field path for a given filter name,\n * e.g., `${filterUrlParam}.status`.\n */\n const getFilterFormFieldName = useCallback((name: string) => {\n return `filter.${name}`;\n }, []);\n\n /**\n * getFilterValueByName\n *\n * Returns the committed value for a filter from the controlled state.\n */\n const getFilterValueByName = useCallback(\n (name: string) => {\n return (filterValue as Record<string, unknown>)[name];\n },\n [filterValue],\n );\n\n /** Open the filter edit modal for the given filter name. */\n const showFilterModal = useCallback(\n (name: string) => {\n const prev = getFilterValueByName(name);\n setCurrentModalFilter({\n name,\n hadValue: typeof prev !== 'undefined',\n previousValue: prev,\n });\n },\n [getFilterValueByName],\n );\n\n /** Close the filter edit modal. Rollback un-applied edits to controlled state. */\n const closeFilterModal = useCallback(() => {\n if (currentModalFilter?.name) {\n const fieldName = getFilterFormFieldName(currentModalFilter.name);\n // if the filter had a value, set it back to the previous value,\n // otherwise unregister the field\n if (currentModalFilter.hadValue) {\n setValue(fieldName, currentModalFilter.previousValue);\n } else {\n unregister(fieldName);\n }\n }\n setCurrentModalFilter(null);\n }, [getFilterFormFieldName, currentModalFilter, setValue, unregister]);\n\n /**\n * Auto-close on submit success\n *\n * Close the modal only on new successful submissions. We track the last\n * submitCount and only react when it changes AND the form reports a\n * successful submit. This prevents closing when `isSubmitSuccessful` remains\n * true without a new submit event.\n */\n const lastSubmitCountRef = useRef<number>(0);\n useEffect(() => {\n if (\n formState.submitCount !== lastSubmitCountRef.current &&\n formState.isSubmitSuccessful\n ) {\n // On successful submit, close without rollback\n setCurrentModalFilter(null);\n }\n lastSubmitCountRef.current = formState.submitCount;\n }, [\n formState.submitCount,\n formState.isSubmitSuccessful,\n setCurrentModalFilter,\n ]);\n\n /**\n * activeFilters\n *\n * Filter names derived from the controlled form state. A filter is considered\n * active when a field exists at `filter.<name>`. Newly added filters become\n * active immediately (seeded default), and will be rolled back on cancel.\n */\n const activeFilters = useMemo(() => {\n return config\n .filter((f) => {\n return Object.hasOwn(filterValue ?? {}, f.name);\n })\n .map((f) => {\n return f.name;\n });\n }, [config, filterValue]);\n\n /**\n * unusedFilters\n *\n * Complement of activeFilters (names without a corresponding `filter.<name>`\n * field in the controlled form state).\n */\n const unusedFilters = useMemo(() => {\n return config\n .filter((f) => {\n return !Object.hasOwn(filterValue ?? {}, f.name);\n })\n .map((f) => {\n return f.name;\n });\n }, [config, filterValue]);\n\n /**\n * getRegistryFilterByName\n *\n * Looks up the concrete registry entry for a filter by name, enabling access\n * to typed Form/Display components and other registry-level metadata.\n */\n const getFilterInstanceByName = useCallback(\n (name: string) => {\n return config.find((f) => {\n return f.name === name;\n }) as FilterInstance<unknown, unknown>;\n },\n [config],\n );\n\n /**\n * addFilter\n *\n * Seeds the filter with its registry default value inside the form and opens\n * the modal for immediate editing. No URL writes happen here.\n */\n const addFilter = useCallback(\n (name: string) => {\n const inst = getFilterInstanceByName(name);\n showFilterModal(name);\n setValue(getFilterFormFieldName(name), inst.defaultValue);\n },\n [\n getFilterFormFieldName,\n getFilterInstanceByName,\n setValue,\n showFilterModal,\n ],\n );\n\n /**\n * removeFilter\n *\n * Unregisters the filter field from the form. This immediately removes the\n * filter from the active list since derived state watches the form. It\n * closes the modal without rollback if the removed filter is currently open.\n */\n const removeFilter = useCallback(\n (name: string) => {\n // unregister form field\n unregister(getFilterFormFieldName(name));\n // close filter modal if open\n if (currentModalFilter?.name === name) {\n // Explicit removal: close without rollback\n setCurrentModalFilter(null);\n }\n // trigger form submit (to update filter state)\n triggerSubmit();\n },\n [\n getFilterFormFieldName,\n currentModalFilter,\n setCurrentModalFilter,\n triggerSubmit,\n unregister,\n ],\n );\n\n /**\n * hasError\n *\n * Helper that checks the ex-forms field state for a specific filter and\n * reports whether the field is currently invalid.\n */\n const hasError = useCallback(\n (name: string) => {\n return getFieldState(getFilterFormFieldName(name)).invalid;\n },\n [getFieldState, getFilterFormFieldName],\n );\n\n const contextValue: FiltersContextValue = useMemo(() => {\n return {\n activeFilters,\n addFilter,\n closeFilterModal,\n getFilterFormFieldName,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n modalFilterName: currentModalFilter?.name,\n removeFilter,\n showFilterModal,\n unusedFilters,\n };\n }, [\n activeFilters,\n addFilter,\n closeFilterModal,\n getFilterFormFieldName,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n currentModalFilter,\n removeFilter,\n showFilterModal,\n unusedFilters,\n ]);\n\n return (\n <FiltersContext.Provider value={contextValue}>\n {children}\n </FiltersContext.Provider>\n );\n};\n\n/**\n * useFilters\n *\n * Convenience hook to consume the FiltersContext. Throws a descriptive error\n * when used outside of a FiltersContextProvider to make integration mistakes\n * obvious during development.\n */\nexport const useFilters = (): FiltersContextValue => {\n const ctx = useContext(FiltersContext);\n if (!ctx) {\n throw new Error('useFilters must be used within FiltersContextProvider');\n }\n return ctx;\n};\n\nexport default FiltersContext;\n","import Label from '@fuf-stack/pixels/Label';\n\nimport { useFilters } from './FiltersContext';\n\n/**\n * ActiveFilters\n *\n * Shows the list of currently applied filters as clickable chips that open\n * the edit modal. Each chip can be removed via its close action.\n */\ninterface ActiveFiltersProps {\n /** CSS class name to apply to each label */\n className?: string;\n}\n\nconst ActiveFilters = ({ className = undefined }: ActiveFiltersProps) => {\n const {\n activeFilters,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n removeFilter,\n showFilterModal,\n } = useFilters();\n return (\n <>\n {activeFilters.map((name) => {\n const instance = getFilterInstanceByName(name);\n const value = getFilterValueByName(name);\n\n // get the display component from the instance\n const DisplayComponent = instance.components.Display;\n\n return (\n <button\n key={name}\n aria-label={`Open ${name} filter`}\n type=\"button\"\n onClick={() => {\n showFilterModal(name);\n }}\n >\n <Label\n className={className}\n color={hasError(name) ? 'danger' : 'primary'}\n variant=\"flat\"\n onClose={() => {\n removeFilter(name);\n }}\n >\n {instance.icon}\n <DisplayComponent config={instance.config} value={value} />\n </Label>\n </button>\n );\n })}\n </>\n );\n};\n\nexport default ActiveFilters;\n","import { FaSliders } from 'react-icons/fa6';\n\nimport Menu from '@fuf-stack/pixels/Menu';\n\nimport { useFilters } from './FiltersContext';\n\ninterface AddFilterMenuProps {\n /** CSS class name map for slots */\n classNames?: Partial<{\n addFilterMenuItem: string;\n addFilterMenuButton: string;\n }>;\n}\n\n/**\n * AddFilterMenu\n *\n * Renders a menu trigger that opens a list of addable filters. Selecting an\n * item triggers the parent to seed a default value and open the modal.\n */\nconst AddFilterMenu = ({ classNames = {} }: AddFilterMenuProps) => {\n const { unusedFilters, addFilter, getFilterInstanceByName } = useFilters();\n\n const menuItems = unusedFilters.map((name) => {\n const instance = getFilterInstanceByName(name);\n const config = instance.config as { text?: string };\n const label = config?.text ?? name;\n return {\n key: name,\n icon: instance.icon,\n label,\n onClick: () => {\n addFilter(name);\n },\n };\n });\n\n return (\n <Menu\n isDisabled={!menuItems.length}\n items={menuItems}\n placement=\"bottom-start\"\n className={{\n item: classNames.addFilterMenuItem,\n trigger: classNames.addFilterMenuButton,\n }}\n triggerButtonProps={{\n 'aria-label': 'Add Filter',\n 'data-testid': 'add_filter_button',\n disableRipple: true,\n size: 'sm',\n variant: 'bordered',\n }}\n >\n <FaSliders />\n Filter\n </Menu>\n );\n};\n\nexport default AddFilterMenu;\n","import { Suspense } from 'react';\nimport { PiSlidersHorizontalBold } from 'react-icons/pi';\n\nimport Button from '@fuf-stack/pixels/Button';\nimport Modal from '@fuf-stack/pixels/Modal';\nimport SubmitButton from '@fuf-stack/uniform/SubmitButton';\n\nimport { useFilters } from './FiltersContext';\n\ninterface FilterModalProps {\n classNames?: Partial<{\n header: string;\n footer: string;\n body: string;\n }>;\n}\n\nconst FilterModal = ({ classNames = {} }: FilterModalProps) => {\n const {\n closeFilterModal,\n getFilterFormFieldName,\n getFilterInstanceByName,\n modalFilterName,\n removeFilter,\n } = useFilters();\n\n // don't render if no filter is open\n if (!modalFilterName) {\n return null;\n }\n\n const instance = getFilterInstanceByName(modalFilterName);\n const config = instance.config as { text?: string };\n\n // get the form component from the instance\n const FormComponent = instance.components.Form;\n\n return (\n <Modal\n isOpen\n onClose={closeFilterModal}\n className={{\n body: classNames.body,\n footer: classNames.footer,\n header: classNames.header,\n }}\n footer={\n <>\n <Button\n ariaLabel=\"Remove filter\"\n color=\"danger\"\n testId=\"remove_filter_button\"\n variant=\"flat\"\n onClick={() => {\n removeFilter(modalFilterName);\n }}\n >\n Remove\n </Button>\n <SubmitButton ariaLabel=\"Apply filter\" testId=\"apply_filter_button\">\n Apply Filter\n </SubmitButton>\n </>\n }\n header={\n <>\n {instance.icon ?? <PiSlidersHorizontalBold />}\n <div>{`${config?.text ?? modalFilterName} Filter`}</div>\n </>\n }\n >\n <Suspense>\n <FormComponent\n config={config}\n fieldName={getFilterFormFieldName(modalFilterName)}\n />\n </Suspense>\n </Modal>\n );\n};\n\nexport default FilterModal;\n","import { useState } from 'react';\nimport { FaSearch } from 'react-icons/fa';\n\nimport { motion } from '@fuf-stack/pixel-motion';\nimport Button from '@fuf-stack/pixels/Button';\nimport { useFormContext } from '@fuf-stack/uniform/hooks/useFormContext';\nimport Input from '@fuf-stack/uniform/Input';\nimport SubmitButton from '@fuf-stack/uniform/SubmitButton';\n\nexport type SearchConfiguration =\n | boolean\n | {\n /** Placeholder shown in the search input */\n placeholder?: string;\n };\n\ninterface SearchInputProps {\n /** Slots class names passed from parent variants */\n classNames?: Partial<{\n searchWrapper: string;\n searchShowButton: string;\n searchMotionDiv: string;\n searchInput: string;\n searchInputWrapper: string;\n searchSubmitButton: string;\n }>;\n /** Search configuration */\n config: SearchConfiguration;\n}\n\n/**\n * SearchInput\n *\n * By default renders only a search button. When clicked, the text input animates in\n * and a trailing submit button is shown.\n */\nconst SearchInput = ({ classNames = {}, config }: SearchInputProps) => {\n const { formState, setFocus, triggerSubmit } = useFormContext();\n\n // Auto-open if there is an initial or externally set search value\n const isInitiallyVisible = !!formState?.defaultValues?.search;\n const [isVisible, setIsVisible] = useState(isInitiallyVisible);\n\n const placeholder =\n typeof config === 'object' ? config.placeholder : undefined;\n\n return (\n <div className={classNames.searchWrapper}>\n {!isVisible && (\n <Button\n ariaLabel=\"Show search input\"\n className={classNames.searchShowButton}\n icon={<FaSearch />}\n size=\"sm\"\n testId=\"show_search_input_button\"\n variant=\"bordered\"\n onClick={() => {\n setIsVisible(true);\n }}\n />\n )}\n {isVisible ? (\n <motion.div\n key=\"search-input\"\n animate={{ opacity: 1 }}\n className={classNames.searchMotionDiv}\n // if the input was not initially visible, animate in\n initial={!isInitiallyVisible ? { opacity: 0.5 } : false}\n onAnimationComplete={() => {\n // if the input was not initially visible, focus it\n if (!isInitiallyVisible) {\n setFocus('search');\n }\n }}\n transition={{\n duration: 0.3,\n ease: 'circOut',\n }}\n >\n <Input\n clearable\n debounceDelay={0}\n name=\"search\"\n placeholder={placeholder}\n size=\"sm\"\n className={{\n input: classNames.searchInput,\n inputWrapper: classNames.searchInputWrapper,\n }}\n // submit on clear\n onClear={() => {\n triggerSubmit();\n }}\n />\n <SubmitButton\n ariaLabel=\"Submit search\"\n // eslint-disable-next-line react/no-children-prop\n children={null}\n className={classNames.searchSubmitButton}\n color=\"primary\"\n icon={<FaSearch />}\n size=\"sm\"\n testId=\"submit_search_button\"\n />\n </motion.div>\n ) : null}\n </div>\n );\n};\n\nexport default SearchInput;\n","import type { TVClassName } from '@fuf-stack/pixel-utils';\nimport type { VetoInput } from '@fuf-stack/veto';\nimport type { ReactNode } from 'react';\nimport type { FiltersConfiguration } from './filters/types';\nimport type { SearchConfiguration } from './Subcomponents/SearchInput';\n\nimport createDebug from 'debug';\n\nimport { tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\nimport Form from '@fuf-stack/uniform/Form';\n\nimport { useFilterValidation } from './hooks/useFilterValidation';\nimport ActiveFilters from './Subcomponents/ActiveFilters';\nimport AddFilterMenu from './Subcomponents/AddFilterMenu';\nimport FilterModal from './Subcomponents/FilterModal';\nimport { FiltersContextProvider } from './Subcomponents/FiltersContext';\nimport SearchInput from './Subcomponents/SearchInput';\n\nconst debug = createDebug('megapixels:Filter');\n\n// filter styling variants\nexport const filterVariants = tv({\n slots: {\n // outer wrapper\n base: 'flex flex-auto flex-col',\n // add filter menu trigger button\n addFilterMenuButton: '',\n // add filter menu item\n addFilterMenuItem: '',\n // active filter label\n activeFilterLabel: 'h-8 cursor-pointer rounded-md dark:text-foreground',\n // filter modal body\n filterModalBody: '',\n // filter modal header\n filterModalHeader: 'flex items-center gap-3 text-default-700',\n // filter modal footer\n filterModalFooter: 'justify-between',\n // form element\n form: 'mb-3 flex flex-wrap gap-3',\n // search input field\n searchInput: '',\n // search input wrapper (inner control)\n searchInputWrapper: '',\n // search motion container\n searchMotionDiv: 'flex w-72 gap-2',\n // search show button\n searchShowButton: '',\n // search submit button\n searchSubmitButton: '',\n // search wrapper\n searchWrapper: 'flex items-center',\n },\n});\n\ntype ClassName = TVClassName<typeof filterVariants>;\n\nexport interface FilterValues {\n search?: string;\n filter?: string | Record<string, unknown> | null;\n}\n\nexport type FilterChildRenderFn = (values: {\n search?: string;\n filter?: Record<string, unknown>;\n}) => ReactNode;\n\n/**\n * Filter\n *\n * Controlled, form-driven filter UI.\n *\n * Responsibilities\n * - Derives initial form values from the controlled `values` prop\n * - Builds a composite validation schema from the filter registry (and optional search)\n * - Exposes ergonomic UI: active filters list, add/remove actions, and per-filter modal\n * - Commits changes by invoking the controlled `onChange` callback on submit\n *\n * Structure\n * - Owns an ex-forms `Form` that wraps the entire filter experience\n * - Optionally renders a search input bound to the `search` field\n * - Renders ActiveFilters, AddFilterMenu, and FilterModal inside a shared context\n * - Optionally renders children as a render-prop with the resolved `values`\n */\nexport interface FilterProps {\n /** Optional render-prop that receives the resolved, controlled values */\n children?: FilterChildRenderFn;\n /** CSS class name */\n className?: ClassName;\n /** Configuration of the filter */\n config: {\n /**\n * Declarative filter configuration. Each entry ties a logical name to a\n * registry filter type and (optionally) per-usage config overrides.\n */\n filters: FiltersConfiguration;\n /** Optional configuration for search field */\n search?: SearchConfiguration;\n };\n /** ex-forms form instance name. Defaults to \"filterComponentForm\". */\n formName?: string;\n /** Controlled setter invoked on submit with the next canonical values */\n onChange: (nextValues: FilterValues) => void;\n /** Controlled committed state: the canonical `search` and `filter` values */\n values: FilterValues;\n}\n\n/**\n * Renders the filter UI bound to a single ex-forms `Form`.\n * The form is the source of truth during user interaction; the committed\n * state is controlled by the parent via `values`/`onChange`.\n */\nconst Filter = ({\n children = undefined,\n className = undefined,\n config,\n formName = 'filterComponentForm',\n onChange,\n values,\n}: FilterProps) => {\n // Submit handler: map form state back into the controlled `values` shape\n const handleSubmit = (nextValues: Record<string, unknown>) => {\n debug('handleSubmit', { nextValues });\n onChange(nextValues as FilterValues);\n };\n\n // Build validation schema for all configured filters (and optional search)\n const validation = useFilterValidation(\n config.filters,\n Boolean(config.search),\n );\n\n // validate controlled values are valid\n const {\n data: valuesValidated,\n errors,\n success,\n } = validation.validate(values as VetoInput);\n\n // classNames from slots\n const variants = filterVariants();\n const classNames = variantsToClassNames(variants, className, 'base');\n\n debug('render', {\n props: { config, values },\n validation: { errors, success, valuesValidated },\n });\n\n return (\n <div className={classNames.base}>\n {/*\n Uniform Form wrapper\n - initialValues derive from controlled props (with optional defaults)\n - validation is built from the registry for all configured filters\n - onSubmit maps form values back into values/onChange\n */}\n <Form\n className={classNames.form}\n // disable debug mode for now\n debug={{ disable: true }}\n initialValues={valuesValidated ?? {}}\n name={formName}\n onSubmit={handleSubmit}\n validation={validation}\n >\n {/* Render search if search config is provided */}\n {config.search ? (\n <SearchInput\n config={config.search}\n classNames={{\n searchInput: classNames.searchInput,\n searchInputWrapper: classNames.searchInputWrapper,\n searchMotionDiv: classNames.searchMotionDiv,\n searchShowButton: classNames.searchShowButton,\n searchSubmitButton: classNames.searchSubmitButton,\n searchWrapper: classNames.searchWrapper,\n }}\n />\n ) : null}\n {/*\n FiltersContextProvider exposes a minimal API for the UI layer:\n - activeFilters/unusedFilters by name\n - helpers to get merged config, value, components, and field names\n - methods to add/remove filters and show/close the modal\n */}\n <FiltersContextProvider config={config.filters}>\n <ActiveFilters className={classNames.activeFilterLabel} />\n <AddFilterMenu\n classNames={{\n addFilterMenuButton: classNames.addFilterMenuButton,\n addFilterMenuItem: classNames.addFilterMenuItem,\n }}\n />\n <FilterModal\n classNames={{\n body: classNames.filterModalBody,\n footer: classNames.filterModalFooter,\n header: classNames.filterModalHeader,\n }}\n />\n </FiltersContextProvider>\n </Form>\n {/* Children can consume derived search string and parsed filter object */}\n {children?.(valuesValidated ?? {})}\n </div>\n );\n};\n\nexport default Filter;\n","import type { FilterDefinition, FilterFactory } from './types';\n\n/**\n * createFilter\n *\n * Builds a filter factory from a static FilterDefinition. The returned factory\n * accepts a usage descriptor (name/icon and optional partial config) and\n * produces a concrete FilterInstance with:\n * - merged config (shallow: definition.defaults.config overlaid by overrides)\n * - Form/Display components\n * - validate function (forwarded from the definition)\n * - defaultValue (forwarded from the definition)\n * - name and icon for UI integration\n *\n * @typeParam Config - Configuration object shape for the filter\n * @typeParam Value - Runtime value type for the filter\n * @param definition - Static description of the filter (components, defaults, validate)\n * @returns FilterFactory that creates FilterInstance<Config, Value>\n */\nconst createFilter = <Config, Value>(\n definition: FilterDefinition<Config, Value>,\n): FilterFactory<Config, Value> => {\n return ({ name, icon, config }) => {\n return {\n components: definition.components,\n config: { ...definition.defaults.config, ...(config ?? {}) } as Config,\n defaultValue: definition.defaults.value,\n icon,\n name,\n validation: definition.validation,\n };\n };\n};\n\nexport default createFilter;\n","import type { FilterDisplayProps } from '../types';\nimport type { Config, Value } from './schema';\n\n/**\n * Read-only presentation for the boolean filter.\n * Displays human-readable text based on the current boolean `value`\n * and the provided `config` strings.\n */\nconst Display = ({\n value,\n config: { text, textPrefix, textNoWord },\n}: FilterDisplayProps<Config, Value>) => {\n if (typeof value === 'boolean') {\n return (\n <>\n {`${value ? textPrefix : `${textPrefix} ${textNoWord ?? 'no'}`} ${text}`}\n </>\n );\n }\n return <>{`${text}...`}</>;\n};\n\nexport default Display;\n","import type { FilterFormProps } from '../types';\nimport type { Config } from './schema';\n\nimport Switch from '@fuf-stack/uniform/Switch';\n\n/**\n * Renders the form control for the boolean filter.\n * Uses a `Switch` to toggle the boolean value and composes\n * the label from the provided `config` and `fieldName`.\n */\nconst Form = ({\n fieldName,\n config: { text, textPrefix },\n}: FilterFormProps<Config>) => {\n return <Switch label={`${textPrefix} ${text}`} name={fieldName} />;\n};\n\nexport default Form;\n","import type { vInfer } from '@fuf-stack/veto';\n\nimport { boolean, object, string } from '@fuf-stack/veto';\n\n/** configuration of the filter */\nexport const config = object({\n /**\n * Human‑readable label used in the UI (e.g. in the chip and modal header).\n * Examples: \"Magical\", \"Haunted\"\n */\n text: string(),\n /**\n * Optional word shown before the label when building sentence‑like chips.\n * Examples: \"is\" → \"is Magical\"\n */\n textPrefix: string().optional(),\n /**\n * Optional negation word used when a boolean value is false.\n * Examples: \"not\" → \"is not Magical\"\n */\n textNoWord: string().optional(),\n});\n\n/** validate the filter value */\nexport const validate = (_config?: Config) => {\n return boolean().optional();\n};\n\nexport type Config = vInfer<typeof config>;\nexport type Value = vInfer<ReturnType<typeof validate>>;\n","/* eslint-disable import-x/prefer-default-export */\n\nimport type { Config, Value } from './schema';\n\nimport createFilter from '../createFilter';\nimport Display from './Display';\nimport Form from './Form';\nimport { validate } from './schema';\n\n/**\n * Boolean filter definition for the Filter system.\n * Provides Display and Form components, default value/config, and validation.\n *\n * Defaults:\n * - value: true\n * - config: { text: 'Active', textPrefix: 'is', textNoWord: 'no' }\n *\n * @see Display\n * @see Form\n * @see validate\n */\nexport const boolean = createFilter<Config, Value>({\n components: { Display, Form },\n defaults: {\n value: true,\n config: { text: 'Active', textPrefix: 'is', textNoWord: 'no' },\n },\n validation: validate,\n});\n","import type { FilterDisplayProps } from '../types';\nimport type { Config, Value } from './schema';\n\n/**\n * Read-only presentation for the checkboxes filter.\n * Resolves and displays selected option labels based on `value` and `config`.\n * Supports string, ReactNode, and function labels (mode: 'display').\n */\nconst Display = ({\n value,\n config: { text, options },\n}: FilterDisplayProps<Config, Value>) => {\n if (value && value.length > 0) {\n return (\n <span className=\"flex items-center gap-1\">\n {text} is\n {value.map((val) => {\n const option = options.find((op) => {\n return op.value === val;\n });\n const label = option?.label ?? val;\n const resolvedLabel =\n typeof label === 'function' ? label('display') : label;\n return <span key={val}>{resolvedLabel}</span>;\n })}\n </span>\n );\n }\n return `${text} is ...`;\n};\n\nexport default Display;\n","import type { FilterFormProps } from '../types';\nimport type { Config } from './schema';\n\nimport Checkboxes from '@fuf-stack/uniform/Checkboxes';\n\n/**\n * Renders the form control for the checkboxes filter.\n * Uses a `Checkboxes` to select multiple options.\n * Resolves function labels with 'form' mode.\n */\nconst Form = ({ fieldName, config }: FilterFormProps<Config>) => {\n const resolvedOptions = config.options.map((option) => {\n return {\n ...option,\n label:\n typeof option.label === 'function'\n ? option.label('form')\n : option.label,\n };\n });\n\n return <Checkboxes name={fieldName} options={resolvedOptions} />;\n};\n\nexport default Form;\n","import type { vInfer } from '@fuf-stack/veto';\nimport type { ReactNode } from 'react';\n\nimport { any, array, object, refineArray, string } from '@fuf-stack/veto';\n\n/** configuration of the filter */\nexport const config = object({\n /**\n * Human‑readable label used in the UI (e.g. label and modal header).\n * Example: \"Snacks\", \"Mood\"\n */\n text: string(),\n /**\n * Options rendered as multiple checkboxes. Each option needs a `label`\n * (what the user sees) and a `value` (what is written into the form state).\n * Label can be a string, React node, or a function that receives mode\n * ('form' or 'display') and returns a React node.\n */\n options: array(object({ label: any(), value: string() })),\n});\n\n/** Type-safe Config that overrides label to support ReactNode or function */\nexport type Config = Omit<vInfer<typeof config>, 'options'> & {\n options: {\n label: ReactNode | ((mode: 'form' | 'display') => ReactNode);\n value: string;\n }[];\n};\n\n/** validate the filter value */\nexport const validate = (cfg?: Config) => {\n return refineArray(array(string()).optional())({\n unique: true,\n custom: (values, ctx) => {\n if (!cfg) {\n return;\n }\n values.forEach((value) => {\n if (\n !cfg.options.find((option) => {\n return option?.value === value;\n })\n ) {\n ctx.addIssue({\n code: 'custom',\n message: `Invalid value: ${value}`,\n });\n }\n });\n },\n });\n};\n\nexport type Value = vInfer<ReturnType<typeof validate>>;\n","/* eslint-disable import-x/prefer-default-export */\n\nimport type { Config, Value } from './schema';\n\nimport createFilter from '../createFilter';\nimport Display from './Display';\nimport Form from './Form';\nimport { validate } from './schema';\n\n/**\n * Checkboxes filter definition for the Filter system.\n * Provides Display and Form components, default value/config, and validation.\n *\n * Defaults:\n * - value: []\n * - config: { text: 'Options', options: [] }\n *\n * @see Display\n * @see Form\n * @see validate\n */\nexport const checkboxes = createFilter<Config, Value>({\n components: { Display, Form },\n defaults: { value: [], config: { text: 'Options', options: [] } },\n validation: validate,\n});\n","import Filter from './Filter';\nimport { boolean } from './filters/boolean/boolean';\nimport { checkboxes } from './filters/checkboxes/checkboxes';\n\n// export types\nexport type * from './filters/types';\n\n// export helpers\nexport { default as createFilter } from './filters/createFilter';\n\n// export all filters\nexport const filters = {\n boolean,\n checkboxes,\n};\n\n// export everything from the Filter component (types and filterVariants)\nexport * from './Filter';\n\n// export the Filter component as default\nexport default Filter;\n"],"mappings":"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"}
@@ -1,12 +1,47 @@
1
- import { vInfer } from "@fuf-stack/veto";
1
+ import { TVClassName } from "@fuf-stack/pixel-utils";
2
2
  import { ReactNode } from "react";
3
- import * as tailwind_variants0 from "tailwind-variants";
3
+ import { vInfer } from "@fuf-stack/veto";
4
4
  import * as react_jsx_runtime0 from "react/jsx-runtime";
5
- import { TVClassName } from "@fuf-stack/pixel-utils";
5
+ import * as _fuf_stack_veto_dist_types_d_CNPgNK_V0 from "@fuf-stack/veto/dist/types.d-CNPgNK-V";
6
+ import * as tailwind_variants0 from "tailwind-variants";
6
7
 
7
8
  //#region src/Filter/filters/checkboxes/schema.d.ts
8
9
  /** configuration of the filter */
9
- declare const config$1: any;
10
+ declare const config$1: _fuf_stack_veto_dist_types_d_CNPgNK_V0.q<{
11
+ /**
12
+ * Human‑readable label used in the UI (e.g. label and modal header).
13
+ * Example: "Snacks", "Mood"
14
+ */
15
+ text: _fuf_stack_veto_dist_types_d_CNPgNK_V0.h;
16
+ /**
17
+ * Options rendered as multiple checkboxes. Each option needs a `label`
18
+ * (what the user sees) and a `value` (what is written into the form state).
19
+ * Label can be a string, React node, or a function that receives mode
20
+ * ('form' or 'display') and returns a React node.
21
+ */
22
+ options: _fuf_stack_veto_dist_types_d_CNPgNK_V0.c<_fuf_stack_veto_dist_types_d_CNPgNK_V0.q<{
23
+ label: _fuf_stack_veto_dist_types_d_CNPgNK_V0.b;
24
+ value: _fuf_stack_veto_dist_types_d_CNPgNK_V0.h;
25
+ }, "strict", _fuf_stack_veto_dist_types_d_CNPgNK_V0.Z, {
26
+ value: string;
27
+ label?: any;
28
+ }, {
29
+ value: string;
30
+ label?: any;
31
+ }>, "many">;
32
+ }, "strict", _fuf_stack_veto_dist_types_d_CNPgNK_V0.Z, {
33
+ text: string;
34
+ options: {
35
+ value: string;
36
+ label?: any;
37
+ }[];
38
+ }, {
39
+ text: string;
40
+ options: {
41
+ value: string;
42
+ label?: any;
43
+ }[];
44
+ }>;
10
45
  /** Type-safe Config that overrides label to support ReactNode or function */
11
46
  type Config = Omit<vInfer<typeof config$1>, 'options'> & {
12
47
  options: {
@@ -335,9 +370,13 @@ declare const createFilter: <Config$1, Value>(definition: FilterDefinition<Confi
335
370
  //#endregion
336
371
  //#region src/Filter/index.d.ts
337
372
  declare const filters: {
338
- boolean: FilterFactory<any, any>;
339
- checkboxes: FilterFactory<Config, any[]>;
373
+ boolean: FilterFactory<{
374
+ text: string;
375
+ textPrefix?: string | undefined;
376
+ textNoWord?: string | undefined;
377
+ }, boolean | undefined>;
378
+ checkboxes: FilterFactory<Config, string[]>;
340
379
  };
341
380
  //#endregion
342
381
  export { FilterProps as a, FilterDefinition as c, FilterFormProps as d, FilterInstance as f, FilterChildRenderFn as i, FilterDisplayProps as l, createFilter as n, FilterValues as o, FiltersConfiguration as p, Filter as r, filterVariants as s, filters as t, FilterFactory as u };
343
- //# sourceMappingURL=index-C-2_lJp0.d.cts.map
382
+ //# sourceMappingURL=index-BIQQB435.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BIQQB435.d.ts","names":[],"sources":["../src/Filter/filters/checkboxes/schema.ts","../src/Filter/filters/types.ts","../src/Filter/Subcomponents/SearchInput.tsx","../src/Filter/Filter.tsx","../src/Filter/filters/createFilter.ts","../src/Filter/index.ts"],"sourcesContent":[],"mappings":"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"}
@@ -1,12 +1,47 @@
1
- import { TVClassName } from "@fuf-stack/pixel-utils";
2
- import { ReactNode } from "react";
1
+ import * as _fuf_stack_veto_dist_types_d_CNPgNK_V0 from "@fuf-stack/veto/dist/types.d-CNPgNK-V";
3
2
  import { vInfer } from "@fuf-stack/veto";
4
- import * as react_jsx_runtime0 from "react/jsx-runtime";
3
+ import { ReactNode } from "react";
5
4
  import * as tailwind_variants0 from "tailwind-variants";
5
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
6
+ import { TVClassName } from "@fuf-stack/pixel-utils";
6
7
 
7
8
  //#region src/Filter/filters/checkboxes/schema.d.ts
8
9
  /** configuration of the filter */
9
- declare const config$1: any;
10
+ declare const config$1: _fuf_stack_veto_dist_types_d_CNPgNK_V0.q<{
11
+ /**
12
+ * Human‑readable label used in the UI (e.g. label and modal header).
13
+ * Example: "Snacks", "Mood"
14
+ */
15
+ text: _fuf_stack_veto_dist_types_d_CNPgNK_V0.h;
16
+ /**
17
+ * Options rendered as multiple checkboxes. Each option needs a `label`
18
+ * (what the user sees) and a `value` (what is written into the form state).
19
+ * Label can be a string, React node, or a function that receives mode
20
+ * ('form' or 'display') and returns a React node.
21
+ */
22
+ options: _fuf_stack_veto_dist_types_d_CNPgNK_V0.c<_fuf_stack_veto_dist_types_d_CNPgNK_V0.q<{
23
+ label: _fuf_stack_veto_dist_types_d_CNPgNK_V0.b;
24
+ value: _fuf_stack_veto_dist_types_d_CNPgNK_V0.h;
25
+ }, "strict", _fuf_stack_veto_dist_types_d_CNPgNK_V0.Z, {
26
+ value: string;
27
+ label?: any;
28
+ }, {
29
+ value: string;
30
+ label?: any;
31
+ }>, "many">;
32
+ }, "strict", _fuf_stack_veto_dist_types_d_CNPgNK_V0.Z, {
33
+ text: string;
34
+ options: {
35
+ value: string;
36
+ label?: any;
37
+ }[];
38
+ }, {
39
+ text: string;
40
+ options: {
41
+ value: string;
42
+ label?: any;
43
+ }[];
44
+ }>;
10
45
  /** Type-safe Config that overrides label to support ReactNode or function */
11
46
  type Config = Omit<vInfer<typeof config$1>, 'options'> & {
12
47
  options: {
@@ -335,9 +370,13 @@ declare const createFilter: <Config$1, Value>(definition: FilterDefinition<Confi
335
370
  //#endregion
336
371
  //#region src/Filter/index.d.ts
337
372
  declare const filters: {
338
- boolean: FilterFactory<any, any>;
339
- checkboxes: FilterFactory<Config, any[]>;
373
+ boolean: FilterFactory<{
374
+ text: string;
375
+ textPrefix?: string | undefined;
376
+ textNoWord?: string | undefined;
377
+ }, boolean | undefined>;
378
+ checkboxes: FilterFactory<Config, string[]>;
340
379
  };
341
380
  //#endregion
342
381
  export { FilterProps as a, FilterDefinition as c, FilterFormProps as d, FilterInstance as f, FilterChildRenderFn as i, FilterDisplayProps as l, createFilter as n, FilterValues as o, FiltersConfiguration as p, Filter as r, filterVariants as s, filters as t, FilterFactory as u };
343
- //# sourceMappingURL=index-OWKeKysC.d.ts.map
382
+ //# sourceMappingURL=index-Ck6wyFDZ.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-Ck6wyFDZ.d.cts","names":[],"sources":["../src/Filter/filters/checkboxes/schema.ts","../src/Filter/filters/types.ts","../src/Filter/Subcomponents/SearchInput.tsx","../src/Filter/Filter.tsx","../src/Filter/filters/createFilter.ts","../src/Filter/index.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_Filter = require('./Filter-Bc0LWCnZ.cjs');
1
+ const require_Filter = require('./Filter-obuSI5QN.cjs');
2
2
 
3
3
  //#region src/index.ts
4
4
  /* v8 ignore stop */
package/dist/index.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as FilterProps, c as FilterDefinition, d as FilterFormProps, f as FilterInstance, i as FilterChildRenderFn, l as FilterDisplayProps, n as createFilter, o as FilterValues, p as FiltersConfiguration, s as filterVariants, t as filters, u as FilterFactory } from "./index-C-2_lJp0.cjs";
1
+ import { a as FilterProps, c as FilterDefinition, d as FilterFormProps, f as FilterInstance, i as FilterChildRenderFn, l as FilterDisplayProps, n as createFilter, o as FilterValues, p as FiltersConfiguration, s as filterVariants, t as filters, u as FilterFactory } from "./index-Ck6wyFDZ.cjs";
2
2
  export { FilterChildRenderFn, FilterDefinition, FilterDisplayProps, FilterFactory, FilterFormProps, FilterInstance, FilterProps, FilterValues, FiltersConfiguration, createFilter, filterVariants, filters };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as FilterProps, c as FilterDefinition, d as FilterFormProps, f as FilterInstance, i as FilterChildRenderFn, l as FilterDisplayProps, n as createFilter, o as FilterValues, p as FiltersConfiguration, s as filterVariants, t as filters, u as FilterFactory } from "./index-OWKeKysC.js";
1
+ import { a as FilterProps, c as FilterDefinition, d as FilterFormProps, f as FilterInstance, i as FilterChildRenderFn, l as FilterDisplayProps, n as createFilter, o as FilterValues, p as FiltersConfiguration, s as filterVariants, t as filters, u as FilterFactory } from "./index-BIQQB435.js";
2
2
  export { FilterChildRenderFn, FilterDefinition, FilterDisplayProps, FilterFactory, FilterFormProps, FilterInstance, FilterProps, FilterValues, FiltersConfiguration, createFilter, filterVariants, filters };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { i as filterVariants, n as filters, r as createFilter_default } from "./Filter-nSuQco2t.js";
1
+ import { i as filterVariants, n as filters, r as createFilter_default } from "./Filter-D_PSnttT.js";
2
2
 
3
3
  //#region src/index.ts
4
4
  /* v8 ignore stop */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuf-stack/megapixels",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "description": "fuf react advanced components library",
5
5
  "author": "Fröhlich ∧ Frei",
6
6
  "homepage": "https://github.com/fuf-stack/megapixels#readme",
@@ -45,20 +45,20 @@
45
45
  "react-dom": ">=18"
46
46
  },
47
47
  "dependencies": {
48
- "@fuf-stack/pixel-motion": "1.1.0",
49
- "@fuf-stack/pixel-utils": "1.1.0",
50
- "@fuf-stack/pixels": "1.7.0",
51
- "@fuf-stack/uniform": "1.11.1",
52
- "@fuf-stack/veto": "0.13.1",
48
+ "@fuf-stack/pixel-motion": "1.1.1",
49
+ "@fuf-stack/pixel-utils": "1.1.1",
50
+ "@fuf-stack/pixels": "1.7.1",
51
+ "@fuf-stack/uniform": "1.11.3",
52
+ "@fuf-stack/veto": "0.13.2",
53
53
  "debug": "4.4.3",
54
54
  "react-icons": "5.5.0"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@types/debug": "4.1.12",
58
- "@types/react": "19.2.7",
58
+ "@types/react": "19.2.8",
59
59
  "@types/react-dom": "19.2.3",
60
60
  "react": "19.2.3",
61
61
  "react-dom": "19.2.3"
62
62
  },
63
- "gitHead": "abae56906882f471a06ffaa6081a3de66a431466"
63
+ "gitHead": "b68c72db4df79ae8c5efcf07e42daac808c0a9aa"
64
64
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"Filter-Bc0LWCnZ.cjs","names":["filterSchema: Record<string, VetoTypeAny>","filters","config","contextValue: FiltersContextValue","Label","Menu","FaSliders","config","Modal","Button","SubmitButton","PiSlidersHorizontalBold","Suspense","config","Button","FaSearch","motion","Input","SubmitButton","debug","config","Form","SearchInput","ActiveFilters","AddFilterMenu","FilterModal","config","Display","Form","Switch","config","validate","createFilter","validate","Checkboxes","config","createFilter","Filter"],"sources":["../src/Filter/hooks/useFilterValidation.ts","../src/Filter/Subcomponents/FiltersContext.tsx","../src/Filter/Subcomponents/ActiveFilters.tsx","../src/Filter/Subcomponents/AddFilterMenu.tsx","../src/Filter/Subcomponents/FilterModal.tsx","../src/Filter/Subcomponents/SearchInput.tsx","../src/Filter/Filter.tsx","../src/Filter/filters/createFilter.ts","../src/Filter/filters/boolean/Display.tsx","../src/Filter/filters/boolean/Form.tsx","../src/Filter/filters/boolean/schema.ts","../src/Filter/filters/boolean/boolean.ts","../src/Filter/filters/checkboxes/Display.tsx","../src/Filter/filters/checkboxes/Form.tsx","../src/Filter/filters/checkboxes/schema.ts","../src/Filter/filters/checkboxes/checkboxes.ts","../src/Filter/index.ts"],"sourcesContent":["import type { VetoInstance, VetoRawShape, VetoTypeAny } from '@fuf-stack/veto';\nimport type { FilterInstance } from '../filters/types';\n\nimport { useMemo } from 'react';\n\nimport { object, string, stringToJSON, veto } from '@fuf-stack/veto';\n\n/**\n * useFilterValidation\n *\n * Builds a composite validation schema from all provided filter definitions\n * under \"filter\" and optionally includes a \"search\" string field.\n * Memoized by inputs.\n */\nexport const useFilterValidation = (\n filters: FilterInstance<unknown, unknown>[],\n withSearch?: boolean,\n) => {\n return useMemo<VetoInstance>(() => {\n // build filter validation\n let filterSchema: Record<string, VetoTypeAny> = {};\n filters.forEach((f) => {\n filterSchema = {\n ...filterSchema,\n [f.name]: f.validation(f.config) as VetoTypeAny,\n };\n });\n\n const validationSchema: VetoRawShape = {\n // filter validation\n filter: stringToJSON()\n .pipe(object(filterSchema))\n .or(object(filterSchema))\n .optional()\n .nullable()\n // transform null to undefined\n .transform((val) => {\n return val ?? undefined;\n }),\n // optional search validation\n ...(withSearch\n ? { search: string({ min: 0 }).nullable().optional() }\n : {}),\n };\n\n return veto(validationSchema);\n }, [filters, withSearch]);\n};\n\nexport default useFilterValidation;\n","import type { ReactNode } from 'react';\nimport type { FilterInstance, FiltersConfiguration } from '../filters/types';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useFormContext } from '@fuf-stack/uniform/hooks/useFormContext';\n\ninterface FiltersContextValue {\n /** Active filters (names only) */\n activeFilters: string[];\n /** Seed default value and open modal for a filter usage. */\n addFilter: (name: string) => void;\n /** Close the modal. */\n closeFilterModal: () => void;\n /** Build fully-qualified form field path for a filter name */\n getFilterFormFieldName: (name: string) => string;\n /** Get current form value for a given filter name */\n getFilterValueByName: (name: string) => unknown;\n /** Get filter instance by name */\n getFilterInstanceByName: (name: string) => FilterInstance<unknown, unknown>;\n /** Validation helper for a specific filter field. */\n hasError: (name: string) => boolean;\n /** Name of the current filter that has its modal open */\n modalFilterName: string | undefined;\n /** Remove a filter from the form. */\n removeFilter: (name: string) => void;\n /** Open the modal for a given filter name. */\n showFilterModal: (name: string) => void;\n /** Filters that are not active (names only) */\n unusedFilters: string[];\n}\n\n/**\n * FiltersContext\n *\n * Central state for the filter UI with a clear boundary:\n * - The parent component controls committed filter values (via value/onChange)\n * - The form acts as an edit buffer (used by the modal)\n *\n * Design:\n * - activeFilters/unusedFilters are names-only and derived from the controlled\n * form state\n * - getFilterInstanceByName gives access to the concrete registry entry to\n * retrieve the correct Form/Display components\n * - add seeds defaults in the form and opens the modal\n * - remove un-registers the form field; if the removed filter is currently\n * open in the modal, the modal is closed without rollback\n * - on a new successful form submit (Apply), the modal closes without rollback\n * by subscribing to ex-forms submit state\n */\nconst FiltersContext = createContext<FiltersContextValue | undefined>(\n undefined,\n);\n\nexport const FiltersContextProvider = ({\n children,\n config,\n}: {\n children: ReactNode;\n config: FiltersConfiguration;\n}) => {\n // ex-forms integration:\n // - setValue/unregister/getFieldState: core helpers to manipulate and validate fields\n // - formState: we subscribe to submit-success to auto-close the modal after Apply\n const {\n formState,\n getFieldState,\n setValue,\n triggerSubmit,\n unregister,\n watch,\n } = useFormContext();\n\n /**\n * currentModalFilter\n *\n * Single source of truth for the filter edit modal and its rollback snapshot.\n * - name: which filter's modal is currently open (null when closed)\n * - hadValue/previousValue: snapshot of the controlled value taken when the\n * modal is opened; used to restore state if the user cancels/closes without\n * applying.\n *\n * Lifecycle semantics:\n * - showFilterModal(name): capture snapshot (current controlled value) and open\n * the modal for that filter.\n * - closeFilterModal(): if a snapshot exists, roll back un-applied edits by\n * restoring the previous value (setValue) or removing the field (unregister)\n * when it did not exist before; then clear currentModalFilter.\n * - On successful submit (Apply): close and clear currentModalFilter WITHOUT rollback\n * so edits remain committed.\n * - removeFilter(name): unregisters the field; when removing the filter that is\n * currently open, close the modal WITHOUT rollback (since removal is explicit).\n */\n const [currentModalFilter, setCurrentModalFilter] = useState<{\n name: string;\n hadValue: boolean;\n previousValue: unknown;\n } | null>(null);\n\n // Read current filter values from the form as the live edit buffer\n const filterValue = watch('filter', {});\n\n /**\n * getFilterFormFieldName\n *\n * Returns the fully-qualified field path for a given filter name,\n * e.g., `${filterUrlParam}.status`.\n */\n const getFilterFormFieldName = useCallback((name: string) => {\n return `filter.${name}`;\n }, []);\n\n /**\n * getFilterValueByName\n *\n * Returns the committed value for a filter from the controlled state.\n */\n const getFilterValueByName = useCallback(\n (name: string) => {\n return (filterValue as Record<string, unknown>)[name];\n },\n [filterValue],\n );\n\n /** Open the filter edit modal for the given filter name. */\n const showFilterModal = useCallback(\n (name: string) => {\n const prev = getFilterValueByName(name);\n setCurrentModalFilter({\n name,\n hadValue: typeof prev !== 'undefined',\n previousValue: prev,\n });\n },\n [getFilterValueByName],\n );\n\n /** Close the filter edit modal. Rollback un-applied edits to controlled state. */\n const closeFilterModal = useCallback(() => {\n if (currentModalFilter?.name) {\n const fieldName = getFilterFormFieldName(currentModalFilter.name);\n // if the filter had a value, set it back to the previous value,\n // otherwise unregister the field\n if (currentModalFilter.hadValue) {\n setValue(fieldName, currentModalFilter.previousValue);\n } else {\n unregister(fieldName);\n }\n }\n setCurrentModalFilter(null);\n }, [getFilterFormFieldName, currentModalFilter, setValue, unregister]);\n\n /**\n * Auto-close on submit success\n *\n * Close the modal only on new successful submissions. We track the last\n * submitCount and only react when it changes AND the form reports a\n * successful submit. This prevents closing when `isSubmitSuccessful` remains\n * true without a new submit event.\n */\n const lastSubmitCountRef = useRef<number>(0);\n useEffect(() => {\n if (\n formState.submitCount !== lastSubmitCountRef.current &&\n formState.isSubmitSuccessful\n ) {\n // On successful submit, close without rollback\n setCurrentModalFilter(null);\n }\n lastSubmitCountRef.current = formState.submitCount;\n }, [\n formState.submitCount,\n formState.isSubmitSuccessful,\n setCurrentModalFilter,\n ]);\n\n /**\n * activeFilters\n *\n * Filter names derived from the controlled form state. A filter is considered\n * active when a field exists at `filter.<name>`. Newly added filters become\n * active immediately (seeded default), and will be rolled back on cancel.\n */\n const activeFilters = useMemo(() => {\n return config\n .filter((f) => {\n return Object.hasOwn(filterValue ?? {}, f.name);\n })\n .map((f) => {\n return f.name;\n });\n }, [config, filterValue]);\n\n /**\n * unusedFilters\n *\n * Complement of activeFilters (names without a corresponding `filter.<name>`\n * field in the controlled form state).\n */\n const unusedFilters = useMemo(() => {\n return config\n .filter((f) => {\n return !Object.hasOwn(filterValue ?? {}, f.name);\n })\n .map((f) => {\n return f.name;\n });\n }, [config, filterValue]);\n\n /**\n * getRegistryFilterByName\n *\n * Looks up the concrete registry entry for a filter by name, enabling access\n * to typed Form/Display components and other registry-level metadata.\n */\n const getFilterInstanceByName = useCallback(\n (name: string) => {\n return config.find((f) => {\n return f.name === name;\n }) as FilterInstance<unknown, unknown>;\n },\n [config],\n );\n\n /**\n * addFilter\n *\n * Seeds the filter with its registry default value inside the form and opens\n * the modal for immediate editing. No URL writes happen here.\n */\n const addFilter = useCallback(\n (name: string) => {\n const inst = getFilterInstanceByName(name);\n showFilterModal(name);\n setValue(getFilterFormFieldName(name), inst.defaultValue);\n },\n [\n getFilterFormFieldName,\n getFilterInstanceByName,\n setValue,\n showFilterModal,\n ],\n );\n\n /**\n * removeFilter\n *\n * Unregisters the filter field from the form. This immediately removes the\n * filter from the active list since derived state watches the form. It\n * closes the modal without rollback if the removed filter is currently open.\n */\n const removeFilter = useCallback(\n (name: string) => {\n // unregister form field\n unregister(getFilterFormFieldName(name));\n // close filter modal if open\n if (currentModalFilter?.name === name) {\n // Explicit removal: close without rollback\n setCurrentModalFilter(null);\n }\n // trigger form submit (to update filter state)\n triggerSubmit();\n },\n [\n getFilterFormFieldName,\n currentModalFilter,\n setCurrentModalFilter,\n triggerSubmit,\n unregister,\n ],\n );\n\n /**\n * hasError\n *\n * Helper that checks the ex-forms field state for a specific filter and\n * reports whether the field is currently invalid.\n */\n const hasError = useCallback(\n (name: string) => {\n return getFieldState(getFilterFormFieldName(name)).invalid;\n },\n [getFieldState, getFilterFormFieldName],\n );\n\n const contextValue: FiltersContextValue = useMemo(() => {\n return {\n activeFilters,\n addFilter,\n closeFilterModal,\n getFilterFormFieldName,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n modalFilterName: currentModalFilter?.name,\n removeFilter,\n showFilterModal,\n unusedFilters,\n };\n }, [\n activeFilters,\n addFilter,\n closeFilterModal,\n getFilterFormFieldName,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n currentModalFilter,\n removeFilter,\n showFilterModal,\n unusedFilters,\n ]);\n\n return (\n <FiltersContext.Provider value={contextValue}>\n {children}\n </FiltersContext.Provider>\n );\n};\n\n/**\n * useFilters\n *\n * Convenience hook to consume the FiltersContext. Throws a descriptive error\n * when used outside of a FiltersContextProvider to make integration mistakes\n * obvious during development.\n */\nexport const useFilters = (): FiltersContextValue => {\n const ctx = useContext(FiltersContext);\n if (!ctx) {\n throw new Error('useFilters must be used within FiltersContextProvider');\n }\n return ctx;\n};\n\nexport default FiltersContext;\n","import Label from '@fuf-stack/pixels/Label';\n\nimport { useFilters } from './FiltersContext';\n\n/**\n * ActiveFilters\n *\n * Shows the list of currently applied filters as clickable chips that open\n * the edit modal. Each chip can be removed via its close action.\n */\ninterface ActiveFiltersProps {\n /** CSS class name to apply to each label */\n className?: string;\n}\n\nconst ActiveFilters = ({ className = undefined }: ActiveFiltersProps) => {\n const {\n activeFilters,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n removeFilter,\n showFilterModal,\n } = useFilters();\n return (\n <>\n {activeFilters.map((name) => {\n const instance = getFilterInstanceByName(name);\n const value = getFilterValueByName(name);\n\n // get the display component from the instance\n const DisplayComponent = instance.components.Display;\n\n return (\n <button\n key={name}\n aria-label={`Open ${name} filter`}\n type=\"button\"\n onClick={() => {\n showFilterModal(name);\n }}\n >\n <Label\n className={className}\n color={hasError(name) ? 'danger' : 'primary'}\n variant=\"flat\"\n onClose={() => {\n removeFilter(name);\n }}\n >\n {instance.icon}\n <DisplayComponent config={instance.config} value={value} />\n </Label>\n </button>\n );\n })}\n </>\n );\n};\n\nexport default ActiveFilters;\n","import { FaSliders } from 'react-icons/fa6';\n\nimport Menu from '@fuf-stack/pixels/Menu';\n\nimport { useFilters } from './FiltersContext';\n\ninterface AddFilterMenuProps {\n /** CSS class name map for slots */\n classNames?: Partial<{\n addFilterMenuItem: string;\n addFilterMenuButton: string;\n }>;\n}\n\n/**\n * AddFilterMenu\n *\n * Renders a menu trigger that opens a list of addable filters. Selecting an\n * item triggers the parent to seed a default value and open the modal.\n */\nconst AddFilterMenu = ({ classNames = {} }: AddFilterMenuProps) => {\n const { unusedFilters, addFilter, getFilterInstanceByName } = useFilters();\n\n const menuItems = unusedFilters.map((name) => {\n const instance = getFilterInstanceByName(name);\n const config = instance.config as { text?: string };\n const label = config?.text ?? name;\n return {\n key: name,\n icon: instance.icon,\n label,\n onClick: () => {\n addFilter(name);\n },\n };\n });\n\n return (\n <Menu\n isDisabled={!menuItems.length}\n items={menuItems}\n placement=\"bottom-start\"\n className={{\n item: classNames.addFilterMenuItem,\n trigger: classNames.addFilterMenuButton,\n }}\n triggerButtonProps={{\n 'aria-label': 'Add Filter',\n 'data-testid': 'add_filter_button',\n disableRipple: true,\n size: 'sm',\n variant: 'bordered',\n }}\n >\n <FaSliders />\n Filter\n </Menu>\n );\n};\n\nexport default AddFilterMenu;\n","import { Suspense } from 'react';\nimport { PiSlidersHorizontalBold } from 'react-icons/pi';\n\nimport Button from '@fuf-stack/pixels/Button';\nimport Modal from '@fuf-stack/pixels/Modal';\nimport SubmitButton from '@fuf-stack/uniform/SubmitButton';\n\nimport { useFilters } from './FiltersContext';\n\ninterface FilterModalProps {\n classNames?: Partial<{\n header: string;\n footer: string;\n body: string;\n }>;\n}\n\nconst FilterModal = ({ classNames = {} }: FilterModalProps) => {\n const {\n closeFilterModal,\n getFilterFormFieldName,\n getFilterInstanceByName,\n modalFilterName,\n removeFilter,\n } = useFilters();\n\n // don't render if no filter is open\n if (!modalFilterName) {\n return null;\n }\n\n const instance = getFilterInstanceByName(modalFilterName);\n const config = instance.config as { text?: string };\n\n // get the form component from the instance\n const FormComponent = instance.components.Form;\n\n return (\n <Modal\n isOpen\n onClose={closeFilterModal}\n className={{\n body: classNames.body,\n footer: classNames.footer,\n header: classNames.header,\n }}\n footer={\n <>\n <Button\n ariaLabel=\"Remove filter\"\n color=\"danger\"\n testId=\"remove_filter_button\"\n variant=\"flat\"\n onClick={() => {\n removeFilter(modalFilterName);\n }}\n >\n Remove\n </Button>\n <SubmitButton ariaLabel=\"Apply filter\" testId=\"apply_filter_button\">\n Apply Filter\n </SubmitButton>\n </>\n }\n header={\n <>\n {instance.icon ?? <PiSlidersHorizontalBold />}\n <div>{`${config?.text ?? modalFilterName} Filter`}</div>\n </>\n }\n >\n <Suspense>\n <FormComponent\n config={config}\n fieldName={getFilterFormFieldName(modalFilterName)}\n />\n </Suspense>\n </Modal>\n );\n};\n\nexport default FilterModal;\n","import { useState } from 'react';\nimport { FaSearch } from 'react-icons/fa';\n\nimport { motion } from '@fuf-stack/pixel-motion';\nimport Button from '@fuf-stack/pixels/Button';\nimport { useFormContext } from '@fuf-stack/uniform/hooks/useFormContext';\nimport Input from '@fuf-stack/uniform/Input';\nimport SubmitButton from '@fuf-stack/uniform/SubmitButton';\n\nexport type SearchConfiguration =\n | boolean\n | {\n /** Placeholder shown in the search input */\n placeholder?: string;\n };\n\ninterface SearchInputProps {\n /** Slots class names passed from parent variants */\n classNames?: Partial<{\n searchWrapper: string;\n searchShowButton: string;\n searchMotionDiv: string;\n searchInput: string;\n searchInputWrapper: string;\n searchSubmitButton: string;\n }>;\n /** Search configuration */\n config: SearchConfiguration;\n}\n\n/**\n * SearchInput\n *\n * By default renders only a search button. When clicked, the text input animates in\n * and a trailing submit button is shown.\n */\nconst SearchInput = ({ classNames = {}, config }: SearchInputProps) => {\n const { formState, setFocus, triggerSubmit } = useFormContext();\n\n // Auto-open if there is an initial or externally set search value\n const isInitiallyVisible = !!formState?.defaultValues?.search;\n const [isVisible, setIsVisible] = useState(isInitiallyVisible);\n\n const placeholder =\n typeof config === 'object' ? config.placeholder : undefined;\n\n return (\n <div className={classNames.searchWrapper}>\n {!isVisible && (\n <Button\n ariaLabel=\"Show search input\"\n className={classNames.searchShowButton}\n icon={<FaSearch />}\n size=\"sm\"\n testId=\"show_search_input_button\"\n variant=\"bordered\"\n onClick={() => {\n setIsVisible(true);\n }}\n />\n )}\n {isVisible ? (\n <motion.div\n key=\"search-input\"\n animate={{ opacity: 1 }}\n className={classNames.searchMotionDiv}\n // if the input was not initially visible, animate in\n initial={!isInitiallyVisible ? { opacity: 0.5 } : false}\n onAnimationComplete={() => {\n // if the input was not initially visible, focus it\n if (!isInitiallyVisible) {\n setFocus('search');\n }\n }}\n transition={{\n duration: 0.3,\n ease: 'circOut',\n }}\n >\n <Input\n clearable\n debounceDelay={0}\n name=\"search\"\n placeholder={placeholder}\n size=\"sm\"\n className={{\n input: classNames.searchInput,\n inputWrapper: classNames.searchInputWrapper,\n }}\n // submit on clear\n onClear={() => {\n triggerSubmit();\n }}\n />\n <SubmitButton\n ariaLabel=\"Submit search\"\n // eslint-disable-next-line react/no-children-prop\n children={null}\n className={classNames.searchSubmitButton}\n color=\"primary\"\n icon={<FaSearch />}\n size=\"sm\"\n testId=\"submit_search_button\"\n />\n </motion.div>\n ) : null}\n </div>\n );\n};\n\nexport default SearchInput;\n","import type { TVClassName } from '@fuf-stack/pixel-utils';\nimport type { VetoInput } from '@fuf-stack/veto';\nimport type { ReactNode } from 'react';\nimport type { FiltersConfiguration } from './filters/types';\nimport type { SearchConfiguration } from './Subcomponents/SearchInput';\n\nimport createDebug from 'debug';\n\nimport { tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\nimport Form from '@fuf-stack/uniform/Form';\n\nimport { useFilterValidation } from './hooks/useFilterValidation';\nimport ActiveFilters from './Subcomponents/ActiveFilters';\nimport AddFilterMenu from './Subcomponents/AddFilterMenu';\nimport FilterModal from './Subcomponents/FilterModal';\nimport { FiltersContextProvider } from './Subcomponents/FiltersContext';\nimport SearchInput from './Subcomponents/SearchInput';\n\nconst debug = createDebug('megapixels:Filter');\n\n// filter styling variants\nexport const filterVariants = tv({\n slots: {\n // outer wrapper\n base: 'flex flex-auto flex-col',\n // add filter menu trigger button\n addFilterMenuButton: '',\n // add filter menu item\n addFilterMenuItem: '',\n // active filter label\n activeFilterLabel: 'h-8 cursor-pointer rounded-md dark:text-foreground',\n // filter modal body\n filterModalBody: '',\n // filter modal header\n filterModalHeader: 'flex items-center gap-3 text-default-700',\n // filter modal footer\n filterModalFooter: 'justify-between',\n // form element\n form: 'mb-3 flex flex-wrap gap-3',\n // search input field\n searchInput: '',\n // search input wrapper (inner control)\n searchInputWrapper: '',\n // search motion container\n searchMotionDiv: 'flex w-72 gap-2',\n // search show button\n searchShowButton: '',\n // search submit button\n searchSubmitButton: '',\n // search wrapper\n searchWrapper: 'flex items-center',\n },\n});\n\ntype ClassName = TVClassName<typeof filterVariants>;\n\nexport interface FilterValues {\n search?: string;\n filter?: string | Record<string, unknown> | null;\n}\n\nexport type FilterChildRenderFn = (values: {\n search?: string;\n filter?: Record<string, unknown>;\n}) => ReactNode;\n\n/**\n * Filter\n *\n * Controlled, form-driven filter UI.\n *\n * Responsibilities\n * - Derives initial form values from the controlled `values` prop\n * - Builds a composite validation schema from the filter registry (and optional search)\n * - Exposes ergonomic UI: active filters list, add/remove actions, and per-filter modal\n * - Commits changes by invoking the controlled `onChange` callback on submit\n *\n * Structure\n * - Owns an ex-forms `Form` that wraps the entire filter experience\n * - Optionally renders a search input bound to the `search` field\n * - Renders ActiveFilters, AddFilterMenu, and FilterModal inside a shared context\n * - Optionally renders children as a render-prop with the resolved `values`\n */\nexport interface FilterProps {\n /** Optional render-prop that receives the resolved, controlled values */\n children?: FilterChildRenderFn;\n /** CSS class name */\n className?: ClassName;\n /** Configuration of the filter */\n config: {\n /**\n * Declarative filter configuration. Each entry ties a logical name to a\n * registry filter type and (optionally) per-usage config overrides.\n */\n filters: FiltersConfiguration;\n /** Optional configuration for search field */\n search?: SearchConfiguration;\n };\n /** ex-forms form instance name. Defaults to \"filterComponentForm\". */\n formName?: string;\n /** Controlled setter invoked on submit with the next canonical values */\n onChange: (nextValues: FilterValues) => void;\n /** Controlled committed state: the canonical `search` and `filter` values */\n values: FilterValues;\n}\n\n/**\n * Renders the filter UI bound to a single ex-forms `Form`.\n * The form is the source of truth during user interaction; the committed\n * state is controlled by the parent via `values`/`onChange`.\n */\nconst Filter = ({\n children = undefined,\n className = undefined,\n config,\n formName = 'filterComponentForm',\n onChange,\n values,\n}: FilterProps) => {\n // Submit handler: map form state back into the controlled `values` shape\n const handleSubmit = (nextValues: Record<string, unknown>) => {\n debug('handleSubmit', { nextValues });\n onChange(nextValues as FilterValues);\n };\n\n // Build validation schema for all configured filters (and optional search)\n const validation = useFilterValidation(\n config.filters,\n Boolean(config.search),\n );\n\n // validate controlled values are valid\n const {\n data: valuesValidated,\n errors,\n success,\n } = validation.validate(values as VetoInput);\n\n // classNames from slots\n const variants = filterVariants();\n const classNames = variantsToClassNames(variants, className, 'base');\n\n debug('render', {\n props: { config, values },\n validation: { errors, success, valuesValidated },\n });\n\n return (\n <div className={classNames.base}>\n {/*\n Uniform Form wrapper\n - initialValues derive from controlled props (with optional defaults)\n - validation is built from the registry for all configured filters\n - onSubmit maps form values back into values/onChange\n */}\n <Form\n className={classNames.form}\n // disable debug mode for now\n debug={{ disable: true }}\n initialValues={valuesValidated ?? {}}\n name={formName}\n onSubmit={handleSubmit}\n validation={validation}\n >\n {/* Render search if search config is provided */}\n {config.search ? (\n <SearchInput\n config={config.search}\n classNames={{\n searchInput: classNames.searchInput,\n searchInputWrapper: classNames.searchInputWrapper,\n searchMotionDiv: classNames.searchMotionDiv,\n searchShowButton: classNames.searchShowButton,\n searchSubmitButton: classNames.searchSubmitButton,\n searchWrapper: classNames.searchWrapper,\n }}\n />\n ) : null}\n {/*\n FiltersContextProvider exposes a minimal API for the UI layer:\n - activeFilters/unusedFilters by name\n - helpers to get merged config, value, components, and field names\n - methods to add/remove filters and show/close the modal\n */}\n <FiltersContextProvider config={config.filters}>\n <ActiveFilters className={classNames.activeFilterLabel} />\n <AddFilterMenu\n classNames={{\n addFilterMenuButton: classNames.addFilterMenuButton,\n addFilterMenuItem: classNames.addFilterMenuItem,\n }}\n />\n <FilterModal\n classNames={{\n body: classNames.filterModalBody,\n footer: classNames.filterModalFooter,\n header: classNames.filterModalHeader,\n }}\n />\n </FiltersContextProvider>\n </Form>\n {/* Children can consume derived search string and parsed filter object */}\n {children?.(valuesValidated ?? {})}\n </div>\n );\n};\n\nexport default Filter;\n","import type { FilterDefinition, FilterFactory } from './types';\n\n/**\n * createFilter\n *\n * Builds a filter factory from a static FilterDefinition. The returned factory\n * accepts a usage descriptor (name/icon and optional partial config) and\n * produces a concrete FilterInstance with:\n * - merged config (shallow: definition.defaults.config overlaid by overrides)\n * - Form/Display components\n * - validate function (forwarded from the definition)\n * - defaultValue (forwarded from the definition)\n * - name and icon for UI integration\n *\n * @typeParam Config - Configuration object shape for the filter\n * @typeParam Value - Runtime value type for the filter\n * @param definition - Static description of the filter (components, defaults, validate)\n * @returns FilterFactory that creates FilterInstance<Config, Value>\n */\nconst createFilter = <Config, Value>(\n definition: FilterDefinition<Config, Value>,\n): FilterFactory<Config, Value> => {\n return ({ name, icon, config }) => {\n return {\n components: definition.components,\n config: { ...definition.defaults.config, ...(config ?? {}) } as Config,\n defaultValue: definition.defaults.value,\n icon,\n name,\n validation: definition.validation,\n };\n };\n};\n\nexport default createFilter;\n","import type { FilterDisplayProps } from '../types';\nimport type { Config, Value } from './schema';\n\n/**\n * Read-only presentation for the boolean filter.\n * Displays human-readable text based on the current boolean `value`\n * and the provided `config` strings.\n */\nconst Display = ({\n value,\n config: { text, textPrefix, textNoWord },\n}: FilterDisplayProps<Config, Value>) => {\n if (typeof value === 'boolean') {\n return (\n <>\n {`${value ? textPrefix : `${textPrefix} ${textNoWord ?? 'no'}`} ${text}`}\n </>\n );\n }\n return <>{`${text}...`}</>;\n};\n\nexport default Display;\n","import type { FilterFormProps } from '../types';\nimport type { Config } from './schema';\n\nimport Switch from '@fuf-stack/uniform/Switch';\n\n/**\n * Renders the form control for the boolean filter.\n * Uses a `Switch` to toggle the boolean value and composes\n * the label from the provided `config` and `fieldName`.\n */\nconst Form = ({\n fieldName,\n config: { text, textPrefix },\n}: FilterFormProps<Config>) => {\n return <Switch label={`${textPrefix} ${text}`} name={fieldName} />;\n};\n\nexport default Form;\n","import type { vInfer } from '@fuf-stack/veto';\n\nimport { boolean, object, string } from '@fuf-stack/veto';\n\n/** configuration of the filter */\nexport const config = object({\n /**\n * Human‑readable label used in the UI (e.g. in the chip and modal header).\n * Examples: \"Magical\", \"Haunted\"\n */\n text: string(),\n /**\n * Optional word shown before the label when building sentence‑like chips.\n * Examples: \"is\" → \"is Magical\"\n */\n textPrefix: string().optional(),\n /**\n * Optional negation word used when a boolean value is false.\n * Examples: \"not\" → \"is not Magical\"\n */\n textNoWord: string().optional(),\n});\n\n/** validate the filter value */\nexport const validate = (_config?: Config) => {\n return boolean().optional();\n};\n\nexport type Config = vInfer<typeof config>;\nexport type Value = vInfer<ReturnType<typeof validate>>;\n","/* eslint-disable import-x/prefer-default-export */\n\nimport type { Config, Value } from './schema';\n\nimport createFilter from '../createFilter';\nimport Display from './Display';\nimport Form from './Form';\nimport { validate } from './schema';\n\n/**\n * Boolean filter definition for the Filter system.\n * Provides Display and Form components, default value/config, and validation.\n *\n * Defaults:\n * - value: true\n * - config: { text: 'Active', textPrefix: 'is', textNoWord: 'no' }\n *\n * @see Display\n * @see Form\n * @see validate\n */\nexport const boolean = createFilter<Config, Value>({\n components: { Display, Form },\n defaults: {\n value: true,\n config: { text: 'Active', textPrefix: 'is', textNoWord: 'no' },\n },\n validation: validate,\n});\n","import type { FilterDisplayProps } from '../types';\nimport type { Config, Value } from './schema';\n\n/**\n * Read-only presentation for the checkboxes filter.\n * Resolves and displays selected option labels based on `value` and `config`.\n * Supports string, ReactNode, and function labels (mode: 'display').\n */\nconst Display = ({\n value,\n config: { text, options },\n}: FilterDisplayProps<Config, Value>) => {\n if (value && value.length > 0) {\n return (\n <span className=\"flex items-center gap-1\">\n {text} is\n {value.map((val) => {\n const option = options.find((op) => {\n return op.value === val;\n });\n const label = option?.label ?? val;\n const resolvedLabel =\n typeof label === 'function' ? label('display') : label;\n return <span key={val}>{resolvedLabel}</span>;\n })}\n </span>\n );\n }\n return `${text} is ...`;\n};\n\nexport default Display;\n","import type { FilterFormProps } from '../types';\nimport type { Config } from './schema';\n\nimport Checkboxes from '@fuf-stack/uniform/Checkboxes';\n\n/**\n * Renders the form control for the checkboxes filter.\n * Uses a `Checkboxes` to select multiple options.\n * Resolves function labels with 'form' mode.\n */\nconst Form = ({ fieldName, config }: FilterFormProps<Config>) => {\n const resolvedOptions = config.options.map((option) => {\n return {\n ...option,\n label:\n typeof option.label === 'function'\n ? option.label('form')\n : option.label,\n };\n });\n\n return <Checkboxes name={fieldName} options={resolvedOptions} />;\n};\n\nexport default Form;\n","import type { vInfer } from '@fuf-stack/veto';\nimport type { ReactNode } from 'react';\n\nimport { any, array, object, refineArray, string } from '@fuf-stack/veto';\n\n/** configuration of the filter */\nexport const config = object({\n /**\n * Human‑readable label used in the UI (e.g. label and modal header).\n * Example: \"Snacks\", \"Mood\"\n */\n text: string(),\n /**\n * Options rendered as multiple checkboxes. Each option needs a `label`\n * (what the user sees) and a `value` (what is written into the form state).\n * Label can be a string, React node, or a function that receives mode\n * ('form' or 'display') and returns a React node.\n */\n options: array(object({ label: any(), value: string() })),\n});\n\n/** Type-safe Config that overrides label to support ReactNode or function */\nexport type Config = Omit<vInfer<typeof config>, 'options'> & {\n options: {\n label: ReactNode | ((mode: 'form' | 'display') => ReactNode);\n value: string;\n }[];\n};\n\n/** validate the filter value */\nexport const validate = (cfg?: Config) => {\n return refineArray(array(string()).optional())({\n unique: true,\n custom: (values, ctx) => {\n if (!cfg) {\n return;\n }\n values.forEach((value) => {\n if (\n !cfg.options.find((option) => {\n return option?.value === value;\n })\n ) {\n ctx.addIssue({\n code: 'custom',\n message: `Invalid value: ${value}`,\n });\n }\n });\n },\n });\n};\n\nexport type Value = vInfer<ReturnType<typeof validate>>;\n","/* eslint-disable import-x/prefer-default-export */\n\nimport type { Config, Value } from './schema';\n\nimport createFilter from '../createFilter';\nimport Display from './Display';\nimport Form from './Form';\nimport { validate } from './schema';\n\n/**\n * Checkboxes filter definition for the Filter system.\n * Provides Display and Form components, default value/config, and validation.\n *\n * Defaults:\n * - value: []\n * - config: { text: 'Options', options: [] }\n *\n * @see Display\n * @see Form\n * @see validate\n */\nexport const checkboxes = createFilter<Config, Value>({\n components: { Display, Form },\n defaults: { value: [], config: { text: 'Options', options: [] } },\n validation: validate,\n});\n","import Filter from './Filter';\nimport { boolean } from './filters/boolean/boolean';\nimport { checkboxes } from './filters/checkboxes/checkboxes';\n\n// export types\nexport type * from './filters/types';\n\n// export helpers\nexport { default as createFilter } from './filters/createFilter';\n\n// export all filters\nexport const filters = {\n boolean,\n checkboxes,\n};\n\n// export everything from the Filter component (types and filterVariants)\nexport * from './Filter';\n\n// export the Filter component as default\nexport default Filter;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Filter-nSuQco2t.js","names":["filterSchema: Record<string, VetoTypeAny>","filters","config","contextValue: FiltersContextValue","config","config","config","SearchInput","ActiveFilters","AddFilterMenu","FilterModal","config","Display","Form","config","validate","boolean","createFilter","validate","Form","config","createFilter","Filter"],"sources":["../src/Filter/hooks/useFilterValidation.ts","../src/Filter/Subcomponents/FiltersContext.tsx","../src/Filter/Subcomponents/ActiveFilters.tsx","../src/Filter/Subcomponents/AddFilterMenu.tsx","../src/Filter/Subcomponents/FilterModal.tsx","../src/Filter/Subcomponents/SearchInput.tsx","../src/Filter/Filter.tsx","../src/Filter/filters/createFilter.ts","../src/Filter/filters/boolean/Display.tsx","../src/Filter/filters/boolean/Form.tsx","../src/Filter/filters/boolean/schema.ts","../src/Filter/filters/boolean/boolean.ts","../src/Filter/filters/checkboxes/Display.tsx","../src/Filter/filters/checkboxes/Form.tsx","../src/Filter/filters/checkboxes/schema.ts","../src/Filter/filters/checkboxes/checkboxes.ts","../src/Filter/index.ts"],"sourcesContent":["import type { VetoInstance, VetoRawShape, VetoTypeAny } from '@fuf-stack/veto';\nimport type { FilterInstance } from '../filters/types';\n\nimport { useMemo } from 'react';\n\nimport { object, string, stringToJSON, veto } from '@fuf-stack/veto';\n\n/**\n * useFilterValidation\n *\n * Builds a composite validation schema from all provided filter definitions\n * under \"filter\" and optionally includes a \"search\" string field.\n * Memoized by inputs.\n */\nexport const useFilterValidation = (\n filters: FilterInstance<unknown, unknown>[],\n withSearch?: boolean,\n) => {\n return useMemo<VetoInstance>(() => {\n // build filter validation\n let filterSchema: Record<string, VetoTypeAny> = {};\n filters.forEach((f) => {\n filterSchema = {\n ...filterSchema,\n [f.name]: f.validation(f.config) as VetoTypeAny,\n };\n });\n\n const validationSchema: VetoRawShape = {\n // filter validation\n filter: stringToJSON()\n .pipe(object(filterSchema))\n .or(object(filterSchema))\n .optional()\n .nullable()\n // transform null to undefined\n .transform((val) => {\n return val ?? undefined;\n }),\n // optional search validation\n ...(withSearch\n ? { search: string({ min: 0 }).nullable().optional() }\n : {}),\n };\n\n return veto(validationSchema);\n }, [filters, withSearch]);\n};\n\nexport default useFilterValidation;\n","import type { ReactNode } from 'react';\nimport type { FilterInstance, FiltersConfiguration } from '../filters/types';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useFormContext } from '@fuf-stack/uniform/hooks/useFormContext';\n\ninterface FiltersContextValue {\n /** Active filters (names only) */\n activeFilters: string[];\n /** Seed default value and open modal for a filter usage. */\n addFilter: (name: string) => void;\n /** Close the modal. */\n closeFilterModal: () => void;\n /** Build fully-qualified form field path for a filter name */\n getFilterFormFieldName: (name: string) => string;\n /** Get current form value for a given filter name */\n getFilterValueByName: (name: string) => unknown;\n /** Get filter instance by name */\n getFilterInstanceByName: (name: string) => FilterInstance<unknown, unknown>;\n /** Validation helper for a specific filter field. */\n hasError: (name: string) => boolean;\n /** Name of the current filter that has its modal open */\n modalFilterName: string | undefined;\n /** Remove a filter from the form. */\n removeFilter: (name: string) => void;\n /** Open the modal for a given filter name. */\n showFilterModal: (name: string) => void;\n /** Filters that are not active (names only) */\n unusedFilters: string[];\n}\n\n/**\n * FiltersContext\n *\n * Central state for the filter UI with a clear boundary:\n * - The parent component controls committed filter values (via value/onChange)\n * - The form acts as an edit buffer (used by the modal)\n *\n * Design:\n * - activeFilters/unusedFilters are names-only and derived from the controlled\n * form state\n * - getFilterInstanceByName gives access to the concrete registry entry to\n * retrieve the correct Form/Display components\n * - add seeds defaults in the form and opens the modal\n * - remove un-registers the form field; if the removed filter is currently\n * open in the modal, the modal is closed without rollback\n * - on a new successful form submit (Apply), the modal closes without rollback\n * by subscribing to ex-forms submit state\n */\nconst FiltersContext = createContext<FiltersContextValue | undefined>(\n undefined,\n);\n\nexport const FiltersContextProvider = ({\n children,\n config,\n}: {\n children: ReactNode;\n config: FiltersConfiguration;\n}) => {\n // ex-forms integration:\n // - setValue/unregister/getFieldState: core helpers to manipulate and validate fields\n // - formState: we subscribe to submit-success to auto-close the modal after Apply\n const {\n formState,\n getFieldState,\n setValue,\n triggerSubmit,\n unregister,\n watch,\n } = useFormContext();\n\n /**\n * currentModalFilter\n *\n * Single source of truth for the filter edit modal and its rollback snapshot.\n * - name: which filter's modal is currently open (null when closed)\n * - hadValue/previousValue: snapshot of the controlled value taken when the\n * modal is opened; used to restore state if the user cancels/closes without\n * applying.\n *\n * Lifecycle semantics:\n * - showFilterModal(name): capture snapshot (current controlled value) and open\n * the modal for that filter.\n * - closeFilterModal(): if a snapshot exists, roll back un-applied edits by\n * restoring the previous value (setValue) or removing the field (unregister)\n * when it did not exist before; then clear currentModalFilter.\n * - On successful submit (Apply): close and clear currentModalFilter WITHOUT rollback\n * so edits remain committed.\n * - removeFilter(name): unregisters the field; when removing the filter that is\n * currently open, close the modal WITHOUT rollback (since removal is explicit).\n */\n const [currentModalFilter, setCurrentModalFilter] = useState<{\n name: string;\n hadValue: boolean;\n previousValue: unknown;\n } | null>(null);\n\n // Read current filter values from the form as the live edit buffer\n const filterValue = watch('filter', {});\n\n /**\n * getFilterFormFieldName\n *\n * Returns the fully-qualified field path for a given filter name,\n * e.g., `${filterUrlParam}.status`.\n */\n const getFilterFormFieldName = useCallback((name: string) => {\n return `filter.${name}`;\n }, []);\n\n /**\n * getFilterValueByName\n *\n * Returns the committed value for a filter from the controlled state.\n */\n const getFilterValueByName = useCallback(\n (name: string) => {\n return (filterValue as Record<string, unknown>)[name];\n },\n [filterValue],\n );\n\n /** Open the filter edit modal for the given filter name. */\n const showFilterModal = useCallback(\n (name: string) => {\n const prev = getFilterValueByName(name);\n setCurrentModalFilter({\n name,\n hadValue: typeof prev !== 'undefined',\n previousValue: prev,\n });\n },\n [getFilterValueByName],\n );\n\n /** Close the filter edit modal. Rollback un-applied edits to controlled state. */\n const closeFilterModal = useCallback(() => {\n if (currentModalFilter?.name) {\n const fieldName = getFilterFormFieldName(currentModalFilter.name);\n // if the filter had a value, set it back to the previous value,\n // otherwise unregister the field\n if (currentModalFilter.hadValue) {\n setValue(fieldName, currentModalFilter.previousValue);\n } else {\n unregister(fieldName);\n }\n }\n setCurrentModalFilter(null);\n }, [getFilterFormFieldName, currentModalFilter, setValue, unregister]);\n\n /**\n * Auto-close on submit success\n *\n * Close the modal only on new successful submissions. We track the last\n * submitCount and only react when it changes AND the form reports a\n * successful submit. This prevents closing when `isSubmitSuccessful` remains\n * true without a new submit event.\n */\n const lastSubmitCountRef = useRef<number>(0);\n useEffect(() => {\n if (\n formState.submitCount !== lastSubmitCountRef.current &&\n formState.isSubmitSuccessful\n ) {\n // On successful submit, close without rollback\n setCurrentModalFilter(null);\n }\n lastSubmitCountRef.current = formState.submitCount;\n }, [\n formState.submitCount,\n formState.isSubmitSuccessful,\n setCurrentModalFilter,\n ]);\n\n /**\n * activeFilters\n *\n * Filter names derived from the controlled form state. A filter is considered\n * active when a field exists at `filter.<name>`. Newly added filters become\n * active immediately (seeded default), and will be rolled back on cancel.\n */\n const activeFilters = useMemo(() => {\n return config\n .filter((f) => {\n return Object.hasOwn(filterValue ?? {}, f.name);\n })\n .map((f) => {\n return f.name;\n });\n }, [config, filterValue]);\n\n /**\n * unusedFilters\n *\n * Complement of activeFilters (names without a corresponding `filter.<name>`\n * field in the controlled form state).\n */\n const unusedFilters = useMemo(() => {\n return config\n .filter((f) => {\n return !Object.hasOwn(filterValue ?? {}, f.name);\n })\n .map((f) => {\n return f.name;\n });\n }, [config, filterValue]);\n\n /**\n * getRegistryFilterByName\n *\n * Looks up the concrete registry entry for a filter by name, enabling access\n * to typed Form/Display components and other registry-level metadata.\n */\n const getFilterInstanceByName = useCallback(\n (name: string) => {\n return config.find((f) => {\n return f.name === name;\n }) as FilterInstance<unknown, unknown>;\n },\n [config],\n );\n\n /**\n * addFilter\n *\n * Seeds the filter with its registry default value inside the form and opens\n * the modal for immediate editing. No URL writes happen here.\n */\n const addFilter = useCallback(\n (name: string) => {\n const inst = getFilterInstanceByName(name);\n showFilterModal(name);\n setValue(getFilterFormFieldName(name), inst.defaultValue);\n },\n [\n getFilterFormFieldName,\n getFilterInstanceByName,\n setValue,\n showFilterModal,\n ],\n );\n\n /**\n * removeFilter\n *\n * Unregisters the filter field from the form. This immediately removes the\n * filter from the active list since derived state watches the form. It\n * closes the modal without rollback if the removed filter is currently open.\n */\n const removeFilter = useCallback(\n (name: string) => {\n // unregister form field\n unregister(getFilterFormFieldName(name));\n // close filter modal if open\n if (currentModalFilter?.name === name) {\n // Explicit removal: close without rollback\n setCurrentModalFilter(null);\n }\n // trigger form submit (to update filter state)\n triggerSubmit();\n },\n [\n getFilterFormFieldName,\n currentModalFilter,\n setCurrentModalFilter,\n triggerSubmit,\n unregister,\n ],\n );\n\n /**\n * hasError\n *\n * Helper that checks the ex-forms field state for a specific filter and\n * reports whether the field is currently invalid.\n */\n const hasError = useCallback(\n (name: string) => {\n return getFieldState(getFilterFormFieldName(name)).invalid;\n },\n [getFieldState, getFilterFormFieldName],\n );\n\n const contextValue: FiltersContextValue = useMemo(() => {\n return {\n activeFilters,\n addFilter,\n closeFilterModal,\n getFilterFormFieldName,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n modalFilterName: currentModalFilter?.name,\n removeFilter,\n showFilterModal,\n unusedFilters,\n };\n }, [\n activeFilters,\n addFilter,\n closeFilterModal,\n getFilterFormFieldName,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n currentModalFilter,\n removeFilter,\n showFilterModal,\n unusedFilters,\n ]);\n\n return (\n <FiltersContext.Provider value={contextValue}>\n {children}\n </FiltersContext.Provider>\n );\n};\n\n/**\n * useFilters\n *\n * Convenience hook to consume the FiltersContext. Throws a descriptive error\n * when used outside of a FiltersContextProvider to make integration mistakes\n * obvious during development.\n */\nexport const useFilters = (): FiltersContextValue => {\n const ctx = useContext(FiltersContext);\n if (!ctx) {\n throw new Error('useFilters must be used within FiltersContextProvider');\n }\n return ctx;\n};\n\nexport default FiltersContext;\n","import Label from '@fuf-stack/pixels/Label';\n\nimport { useFilters } from './FiltersContext';\n\n/**\n * ActiveFilters\n *\n * Shows the list of currently applied filters as clickable chips that open\n * the edit modal. Each chip can be removed via its close action.\n */\ninterface ActiveFiltersProps {\n /** CSS class name to apply to each label */\n className?: string;\n}\n\nconst ActiveFilters = ({ className = undefined }: ActiveFiltersProps) => {\n const {\n activeFilters,\n getFilterValueByName,\n getFilterInstanceByName,\n hasError,\n removeFilter,\n showFilterModal,\n } = useFilters();\n return (\n <>\n {activeFilters.map((name) => {\n const instance = getFilterInstanceByName(name);\n const value = getFilterValueByName(name);\n\n // get the display component from the instance\n const DisplayComponent = instance.components.Display;\n\n return (\n <button\n key={name}\n aria-label={`Open ${name} filter`}\n type=\"button\"\n onClick={() => {\n showFilterModal(name);\n }}\n >\n <Label\n className={className}\n color={hasError(name) ? 'danger' : 'primary'}\n variant=\"flat\"\n onClose={() => {\n removeFilter(name);\n }}\n >\n {instance.icon}\n <DisplayComponent config={instance.config} value={value} />\n </Label>\n </button>\n );\n })}\n </>\n );\n};\n\nexport default ActiveFilters;\n","import { FaSliders } from 'react-icons/fa6';\n\nimport Menu from '@fuf-stack/pixels/Menu';\n\nimport { useFilters } from './FiltersContext';\n\ninterface AddFilterMenuProps {\n /** CSS class name map for slots */\n classNames?: Partial<{\n addFilterMenuItem: string;\n addFilterMenuButton: string;\n }>;\n}\n\n/**\n * AddFilterMenu\n *\n * Renders a menu trigger that opens a list of addable filters. Selecting an\n * item triggers the parent to seed a default value and open the modal.\n */\nconst AddFilterMenu = ({ classNames = {} }: AddFilterMenuProps) => {\n const { unusedFilters, addFilter, getFilterInstanceByName } = useFilters();\n\n const menuItems = unusedFilters.map((name) => {\n const instance = getFilterInstanceByName(name);\n const config = instance.config as { text?: string };\n const label = config?.text ?? name;\n return {\n key: name,\n icon: instance.icon,\n label,\n onClick: () => {\n addFilter(name);\n },\n };\n });\n\n return (\n <Menu\n isDisabled={!menuItems.length}\n items={menuItems}\n placement=\"bottom-start\"\n className={{\n item: classNames.addFilterMenuItem,\n trigger: classNames.addFilterMenuButton,\n }}\n triggerButtonProps={{\n 'aria-label': 'Add Filter',\n 'data-testid': 'add_filter_button',\n disableRipple: true,\n size: 'sm',\n variant: 'bordered',\n }}\n >\n <FaSliders />\n Filter\n </Menu>\n );\n};\n\nexport default AddFilterMenu;\n","import { Suspense } from 'react';\nimport { PiSlidersHorizontalBold } from 'react-icons/pi';\n\nimport Button from '@fuf-stack/pixels/Button';\nimport Modal from '@fuf-stack/pixels/Modal';\nimport SubmitButton from '@fuf-stack/uniform/SubmitButton';\n\nimport { useFilters } from './FiltersContext';\n\ninterface FilterModalProps {\n classNames?: Partial<{\n header: string;\n footer: string;\n body: string;\n }>;\n}\n\nconst FilterModal = ({ classNames = {} }: FilterModalProps) => {\n const {\n closeFilterModal,\n getFilterFormFieldName,\n getFilterInstanceByName,\n modalFilterName,\n removeFilter,\n } = useFilters();\n\n // don't render if no filter is open\n if (!modalFilterName) {\n return null;\n }\n\n const instance = getFilterInstanceByName(modalFilterName);\n const config = instance.config as { text?: string };\n\n // get the form component from the instance\n const FormComponent = instance.components.Form;\n\n return (\n <Modal\n isOpen\n onClose={closeFilterModal}\n className={{\n body: classNames.body,\n footer: classNames.footer,\n header: classNames.header,\n }}\n footer={\n <>\n <Button\n ariaLabel=\"Remove filter\"\n color=\"danger\"\n testId=\"remove_filter_button\"\n variant=\"flat\"\n onClick={() => {\n removeFilter(modalFilterName);\n }}\n >\n Remove\n </Button>\n <SubmitButton ariaLabel=\"Apply filter\" testId=\"apply_filter_button\">\n Apply Filter\n </SubmitButton>\n </>\n }\n header={\n <>\n {instance.icon ?? <PiSlidersHorizontalBold />}\n <div>{`${config?.text ?? modalFilterName} Filter`}</div>\n </>\n }\n >\n <Suspense>\n <FormComponent\n config={config}\n fieldName={getFilterFormFieldName(modalFilterName)}\n />\n </Suspense>\n </Modal>\n );\n};\n\nexport default FilterModal;\n","import { useState } from 'react';\nimport { FaSearch } from 'react-icons/fa';\n\nimport { motion } from '@fuf-stack/pixel-motion';\nimport Button from '@fuf-stack/pixels/Button';\nimport { useFormContext } from '@fuf-stack/uniform/hooks/useFormContext';\nimport Input from '@fuf-stack/uniform/Input';\nimport SubmitButton from '@fuf-stack/uniform/SubmitButton';\n\nexport type SearchConfiguration =\n | boolean\n | {\n /** Placeholder shown in the search input */\n placeholder?: string;\n };\n\ninterface SearchInputProps {\n /** Slots class names passed from parent variants */\n classNames?: Partial<{\n searchWrapper: string;\n searchShowButton: string;\n searchMotionDiv: string;\n searchInput: string;\n searchInputWrapper: string;\n searchSubmitButton: string;\n }>;\n /** Search configuration */\n config: SearchConfiguration;\n}\n\n/**\n * SearchInput\n *\n * By default renders only a search button. When clicked, the text input animates in\n * and a trailing submit button is shown.\n */\nconst SearchInput = ({ classNames = {}, config }: SearchInputProps) => {\n const { formState, setFocus, triggerSubmit } = useFormContext();\n\n // Auto-open if there is an initial or externally set search value\n const isInitiallyVisible = !!formState?.defaultValues?.search;\n const [isVisible, setIsVisible] = useState(isInitiallyVisible);\n\n const placeholder =\n typeof config === 'object' ? config.placeholder : undefined;\n\n return (\n <div className={classNames.searchWrapper}>\n {!isVisible && (\n <Button\n ariaLabel=\"Show search input\"\n className={classNames.searchShowButton}\n icon={<FaSearch />}\n size=\"sm\"\n testId=\"show_search_input_button\"\n variant=\"bordered\"\n onClick={() => {\n setIsVisible(true);\n }}\n />\n )}\n {isVisible ? (\n <motion.div\n key=\"search-input\"\n animate={{ opacity: 1 }}\n className={classNames.searchMotionDiv}\n // if the input was not initially visible, animate in\n initial={!isInitiallyVisible ? { opacity: 0.5 } : false}\n onAnimationComplete={() => {\n // if the input was not initially visible, focus it\n if (!isInitiallyVisible) {\n setFocus('search');\n }\n }}\n transition={{\n duration: 0.3,\n ease: 'circOut',\n }}\n >\n <Input\n clearable\n debounceDelay={0}\n name=\"search\"\n placeholder={placeholder}\n size=\"sm\"\n className={{\n input: classNames.searchInput,\n inputWrapper: classNames.searchInputWrapper,\n }}\n // submit on clear\n onClear={() => {\n triggerSubmit();\n }}\n />\n <SubmitButton\n ariaLabel=\"Submit search\"\n // eslint-disable-next-line react/no-children-prop\n children={null}\n className={classNames.searchSubmitButton}\n color=\"primary\"\n icon={<FaSearch />}\n size=\"sm\"\n testId=\"submit_search_button\"\n />\n </motion.div>\n ) : null}\n </div>\n );\n};\n\nexport default SearchInput;\n","import type { TVClassName } from '@fuf-stack/pixel-utils';\nimport type { VetoInput } from '@fuf-stack/veto';\nimport type { ReactNode } from 'react';\nimport type { FiltersConfiguration } from './filters/types';\nimport type { SearchConfiguration } from './Subcomponents/SearchInput';\n\nimport createDebug from 'debug';\n\nimport { tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\nimport Form from '@fuf-stack/uniform/Form';\n\nimport { useFilterValidation } from './hooks/useFilterValidation';\nimport ActiveFilters from './Subcomponents/ActiveFilters';\nimport AddFilterMenu from './Subcomponents/AddFilterMenu';\nimport FilterModal from './Subcomponents/FilterModal';\nimport { FiltersContextProvider } from './Subcomponents/FiltersContext';\nimport SearchInput from './Subcomponents/SearchInput';\n\nconst debug = createDebug('megapixels:Filter');\n\n// filter styling variants\nexport const filterVariants = tv({\n slots: {\n // outer wrapper\n base: 'flex flex-auto flex-col',\n // add filter menu trigger button\n addFilterMenuButton: '',\n // add filter menu item\n addFilterMenuItem: '',\n // active filter label\n activeFilterLabel: 'h-8 cursor-pointer rounded-md dark:text-foreground',\n // filter modal body\n filterModalBody: '',\n // filter modal header\n filterModalHeader: 'flex items-center gap-3 text-default-700',\n // filter modal footer\n filterModalFooter: 'justify-between',\n // form element\n form: 'mb-3 flex flex-wrap gap-3',\n // search input field\n searchInput: '',\n // search input wrapper (inner control)\n searchInputWrapper: '',\n // search motion container\n searchMotionDiv: 'flex w-72 gap-2',\n // search show button\n searchShowButton: '',\n // search submit button\n searchSubmitButton: '',\n // search wrapper\n searchWrapper: 'flex items-center',\n },\n});\n\ntype ClassName = TVClassName<typeof filterVariants>;\n\nexport interface FilterValues {\n search?: string;\n filter?: string | Record<string, unknown> | null;\n}\n\nexport type FilterChildRenderFn = (values: {\n search?: string;\n filter?: Record<string, unknown>;\n}) => ReactNode;\n\n/**\n * Filter\n *\n * Controlled, form-driven filter UI.\n *\n * Responsibilities\n * - Derives initial form values from the controlled `values` prop\n * - Builds a composite validation schema from the filter registry (and optional search)\n * - Exposes ergonomic UI: active filters list, add/remove actions, and per-filter modal\n * - Commits changes by invoking the controlled `onChange` callback on submit\n *\n * Structure\n * - Owns an ex-forms `Form` that wraps the entire filter experience\n * - Optionally renders a search input bound to the `search` field\n * - Renders ActiveFilters, AddFilterMenu, and FilterModal inside a shared context\n * - Optionally renders children as a render-prop with the resolved `values`\n */\nexport interface FilterProps {\n /** Optional render-prop that receives the resolved, controlled values */\n children?: FilterChildRenderFn;\n /** CSS class name */\n className?: ClassName;\n /** Configuration of the filter */\n config: {\n /**\n * Declarative filter configuration. Each entry ties a logical name to a\n * registry filter type and (optionally) per-usage config overrides.\n */\n filters: FiltersConfiguration;\n /** Optional configuration for search field */\n search?: SearchConfiguration;\n };\n /** ex-forms form instance name. Defaults to \"filterComponentForm\". */\n formName?: string;\n /** Controlled setter invoked on submit with the next canonical values */\n onChange: (nextValues: FilterValues) => void;\n /** Controlled committed state: the canonical `search` and `filter` values */\n values: FilterValues;\n}\n\n/**\n * Renders the filter UI bound to a single ex-forms `Form`.\n * The form is the source of truth during user interaction; the committed\n * state is controlled by the parent via `values`/`onChange`.\n */\nconst Filter = ({\n children = undefined,\n className = undefined,\n config,\n formName = 'filterComponentForm',\n onChange,\n values,\n}: FilterProps) => {\n // Submit handler: map form state back into the controlled `values` shape\n const handleSubmit = (nextValues: Record<string, unknown>) => {\n debug('handleSubmit', { nextValues });\n onChange(nextValues as FilterValues);\n };\n\n // Build validation schema for all configured filters (and optional search)\n const validation = useFilterValidation(\n config.filters,\n Boolean(config.search),\n );\n\n // validate controlled values are valid\n const {\n data: valuesValidated,\n errors,\n success,\n } = validation.validate(values as VetoInput);\n\n // classNames from slots\n const variants = filterVariants();\n const classNames = variantsToClassNames(variants, className, 'base');\n\n debug('render', {\n props: { config, values },\n validation: { errors, success, valuesValidated },\n });\n\n return (\n <div className={classNames.base}>\n {/*\n Uniform Form wrapper\n - initialValues derive from controlled props (with optional defaults)\n - validation is built from the registry for all configured filters\n - onSubmit maps form values back into values/onChange\n */}\n <Form\n className={classNames.form}\n // disable debug mode for now\n debug={{ disable: true }}\n initialValues={valuesValidated ?? {}}\n name={formName}\n onSubmit={handleSubmit}\n validation={validation}\n >\n {/* Render search if search config is provided */}\n {config.search ? (\n <SearchInput\n config={config.search}\n classNames={{\n searchInput: classNames.searchInput,\n searchInputWrapper: classNames.searchInputWrapper,\n searchMotionDiv: classNames.searchMotionDiv,\n searchShowButton: classNames.searchShowButton,\n searchSubmitButton: classNames.searchSubmitButton,\n searchWrapper: classNames.searchWrapper,\n }}\n />\n ) : null}\n {/*\n FiltersContextProvider exposes a minimal API for the UI layer:\n - activeFilters/unusedFilters by name\n - helpers to get merged config, value, components, and field names\n - methods to add/remove filters and show/close the modal\n */}\n <FiltersContextProvider config={config.filters}>\n <ActiveFilters className={classNames.activeFilterLabel} />\n <AddFilterMenu\n classNames={{\n addFilterMenuButton: classNames.addFilterMenuButton,\n addFilterMenuItem: classNames.addFilterMenuItem,\n }}\n />\n <FilterModal\n classNames={{\n body: classNames.filterModalBody,\n footer: classNames.filterModalFooter,\n header: classNames.filterModalHeader,\n }}\n />\n </FiltersContextProvider>\n </Form>\n {/* Children can consume derived search string and parsed filter object */}\n {children?.(valuesValidated ?? {})}\n </div>\n );\n};\n\nexport default Filter;\n","import type { FilterDefinition, FilterFactory } from './types';\n\n/**\n * createFilter\n *\n * Builds a filter factory from a static FilterDefinition. The returned factory\n * accepts a usage descriptor (name/icon and optional partial config) and\n * produces a concrete FilterInstance with:\n * - merged config (shallow: definition.defaults.config overlaid by overrides)\n * - Form/Display components\n * - validate function (forwarded from the definition)\n * - defaultValue (forwarded from the definition)\n * - name and icon for UI integration\n *\n * @typeParam Config - Configuration object shape for the filter\n * @typeParam Value - Runtime value type for the filter\n * @param definition - Static description of the filter (components, defaults, validate)\n * @returns FilterFactory that creates FilterInstance<Config, Value>\n */\nconst createFilter = <Config, Value>(\n definition: FilterDefinition<Config, Value>,\n): FilterFactory<Config, Value> => {\n return ({ name, icon, config }) => {\n return {\n components: definition.components,\n config: { ...definition.defaults.config, ...(config ?? {}) } as Config,\n defaultValue: definition.defaults.value,\n icon,\n name,\n validation: definition.validation,\n };\n };\n};\n\nexport default createFilter;\n","import type { FilterDisplayProps } from '../types';\nimport type { Config, Value } from './schema';\n\n/**\n * Read-only presentation for the boolean filter.\n * Displays human-readable text based on the current boolean `value`\n * and the provided `config` strings.\n */\nconst Display = ({\n value,\n config: { text, textPrefix, textNoWord },\n}: FilterDisplayProps<Config, Value>) => {\n if (typeof value === 'boolean') {\n return (\n <>\n {`${value ? textPrefix : `${textPrefix} ${textNoWord ?? 'no'}`} ${text}`}\n </>\n );\n }\n return <>{`${text}...`}</>;\n};\n\nexport default Display;\n","import type { FilterFormProps } from '../types';\nimport type { Config } from './schema';\n\nimport Switch from '@fuf-stack/uniform/Switch';\n\n/**\n * Renders the form control for the boolean filter.\n * Uses a `Switch` to toggle the boolean value and composes\n * the label from the provided `config` and `fieldName`.\n */\nconst Form = ({\n fieldName,\n config: { text, textPrefix },\n}: FilterFormProps<Config>) => {\n return <Switch label={`${textPrefix} ${text}`} name={fieldName} />;\n};\n\nexport default Form;\n","import type { vInfer } from '@fuf-stack/veto';\n\nimport { boolean, object, string } from '@fuf-stack/veto';\n\n/** configuration of the filter */\nexport const config = object({\n /**\n * Human‑readable label used in the UI (e.g. in the chip and modal header).\n * Examples: \"Magical\", \"Haunted\"\n */\n text: string(),\n /**\n * Optional word shown before the label when building sentence‑like chips.\n * Examples: \"is\" → \"is Magical\"\n */\n textPrefix: string().optional(),\n /**\n * Optional negation word used when a boolean value is false.\n * Examples: \"not\" → \"is not Magical\"\n */\n textNoWord: string().optional(),\n});\n\n/** validate the filter value */\nexport const validate = (_config?: Config) => {\n return boolean().optional();\n};\n\nexport type Config = vInfer<typeof config>;\nexport type Value = vInfer<ReturnType<typeof validate>>;\n","/* eslint-disable import-x/prefer-default-export */\n\nimport type { Config, Value } from './schema';\n\nimport createFilter from '../createFilter';\nimport Display from './Display';\nimport Form from './Form';\nimport { validate } from './schema';\n\n/**\n * Boolean filter definition for the Filter system.\n * Provides Display and Form components, default value/config, and validation.\n *\n * Defaults:\n * - value: true\n * - config: { text: 'Active', textPrefix: 'is', textNoWord: 'no' }\n *\n * @see Display\n * @see Form\n * @see validate\n */\nexport const boolean = createFilter<Config, Value>({\n components: { Display, Form },\n defaults: {\n value: true,\n config: { text: 'Active', textPrefix: 'is', textNoWord: 'no' },\n },\n validation: validate,\n});\n","import type { FilterDisplayProps } from '../types';\nimport type { Config, Value } from './schema';\n\n/**\n * Read-only presentation for the checkboxes filter.\n * Resolves and displays selected option labels based on `value` and `config`.\n * Supports string, ReactNode, and function labels (mode: 'display').\n */\nconst Display = ({\n value,\n config: { text, options },\n}: FilterDisplayProps<Config, Value>) => {\n if (value && value.length > 0) {\n return (\n <span className=\"flex items-center gap-1\">\n {text} is\n {value.map((val) => {\n const option = options.find((op) => {\n return op.value === val;\n });\n const label = option?.label ?? val;\n const resolvedLabel =\n typeof label === 'function' ? label('display') : label;\n return <span key={val}>{resolvedLabel}</span>;\n })}\n </span>\n );\n }\n return `${text} is ...`;\n};\n\nexport default Display;\n","import type { FilterFormProps } from '../types';\nimport type { Config } from './schema';\n\nimport Checkboxes from '@fuf-stack/uniform/Checkboxes';\n\n/**\n * Renders the form control for the checkboxes filter.\n * Uses a `Checkboxes` to select multiple options.\n * Resolves function labels with 'form' mode.\n */\nconst Form = ({ fieldName, config }: FilterFormProps<Config>) => {\n const resolvedOptions = config.options.map((option) => {\n return {\n ...option,\n label:\n typeof option.label === 'function'\n ? option.label('form')\n : option.label,\n };\n });\n\n return <Checkboxes name={fieldName} options={resolvedOptions} />;\n};\n\nexport default Form;\n","import type { vInfer } from '@fuf-stack/veto';\nimport type { ReactNode } from 'react';\n\nimport { any, array, object, refineArray, string } from '@fuf-stack/veto';\n\n/** configuration of the filter */\nexport const config = object({\n /**\n * Human‑readable label used in the UI (e.g. label and modal header).\n * Example: \"Snacks\", \"Mood\"\n */\n text: string(),\n /**\n * Options rendered as multiple checkboxes. Each option needs a `label`\n * (what the user sees) and a `value` (what is written into the form state).\n * Label can be a string, React node, or a function that receives mode\n * ('form' or 'display') and returns a React node.\n */\n options: array(object({ label: any(), value: string() })),\n});\n\n/** Type-safe Config that overrides label to support ReactNode or function */\nexport type Config = Omit<vInfer<typeof config>, 'options'> & {\n options: {\n label: ReactNode | ((mode: 'form' | 'display') => ReactNode);\n value: string;\n }[];\n};\n\n/** validate the filter value */\nexport const validate = (cfg?: Config) => {\n return refineArray(array(string()).optional())({\n unique: true,\n custom: (values, ctx) => {\n if (!cfg) {\n return;\n }\n values.forEach((value) => {\n if (\n !cfg.options.find((option) => {\n return option?.value === value;\n })\n ) {\n ctx.addIssue({\n code: 'custom',\n message: `Invalid value: ${value}`,\n });\n }\n });\n },\n });\n};\n\nexport type Value = vInfer<ReturnType<typeof validate>>;\n","/* eslint-disable import-x/prefer-default-export */\n\nimport type { Config, Value } from './schema';\n\nimport createFilter from '../createFilter';\nimport Display from './Display';\nimport Form from './Form';\nimport { validate } from './schema';\n\n/**\n * Checkboxes filter definition for the Filter system.\n * Provides Display and Form components, default value/config, and validation.\n *\n * Defaults:\n * - value: []\n * - config: { text: 'Options', options: [] }\n *\n * @see Display\n * @see Form\n * @see validate\n */\nexport const checkboxes = createFilter<Config, Value>({\n components: { Display, Form },\n defaults: { value: [], config: { text: 'Options', options: [] } },\n validation: validate,\n});\n","import Filter from './Filter';\nimport { boolean } from './filters/boolean/boolean';\nimport { checkboxes } from './filters/checkboxes/checkboxes';\n\n// export types\nexport type * from './filters/types';\n\n// export helpers\nexport { default as createFilter } from './filters/createFilter';\n\n// export all filters\nexport const filters = {\n boolean,\n checkboxes,\n};\n\n// export everything from the Filter component (types and filterVariants)\nexport * from './Filter';\n\n// export the Filter component as default\nexport default Filter;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-C-2_lJp0.d.cts","names":[],"sources":["../src/Filter/filters/checkboxes/schema.ts","../src/Filter/filters/types.ts","../src/Filter/Subcomponents/SearchInput.tsx","../src/Filter/Filter.tsx","../src/Filter/filters/createFilter.ts","../src/Filter/index.ts"],"sourcesContent":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-OWKeKysC.d.ts","names":[],"sources":["../src/Filter/filters/checkboxes/schema.ts","../src/Filter/filters/types.ts","../src/Filter/Subcomponents/SearchInput.tsx","../src/Filter/Filter.tsx","../src/Filter/filters/createFilter.ts","../src/Filter/index.ts"],"sourcesContent":[],"mappings":"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"}