@kopexa/filter 0.0.25 → 0.0.26

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 (51) hide show
  1. package/dist/chunk-6TRAIAKS.mjs +178 -0
  2. package/dist/chunk-I7WCYMXD.mjs +133 -0
  3. package/dist/{chunk-45QJL74L.mjs → chunk-JSRGUDCG.mjs} +49 -24
  4. package/dist/chunk-NUDUXOHP.mjs +243 -0
  5. package/dist/chunk-ON2UFJ3Y.mjs +32 -0
  6. package/dist/{chunk-RFCPJLIQ.mjs → chunk-SJXRD3RO.mjs} +6 -1
  7. package/dist/{chunk-EF4VI36D.mjs → chunk-UBTUCPOG.mjs} +1 -1
  8. package/dist/{chunk-3ZBNWXRA.mjs → chunk-WD7YU6IN.mjs} +17 -14
  9. package/dist/chunk-XCWKWXBW.mjs +602 -0
  10. package/dist/{chunk-URDCG5NI.mjs → chunk-YTYOFT33.mjs} +52 -0
  11. package/dist/filter-active.js +108 -28
  12. package/dist/filter-active.mjs +4 -4
  13. package/dist/filter-bar-internal.d.mts +25 -0
  14. package/dist/filter-bar-internal.d.ts +25 -0
  15. package/dist/filter-bar-internal.js +648 -0
  16. package/dist/filter-bar-internal.mjs +11 -0
  17. package/dist/filter-bar-messages.d.mts +124 -0
  18. package/dist/filter-bar-messages.d.ts +124 -0
  19. package/dist/filter-bar-messages.js +156 -0
  20. package/dist/filter-bar-messages.mjs +7 -0
  21. package/dist/filter-bar-types.d.mts +112 -0
  22. package/dist/filter-bar-types.d.ts +112 -0
  23. package/dist/filter-bar-types.js +56 -0
  24. package/dist/filter-bar-types.mjs +8 -0
  25. package/dist/filter-bar.d.mts +29 -0
  26. package/dist/filter-bar.d.ts +29 -0
  27. package/dist/filter-bar.js +942 -0
  28. package/dist/filter-bar.mjs +11 -0
  29. package/dist/filter-menu.js +161 -1
  30. package/dist/filter-menu.mjs +2 -1
  31. package/dist/filter-trigger.js +52 -0
  32. package/dist/filter-trigger.mjs +2 -2
  33. package/dist/filter-value-editor.js +65 -10
  34. package/dist/filter-value-editor.mjs +3 -3
  35. package/dist/filter.d.mts +6 -0
  36. package/dist/filter.d.ts +6 -0
  37. package/dist/filter.mjs +2 -2
  38. package/dist/index.d.mts +4 -0
  39. package/dist/index.d.ts +4 -0
  40. package/dist/index.js +1263 -31
  41. package/dist/index.mjs +28 -14
  42. package/dist/messages.d.mts +50 -0
  43. package/dist/messages.d.ts +50 -0
  44. package/dist/messages.js +52 -0
  45. package/dist/messages.mjs +1 -1
  46. package/dist/search-filter-bar.d.mts +44 -0
  47. package/dist/search-filter-bar.d.ts +44 -0
  48. package/dist/search-filter-bar.js +1007 -0
  49. package/dist/search-filter-bar.mjs +11 -0
  50. package/package.json +19 -16
  51. package/dist/{chunk-SH7DBK54.mjs → chunk-LWDVRMCI.mjs} +3 -3
@@ -168,6 +168,58 @@ var messages = (0, import_i18n.defineMessages)({
168
168
  id: "filter.operator.is_not_empty",
169
169
  defaultMessage: "is not empty",
170
170
  description: "Operator: is not empty"
171
+ },
172
+ // Additional UI strings
173
+ loading: {
174
+ id: "filter.loading",
175
+ defaultMessage: "Loading...",
176
+ description: "Loading state text"
177
+ },
178
+ boolean_true: {
179
+ id: "filter.boolean_true",
180
+ defaultMessage: "Yes",
181
+ description: "Boolean true value display"
182
+ },
183
+ boolean_false: {
184
+ id: "filter.boolean_false",
185
+ defaultMessage: "No",
186
+ description: "Boolean false value display"
187
+ },
188
+ range_min: {
189
+ id: "filter.range_min",
190
+ defaultMessage: "Min",
191
+ description: "Minimum value placeholder for range inputs"
192
+ },
193
+ range_max: {
194
+ id: "filter.range_max",
195
+ defaultMessage: "Max",
196
+ description: "Maximum value placeholder for range inputs"
197
+ },
198
+ // Accessibility labels
199
+ remove_filter: {
200
+ id: "filter.remove_filter",
201
+ defaultMessage: "Remove {field} filter",
202
+ description: "Accessibility label for remove filter button"
203
+ },
204
+ operator_label: {
205
+ id: "filter.operator_label",
206
+ defaultMessage: "{field} operator",
207
+ description: "Accessibility label for operator select"
208
+ },
209
+ value_label: {
210
+ id: "filter.value_label",
211
+ defaultMessage: "{field} value",
212
+ description: "Accessibility label for value input"
213
+ },
214
+ value_min_label: {
215
+ id: "filter.value_min_label",
216
+ defaultMessage: "{field} minimum value",
217
+ description: "Accessibility label for minimum value input"
218
+ },
219
+ value_max_label: {
220
+ id: "filter.value_max_label",
221
+ defaultMessage: "{field} maximum value",
222
+ description: "Accessibility label for maximum value input"
171
223
  }
172
224
  });
173
225
 
@@ -309,27 +361,29 @@ function ValueInput({
309
361
  placeholder: (_c = field.placeholder) != null ? _c : t.formatMessage(messages.select_value)
310
362
  }
311
363
  ) }),
312
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_select.Select.Content, { children: (_d = field.options) == null ? void 0 : _d.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
364
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_select.Select.Content, { children: (_d = field.options) == null ? void 0 : _d.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
313
365
  import_select.Select.Item,
314
366
  {
315
367
  value: option.value,
316
368
  disabled: option.disabled,
317
- children: [
318
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mr-2 size-4", children: option.icon }),
369
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-2", children: [
370
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "size-4 flex-shrink-0", children: option.icon }),
319
371
  option.label
320
- ]
372
+ ] })
321
373
  },
322
374
  option.value
323
375
  )) })
324
376
  ] });
325
377
  case "multiselect": {
326
- const selectedValues = Array.isArray(value) ? value : [];
327
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-2 max-h-[200px] overflow-auto", children: (_e = field.options) == null ? void 0 : _e.map((option) => (
378
+ const selectedValues = Array.isArray(value) ? value.filter(
379
+ (v) => typeof v === "string" && v.length > 1
380
+ ) : [];
381
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-1 max-h-[200px] overflow-auto p-1", children: (_e = field.options) == null ? void 0 : _e.map((option) => (
328
382
  // biome-ignore lint/a11y/noLabelWithoutControl: Checkbox is a custom form control inside the label
329
383
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
330
384
  "label",
331
385
  {
332
- className: "flex items-center gap-2 cursor-pointer",
386
+ className: "flex items-center gap-2 cursor-pointer hover:bg-muted/50 rounded-md px-2 py-1.5",
333
387
  children: [
334
388
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
335
389
  import_checkbox.Checkbox,
@@ -342,11 +396,12 @@ function ValueInput({
342
396
  onChange(selectedValues.filter((v) => v !== option.value));
343
397
  }
344
398
  },
345
- disabled: option.disabled
399
+ disabled: option.disabled,
400
+ className: "flex-shrink-0 border-border bg-background data-[state=checked]:bg-primary data-[state=checked]:border-primary [&_svg]:text-primary-foreground"
346
401
  }
347
402
  ),
348
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "size-4", children: option.icon }),
349
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm", children: option.label })
403
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "flex-shrink-0 [&>*]:size-5", children: option.icon }),
404
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm truncate", children: option.label })
350
405
  ]
351
406
  },
352
407
  option.value
@@ -458,6 +513,7 @@ function FilterField({ filter }) {
458
513
  const field = fields.get(filter.fieldId);
459
514
  if (!field) return null;
460
515
  const availableOperators = (_a = field.operators) != null ? _a : DEFAULT_OPERATORS[field.type];
516
+ const hasSingleOperator = availableOperators.length === 1;
461
517
  const getOperatorLabel = (op) => {
462
518
  const opKey = `op_${op}`;
463
519
  return messages[opKey] ? t.formatMessage(messages[opKey]) : op;
@@ -482,20 +538,29 @@ function FilterField({ filter }) {
482
538
  field.icon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "size-4 flex-shrink-0", children: field.icon }),
483
539
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: field.label })
484
540
  ] }),
485
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: styles.fieldOperator(), children: [
541
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: styles.fieldOperator(), children: hasSingleOperator ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
542
+ "span",
543
+ {
544
+ className: styles.fieldOperatorSelect(),
545
+ style: { width: operatorWidth },
546
+ children: currentOperatorLabel
547
+ }
548
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
486
549
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
487
550
  "select",
488
551
  {
489
552
  className: styles.fieldOperatorSelect(),
490
553
  value: filter.operator,
491
554
  onChange: handleOperatorChange,
492
- title: currentOperatorLabel,
555
+ "aria-label": t.formatMessage(messages.operator_label, {
556
+ field: field.label
557
+ }),
493
558
  style: { width: operatorWidth },
494
559
  children: availableOperators.map((op) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: op, children: getOperatorLabel(op) }, op))
495
560
  }
496
561
  ),
497
562
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.ChevronDownIcon, { className: styles.fieldOperatorIcon() })
498
- ] }),
563
+ ] }) }),
499
564
  useInlineInput && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(InlineValueInput, { filter, field }),
500
565
  useInlineSwitch && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: styles.fieldValue(), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
501
566
  import_switch.Switch,
@@ -515,7 +580,9 @@ function FilterField({ filter }) {
515
580
  type: "button",
516
581
  className: styles.fieldRemove(),
517
582
  onClick: () => removeFilter(filter.id),
518
- "aria-label": "Remove filter",
583
+ "aria-label": t.formatMessage(messages.remove_filter, {
584
+ field: field.label
585
+ }),
519
586
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.CloseIcon, { className: "size-3" })
520
587
  }
521
588
  )
@@ -544,6 +611,8 @@ function InlineValueInput({
544
611
  const placeholder = (_a = field.placeholder) != null ? _a : t.formatMessage(messages.enter_value);
545
612
  if (filter.operator === "between") {
546
613
  const [min, max] = Array.isArray(filter.value) ? filter.value : [void 0, void 0];
614
+ const minPlaceholder = t.formatMessage(messages.range_min);
615
+ const maxPlaceholder = t.formatMessage(messages.range_max);
547
616
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: (0, import_shared_utils.cn)(styles.fieldValue(), "gap-1"), children: [
548
617
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
549
618
  "input",
@@ -555,8 +624,11 @@ function InlineValueInput({
555
624
  const val = e.target.value ? Number(e.target.value) : void 0;
556
625
  updateFilter(filter.id, { value: [val, max] });
557
626
  },
558
- placeholder: "Min",
559
- style: { width: getInputWidth(min, "Min", 3) },
627
+ placeholder: minPlaceholder,
628
+ "aria-label": t.formatMessage(messages.value_min_label, {
629
+ field: field.label
630
+ }),
631
+ style: { width: getInputWidth(min, minPlaceholder, 3) },
560
632
  min: field.min,
561
633
  max: field.max,
562
634
  step: field.step
@@ -573,8 +645,11 @@ function InlineValueInput({
573
645
  const val = e.target.value ? Number(e.target.value) : void 0;
574
646
  updateFilter(filter.id, { value: [min, val] });
575
647
  },
576
- placeholder: "Max",
577
- style: { width: getInputWidth(max, "Max", 3) },
648
+ placeholder: maxPlaceholder,
649
+ "aria-label": t.formatMessage(messages.value_max_label, {
650
+ field: field.label
651
+ }),
652
+ style: { width: getInputWidth(max, maxPlaceholder, 3) },
578
653
  min: field.min,
579
654
  max: field.max,
580
655
  step: field.step
@@ -590,6 +665,9 @@ function InlineValueInput({
590
665
  value: filter.value !== void 0 && filter.value !== null ? String(filter.value) : "",
591
666
  onChange: handleChange,
592
667
  placeholder,
668
+ "aria-label": t.formatMessage(messages.value_label, {
669
+ field: field.label
670
+ }),
593
671
  style: { width: getInputWidth(filter.value, placeholder, 6) },
594
672
  min: field.min,
595
673
  max: field.max,
@@ -602,7 +680,8 @@ function PopoverValueEditor({
602
680
  field
603
681
  }) {
604
682
  const { styles, updateFilter } = useFilterContext();
605
- const valueDisplay = field.renderValue ? field.renderValue({ filter, field }) : getValueDisplay(filter, field);
683
+ const t = (0, import_i18n3.useSafeIntl)();
684
+ const valueDisplay = field.renderValue ? field.renderValue({ filter, field }) : getValueDisplay(filter, field, t);
606
685
  const hasValue = filter.value !== void 0 && filter.value !== null && filter.value !== "" && !(Array.isArray(filter.value) && filter.value.length === 0);
607
686
  const handleCustomChange = (value) => {
608
687
  updateFilter(filter.id, { value });
@@ -615,7 +694,7 @@ function PopoverValueEditor({
615
694
  render: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {}),
616
695
  nativeButton: false,
617
696
  children: [
618
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: styles.fieldValueText(), children: hasValue ? valueDisplay : "Select..." }),
697
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: styles.fieldValueText(), children: hasValue ? valueDisplay : t.formatMessage(messages.select_value) }),
619
698
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.ChevronDownIcon, { className: styles.fieldValueIcon() })
620
699
  ]
621
700
  }
@@ -642,7 +721,7 @@ function PopoverValueEditor({
642
721
  )
643
722
  ] });
644
723
  }
645
- function getValueDisplay(filter, field) {
724
+ function getValueDisplay(filter, field, t) {
646
725
  var _a, _b, _c, _d;
647
726
  const { value, operator } = filter;
648
727
  if (operator === "is_empty" || operator === "is_not_empty") {
@@ -652,19 +731,20 @@ function getValueDisplay(filter, field) {
652
731
  return null;
653
732
  }
654
733
  if (field.type === "boolean") {
655
- return value ? "Yes" : "No";
734
+ return value ? t.formatMessage(messages.boolean_true) : t.formatMessage(messages.boolean_false);
656
735
  }
657
736
  if (field.type === "select" && field.options) {
658
737
  const option = field.options.find((o) => o.value === value);
659
738
  return (_a = option == null ? void 0 : option.label) != null ? _a : String(value);
660
739
  }
661
- if (field.type === "multiselect" && Array.isArray(value)) {
662
- if (value.length === 0) return null;
663
- if (value.length === 1 && field.options) {
664
- const option = field.options.find((o) => o.value === value[0]);
665
- return (_b = option == null ? void 0 : option.label) != null ? _b : String(value[0]);
740
+ if (field.type === "multiselect") {
741
+ const values = Array.isArray(value) ? value.filter((v) => typeof v === "string" && v.length > 1) : [];
742
+ if (values.length === 0) return null;
743
+ if (values.length === 1 && field.options) {
744
+ const option = field.options.find((o) => o.value === values[0]);
745
+ return (_b = option == null ? void 0 : option.label) != null ? _b : String(values[0]);
666
746
  }
667
- return `${value.length} selected`;
747
+ return `${values.length} selected`;
668
748
  }
669
749
  if (field.type === "date" && value instanceof Date) {
670
750
  return value.toLocaleDateString();
@@ -2,11 +2,11 @@
2
2
  "use client";
3
3
  import {
4
4
  FilterActive
5
- } from "./chunk-45QJL74L.mjs";
6
- import "./chunk-3ZBNWXRA.mjs";
7
- import "./chunk-URDCG5NI.mjs";
8
- import "./chunk-I3Z2T4N2.mjs";
5
+ } from "./chunk-JSRGUDCG.mjs";
6
+ import "./chunk-WD7YU6IN.mjs";
9
7
  import "./chunk-PHESMHTT.mjs";
8
+ import "./chunk-YTYOFT33.mjs";
9
+ import "./chunk-I3Z2T4N2.mjs";
10
10
  export {
11
11
  FilterActive
12
12
  };
@@ -0,0 +1,25 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { FilterBarFieldConfig, FilterBarI18nConfig, FilterBarValue } from './filter-bar-types.mjs';
3
+ import 'react';
4
+
5
+ interface AddFilterDropdownProps {
6
+ fieldGroups: Map<string | undefined, FilterBarFieldConfig[]>;
7
+ isFieldAvailable: (fieldId: string) => boolean;
8
+ onAddFilter: (fieldId: string) => void;
9
+ i18n: FilterBarI18nConfig;
10
+ disabled?: boolean;
11
+ }
12
+ declare function AddFilterDropdown(props: AddFilterDropdownProps): react_jsx_runtime.JSX.Element;
13
+ interface FilterPillProps {
14
+ filter: FilterBarValue;
15
+ field: FilterBarFieldConfig;
16
+ i18n: FilterBarI18nConfig;
17
+ onUpdate: (updates: Partial<FilterBarValue>) => void;
18
+ onRemove: () => void;
19
+ autoOpen?: boolean;
20
+ onAutoOpenComplete?: () => void;
21
+ disabled?: boolean;
22
+ }
23
+ declare function FilterPill(props: FilterPillProps): react_jsx_runtime.JSX.Element;
24
+
25
+ export { AddFilterDropdown, type AddFilterDropdownProps, FilterPill, type FilterPillProps };
@@ -0,0 +1,25 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { FilterBarFieldConfig, FilterBarI18nConfig, FilterBarValue } from './filter-bar-types.js';
3
+ import 'react';
4
+
5
+ interface AddFilterDropdownProps {
6
+ fieldGroups: Map<string | undefined, FilterBarFieldConfig[]>;
7
+ isFieldAvailable: (fieldId: string) => boolean;
8
+ onAddFilter: (fieldId: string) => void;
9
+ i18n: FilterBarI18nConfig;
10
+ disabled?: boolean;
11
+ }
12
+ declare function AddFilterDropdown(props: AddFilterDropdownProps): react_jsx_runtime.JSX.Element;
13
+ interface FilterPillProps {
14
+ filter: FilterBarValue;
15
+ field: FilterBarFieldConfig;
16
+ i18n: FilterBarI18nConfig;
17
+ onUpdate: (updates: Partial<FilterBarValue>) => void;
18
+ onRemove: () => void;
19
+ autoOpen?: boolean;
20
+ onAutoOpenComplete?: () => void;
21
+ disabled?: boolean;
22
+ }
23
+ declare function FilterPill(props: FilterPillProps): react_jsx_runtime.JSX.Element;
24
+
25
+ export { AddFilterDropdown, type AddFilterDropdownProps, FilterPill, type FilterPillProps };