@fuf-stack/megapixels 0.11.25 → 0.11.27

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.
Files changed (30) hide show
  1. package/dist/Filter/index.cjs +1 -1
  2. package/dist/Filter/index.d.cts +1 -1
  3. package/dist/Filter/index.d.ts +1 -1
  4. package/dist/Filter/index.js +1 -1
  5. package/dist/{Filter-BVwu1kNx.cjs → Filter-B_YqTFA5.cjs} +23 -29
  6. package/dist/Filter-B_YqTFA5.cjs.map +1 -0
  7. package/dist/{Filter-MoxrK8MI.js → Filter-DHNzbevz.js} +23 -23
  8. package/dist/{Filter-MoxrK8MI.js.map → Filter-DHNzbevz.js.map} +1 -1
  9. package/dist/Notification/index.cjs +1 -1
  10. package/dist/Notification/index.d.cts +1 -1
  11. package/dist/Notification/index.d.ts +1 -1
  12. package/dist/Notification/index.js +1 -1
  13. package/dist/{Notification-B-G4OVD2.js → Notification-5tyFF-87.js} +1 -1
  14. package/dist/{Notification-B-G4OVD2.js.map → Notification-5tyFF-87.js.map} +1 -1
  15. package/dist/{Notification-BjftuLye.cjs → Notification-ClLRWj0j.cjs} +1 -2
  16. package/dist/{Notification-BjftuLye.cjs.map → Notification-ClLRWj0j.cjs.map} +1 -1
  17. package/dist/{index-CJCs9Cxu.d.cts → index-BkliAQ5x.d.cts} +1 -1
  18. package/dist/{index-CJCs9Cxu.d.cts.map → index-BkliAQ5x.d.cts.map} +1 -1
  19. package/dist/{index-7N5og-TT.d.ts → index-DNAyXW3U.d.ts} +1 -1
  20. package/dist/{index-7N5og-TT.d.ts.map → index-DNAyXW3U.d.ts.map} +1 -1
  21. package/dist/{index-DMd9TyqF.d.cts → index-DRyBPfQT.d.cts} +1 -1
  22. package/dist/{index-DMd9TyqF.d.cts.map → index-DRyBPfQT.d.cts.map} +1 -1
  23. package/dist/{index-DaLo1TQx.d.ts → index-DRyBPfQT.d.ts} +1 -1
  24. package/dist/{index-DaLo1TQx.d.ts.map → index-DRyBPfQT.d.ts.map} +1 -1
  25. package/dist/index.cjs +2 -2
  26. package/dist/index.d.cts +2 -2
  27. package/dist/index.d.ts +2 -2
  28. package/dist/index.js +2 -2
  29. package/package.json +6 -6
  30. package/dist/Filter-BVwu1kNx.cjs.map +0 -1
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_Filter = require("../Filter-BVwu1kNx.cjs");
5
+ const require_Filter = require("../Filter-B_YqTFA5.cjs");
6
6
  exports.createFilter = require_Filter.createFilter;
7
7
  exports.default = require_Filter.Filter_default;
8
8
  exports.filterVariants = require_Filter.filterVariants;
@@ -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-CJCs9Cxu.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-BkliAQ5x.cjs";
2
2
  export { FilterChildRenderFn, type FilterDefinition, type FilterDisplayProps, type FilterFactory, type FilterFormProps, type FilterInstance, FilterProps, FilterValues, type 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-7N5og-TT.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-DNAyXW3U.js";
2
2
  export { FilterChildRenderFn, type FilterDefinition, type FilterDisplayProps, type FilterFactory, type FilterFormProps, type FilterInstance, FilterProps, FilterValues, type FiltersConfiguration, createFilter, Filter as default, filterVariants, filters };
@@ -1,2 +1,2 @@
1
- import { i as filterVariants, n as filters, r as createFilter, t as Filter_default } from "../Filter-MoxrK8MI.js";
1
+ import { i as filterVariants, n as filters, r as createFilter, t as Filter_default } from "../Filter-DHNzbevz.js";
2
2
  export { createFilter, Filter_default as default, filterVariants, filters };
@@ -311,17 +311,17 @@ const ActiveFilters = ({ className = void 0 }) => {
311
311
  const DisplayComponent = instance.components.Display;
312
312
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
313
313
  "aria-label": `Open ${name} filter`,
314
- type: "button",
315
314
  onClick: () => {
316
315
  showFilterModal(name);
317
316
  },
317
+ type: "button",
318
318
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_fuf_stack_pixels_Label.default, {
319
319
  className,
320
320
  color: hasError(name) ? "danger" : "primary",
321
- variant: "flat",
322
321
  onClose: () => {
323
322
  removeFilter(name);
324
323
  },
324
+ variant: "flat",
325
325
  children: [instance.icon, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DisplayComponent, {
326
326
  config: instance.config,
327
327
  value
@@ -353,13 +353,13 @@ const AddFilterMenu = ({ classNames = {} }) => {
353
353
  };
354
354
  });
355
355
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_fuf_stack_pixels_Menu.default, {
356
- isDisabled: !menuItems.length,
357
- items: menuItems,
358
- placement: "bottom-start",
359
356
  className: {
360
357
  item: classNames.addFilterMenuItem,
361
358
  trigger: classNames.addFilterMenuButton
362
359
  },
360
+ isDisabled: !menuItems.length,
361
+ items: menuItems,
362
+ placement: "bottom-start",
363
363
  triggerButtonProps: {
364
364
  "aria-label": "Add Filter",
365
365
  "data-testid": "add_filter_button",
@@ -379,8 +379,6 @@ const FilterModal = ({ classNames = {} }) => {
379
379
  const config = instance.config;
380
380
  const FormComponent = instance.components.Form;
381
381
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_pixels_Modal.default, {
382
- isOpen: true,
383
- onClose: closeFilterModal,
384
382
  className: {
385
383
  body: classNames.body,
386
384
  footer: classNames.footer,
@@ -389,11 +387,11 @@ const FilterModal = ({ classNames = {} }) => {
389
387
  footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_pixels_Button.default, {
390
388
  ariaLabel: "Remove filter",
391
389
  color: "danger",
392
- testId: "remove_filter_button",
393
- variant: "flat",
394
390
  onClick: () => {
395
391
  removeFilter(modalFilterName);
396
392
  },
393
+ testId: "remove_filter_button",
394
+ variant: "flat",
397
395
  children: "Remove"
398
396
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_uniform_SubmitButton.default, {
399
397
  ariaLabel: "Apply filter",
@@ -401,6 +399,8 @@ const FilterModal = ({ classNames = {} }) => {
401
399
  children: "Apply Filter"
402
400
  })] }),
403
401
  header: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [instance.icon ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiSlidersHorizontalBold, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: `${config?.text ?? modalFilterName} Filter` })] }),
402
+ isOpen: true,
403
+ onClose: closeFilterModal,
404
404
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FormComponent, {
405
405
  config,
406
406
  fieldName: getFilterFormFieldName(modalFilterName)
@@ -426,12 +426,12 @@ const SearchInput = ({ classNames = {}, config }) => {
426
426
  ariaLabel: "Show search input",
427
427
  className: classNames.searchShowButton,
428
428
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_fa.FaSearch, {}),
429
- size: "sm",
430
- testId: "show_search_input_button",
431
- variant: "bordered",
432
429
  onClick: () => {
433
430
  setIsVisible(true);
434
- }
431
+ },
432
+ size: "sm",
433
+ testId: "show_search_input_button",
434
+ variant: "bordered"
435
435
  }), isVisible ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_fuf_stack_pixel_motion.motion.div, {
436
436
  animate: { opacity: 1 },
437
437
  className: classNames.searchMotionDiv,
@@ -447,23 +447,23 @@ const SearchInput = ({ classNames = {}, config }) => {
447
447
  clearable: true,
448
448
  debounceDelay: 0,
449
449
  name: "search",
450
+ onClear: () => {
451
+ triggerSubmit();
452
+ },
450
453
  placeholder,
451
- size: "sm",
452
454
  className: {
453
455
  input: classNames.searchInput,
454
456
  inputWrapper: classNames.searchInputWrapper
455
457
  },
456
- onClear: () => {
457
- triggerSubmit();
458
- }
458
+ size: "sm"
459
459
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fuf_stack_uniform_SubmitButton.default, {
460
- ariaLabel: "Submit search",
461
- children: null,
462
460
  className: classNames.searchSubmitButton,
463
461
  color: "primary",
464
462
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_fa.FaSearch, {}),
465
463
  size: "sm",
466
- testId: "submit_search_button"
464
+ testId: "submit_search_button",
465
+ ariaLabel: "Submit search",
466
+ children: null
467
467
  })]
468
468
  }, "search-input") : null]
469
469
  });
@@ -521,7 +521,6 @@ const Filter = ({ children = void 0, className = void 0, config, formName = "fil
521
521
  onSubmit: handleSubmit,
522
522
  validation,
523
523
  children: [config.search ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchInput, {
524
- config: config.search,
525
524
  classNames: {
526
525
  searchInput: classNames.searchInput,
527
526
  searchInputWrapper: classNames.searchInputWrapper,
@@ -529,7 +528,8 @@ const Filter = ({ children = void 0, className = void 0, config, formName = "fil
529
528
  searchShowButton: classNames.searchShowButton,
530
529
  searchSubmitButton: classNames.searchSubmitButton,
531
530
  searchWrapper: classNames.searchWrapper
532
- }
531
+ },
532
+ config: config.search
533
533
  }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(FiltersContextProvider, {
534
534
  config: config.filters,
535
535
  children: [
@@ -758,12 +758,6 @@ Object.defineProperty(exports, "Filter_default", {
758
758
  return Filter_default;
759
759
  }
760
760
  });
761
- Object.defineProperty(exports, "__toESM", {
762
- enumerable: true,
763
- get: function() {
764
- return __toESM;
765
- }
766
- });
767
761
  Object.defineProperty(exports, "createFilter", {
768
762
  enumerable: true,
769
763
  get: function() {
@@ -783,4 +777,4 @@ Object.defineProperty(exports, "filters", {
783
777
  }
784
778
  });
785
779
 
786
- //# sourceMappingURL=Filter-BVwu1kNx.cjs.map
780
+ //# sourceMappingURL=Filter-B_YqTFA5.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Filter-B_YqTFA5.cjs","names":["Label","Menu","FaSliders","Modal","Button","SubmitButton","PiSlidersHorizontalBold","Suspense","Button","FaSearch","motion","Input","SubmitButton","debug","Form","Display","Form","Switch","config","validate","validate","Checkboxes"],"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 onClick={() => {\n showFilterModal(name);\n }}\n type=\"button\"\n >\n <Label\n className={className}\n color={hasError(name) ? 'danger' : 'primary'}\n onClose={() => {\n removeFilter(name);\n }}\n variant=\"flat\"\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 className={{\n item: classNames.addFilterMenuItem,\n trigger: classNames.addFilterMenuButton,\n }}\n isDisabled={!menuItems.length}\n items={menuItems}\n placement=\"bottom-start\"\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 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 onClick={() => {\n removeFilter(modalFilterName);\n }}\n testId=\"remove_filter_button\"\n variant=\"flat\"\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 isOpen\n onClose={closeFilterModal}\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 onClick={() => {\n setIsVisible(true);\n }}\n size=\"sm\"\n testId=\"show_search_input_button\"\n variant=\"bordered\"\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 // submit on clear\n onClear={() => {\n triggerSubmit();\n }}\n placeholder={placeholder}\n className={{\n input: classNames.searchInput,\n inputWrapper: classNames.searchInputWrapper,\n }}\n size=\"sm\"\n />\n <SubmitButton\n className={classNames.searchSubmitButton}\n color=\"primary\"\n icon={<FaSearch />}\n size=\"sm\"\n testId=\"submit_search_button\"\n ariaLabel=\"Submit search\"\n // eslint-disable-next-line react/no-children-prop\n children={null}\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);\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 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 config={config.search}\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 ?? {}) },\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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"}
@@ -279,17 +279,17 @@ const ActiveFilters = ({ className = void 0 }) => {
279
279
  const DisplayComponent = instance.components.Display;
280
280
  return /* @__PURE__ */ jsx("button", {
281
281
  "aria-label": `Open ${name} filter`,
282
- type: "button",
283
282
  onClick: () => {
284
283
  showFilterModal(name);
285
284
  },
285
+ type: "button",
286
286
  children: /* @__PURE__ */ jsxs(Label, {
287
287
  className,
288
288
  color: hasError(name) ? "danger" : "primary",
289
- variant: "flat",
290
289
  onClose: () => {
291
290
  removeFilter(name);
292
291
  },
292
+ variant: "flat",
293
293
  children: [instance.icon, /* @__PURE__ */ jsx(DisplayComponent, {
294
294
  config: instance.config,
295
295
  value
@@ -321,13 +321,13 @@ const AddFilterMenu = ({ classNames = {} }) => {
321
321
  };
322
322
  });
323
323
  return /* @__PURE__ */ jsxs(Menu, {
324
- isDisabled: !menuItems.length,
325
- items: menuItems,
326
- placement: "bottom-start",
327
324
  className: {
328
325
  item: classNames.addFilterMenuItem,
329
326
  trigger: classNames.addFilterMenuButton
330
327
  },
328
+ isDisabled: !menuItems.length,
329
+ items: menuItems,
330
+ placement: "bottom-start",
331
331
  triggerButtonProps: {
332
332
  "aria-label": "Add Filter",
333
333
  "data-testid": "add_filter_button",
@@ -347,8 +347,6 @@ const FilterModal = ({ classNames = {} }) => {
347
347
  const config = instance.config;
348
348
  const FormComponent = instance.components.Form;
349
349
  return /* @__PURE__ */ jsx(Modal, {
350
- isOpen: true,
351
- onClose: closeFilterModal,
352
350
  className: {
353
351
  body: classNames.body,
354
352
  footer: classNames.footer,
@@ -357,11 +355,11 @@ const FilterModal = ({ classNames = {} }) => {
357
355
  footer: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
358
356
  ariaLabel: "Remove filter",
359
357
  color: "danger",
360
- testId: "remove_filter_button",
361
- variant: "flat",
362
358
  onClick: () => {
363
359
  removeFilter(modalFilterName);
364
360
  },
361
+ testId: "remove_filter_button",
362
+ variant: "flat",
365
363
  children: "Remove"
366
364
  }), /* @__PURE__ */ jsx(SubmitButton, {
367
365
  ariaLabel: "Apply filter",
@@ -369,6 +367,8 @@ const FilterModal = ({ classNames = {} }) => {
369
367
  children: "Apply Filter"
370
368
  })] }),
371
369
  header: /* @__PURE__ */ jsxs(Fragment, { children: [instance.icon ?? /* @__PURE__ */ jsx(PiSlidersHorizontalBold, {}), /* @__PURE__ */ jsx("div", { children: `${config?.text ?? modalFilterName} Filter` })] }),
370
+ isOpen: true,
371
+ onClose: closeFilterModal,
372
372
  children: /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(FormComponent, {
373
373
  config,
374
374
  fieldName: getFilterFormFieldName(modalFilterName)
@@ -394,12 +394,12 @@ const SearchInput = ({ classNames = {}, config }) => {
394
394
  ariaLabel: "Show search input",
395
395
  className: classNames.searchShowButton,
396
396
  icon: /* @__PURE__ */ jsx(FaSearch, {}),
397
- size: "sm",
398
- testId: "show_search_input_button",
399
- variant: "bordered",
400
397
  onClick: () => {
401
398
  setIsVisible(true);
402
- }
399
+ },
400
+ size: "sm",
401
+ testId: "show_search_input_button",
402
+ variant: "bordered"
403
403
  }), isVisible ? /* @__PURE__ */ jsxs(motion.div, {
404
404
  animate: { opacity: 1 },
405
405
  className: classNames.searchMotionDiv,
@@ -415,23 +415,23 @@ const SearchInput = ({ classNames = {}, config }) => {
415
415
  clearable: true,
416
416
  debounceDelay: 0,
417
417
  name: "search",
418
+ onClear: () => {
419
+ triggerSubmit();
420
+ },
418
421
  placeholder,
419
- size: "sm",
420
422
  className: {
421
423
  input: classNames.searchInput,
422
424
  inputWrapper: classNames.searchInputWrapper
423
425
  },
424
- onClear: () => {
425
- triggerSubmit();
426
- }
426
+ size: "sm"
427
427
  }), /* @__PURE__ */ jsx(SubmitButton, {
428
- ariaLabel: "Submit search",
429
- children: null,
430
428
  className: classNames.searchSubmitButton,
431
429
  color: "primary",
432
430
  icon: /* @__PURE__ */ jsx(FaSearch, {}),
433
431
  size: "sm",
434
- testId: "submit_search_button"
432
+ testId: "submit_search_button",
433
+ ariaLabel: "Submit search",
434
+ children: null
435
435
  })]
436
436
  }, "search-input") : null]
437
437
  });
@@ -489,7 +489,6 @@ const Filter = ({ children = void 0, className = void 0, config, formName = "fil
489
489
  onSubmit: handleSubmit,
490
490
  validation,
491
491
  children: [config.search ? /* @__PURE__ */ jsx(SearchInput, {
492
- config: config.search,
493
492
  classNames: {
494
493
  searchInput: classNames.searchInput,
495
494
  searchInputWrapper: classNames.searchInputWrapper,
@@ -497,7 +496,8 @@ const Filter = ({ children = void 0, className = void 0, config, formName = "fil
497
496
  searchShowButton: classNames.searchShowButton,
498
497
  searchSubmitButton: classNames.searchSubmitButton,
499
498
  searchWrapper: classNames.searchWrapper
500
- }
499
+ },
500
+ config: config.search
501
501
  }) : null, /* @__PURE__ */ jsxs(FiltersContextProvider, {
502
502
  config: config.filters,
503
503
  children: [
@@ -722,4 +722,4 @@ var Filter_default = Filter;
722
722
  //#endregion
723
723
  export { filterVariants as i, filters as n, createFilter as r, Filter_default as t };
724
724
 
725
- //# sourceMappingURL=Filter-MoxrK8MI.js.map
725
+ //# sourceMappingURL=Filter-DHNzbevz.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Filter-MoxrK8MI.js","names":["Display","Form","config","validate","boolean","validate","Form"],"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
+ {"version":3,"file":"Filter-DHNzbevz.js","names":["Display","Form","config","validate","boolean","validate","Form"],"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 onClick={() => {\n showFilterModal(name);\n }}\n type=\"button\"\n >\n <Label\n className={className}\n color={hasError(name) ? 'danger' : 'primary'}\n onClose={() => {\n removeFilter(name);\n }}\n variant=\"flat\"\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 className={{\n item: classNames.addFilterMenuItem,\n trigger: classNames.addFilterMenuButton,\n }}\n isDisabled={!menuItems.length}\n items={menuItems}\n placement=\"bottom-start\"\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 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 onClick={() => {\n removeFilter(modalFilterName);\n }}\n testId=\"remove_filter_button\"\n variant=\"flat\"\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 isOpen\n onClose={closeFilterModal}\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 onClick={() => {\n setIsVisible(true);\n }}\n size=\"sm\"\n testId=\"show_search_input_button\"\n variant=\"bordered\"\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 // submit on clear\n onClear={() => {\n triggerSubmit();\n }}\n placeholder={placeholder}\n className={{\n input: classNames.searchInput,\n inputWrapper: classNames.searchInputWrapper,\n }}\n size=\"sm\"\n />\n <SubmitButton\n className={classNames.searchSubmitButton}\n color=\"primary\"\n icon={<FaSearch />}\n size=\"sm\"\n testId=\"submit_search_button\"\n ariaLabel=\"Submit search\"\n // eslint-disable-next-line react/no-children-prop\n children={null}\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);\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 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 config={config.search}\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 ?? {}) },\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,MAAa,uBACX,SACA,eACG;CACH,OAAO,cAA4B;EAEjC,IAAI,eAA4C,CAAC;EACjD,QAAQ,SAAS,MAAM;GACrB,eAAe;IACb,GAAG;KACF,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM;GACjC;EACF,CAAC;EAmBD,OAAO,KAAK;GAfV,QAAQ,aAAa,EAClB,KAAK,OAAO,YAAY,CAAC,EACzB,GAAG,OAAO,YAAY,CAAC,EACvB,SAAS,EACT,SAAS,EAET,WAAW,QAAQ;IAClB,OAAO,OAAO,KAAA;GAChB,CAAC;GAEH,GAAI,aACA,EAAE,QAAQ,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,IACnD,CAAC;EAGoB,CAAC;CAC9B,GAAG,CAAC,SAAS,UAAU,CAAC;AAC1B;;;;;;;;;;;;;;;;;;;;;ACWA,MAAM,iBAAiB,cACrB,KAAA,CACF;AAEA,MAAa,0BAA0B,EACrC,UACA,aAII;CAIJ,MAAM,EACJ,WACA,eACA,UACA,eACA,YACA,UACE,eAAe;;;;;;;;;;;;;;;;;;;;;CAsBnB,MAAM,CAAC,oBAAoB,yBAAyB,SAI1C,IAAI;CAGd,MAAM,cAAc,MAAM,UAAU,CAAC,CAAC;;;;;;;CAQtC,MAAM,yBAAyB,aAAa,SAAiB;EAC3D,OAAO,UAAU;CACnB,GAAG,CAAC,CAAC;;;;;;CAOL,MAAM,uBAAuB,aAC1B,SAAiB;EAChB,OAAQ,YAAwC;CAClD,GACA,CAAC,WAAW,CACd;;CAGA,MAAM,kBAAkB,aACrB,SAAiB;EAChB,MAAM,OAAO,qBAAqB,IAAI;EACtC,sBAAsB;GACpB;GACA,UAAU,OAAO,SAAS;GAC1B,eAAe;EACjB,CAAC;CACH,GACA,CAAC,oBAAoB,CACvB;;CAGA,MAAM,mBAAmB,kBAAkB;EACzC,IAAI,oBAAoB,MAAM;GAC5B,MAAM,YAAY,uBAAuB,mBAAmB,IAAI;GAGhE,IAAI,mBAAmB,UACrB,SAAS,WAAW,mBAAmB,aAAa;QAEpD,WAAW,SAAS;EAExB;EACA,sBAAsB,IAAI;CAC5B,GAAG;EAAC;EAAwB;EAAoB;EAAU;CAAU,CAAC;;;;;;;;;CAUrE,MAAM,qBAAqB,OAAe,CAAC;CAC3C,gBAAgB;EACd,IACE,UAAU,gBAAgB,mBAAmB,WAC7C,UAAU,oBAGV,sBAAsB,IAAI;EAE5B,mBAAmB,UAAU,UAAU;CACzC,GAAG;EACD,UAAU;EACV,UAAU;EACV;CACF,CAAC;;;;;;;;CASD,MAAM,gBAAgB,cAAc;EAClC,OAAO,OACJ,QAAQ,MAAM;GACb,OAAO,OAAO,OAAO,eAAe,CAAC,GAAG,EAAE,IAAI;EAChD,CAAC,EACA,KAAK,MAAM;GACV,OAAO,EAAE;EACX,CAAC;CACL,GAAG,CAAC,QAAQ,WAAW,CAAC;;;;;;;CAQxB,MAAM,gBAAgB,cAAc;EAClC,OAAO,OACJ,QAAQ,MAAM;GACb,OAAO,CAAC,OAAO,OAAO,eAAe,CAAC,GAAG,EAAE,IAAI;EACjD,CAAC,EACA,KAAK,MAAM;GACV,OAAO,EAAE;EACX,CAAC;CACL,GAAG,CAAC,QAAQ,WAAW,CAAC;;;;;;;CAQxB,MAAM,0BAA0B,aAC7B,SAAiB;EAChB,OAAO,OAAO,MAAM,MAAM;GACxB,OAAO,EAAE,SAAS;EACpB,CAAC;CACH,GACA,CAAC,MAAM,CACT;;;;;;;CAQA,MAAM,YAAY,aACf,SAAiB;EAChB,MAAM,OAAO,wBAAwB,IAAI;EACzC,gBAAgB,IAAI;EACpB,SAAS,uBAAuB,IAAI,GAAG,KAAK,YAAY;CAC1D,GACA;EACE;EACA;EACA;EACA;CACF,CACF;;;;;;;;CASA,MAAM,eAAe,aAClB,SAAiB;EAEhB,WAAW,uBAAuB,IAAI,CAAC;EAEvC,IAAI,oBAAoB,SAAS,MAE/B,sBAAsB,IAAI;EAG5B,cAAc;CAChB,GACA;EACE;EACA;EACA;EACA;EACA;CACF,CACF;;;;;;;CAQA,MAAM,WAAW,aACd,SAAiB;EAChB,OAAO,cAAc,uBAAuB,IAAI,CAAC,EAAE;CACrD,GACA,CAAC,eAAe,sBAAsB,CACxC;CAEA,MAAM,eAAoC,cAAc;EACtD,OAAO;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA,iBAAiB,oBAAoB;GACrC;GACA;GACA;EACF;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,OACE,oBAAC,eAAe,UAAhB;EAAyB,OAAO;EAC7B;CACsB,CAAA;AAE7B;;;;;;;;AASA,MAAa,mBAAwC;CACnD,MAAM,MAAM,WAAW,cAAc;CACrC,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,uDAAuD;CAEzE,OAAO;AACT;;;ACtUA,MAAM,iBAAiB,EAAE,YAAY,KAAA,QAAoC;CACvE,MAAM,EACJ,eACA,sBACA,yBACA,UACA,cACA,oBACE,WAAW;CACf,OACE,oBAAA,UAAA,EAAA,UACG,cAAc,KAAK,SAAS;EAC3B,MAAM,WAAW,wBAAwB,IAAI;EAC7C,MAAM,QAAQ,qBAAqB,IAAI;EAGvC,MAAM,mBAAmB,SAAS,WAAW;EAE7C,OACE,oBAAC,UAAD;GAEE,cAAY,QAAQ,KAAK;GACzB,eAAe;IACb,gBAAgB,IAAI;GACtB;GACA,MAAK;aAEL,qBAAC,OAAD;IACa;IACX,OAAO,SAAS,IAAI,IAAI,WAAW;IACnC,eAAe;KACb,aAAa,IAAI;IACnB;IACA,SAAQ;cANV,CAQG,SAAS,MACV,oBAAC,kBAAD;KAAkB,QAAQ,SAAS;KAAe;IAAQ,CAAA,CACrD;;EACD,GAlBD,IAkBC;CAEZ,CAAC,EACD,CAAA;AAEN;;;;;;;;;ACtCA,MAAM,iBAAiB,EAAE,aAAa,CAAC,QAA4B;CACjE,MAAM,EAAE,eAAe,WAAW,4BAA4B,WAAW;CAEzE,MAAM,YAAY,cAAc,KAAK,SAAS;EAC5C,MAAM,WAAW,wBAAwB,IAAI;EAE7C,MAAM,QADS,SAAS,QACF,QAAQ;EAC9B,OAAO;GACL,KAAK;GACL,MAAM,SAAS;GACf;GACA,eAAe;IACb,UAAU,IAAI;GAChB;EACF;CACF,CAAC;CAED,OACE,qBAAC,MAAD;EACE,WAAW;GACT,MAAM,WAAW;GACjB,SAAS,WAAW;EACtB;EACA,YAAY,CAAC,UAAU;EACvB,OAAO;EACP,WAAU;EACV,oBAAoB;GAClB,cAAc;GACd,eAAe;GACf,eAAe;GACf,MAAM;GACN,SAAS;EACX;YAdF,CAgBE,oBAAC,WAAD,CAAY,CAAA,GAAC,QAET;;AAEV;;;ACzCA,MAAM,eAAe,EAAE,aAAa,CAAC,QAA0B;CAC7D,MAAM,EACJ,kBACA,wBACA,yBACA,iBACA,iBACE,WAAW;CAGf,IAAI,CAAC,iBACH,OAAO;CAGT,MAAM,WAAW,wBAAwB,eAAe;CACxD,MAAM,SAAS,SAAS;CAGxB,MAAM,gBAAgB,SAAS,WAAW;CAE1C,OACE,oBAAC,OAAD;EACE,WAAW;GACT,MAAM,WAAW;GACjB,QAAQ,WAAW;GACnB,QAAQ,WAAW;EACrB;EACA,QACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAD;GACE,WAAU;GACV,OAAM;GACN,eAAe;IACb,aAAa,eAAe;GAC9B;GACA,QAAO;GACP,SAAQ;aACT;EAEO,CAAA,GACR,oBAAC,cAAD;GAAc,WAAU;GAAe,QAAO;aAAsB;EAEtD,CAAA,CACd,EAAA,CAAA;EAEJ,QACE,qBAAA,UAAA,EAAA,UAAA,CACG,SAAS,QAAQ,oBAAC,yBAAD,CAA0B,CAAA,GAC5C,oBAAC,OAAD,EAAA,UAAM,GAAG,QAAQ,QAAQ,gBAAgB,SAAc,CAAA,CACvD,EAAA,CAAA;EAEJ,QAAA;EACA,SAAS;YAET,oBAAC,UAAD,EAAA,UACE,oBAAC,eAAD;GACU;GACR,WAAW,uBAAuB,eAAe;EAClD,CAAA,EACO,CAAA;CACL,CAAA;AAEX;;;;;;;;;AC3CA,MAAM,eAAe,EAAE,aAAa,CAAC,GAAG,aAA+B;CACrE,MAAM,EAAE,WAAW,UAAU,kBAAkB,eAAe;CAG9D,MAAM,qBAAqB,CAAC,CAAC,WAAW,eAAe;CACvD,MAAM,CAAC,WAAW,gBAAgB,SAAS,kBAAkB;CAE7D,MAAM,cACJ,OAAO,WAAW,WAAW,OAAO,cAAc,KAAA;CAEpD,OACE,qBAAC,OAAD;EAAK,WAAW,WAAW;YAA3B,CACG,CAAC,aACA,oBAAC,QAAD;GACE,WAAU;GACV,WAAW,WAAW;GACtB,MAAM,oBAAC,UAAD,CAAW,CAAA;GACjB,eAAe;IACb,aAAa,IAAI;GACnB;GACA,MAAK;GACL,QAAO;GACP,SAAQ;EACT,CAAA,GAEF,YACC,qBAAC,OAAO,KAAR;GAEE,SAAS,EAAE,SAAS,EAAE;GACtB,WAAW,WAAW;GAEtB,SAAS,CAAC,qBAAqB,EAAE,SAAS,GAAI,IAAI;GAClD,2BAA2B;IAEzB,IAAI,CAAC,oBACH,SAAS,QAAQ;GAErB;GACA,YAAY;IACV,UAAU;IACV,MAAM;GACR;aAfF,CAiBE,oBAAC,OAAD;IACE,WAAA;IACA,eAAe;IACf,MAAK;IAEL,eAAe;KACb,cAAc;IAChB;IACa;IACb,WAAW;KACT,OAAO,WAAW;KAClB,cAAc,WAAW;IAC3B;IACA,MAAK;GACN,CAAA,GACD,oBAAC,cAAD;IACE,WAAW,WAAW;IACtB,OAAM;IACN,MAAM,oBAAC,UAAD,CAAW,CAAA;IACjB,MAAK;IACL,QAAO;IACP,WAAU;IAEV,UAAU;GACX,CAAA,CACS;KAzCN,cAyCM,IACV,IACD;;AAET;;;AC1FA,MAAM,QAAQ,YAAY,mBAAmB;AAG7C,MAAa,iBAAiB,GAAG,EAC/B,OAAO;CAEL,MAAM;CAEN,qBAAqB;CAErB,mBAAmB;CAEnB,mBAAmB;CAEnB,iBAAiB;CAEjB,mBAAmB;CAEnB,mBAAmB;CAEnB,MAAM;CAEN,aAAa;CAEb,oBAAoB;CAEpB,iBAAiB;CAEjB,kBAAkB;CAElB,oBAAoB;CAEpB,eAAe;AACjB,EACF,CAAC;;;;;;AA2DD,MAAM,UAAU,EACd,WAAW,KAAA,GACX,YAAY,KAAA,GACZ,QACA,WAAW,uBACX,UACA,aACiB;CAEjB,MAAM,gBAAgB,eAAwC;EAC5D,MAAM,gBAAgB,EAAE,WAAW,CAAC;EACpC,SAAS,UAAU;CACrB;CAGA,MAAM,aAAa,oBACjB,OAAO,SACP,QAAQ,OAAO,MAAM,CACvB;CAGA,MAAM,EACJ,MAAM,iBACN,QACA,YACE,WAAW,SAAS,MAAmB;CAI3C,MAAM,aAAa,qBADF,eAC8B,GAAG,WAAW,MAAM;CAEnE,MAAM,UAAU;EACd,OAAO;GAAE;GAAQ;EAAO;EACxB,YAAY;GAAE;GAAQ;GAAS;EAAgB;CACjD,CAAC;CAED,OACE,qBAAC,OAAD;EAAK,WAAW,WAAW;YAA3B,CAOE,qBAAC,MAAD;GACE,WAAW,WAAW;GAEtB,OAAO,EAAE,SAAS,KAAK;GACvB,eAAe,mBAAmB,CAAC;GACnC,MAAM;GACN,UAAU;GACE;aAPd,CAUG,OAAO,SACN,oBAAC,aAAD;IACE,YAAY;KACV,aAAa,WAAW;KACxB,oBAAoB,WAAW;KAC/B,iBAAiB,WAAW;KAC5B,kBAAkB,WAAW;KAC7B,oBAAoB,WAAW;KAC/B,eAAe,WAAW;IAC5B;IACA,QAAQ,OAAO;GAChB,CAAA,IACC,MAOJ,qBAAC,wBAAD;IAAwB,QAAQ,OAAO;cAAvC;KACE,oBAAC,eAAD,EAAe,WAAW,WAAW,kBAAoB,CAAA;KACzD,oBAAC,eAAD,EACE,YAAY;MACV,qBAAqB,WAAW;MAChC,mBAAmB,WAAW;KAChC,EACD,CAAA;KACD,oBAAC,aAAD,EACE,YAAY;MACV,MAAM,WAAW;MACjB,QAAQ,WAAW;MACnB,QAAQ,WAAW;KACrB,EACD,CAAA;IACqB;KACpB;MAEL,WAAW,mBAAmB,CAAC,CAAC,CAC9B;;AAET;;;;;;;;;;;;;;;;;;;;AC1LA,MAAM,gBACJ,eACiC;CACjC,QAAQ,EAAE,MAAM,MAAM,aAAa;EACjC,OAAO;GACL,YAAY,WAAW;GACvB,QAAQ;IAAE,GAAG,WAAW,SAAS;IAAQ,GAAI,UAAU,CAAC;GAAG;GAC3D,cAAc,WAAW,SAAS;GAClC;GACA;GACA,YAAY,WAAW;EACzB;CACF;AACF;;;;;;;;ACxBA,MAAMA,aAAW,EACf,OACA,QAAQ,EAAE,MAAM,YAAY,mBACW;CACvC,IAAI,OAAO,UAAU,WACnB,OACE,oBAAA,UAAA,EAAA,UACG,GAAG,QAAQ,aAAa,GAAG,WAAW,GAAG,cAAc,OAAO,GAAG,OAClE,CAAA;CAGN,OAAO,oBAAA,UAAA,EAAA,UAAG,GAAG,KAAK,KAAO,CAAA;AAC3B;;;;;;;;ACVA,MAAMC,UAAQ,EACZ,WACA,QAAQ,EAAE,MAAM,mBACa;CAC7B,OAAO,oBAAC,QAAD;EAAQ,OAAO,GAAG,WAAW,GAAG;EAAQ,MAAM;CAAY,CAAA;AACnE;ACVsB,OAAO;;;;;CAK3B,MAAM,OAAO;;;;;CAKb,YAAY,OAAO,EAAE,SAAS;;;;;CAK9B,YAAY,OAAO,EAAE,SAAS;AAChC,CAAC;;AAGD,MAAaE,cAAY,YAAqB;CAC5C,OAAO,QAAQ,EAAE,SAAS;AAC5B;;;;;;;;;;;;;;;ACLA,MAAaC,YAAU,aAA4B;CACjD,YAAY;EAAE,SAAA;EAAS,MAAA;CAAK;CAC5B,UAAU;EACR,OAAO;EACP,QAAQ;GAAE,MAAM;GAAU,YAAY;GAAM,YAAY;EAAK;CAC/D;CACA,YAAYC;AACd,CAAC;;;;;;;;ACpBD,MAAM,WAAW,EACf,OACA,QAAQ,EAAE,MAAM,gBACuB;CACvC,IAAI,SAAS,MAAM,SAAS,GAC1B,OACE,qBAAC,QAAD;EAAM,WAAU;YAAhB;GACG;GAAK;GACL,MAAM,KAAK,QAAQ;IAIlB,MAAM,QAHS,QAAQ,MAAM,OAAO;KAClC,OAAO,GAAG,UAAU;IACtB,CACmB,GAAG,SAAS;IAG/B,OAAO,oBAAC,QAAD,EAAA,UADL,OAAO,UAAU,aAAa,MAAM,SAAS,IAAI,MACP,GAA1B,GAA0B;GAC9C,CAAC;EACG;;CAGV,OAAO,GAAG,KAAK;AACjB;;;;;;;;ACnBA,MAAMC,UAAQ,EAAE,WAAW,aAAsC;CAW/D,OAAO,oBAAC,YAAD;EAAY,MAAM;EAAW,SAVZ,OAAO,QAAQ,KAAK,WAAW;GACrD,OAAO;IACL,GAAG;IACH,OACE,OAAO,OAAO,UAAU,aACpB,OAAO,MAAM,MAAM,IACnB,OAAO;GACf;EACF,CAE2D;CAAI,CAAA;AACjE;AChBsB,OAAO;;;;;CAK3B,MAAM,OAAO;;;;;;;CAOb,SAAS,MAAM,OAAO;EAAE,OAAO,IAAI;EAAG,OAAO,OAAO;CAAE,CAAC,CAAC;AAC1D,CAAC;;AAWD,MAAa,YAAY,QAAiB;CACxC,OAAO,YAAY,MAAM,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE;EAC7C,QAAQ;EACR,SAAS,QAAQ,QAAQ;GACvB,IAAI,CAAC,KACH;GAEF,OAAO,SAAS,UAAU;IACxB,IACE,CAAC,IAAI,QAAQ,MAAM,WAAW;KAC5B,OAAO,QAAQ,UAAU;IAC3B,CAAC,GAED,IAAI,SAAS;KACX,MAAM;KACN,SAAS,kBAAkB;IAC7B,CAAC;GAEL,CAAC;EACH;CACF,CAAC;AACH;;;AExCA,MAAa,UAAU;CACrB,SAAA;CACA,YDQwB,aAA4B;EACpD,YAAY;GAAE;GAAS,MAAA;EAAK;EAC5B,UAAU;GAAE,OAAO,CAAC;GAAG,QAAQ;IAAE,MAAM;IAAW,SAAS,CAAC;GAAE;EAAE;EAChE,YAAY;CACd,CCZE;AACF;AAMA,IAAA,iBAAe"}
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_Notification = require("../Notification-BjftuLye.cjs");
5
+ const require_Notification = require("../Notification-ClLRWj0j.cjs");
6
6
  exports.NotificationHost = require_Notification.NotificationHost;
7
7
  exports.default = require_Notification.Notification_default;
8
8
  exports.notification = require_Notification.notification;
@@ -1,2 +1,2 @@
1
- import { a as notification, i as NotificationRenderProps, n as NotificationHostProps, r as NotificationOptions, t as NotificationHost } from "../index-DMd9TyqF.cjs";
1
+ import { a as notification, i as NotificationRenderProps, n as NotificationHostProps, r as NotificationOptions, t as NotificationHost } from "../index-DRyBPfQT.cjs";
2
2
  export { NotificationHost, type NotificationHostProps, type NotificationOptions, type NotificationRenderProps, notification as default, notification };
@@ -1,2 +1,2 @@
1
- import { a as notification, i as NotificationRenderProps, n as NotificationHostProps, r as NotificationOptions, t as NotificationHost } from "../index-DaLo1TQx.js";
1
+ import { a as notification, i as NotificationRenderProps, n as NotificationHostProps, r as NotificationOptions, t as NotificationHost } from "../index-DRyBPfQT.js";
2
2
  export { NotificationHost, type NotificationHostProps, type NotificationOptions, type NotificationRenderProps, notification as default, notification };
@@ -1,2 +1,2 @@
1
- import { n as NotificationHost, r as notification, t as Notification_default } from "../Notification-B-G4OVD2.js";
1
+ import { n as NotificationHost, r as notification, t as Notification_default } from "../Notification-5tyFF-87.js";
2
2
  export { NotificationHost, Notification_default as default, notification };
@@ -101,4 +101,4 @@ var Notification_default = notification;
101
101
  //#endregion
102
102
  export { NotificationHost as n, notification as r, Notification_default as t };
103
103
 
104
- //# sourceMappingURL=Notification-B-G4OVD2.js.map
104
+ //# sourceMappingURL=Notification-5tyFF-87.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Notification-B-G4OVD2.js","names":[],"sources":["../src/Notification/notification.tsx","../src/Notification/NotificationHost.tsx","../src/Notification/index.ts"],"sourcesContent":["import type { ModalStoreApi } from '@fuf-stack/pixels/Modal';\nimport type { ToastOptions } from '@fuf-stack/pixels/Toast';\nimport type { ReactNode } from 'react';\n\nimport { modal } from '@fuf-stack/pixels/Modal';\nimport { toast } from '@fuf-stack/pixels/Toast';\n\n/**\n * Props passed to function-based render props on a notification (e.g.\n * `endContent`), exposing helpers usable while rendering.\n */\nexport interface NotificationRenderProps {\n /** Imperative modal API for opening/closing a modal from a notification. */\n modal: ModalStoreApi;\n}\n\n/** Options accepted by every `notification.<variant>()` call */\nexport interface NotificationOptions extends Omit<ToastOptions, 'endContent'> {\n /**\n * The notification's end content. Either a node rendered directly, or a\n * render function that receives the {@link NotificationRenderProps} (incl. a\n * `modal` API to open a modal) and returns the node to render.\n */\n endContent?: ReactNode | ((props: NotificationRenderProps) => ReactNode);\n}\n\n// Render props passed to function-based options (e.g. `endContent`).\nconst renderProps: NotificationRenderProps = { modal };\n\n/**\n * Maps `NotificationOptions` to `ToastOptions` by resolving `endContent`:\n * a render function receives the render props and its returned node is used.\n */\nconst resolveOptions = (\n options?: NotificationOptions,\n): ToastOptions | undefined => {\n if (!options) {\n return undefined;\n }\n // Pull `endContent` out so the remaining options pass through unchanged.\n const { endContent, ...toastOptions } = options;\n\n return {\n ...toastOptions,\n // `ToastOptions.endContent` only accepts a node, so resolve the\n // render-function form down to one (a plain node passes through as-is).\n endContent:\n typeof endContent === 'function' ? endContent(renderProps) : endContent,\n };\n};\n\n/**\n * Imperative API for showing notifications: `default` / `info` / `warn` /\n * `success` / `error` show a notification (each returns an id), and `close`\n * dismisses one by id.\n *\n * Besides a plain node, `endContent` may be a render function that receives\n * the {@link NotificationRenderProps} — including a `modal` API — and returns\n * the node to render, e.g. to open a modal showing details that do not fit\n * into the notification itself.\n *\n * Requires a `<NotificationHost />` to be mounted in the React tree.\n *\n * @example\n * ```tsx\n * notification.error('A request failed.', {\n * title: 'Request failed',\n * endContent: ({ modal }) => (\n * <Button onClick={() => modal.open({ content: details })}>More</Button>\n * ),\n * });\n * ```\n */\nconst notification = {\n /**\n * Show a default notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n default: (message: ReactNode, options?: NotificationOptions) => {\n return toast.default(message, resolveOptions(options));\n },\n /**\n * Show an info notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n info: (message: ReactNode, options?: NotificationOptions) => {\n return toast.info(message, resolveOptions(options));\n },\n /**\n * Show a warning notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n warn: (message: ReactNode, options?: NotificationOptions) => {\n return toast.warn(message, resolveOptions(options));\n },\n /**\n * Show a success notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n success: (message: ReactNode, options?: NotificationOptions) => {\n return toast.success(message, resolveOptions(options));\n },\n /**\n * Show an error notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n error: (message: ReactNode, options?: NotificationOptions) => {\n return toast.error(message, resolveOptions(options));\n },\n /** Close a notification by its id */\n close: (id: string | number) => {\n toast.close(id);\n },\n};\n\nexport default notification;\n","import type { CSSProperties } from 'react';\n\nimport { ModalHost } from '@fuf-stack/pixels/Modal';\nimport { Toaster } from '@fuf-stack/pixels/Toast';\n\nexport interface NotificationHostProps {\n /**\n * Width applied to all toasts. A number is treated as pixels; a string is\n * used verbatim (e.g. `'600px'`, `'40rem'`). Sets Sonner's `--width` CSS\n * variable on the Toaster.\n */\n width?: number | string;\n}\n\n/**\n * Mounts the Toaster and ModalHost.\n *\n * Use once at the top level of your app:\n *\n * ```tsx\n * <NotificationHost />\n * ```\n */\nconst NotificationHost = ({ width = 600 }: NotificationHostProps) => {\n // Sonner defaults to z-index 999999999, which would render toasts above the\n // HeroUI modal (z-50). Lower it so modals opened from a toast's \"More\"\n // button stay on top. `--width` is passed inline because Sonner sets its\n // default `--width` inline on the same element, which beats class-based\n // overrides.\n const toasterStyle = {\n zIndex: 40,\n ...(width != null && {\n '--width': typeof width === 'number' ? `${width}px` : width,\n }),\n } as CSSProperties;\n return (\n <>\n <Toaster style={toasterStyle} />\n <ModalHost />\n </>\n );\n};\n\nexport default NotificationHost;\n","import notification from './notification';\nimport NotificationHost from './NotificationHost';\n\nexport type {\n NotificationOptions,\n NotificationRenderProps,\n} from './notification';\nexport type { NotificationHostProps } from './NotificationHost';\n\nexport { NotificationHost, notification };\nexport default notification;\n"],"mappings":";;;;AA2BA,MAAM,cAAuC,EAAE,MAAM;;;;;AAMrD,MAAM,kBACJ,YAC6B;CAC7B,IAAI,CAAC,SACH;CAGF,MAAM,EAAE,YAAY,GAAG,iBAAiB;CAExC,OAAO;EACL,GAAG;EAGH,YACE,OAAO,eAAe,aAAa,WAAW,WAAW,IAAI;CACjE;AACF;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,eAAe;;;;;CAKnB,UAAU,SAAoB,YAAkC;EAC9D,OAAO,MAAM,QAAQ,SAAS,eAAe,OAAO,CAAC;CACvD;;;;;CAKA,OAAO,SAAoB,YAAkC;EAC3D,OAAO,MAAM,KAAK,SAAS,eAAe,OAAO,CAAC;CACpD;;;;;CAKA,OAAO,SAAoB,YAAkC;EAC3D,OAAO,MAAM,KAAK,SAAS,eAAe,OAAO,CAAC;CACpD;;;;;CAKA,UAAU,SAAoB,YAAkC;EAC9D,OAAO,MAAM,QAAQ,SAAS,eAAe,OAAO,CAAC;CACvD;;;;;CAKA,QAAQ,SAAoB,YAAkC;EAC5D,OAAO,MAAM,MAAM,SAAS,eAAe,OAAO,CAAC;CACrD;;CAEA,QAAQ,OAAwB;EAC9B,MAAM,MAAM,EAAE;CAChB;AACF;;;;;;;;;;;;AC1FA,MAAM,oBAAoB,EAAE,QAAQ,UAAiC;CAYnE,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,SAAD,EAAS,OAAO;EAPlB,QAAQ;EACR,GAAI,SAAS,QAAQ,EACnB,WAAW,OAAO,UAAU,WAAW,GAAG,MAAM,MAAM,MACxD;CAI6B,EAAI,CAAA,GAC/B,oBAAC,WAAD,CAAY,CAAA,CACZ,EAAA,CAAA;AAEN;;;AC/BA,IAAA,uBAAe"}
1
+ {"version":3,"file":"Notification-5tyFF-87.js","names":[],"sources":["../src/Notification/notification.tsx","../src/Notification/NotificationHost.tsx","../src/Notification/index.ts"],"sourcesContent":["import type { ModalStoreApi } from '@fuf-stack/pixels/Modal';\nimport type { ToastOptions } from '@fuf-stack/pixels/Toast';\nimport type { ReactNode } from 'react';\n\nimport { modal } from '@fuf-stack/pixels/Modal';\nimport { toast } from '@fuf-stack/pixels/Toast';\n\n/**\n * Props passed to function-based render props on a notification (e.g.\n * `endContent`), exposing helpers usable while rendering.\n */\nexport interface NotificationRenderProps {\n /** Imperative modal API for opening/closing a modal from a notification. */\n modal: ModalStoreApi;\n}\n\n/** Options accepted by every `notification.<variant>()` call */\nexport interface NotificationOptions extends Omit<ToastOptions, 'endContent'> {\n /**\n * The notification's end content. Either a node rendered directly, or a\n * render function that receives the {@link NotificationRenderProps} (incl. a\n * `modal` API to open a modal) and returns the node to render.\n */\n endContent?: ReactNode | ((props: NotificationRenderProps) => ReactNode);\n}\n\n// Render props passed to function-based options (e.g. `endContent`).\nconst renderProps: NotificationRenderProps = { modal };\n\n/**\n * Maps `NotificationOptions` to `ToastOptions` by resolving `endContent`:\n * a render function receives the render props and its returned node is used.\n */\nconst resolveOptions = (\n options?: NotificationOptions,\n): ToastOptions | undefined => {\n if (!options) {\n return undefined;\n }\n // Pull `endContent` out so the remaining options pass through unchanged.\n const { endContent, ...toastOptions } = options;\n\n return {\n ...toastOptions,\n // `ToastOptions.endContent` only accepts a node, so resolve the\n // render-function form down to one (a plain node passes through as-is).\n endContent:\n typeof endContent === 'function' ? endContent(renderProps) : endContent,\n };\n};\n\n/**\n * Imperative API for showing notifications: `default` / `info` / `warn` /\n * `success` / `error` show a notification (each returns an id), and `close`\n * dismisses one by id.\n *\n * Besides a plain node, `endContent` may be a render function that receives\n * the {@link NotificationRenderProps} — including a `modal` API — and returns\n * the node to render, e.g. to open a modal showing details that do not fit\n * into the notification itself.\n *\n * Requires a `<NotificationHost />` to be mounted in the React tree.\n *\n * @example\n * ```tsx\n * notification.error('A request failed.', {\n * title: 'Request failed',\n * endContent: ({ modal }) => (\n * <Button onClick={() => modal.open({ content: details })}>More</Button>\n * ),\n * });\n * ```\n */\nconst notification = {\n /**\n * Show a default notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n default: (message: ReactNode, options?: NotificationOptions) => {\n return toast.default(message, resolveOptions(options));\n },\n /**\n * Show an info notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n info: (message: ReactNode, options?: NotificationOptions) => {\n return toast.info(message, resolveOptions(options));\n },\n /**\n * Show a warning notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n warn: (message: ReactNode, options?: NotificationOptions) => {\n return toast.warn(message, resolveOptions(options));\n },\n /**\n * Show a success notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n success: (message: ReactNode, options?: NotificationOptions) => {\n return toast.success(message, resolveOptions(options));\n },\n /**\n * Show an error notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n error: (message: ReactNode, options?: NotificationOptions) => {\n return toast.error(message, resolveOptions(options));\n },\n /** Close a notification by its id */\n close: (id: string | number) => {\n toast.close(id);\n },\n};\n\nexport default notification;\n","import type { CSSProperties } from 'react';\n\nimport { ModalHost } from '@fuf-stack/pixels/Modal';\nimport { Toaster } from '@fuf-stack/pixels/Toast';\n\nexport interface NotificationHostProps {\n /**\n * Width applied to all toasts. A number is treated as pixels; a string is\n * used verbatim (e.g. `'600px'`, `'40rem'`). Sets Sonner's `--width` CSS\n * variable on the Toaster.\n */\n width?: number | string;\n}\n\n/**\n * Mounts the Toaster and ModalHost.\n *\n * Use once at the top level of your app:\n *\n * ```tsx\n * <NotificationHost />\n * ```\n */\nconst NotificationHost = ({ width = 600 }: NotificationHostProps) => {\n // Sonner defaults to z-index 999999999, which would render toasts above the\n // HeroUI modal (z-50). Lower it so modals opened from a toast's \"More\"\n // button stay on top. `--width` is passed inline because Sonner sets its\n // default `--width` inline on the same element, which beats class-based\n // overrides.\n const toasterStyle = {\n zIndex: 40,\n ...(width != null && {\n '--width': typeof width === 'number' ? `${width}px` : width,\n }),\n } as CSSProperties;\n return (\n <>\n <Toaster style={toasterStyle} />\n <ModalHost />\n </>\n );\n};\n\nexport default NotificationHost;\n","import notification from './notification';\nimport NotificationHost from './NotificationHost';\n\nexport type {\n NotificationOptions,\n NotificationRenderProps,\n} from './notification';\nexport type { NotificationHostProps } from './NotificationHost';\n\nexport { NotificationHost, notification };\nexport default notification;\n"],"mappings":";;;;AA2BA,MAAM,cAAuC,EAAE,MAAM;;;;;AAMrD,MAAM,kBACJ,YAC6B;CAC7B,IAAI,CAAC,SACH;CAGF,MAAM,EAAE,YAAY,GAAG,iBAAiB;CAExC,OAAO;EACL,GAAG;EAGH,YACE,OAAO,eAAe,aAAa,WAAW,WAAW,IAAI;CACjE;AACF;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,eAAe;;;;;CAKnB,UAAU,SAAoB,YAAkC;EAC9D,OAAO,MAAM,QAAQ,SAAS,eAAe,OAAO,CAAC;CACvD;;;;;CAKA,OAAO,SAAoB,YAAkC;EAC3D,OAAO,MAAM,KAAK,SAAS,eAAe,OAAO,CAAC;CACpD;;;;;CAKA,OAAO,SAAoB,YAAkC;EAC3D,OAAO,MAAM,KAAK,SAAS,eAAe,OAAO,CAAC;CACpD;;;;;CAKA,UAAU,SAAoB,YAAkC;EAC9D,OAAO,MAAM,QAAQ,SAAS,eAAe,OAAO,CAAC;CACvD;;;;;CAKA,QAAQ,SAAoB,YAAkC;EAC5D,OAAO,MAAM,MAAM,SAAS,eAAe,OAAO,CAAC;CACrD;;CAEA,QAAQ,OAAwB;EAC9B,MAAM,MAAM,EAAE;CAChB;AACF;;;;;;;;;;;;AC1FA,MAAM,oBAAoB,EAAE,QAAQ,UAAiC;CAYnE,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,SAAD,EAAS,OAAO;EAPlB,QAAQ;EACR,GAAI,SAAS,QAAQ,EACnB,WAAW,OAAO,UAAU,WAAW,GAAG,MAAM,MAAM,MACxD;CAI6B,EAAI,CAAA,GAC/B,oBAAC,WAAD,CAAY,CAAA,CACZ,EAAA,CAAA;AAEN;;;AC/BA,IAAA,uBAAe"}
@@ -1,4 +1,3 @@
1
- require("./Filter-BVwu1kNx.cjs");
2
1
  let react_jsx_runtime = require("react/jsx-runtime");
3
2
  let _fuf_stack_pixels_Modal = require("@fuf-stack/pixels/Modal");
4
3
  let _fuf_stack_pixels_Toast = require("@fuf-stack/pixels/Toast");
@@ -119,4 +118,4 @@ Object.defineProperty(exports, "notification", {
119
118
  }
120
119
  });
121
120
 
122
- //# sourceMappingURL=Notification-BjftuLye.cjs.map
121
+ //# sourceMappingURL=Notification-ClLRWj0j.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Notification-BjftuLye.cjs","names":["toast","Toaster","ModalHost"],"sources":["../src/Notification/notification.tsx","../src/Notification/NotificationHost.tsx","../src/Notification/index.ts"],"sourcesContent":["import type { ModalStoreApi } from '@fuf-stack/pixels/Modal';\nimport type { ToastOptions } from '@fuf-stack/pixels/Toast';\nimport type { ReactNode } from 'react';\n\nimport { modal } from '@fuf-stack/pixels/Modal';\nimport { toast } from '@fuf-stack/pixels/Toast';\n\n/**\n * Props passed to function-based render props on a notification (e.g.\n * `endContent`), exposing helpers usable while rendering.\n */\nexport interface NotificationRenderProps {\n /** Imperative modal API for opening/closing a modal from a notification. */\n modal: ModalStoreApi;\n}\n\n/** Options accepted by every `notification.<variant>()` call */\nexport interface NotificationOptions extends Omit<ToastOptions, 'endContent'> {\n /**\n * The notification's end content. Either a node rendered directly, or a\n * render function that receives the {@link NotificationRenderProps} (incl. a\n * `modal` API to open a modal) and returns the node to render.\n */\n endContent?: ReactNode | ((props: NotificationRenderProps) => ReactNode);\n}\n\n// Render props passed to function-based options (e.g. `endContent`).\nconst renderProps: NotificationRenderProps = { modal };\n\n/**\n * Maps `NotificationOptions` to `ToastOptions` by resolving `endContent`:\n * a render function receives the render props and its returned node is used.\n */\nconst resolveOptions = (\n options?: NotificationOptions,\n): ToastOptions | undefined => {\n if (!options) {\n return undefined;\n }\n // Pull `endContent` out so the remaining options pass through unchanged.\n const { endContent, ...toastOptions } = options;\n\n return {\n ...toastOptions,\n // `ToastOptions.endContent` only accepts a node, so resolve the\n // render-function form down to one (a plain node passes through as-is).\n endContent:\n typeof endContent === 'function' ? endContent(renderProps) : endContent,\n };\n};\n\n/**\n * Imperative API for showing notifications: `default` / `info` / `warn` /\n * `success` / `error` show a notification (each returns an id), and `close`\n * dismisses one by id.\n *\n * Besides a plain node, `endContent` may be a render function that receives\n * the {@link NotificationRenderProps} — including a `modal` API — and returns\n * the node to render, e.g. to open a modal showing details that do not fit\n * into the notification itself.\n *\n * Requires a `<NotificationHost />` to be mounted in the React tree.\n *\n * @example\n * ```tsx\n * notification.error('A request failed.', {\n * title: 'Request failed',\n * endContent: ({ modal }) => (\n * <Button onClick={() => modal.open({ content: details })}>More</Button>\n * ),\n * });\n * ```\n */\nconst notification = {\n /**\n * Show a default notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n default: (message: ReactNode, options?: NotificationOptions) => {\n return toast.default(message, resolveOptions(options));\n },\n /**\n * Show an info notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n info: (message: ReactNode, options?: NotificationOptions) => {\n return toast.info(message, resolveOptions(options));\n },\n /**\n * Show a warning notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n warn: (message: ReactNode, options?: NotificationOptions) => {\n return toast.warn(message, resolveOptions(options));\n },\n /**\n * Show a success notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n success: (message: ReactNode, options?: NotificationOptions) => {\n return toast.success(message, resolveOptions(options));\n },\n /**\n * Show an error notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n error: (message: ReactNode, options?: NotificationOptions) => {\n return toast.error(message, resolveOptions(options));\n },\n /** Close a notification by its id */\n close: (id: string | number) => {\n toast.close(id);\n },\n};\n\nexport default notification;\n","import type { CSSProperties } from 'react';\n\nimport { ModalHost } from '@fuf-stack/pixels/Modal';\nimport { Toaster } from '@fuf-stack/pixels/Toast';\n\nexport interface NotificationHostProps {\n /**\n * Width applied to all toasts. A number is treated as pixels; a string is\n * used verbatim (e.g. `'600px'`, `'40rem'`). Sets Sonner's `--width` CSS\n * variable on the Toaster.\n */\n width?: number | string;\n}\n\n/**\n * Mounts the Toaster and ModalHost.\n *\n * Use once at the top level of your app:\n *\n * ```tsx\n * <NotificationHost />\n * ```\n */\nconst NotificationHost = ({ width = 600 }: NotificationHostProps) => {\n // Sonner defaults to z-index 999999999, which would render toasts above the\n // HeroUI modal (z-50). Lower it so modals opened from a toast's \"More\"\n // button stay on top. `--width` is passed inline because Sonner sets its\n // default `--width` inline on the same element, which beats class-based\n // overrides.\n const toasterStyle = {\n zIndex: 40,\n ...(width != null && {\n '--width': typeof width === 'number' ? `${width}px` : width,\n }),\n } as CSSProperties;\n return (\n <>\n <Toaster style={toasterStyle} />\n <ModalHost />\n </>\n );\n};\n\nexport default NotificationHost;\n","import notification from './notification';\nimport NotificationHost from './NotificationHost';\n\nexport type {\n NotificationOptions,\n NotificationRenderProps,\n} from './notification';\nexport type { NotificationHostProps } from './NotificationHost';\n\nexport { NotificationHost, notification };\nexport default notification;\n"],"mappings":";;;;;AA2BA,MAAM,cAAuC,EAAE,OAAA,wBAAA,MAAM;;;;;AAMrD,MAAM,kBACJ,YAC6B;CAC7B,IAAI,CAAC,SACH;CAGF,MAAM,EAAE,YAAY,GAAG,iBAAiB;CAExC,OAAO;EACL,GAAG;EAGH,YACE,OAAO,eAAe,aAAa,WAAW,WAAW,IAAI;CACjE;AACF;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,eAAe;;;;;CAKnB,UAAU,SAAoB,YAAkC;EAC9D,OAAOA,wBAAAA,MAAM,QAAQ,SAAS,eAAe,OAAO,CAAC;CACvD;;;;;CAKA,OAAO,SAAoB,YAAkC;EAC3D,OAAOA,wBAAAA,MAAM,KAAK,SAAS,eAAe,OAAO,CAAC;CACpD;;;;;CAKA,OAAO,SAAoB,YAAkC;EAC3D,OAAOA,wBAAAA,MAAM,KAAK,SAAS,eAAe,OAAO,CAAC;CACpD;;;;;CAKA,UAAU,SAAoB,YAAkC;EAC9D,OAAOA,wBAAAA,MAAM,QAAQ,SAAS,eAAe,OAAO,CAAC;CACvD;;;;;CAKA,QAAQ,SAAoB,YAAkC;EAC5D,OAAOA,wBAAAA,MAAM,MAAM,SAAS,eAAe,OAAO,CAAC;CACrD;;CAEA,QAAQ,OAAwB;EAC9B,wBAAA,MAAM,MAAM,EAAE;CAChB;AACF;;;;;;;;;;;;AC1FA,MAAM,oBAAoB,EAAE,QAAQ,UAAiC;CAYnE,OACE,iBAAA,GAAA,kBAAA,MAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAACC,wBAAAA,SAAD,EAAS,OAAO;EAPlB,QAAQ;EACR,GAAI,SAAS,QAAQ,EACnB,WAAW,OAAO,UAAU,WAAW,GAAG,MAAM,MAAM,MACxD;CAI6B,EAAI,CAAA,GAC/B,iBAAA,GAAA,kBAAA,KAACC,wBAAAA,WAAD,CAAY,CAAA,CACZ,EAAA,CAAA;AAEN;;;AC/BA,IAAA,uBAAe"}
1
+ {"version":3,"file":"Notification-ClLRWj0j.cjs","names":["toast","Toaster","ModalHost"],"sources":["../src/Notification/notification.tsx","../src/Notification/NotificationHost.tsx","../src/Notification/index.ts"],"sourcesContent":["import type { ModalStoreApi } from '@fuf-stack/pixels/Modal';\nimport type { ToastOptions } from '@fuf-stack/pixels/Toast';\nimport type { ReactNode } from 'react';\n\nimport { modal } from '@fuf-stack/pixels/Modal';\nimport { toast } from '@fuf-stack/pixels/Toast';\n\n/**\n * Props passed to function-based render props on a notification (e.g.\n * `endContent`), exposing helpers usable while rendering.\n */\nexport interface NotificationRenderProps {\n /** Imperative modal API for opening/closing a modal from a notification. */\n modal: ModalStoreApi;\n}\n\n/** Options accepted by every `notification.<variant>()` call */\nexport interface NotificationOptions extends Omit<ToastOptions, 'endContent'> {\n /**\n * The notification's end content. Either a node rendered directly, or a\n * render function that receives the {@link NotificationRenderProps} (incl. a\n * `modal` API to open a modal) and returns the node to render.\n */\n endContent?: ReactNode | ((props: NotificationRenderProps) => ReactNode);\n}\n\n// Render props passed to function-based options (e.g. `endContent`).\nconst renderProps: NotificationRenderProps = { modal };\n\n/**\n * Maps `NotificationOptions` to `ToastOptions` by resolving `endContent`:\n * a render function receives the render props and its returned node is used.\n */\nconst resolveOptions = (\n options?: NotificationOptions,\n): ToastOptions | undefined => {\n if (!options) {\n return undefined;\n }\n // Pull `endContent` out so the remaining options pass through unchanged.\n const { endContent, ...toastOptions } = options;\n\n return {\n ...toastOptions,\n // `ToastOptions.endContent` only accepts a node, so resolve the\n // render-function form down to one (a plain node passes through as-is).\n endContent:\n typeof endContent === 'function' ? endContent(renderProps) : endContent,\n };\n};\n\n/**\n * Imperative API for showing notifications: `default` / `info` / `warn` /\n * `success` / `error` show a notification (each returns an id), and `close`\n * dismisses one by id.\n *\n * Besides a plain node, `endContent` may be a render function that receives\n * the {@link NotificationRenderProps} — including a `modal` API — and returns\n * the node to render, e.g. to open a modal showing details that do not fit\n * into the notification itself.\n *\n * Requires a `<NotificationHost />` to be mounted in the React tree.\n *\n * @example\n * ```tsx\n * notification.error('A request failed.', {\n * title: 'Request failed',\n * endContent: ({ modal }) => (\n * <Button onClick={() => modal.open({ content: details })}>More</Button>\n * ),\n * });\n * ```\n */\nconst notification = {\n /**\n * Show a default notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n default: (message: ReactNode, options?: NotificationOptions) => {\n return toast.default(message, resolveOptions(options));\n },\n /**\n * Show an info notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n info: (message: ReactNode, options?: NotificationOptions) => {\n return toast.info(message, resolveOptions(options));\n },\n /**\n * Show a warning notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n warn: (message: ReactNode, options?: NotificationOptions) => {\n return toast.warn(message, resolveOptions(options));\n },\n /**\n * Show a success notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n success: (message: ReactNode, options?: NotificationOptions) => {\n return toast.success(message, resolveOptions(options));\n },\n /**\n * Show an error notification.\n * @returns The toast id which can be passed to `notification.close()`\n */\n error: (message: ReactNode, options?: NotificationOptions) => {\n return toast.error(message, resolveOptions(options));\n },\n /** Close a notification by its id */\n close: (id: string | number) => {\n toast.close(id);\n },\n};\n\nexport default notification;\n","import type { CSSProperties } from 'react';\n\nimport { ModalHost } from '@fuf-stack/pixels/Modal';\nimport { Toaster } from '@fuf-stack/pixels/Toast';\n\nexport interface NotificationHostProps {\n /**\n * Width applied to all toasts. A number is treated as pixels; a string is\n * used verbatim (e.g. `'600px'`, `'40rem'`). Sets Sonner's `--width` CSS\n * variable on the Toaster.\n */\n width?: number | string;\n}\n\n/**\n * Mounts the Toaster and ModalHost.\n *\n * Use once at the top level of your app:\n *\n * ```tsx\n * <NotificationHost />\n * ```\n */\nconst NotificationHost = ({ width = 600 }: NotificationHostProps) => {\n // Sonner defaults to z-index 999999999, which would render toasts above the\n // HeroUI modal (z-50). Lower it so modals opened from a toast's \"More\"\n // button stay on top. `--width` is passed inline because Sonner sets its\n // default `--width` inline on the same element, which beats class-based\n // overrides.\n const toasterStyle = {\n zIndex: 40,\n ...(width != null && {\n '--width': typeof width === 'number' ? `${width}px` : width,\n }),\n } as CSSProperties;\n return (\n <>\n <Toaster style={toasterStyle} />\n <ModalHost />\n </>\n );\n};\n\nexport default NotificationHost;\n","import notification from './notification';\nimport NotificationHost from './NotificationHost';\n\nexport type {\n NotificationOptions,\n NotificationRenderProps,\n} from './notification';\nexport type { NotificationHostProps } from './NotificationHost';\n\nexport { NotificationHost, notification };\nexport default notification;\n"],"mappings":";;;;AA2BA,MAAM,cAAuC,EAAE,OAAA,wBAAA,MAAM;;;;;AAMrD,MAAM,kBACJ,YAC6B;CAC7B,IAAI,CAAC,SACH;CAGF,MAAM,EAAE,YAAY,GAAG,iBAAiB;CAExC,OAAO;EACL,GAAG;EAGH,YACE,OAAO,eAAe,aAAa,WAAW,WAAW,IAAI;CACjE;AACF;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,eAAe;;;;;CAKnB,UAAU,SAAoB,YAAkC;EAC9D,OAAOA,wBAAAA,MAAM,QAAQ,SAAS,eAAe,OAAO,CAAC;CACvD;;;;;CAKA,OAAO,SAAoB,YAAkC;EAC3D,OAAOA,wBAAAA,MAAM,KAAK,SAAS,eAAe,OAAO,CAAC;CACpD;;;;;CAKA,OAAO,SAAoB,YAAkC;EAC3D,OAAOA,wBAAAA,MAAM,KAAK,SAAS,eAAe,OAAO,CAAC;CACpD;;;;;CAKA,UAAU,SAAoB,YAAkC;EAC9D,OAAOA,wBAAAA,MAAM,QAAQ,SAAS,eAAe,OAAO,CAAC;CACvD;;;;;CAKA,QAAQ,SAAoB,YAAkC;EAC5D,OAAOA,wBAAAA,MAAM,MAAM,SAAS,eAAe,OAAO,CAAC;CACrD;;CAEA,QAAQ,OAAwB;EAC9B,wBAAA,MAAM,MAAM,EAAE;CAChB;AACF;;;;;;;;;;;;AC1FA,MAAM,oBAAoB,EAAE,QAAQ,UAAiC;CAYnE,OACE,iBAAA,GAAA,kBAAA,MAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAACC,wBAAAA,SAAD,EAAS,OAAO;EAPlB,QAAQ;EACR,GAAI,SAAS,QAAQ,EACnB,WAAW,OAAO,UAAU,WAAW,GAAG,MAAM,MAAM,MACxD;CAI6B,EAAI,CAAA,GAC/B,iBAAA,GAAA,kBAAA,KAACC,wBAAAA,WAAD,CAAY,CAAA,CACZ,EAAA,CAAA;AAEN;;;AC/BA,IAAA,uBAAe"}
@@ -2057,4 +2057,4 @@ declare const filters: {
2057
2057
  };
2058
2058
  //#endregion
2059
2059
  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 };
2060
- //# sourceMappingURL=index-CJCs9Cxu.d.cts.map
2060
+ //# sourceMappingURL=index-BkliAQ5x.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-CJCs9Cxu.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"],"mappings":"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"}
1
+ {"version":3,"file":"index-BkliAQ5x.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"],"mappings":"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"}
@@ -2057,4 +2057,4 @@ declare const filters: {
2057
2057
  };
2058
2058
  //#endregion
2059
2059
  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 };
2060
- //# sourceMappingURL=index-7N5og-TT.d.ts.map
2060
+ //# sourceMappingURL=index-DNAyXW3U.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-7N5og-TT.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"],"mappings":"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"}
1
+ {"version":3,"file":"index-DNAyXW3U.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"],"mappings":";;;;;;cAMa,QAAA,4BAAM,aAAA;;AAAnB;;;;EAAmB;;;;;;;;;;;;KAgBP,MAAA,GAAS,IAAA,CAAK,MAAA,QAAc,QAAA;EACtC,OAAA;IACE,KAAA,EAAO,SAAA,KAAc,IAAA,yBAA6B,SAAA;IAClD,KAAA;EAAA;AAAA;;;;;;;AAnBJ;;;;;;;UCOiB,gBAAA;EACf,UAAA;;;;;IAKE,OAAA,GAAU,KAAA;MAAS,KAAA,EAAO,KAAA;MAAO,MAAA,EAAQ,MAAA;IAAA,MAAa,SAAA;IDGxC;;;;ICEd,IAAA,GAAO,KAAA;MAAS,SAAA;MAAmB,MAAA,EAAQ,MAAA;IAAA,MAAa,SAAA;EAAA;EAE1D,QAAA;IDJwB,yECMtB,MAAA,EAAQ,MAAA,EDLV;ICOE,KAAA,EAAO,KAAA;EAAA;EDNc;;;;ECYvB,UAAA,GAAa,MAAA,GAAS,MAAA;AAAA;;;AAvBxB;;;;;;;;KAoCY,aAAA,mBAAgC,IAAA;EAnBjC,sEAqBT,MAAA,GAAS,OAAA,CAAQ,MAAA,GAfW;EAiB5B,IAAA,GAAO,SAAA,EAxCyB;EA0ChC,IAAA;AAAA,MACI,cAAA,CAAe,MAAA,EAAQ,KAAA;;;;;;;;;;;;UAaZ,cAAA;EA7C2C;EA+C1D,UAAA,EAAY,gBAAA,CAAiB,MAAA,EAAQ,KAAA;EA3CnC;EA6CF,MAAA,EAAQ,MAAA;EA3CN;EA6CF,YAAA,EAAc,KAAA;EAvCd;EAyCA,IAAA,GAAO,SAAA;EAzCM;EA2Cb,IAAA;EA3C4B;EA6C5B,UAAA,GAAa,MAAA,GAAS,MAAA;AAAA;;;;;;;;;KAWZ,oBAAA,GAAuB,cAAc;;;;;;;;;;UAWhC,kBAAA;EA/CI;EAiDnB,MAAA,EAAQ,MAAA;EAjDwB;EAmDhC,KAAA,EAAO,KAAK;AAAA;;;;;;;;;;UAYG,eAAA;EAtCa;EAwC5B,MAAA,EAAQ,MAAM;EApDwB;EAsDtC,SAAA;AAAA;;;KClHU,mBAAA;8CAIN,WAAW;AAAA;;;cCQJ,cAAA,IAAc,KAAA;EAAA;;;gbHFzB;;;;;;;;;;;;;obAGgB;AAAA;EAAA;;;gbAAG;;;;obAE0C;AAAA;EAAA;;;gbAA3D;;;;obACA;AAAA;EAAA;;;;;;;obCN0B;AAAA;gbAA4B;;;;obAW/C;AAAA;;;;;kbAhBT;;;;sbAKmC;EAAA;IAAA;;;kbAKjB;;;;sbAAwC;EAAA;IAAA;;;kbAMjD;;;;sbAMmB;EAAA;IAAA;;;kbAeX;;;;sbAKU;EAAA;IAAA;;;kbAPK;;;;sbAIhC;EAAA;kbAEA;;;;sbAC2B;EAAA;;;;;kbAeE;;;;sbAIf;EAAA;IAAA;;;kbANgB;;;;sbAED;EAAA;IAAA;;;kbAIf;;;;sbAMd;EAAA;IAAA;;;kbAW8B;;;;sbAAiB;EAAA;IAAA;;;kbAWb;;;;sbAIlC;EAAA;kbAAY;;;;sbAcE;EAAA;;;;;kbAEL;;;;;;;;;kbC9GM;;;;sbCuCf;EAAA;IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sbAEY;EAAA;IAAA;;;kbAEe;;;;sbAE3B;EAAA;IAAA;;;kbAG6B;;;;sbAE7B;EAAA;IAAA;;;kbACa;;;;sbAqBF;EAAA;kbASA;;;;sbASS;EAAA;AAAA;;kbAhBpB;;;;sbAOW;EAAA;;obAKX;;;;wbAIA;IAAA;;obAAoB;;;;wbAQN;IAAA;;obAAA;;;;wbAOF;IAAA;;obAPE;;;;wbAAA;IAAA;;obAAA;;;;wbAOb;IAAA;;obAuFF;;;;;;;obC7KA;;;;wbAXgB;IAAA;;obAAD;;;;wbADF;IAAA;;obAAZ;;;;wbAC4B;IAAA;;;;;;wbCP7B;IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KFwCI,SAAA,GAAY,WAAW,QAAQ,cAAA;AAAA,UAEnB,YAAA;EACf,MAAA;EACA,MAAA,YAAkB,MAAM;AAAA;AAAA,KAGd,mBAAA,IAAuB,MAAA;EACjC,MAAA;EACA,MAAA,GAAS,MAAA;AAAA,MACL,SAAS;;;;;;;;;;;;;;;;;;UAmBE,WAAA;;EAEf,QAAA,GAAW,mBAAA;;EAEX,SAAA,GAAY,SAAA;;EAEZ,MAAA;;;;;IAKE,OAAA,EAAS,oBAAA;IAET,MAAA,GAAS,mBAAA;EAAA;;EAGX,QAAA;;EAEA,QAAA,GAAW,UAAA,EAAY,YAAA;;EAEvB,MAAA,EAAQ,YAAA;AAAA;;;;;;cAQJ,MAAA;EAAU,QAAA;EAAA,SAAA;EAAA,MAAA;EAAA,QAAA;EAAA,QAAA;EAAA;AAAA,GAOb,WAAA,iCAAW,GAAA,CAAA,OAAA;;;;;;;AHhHd;;;;;;;;;;;;;cIaM,YAAA,kBACJ,UAAA,EAAY,gBAAA,CAAiB,MAAA,EAAQ,KAAA,MACpC,aAAA,CAAc,MAAA,EAAQ,KAAA;;;cCVZ,OAAA;WAGZ,aAAA"}
@@ -94,4 +94,4 @@ declare const NotificationHost: ({
94
94
  }: NotificationHostProps) => import("react/jsx-runtime").JSX.Element;
95
95
  //#endregion
96
96
  export { notification as a, NotificationRenderProps as i, NotificationHostProps as n, NotificationOptions as r, NotificationHost as t };
97
- //# sourceMappingURL=index-DMd9TyqF.d.cts.map
97
+ //# sourceMappingURL=index-DRyBPfQT.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-DMd9TyqF.d.cts","names":[],"sources":["../src/Notification/notification.tsx","../src/Notification/NotificationHost.tsx"],"mappings":";;;;;;;AAWA;;UAAiB,uBAAA;EAEf;EAAA,KAAA,EAAO,aAAa;AAAA;;UAIL,mBAAA,SAA4B,IAAA,CAAK,YAAA;EAAA;;;;;EAMhD,UAAA,GAAa,SAAA,KAAc,KAAA,EAAO,uBAAA,KAA4B,SAAA;AAAA;;;;;;;;;AAAS;AACxE;;;;;;;;;;;;;cAiDK,YAAA;EAiCqD;;;;qBA5BtC,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;kBAOZ,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;kBAOT,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;qBAON,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;mBAOX,SAAA,EAAS,OAAA,GAAY,mBAAA,UAAZ;;;;;UCrGX,qBAAA;;;;;ADMjB;ECAE,KAAK;AAAA;;ADEe;AAItB;;;;;;;cCMM,gBAAA;EAAoB;AAAA,GAAiB,qBAAqB,iCAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"index-DRyBPfQT.d.cts","names":[],"sources":["../src/Notification/notification.tsx","../src/Notification/NotificationHost.tsx"],"mappings":";;;;;;;AAWA;;UAAiB,uBAAA;EAEf;EAAA,KAAA,EAAO,aAAa;AAAA;;UAIL,mBAAA,SAA4B,IAAA,CAAK,YAAA;EAAA;;;;;EAMhD,UAAA,GAAa,SAAA,KAAc,KAAA,EAAO,uBAAA,KAA4B,SAAA;AAAA;;;;;;;;;AAAS;AACxE;;;;;;;;;;;;;cAiDK,YAAA;EAiCqD;;;;qBA5BtC,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;kBAOZ,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;kBAOT,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;qBAON,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;mBAOX,SAAA,EAAS,OAAA,GAAY,mBAAA,UAAZ;;;;;UCrGX,qBAAA;;;;;ADMjB;ECAE,KAAK;AAAA;;ADEe;AAItB;;;;;;;cCMM,gBAAA;EAAoB;AAAA,GAAiB,qBAAqB,iCAAA,GAAA,CAAA,OAAA"}
@@ -94,4 +94,4 @@ declare const NotificationHost: ({
94
94
  }: NotificationHostProps) => import("react/jsx-runtime").JSX.Element;
95
95
  //#endregion
96
96
  export { notification as a, NotificationRenderProps as i, NotificationHostProps as n, NotificationOptions as r, NotificationHost as t };
97
- //# sourceMappingURL=index-DaLo1TQx.d.ts.map
97
+ //# sourceMappingURL=index-DRyBPfQT.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-DaLo1TQx.d.ts","names":[],"sources":["../src/Notification/notification.tsx","../src/Notification/NotificationHost.tsx"],"mappings":";;;;;;;AAWA;;UAAiB,uBAAA;EAEf;EAAA,KAAA,EAAO,aAAa;AAAA;;UAIL,mBAAA,SAA4B,IAAA,CAAK,YAAA;EAAA;;;;;EAMhD,UAAA,GAAa,SAAA,KAAc,KAAA,EAAO,uBAAA,KAA4B,SAAA;AAAA;;;;;;;;;AAAS;AACxE;;;;;;;;;;;;;cAiDK,YAAA;EAiCqD;;;;qBA5BtC,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;kBAOZ,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;kBAOT,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;qBAON,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;mBAOX,SAAA,EAAS,OAAA,GAAY,mBAAA,UAAZ;;;;;UCrGX,qBAAA;;;;;ADMjB;ECAE,KAAK;AAAA;;ADEe;AAItB;;;;;;;cCMM,gBAAA;EAAoB;AAAA,GAAiB,qBAAqB,iCAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"index-DRyBPfQT.d.ts","names":[],"sources":["../src/Notification/notification.tsx","../src/Notification/NotificationHost.tsx"],"mappings":";;;;;;;AAWA;;UAAiB,uBAAA;EAEf;EAAA,KAAA,EAAO,aAAa;AAAA;;UAIL,mBAAA,SAA4B,IAAA,CAAK,YAAA;EAAA;;;;;EAMhD,UAAA,GAAa,SAAA,KAAc,KAAA,EAAO,uBAAA,KAA4B,SAAA;AAAA;;;;;;;;;AAAS;AACxE;;;;;;;;;;;;;cAiDK,YAAA;EAiCqD;;;;qBA5BtC,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;kBAOZ,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;kBAOT,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;qBAON,SAAA,EAAS,OAAA,GAAY,mBAAA;EAAZ;;;;mBAOX,SAAA,EAAS,OAAA,GAAY,mBAAA,UAAZ;;;;;UCrGX,qBAAA;;;;;ADMjB;ECAE,KAAK;AAAA;;ADEe;AAItB;;;;;;;cCMM,gBAAA;EAAoB;AAAA,GAAiB,qBAAqB,iCAAA,GAAA,CAAA,OAAA"}
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_Filter = require("./Filter-BVwu1kNx.cjs");
3
- const require_Notification = require("./Notification-BjftuLye.cjs");
2
+ const require_Filter = require("./Filter-B_YqTFA5.cjs");
3
+ const require_Notification = require("./Notification-ClLRWj0j.cjs");
4
4
  //#region src/index.ts
5
5
  /* v8 ignore stop */
6
6
  //#endregion
package/dist/index.d.cts CHANGED
@@ -1,3 +1,3 @@
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-CJCs9Cxu.cjs";
2
- import { a as notification, i as NotificationRenderProps, n as NotificationHostProps, r as NotificationOptions, t as NotificationHost } from "./index-DMd9TyqF.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-BkliAQ5x.cjs";
2
+ import { a as notification, i as NotificationRenderProps, n as NotificationHostProps, r as NotificationOptions, t as NotificationHost } from "./index-DRyBPfQT.cjs";
3
3
  export { FilterChildRenderFn, type FilterDefinition, type FilterDisplayProps, type FilterFactory, type FilterFormProps, type FilterInstance, FilterProps, FilterValues, type FiltersConfiguration, NotificationHost, type NotificationHostProps, type NotificationOptions, type NotificationRenderProps, createFilter, filterVariants, filters, notification };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
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-7N5og-TT.js";
2
- import { a as notification, i as NotificationRenderProps, n as NotificationHostProps, r as NotificationOptions, t as NotificationHost } from "./index-DaLo1TQx.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-DNAyXW3U.js";
2
+ import { a as notification, i as NotificationRenderProps, n as NotificationHostProps, r as NotificationOptions, t as NotificationHost } from "./index-DRyBPfQT.js";
3
3
  export { FilterChildRenderFn, type FilterDefinition, type FilterDisplayProps, type FilterFactory, type FilterFormProps, type FilterInstance, FilterProps, FilterValues, type FiltersConfiguration, NotificationHost, type NotificationHostProps, type NotificationOptions, type NotificationRenderProps, createFilter, filterVariants, filters, notification };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { i as filterVariants, n as filters, r as createFilter } from "./Filter-MoxrK8MI.js";
2
- import { n as NotificationHost, r as notification } from "./Notification-B-G4OVD2.js";
1
+ import { i as filterVariants, n as filters, r as createFilter } from "./Filter-DHNzbevz.js";
2
+ import { n as NotificationHost, r as notification } from "./Notification-5tyFF-87.js";
3
3
  //#region src/index.ts
4
4
  /* v8 ignore stop */
5
5
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuf-stack/megapixels",
3
- "version": "0.11.25",
3
+ "version": "0.11.27",
4
4
  "description": "fuf react advanced components library",
5
5
  "author": "Fröhlich ∧ Frei",
6
6
  "homepage": "https://github.com/fuf-stack/megapixels#readme",
@@ -50,10 +50,10 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@fuf-stack/pixel-motion": "1.2.2",
53
- "@fuf-stack/pixel-utils": "1.3.1",
54
- "@fuf-stack/pixels": "1.11.1",
55
- "@fuf-stack/uniform": "1.22.5",
56
- "@fuf-stack/veto": "1.7.2",
53
+ "@fuf-stack/pixel-utils": "1.3.2",
54
+ "@fuf-stack/pixels": "1.11.2",
55
+ "@fuf-stack/uniform": "1.22.7",
56
+ "@fuf-stack/veto": "1.7.3",
57
57
  "debug": "4.4.3",
58
58
  "react-icons": "5.6.0"
59
59
  },
@@ -64,5 +64,5 @@
64
64
  "react": "19.2.6",
65
65
  "react-dom": "19.2.6"
66
66
  },
67
- "gitHead": "5fc894eb5b00c05de016d88466523a07ad858c99"
67
+ "gitHead": "87fd30d29958345d893297d200c3716592e80b2e"
68
68
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"Filter-BVwu1kNx.cjs","names":["Label","Menu","FaSliders","Modal","Button","SubmitButton","PiSlidersHorizontalBold","Suspense","Button","FaSearch","motion","Input","SubmitButton","debug","Form","Display","Form","Switch","config","validate","validate","Checkboxes"],"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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"}