@akinon/akifilter 1.3.6 → 1.4.0

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 (71) hide show
  1. package/dist/cjs/akifilter.d.ts +16 -4
  2. package/dist/cjs/akifilter.d.ts.map +1 -1
  3. package/dist/cjs/akifilter.js +93 -26
  4. package/dist/cjs/common/storage.d.ts.map +1 -1
  5. package/dist/cjs/common/storage.js +6 -1
  6. package/dist/cjs/components/applied-filters.d.ts.map +1 -1
  7. package/dist/cjs/components/applied-filters.js +2 -2
  8. package/dist/cjs/components/filter-toolbar.d.ts +2 -2
  9. package/dist/cjs/components/filter-toolbar.d.ts.map +1 -1
  10. package/dist/cjs/components/filter-toolbar.js +18 -2
  11. package/dist/cjs/filter-builder.d.ts +3 -3
  12. package/dist/cjs/filter-builder.d.ts.map +1 -1
  13. package/dist/cjs/filter-builder.js +5 -8
  14. package/dist/cjs/hooks/use-dynamic-visibility.d.ts +8 -0
  15. package/dist/cjs/hooks/use-dynamic-visibility.d.ts.map +1 -0
  16. package/dist/cjs/hooks/use-dynamic-visibility.js +36 -0
  17. package/dist/cjs/hooks/use-visibility-cleanup.d.ts +13 -0
  18. package/dist/cjs/hooks/use-visibility-cleanup.d.ts.map +1 -0
  19. package/dist/cjs/hooks/use-visibility-cleanup.js +39 -0
  20. package/dist/cjs/i18n/translations/en.d.ts +2 -2
  21. package/dist/cjs/i18n/translations/en.js +2 -2
  22. package/dist/cjs/i18n/translations/tr.d.ts +2 -2
  23. package/dist/cjs/i18n/translations/tr.js +2 -2
  24. package/dist/cjs/index.d.ts +1 -0
  25. package/dist/cjs/index.d.ts.map +1 -1
  26. package/dist/cjs/index.js +1 -0
  27. package/dist/cjs/styles.css +15 -3
  28. package/dist/cjs/styles.d.ts +1 -0
  29. package/dist/cjs/types.d.ts +9 -6
  30. package/dist/cjs/types.d.ts.map +1 -1
  31. package/dist/cjs/utils/schema.d.ts +5 -0
  32. package/dist/cjs/utils/schema.d.ts.map +1 -1
  33. package/dist/cjs/utils/schema.js +25 -3
  34. package/dist/cjs/utils/values.d.ts.map +1 -1
  35. package/dist/cjs/utils/values.js +3 -0
  36. package/dist/esm/akifilter.d.ts +16 -4
  37. package/dist/esm/akifilter.d.ts.map +1 -1
  38. package/dist/esm/akifilter.js +94 -27
  39. package/dist/esm/common/storage.d.ts.map +1 -1
  40. package/dist/esm/common/storage.js +6 -1
  41. package/dist/esm/components/applied-filters.d.ts.map +1 -1
  42. package/dist/esm/components/applied-filters.js +2 -2
  43. package/dist/esm/components/filter-toolbar.d.ts +2 -2
  44. package/dist/esm/components/filter-toolbar.d.ts.map +1 -1
  45. package/dist/esm/components/filter-toolbar.js +18 -2
  46. package/dist/esm/filter-builder.d.ts +3 -3
  47. package/dist/esm/filter-builder.d.ts.map +1 -1
  48. package/dist/esm/filter-builder.js +5 -8
  49. package/dist/esm/hooks/use-dynamic-visibility.d.ts +8 -0
  50. package/dist/esm/hooks/use-dynamic-visibility.d.ts.map +1 -0
  51. package/dist/esm/hooks/use-dynamic-visibility.js +32 -0
  52. package/dist/esm/hooks/use-visibility-cleanup.d.ts +13 -0
  53. package/dist/esm/hooks/use-visibility-cleanup.d.ts.map +1 -0
  54. package/dist/esm/hooks/use-visibility-cleanup.js +35 -0
  55. package/dist/esm/i18n/translations/en.d.ts +2 -2
  56. package/dist/esm/i18n/translations/en.js +2 -2
  57. package/dist/esm/i18n/translations/tr.d.ts +2 -2
  58. package/dist/esm/i18n/translations/tr.js +2 -2
  59. package/dist/esm/index.d.ts +1 -0
  60. package/dist/esm/index.d.ts.map +1 -1
  61. package/dist/esm/index.js +1 -0
  62. package/dist/esm/styles.css +15 -3
  63. package/dist/esm/styles.d.ts +1 -0
  64. package/dist/esm/types.d.ts +9 -6
  65. package/dist/esm/types.d.ts.map +1 -1
  66. package/dist/esm/utils/schema.d.ts +5 -0
  67. package/dist/esm/utils/schema.d.ts.map +1 -1
  68. package/dist/esm/utils/schema.js +22 -2
  69. package/dist/esm/utils/values.d.ts.map +1 -1
  70. package/dist/esm/utils/values.js +3 -0
  71. package/package.json +25 -22
@@ -1,6 +1,7 @@
1
1
  import './styles.css';
2
2
  import { FieldValues, Path } from '@akinon/akiform';
3
3
  import React from 'react';
4
+ import { type AppliedFilter } from './components/applied-filters';
4
5
  import type { AkifilterActionsRef, AkifilterSchema } from './types';
5
6
  type AkifilterFieldValues = FieldValues;
6
7
  export type AkifilterProps<TFieldValues extends AkifilterFieldValues = AkifilterFieldValues> = {
@@ -25,13 +26,15 @@ export type AkifilterProps<TFieldValues extends AkifilterFieldValues = Akifilter
25
26
  */
26
27
  onVisibleFieldsChange?: (keys: Array<Path<TFieldValues>>) => void;
27
28
  /**
28
- * Triggered when user opts to import filters via CSV.
29
+ * Triggered when user selects a file via the CSV import button.
30
+ * Receives the selected File object.
29
31
  */
30
- onImportCsv?: () => void;
32
+ onImportCsv?: (file: File) => void;
31
33
  /**
32
- * Triggered when user opts to import filters via XLS/XLSX.
34
+ * Triggered when user selects a file via the XLS import button.
35
+ * Receives the selected File object.
33
36
  */
34
- onImportXls?: () => void;
37
+ onImportXls?: (file: File) => void;
35
38
  /**
36
39
  * Triggered when user requests clearing all filters.
37
40
  */
@@ -48,6 +51,15 @@ export type AkifilterProps<TFieldValues extends AkifilterFieldValues = Akifilter
48
51
  * Ref to access imperative filter actions like clearing values.
49
52
  */
50
53
  filterActionsRef?: React.Ref<AkifilterActionsRef>;
54
+ /**
55
+ * Additional chips to display in the applied filters area alongside form-based filters.
56
+ * Useful for out-of-band filters such as file uploads.
57
+ */
58
+ externalAppliedFilters?: AppliedFilter[];
59
+ /**
60
+ * Called when the user removes an externally-provided chip.
61
+ */
62
+ onRemoveExternalFilter?: (key: string) => void;
51
63
  };
52
64
  export declare const Akifilter: {
53
65
  <TFieldValues extends AkifilterFieldValues = FieldValues>(props: AkifilterProps<TFieldValues>): React.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"akifilter.d.ts","sourceRoot":"","sources":["../../src/akifilter.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAGtB,OAAO,EAIL,WAAW,EACX,IAAI,EAIL,MAAM,iBAAiB,CAAC;AAWzB,OAAO,KAAK,MAAM,OAAO,CAAC;AA0B1B,OAAO,KAAK,EACV,mBAAmB,EAEnB,eAAe,EAChB,MAAM,SAAS,CAAC;AAYjB,KAAK,oBAAoB,GAAG,WAAW,CAAC;AA0HxC,MAAM,MAAM,cAAc,CACxB,YAAY,SAAS,oBAAoB,GAAG,oBAAoB,IAC9D;IACF;;OAEG;IACH,YAAY,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC7C;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACtC;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACzD;;OAEG;IACH,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,IAAI,CAAC;IAClE;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,gBAAgB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;CACnD,CAAC;AA8wBF,eAAO,MAAM,SAAS;KACpB,YAAY,SAAS,oBAAoB,uBAElC,cAAc,CAAC,YAAY,CAAC;;CAmBpC,CAAC"}
1
+ {"version":3,"file":"akifilter.d.ts","sourceRoot":"","sources":["../../src/akifilter.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAGtB,OAAO,EAIL,WAAW,EACX,IAAI,EAIL,MAAM,iBAAiB,CAAC;AAazB,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AAYtC,OAAO,KAAK,EACV,mBAAmB,EAEnB,eAAe,EAChB,MAAM,SAAS,CAAC;AAajB,KAAK,oBAAoB,GAAG,WAAW,CAAC;AA8JxC,MAAM,MAAM,cAAc,CACxB,YAAY,SAAS,oBAAoB,GAAG,oBAAoB,IAC9D;IACF;;OAEG;IACH,YAAY,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC7C;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACtC;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACzD;;OAEG;IACH,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,IAAI,CAAC;IAClE;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,gBAAgB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAClD;;;OAGG;IACH,sBAAsB,CAAC,EAAE,aAAa,EAAE,CAAC;IACzC;;OAEG;IACH,sBAAsB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD,CAAC;AAu1BF,eAAO,MAAM,SAAS;KACpB,YAAY,SAAS,oBAAoB,uBAElC,cAAc,CAAC,YAAY,CAAC;;CAmBpC,CAAC"}
@@ -24,6 +24,7 @@ const ui_input_1 = require("@akinon/ui-input");
24
24
  const ui_input_number_1 = require("@akinon/ui-input-number");
25
25
  const ui_select_1 = require("@akinon/ui-select");
26
26
  const ui_typography_1 = require("@akinon/ui-typography");
27
+ const ui_upload_1 = require("@akinon/ui-upload");
27
28
  const antd_1 = require("antd");
28
29
  const react_1 = require("react");
29
30
  const react_error_boundary_1 = require("react-error-boundary");
@@ -34,6 +35,8 @@ const filter_toolbar_1 = require("./components/filter-toolbar");
34
35
  const visibility_modal_1 = require("./components/visibility-modal");
35
36
  const constants_1 = require("./constants");
36
37
  const use_debounced_value_1 = require("./hooks/use-debounced-value");
38
+ const use_dynamic_visibility_1 = require("./hooks/use-dynamic-visibility");
39
+ const use_visibility_cleanup_1 = require("./hooks/use-visibility-cleanup");
37
40
  const i18n_1 = require("./i18n");
38
41
  const schema_1 = require("./utils/schema");
39
42
  const values_1 = require("./utils/values");
@@ -63,6 +66,21 @@ const FilterFormItem = (_a) => {
63
66
  });
64
67
  return (react_1.default.createElement(akiform_1.Akiform.Item, Object.assign({}, props, { validateStatus: fieldState.invalid ? 'error' : undefined, help: (_c = (_b = fieldState.error) === null || _b === void 0 ? void 0 : _b.message) !== null && _c !== void 0 ? _c : props.help, className: props.className }), childrenWithProps));
65
68
  };
69
+ const FileFilterInput = ({ value, onChange, accept, disabled, 'aria-label': ariaLabel }) => {
70
+ const handleBeforeUpload = (file) => {
71
+ var _a;
72
+ onChange === null || onChange === void 0 ? void 0 : onChange((_a = file.originFileObj) !== null && _a !== void 0 ? _a : file);
73
+ // Prevent antd from uploading automatically
74
+ return false;
75
+ };
76
+ const handleRemove = () => {
77
+ onChange === null || onChange === void 0 ? void 0 : onChange(null);
78
+ };
79
+ const fileList = value
80
+ ? [{ uid: value.name, name: value.name, originFileObj: value }]
81
+ : [];
82
+ return (react_1.default.createElement(ui_upload_1.Upload, { accept: accept, beforeUpload: handleBeforeUpload, onRemove: handleRemove, fileList: fileList, maxCount: 1, disabled: disabled, "aria-label": ariaLabel }));
83
+ };
66
84
  /**
67
85
  * Checks if a field should be disabled based on config.disabled property.
68
86
  */
@@ -74,17 +92,6 @@ const checkIsDisabled = (field, formValues) => {
74
92
  }
75
93
  return Boolean(configDisabled);
76
94
  };
77
- /**
78
- * Checks if a field should be visible based on config.visible property.
79
- */
80
- const checkIsVisible = (field, formValues) => {
81
- var _a;
82
- const configVisible = (_a = field.config) === null || _a === void 0 ? void 0 : _a.visible;
83
- if (typeof configVisible === 'function') {
84
- return configVisible(formValues);
85
- }
86
- return configVisible !== false;
87
- };
88
95
  const resolveClearedFieldValue = (field, defaultValue) => {
89
96
  if (defaultValue !== undefined) {
90
97
  return defaultValue;
@@ -97,13 +104,19 @@ const resolveClearedFieldValue = (field, defaultValue) => {
97
104
  return false;
98
105
  case 'number':
99
106
  case 'date':
107
+ return null;
100
108
  case 'select':
109
+ if (field.mode === 'multiple' || field.mode === 'tags') {
110
+ return [];
111
+ }
112
+ return null;
113
+ case 'file':
101
114
  return null;
102
115
  default:
103
116
  return undefined;
104
117
  }
105
118
  };
106
- const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onValuesChange, onVisibleFieldsChange, onImportCsv, onImportXls, onClearAll, enableImportCsv, enableImportXls, filterActionsRef }) => {
119
+ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onValuesChange, onVisibleFieldsChange, onImportCsv, onImportXls, onClearAll, enableImportCsv, enableImportXls, filterActionsRef, externalAppliedFilters, onRemoveExternalFilter }) => {
107
120
  // Separate regular fields from section fields
108
121
  const { regularFields, sectionFields } = react_1.default.useMemo(() => (0, schema_1.partitionSchema)(filterSchema), [filterSchema]);
109
122
  // Flatten schema for storage and form value operations
@@ -151,15 +164,29 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
151
164
  return acc;
152
165
  }
153
166
  const label = field.label || field.placeholder || key;
154
- const resolveSelectLabel = () => {
167
+ const fieldOptions = 'options' in field && field.options ? field.options : undefined;
168
+ const resolveLabel = (val) => {
155
169
  var _a;
156
- if (!('options' in field) || !field.options) {
170
+ const match = fieldOptions === null || fieldOptions === void 0 ? void 0 : fieldOptions.find(option => option.value === val);
171
+ return String((_a = match === null || match === void 0 ? void 0 : match.label) !== null && _a !== void 0 ? _a : val);
172
+ };
173
+ const resolveArrayLabels = (values) => {
174
+ return values.map(resolveLabel).join(', ');
175
+ };
176
+ const resolveSelectLabel = () => {
177
+ if (!fieldOptions) {
157
178
  return String(currentValue);
158
179
  }
159
- const match = field.options.find(option => option.value === currentValue);
160
- return String((_a = match === null || match === void 0 ? void 0 : match.label) !== null && _a !== void 0 ? _a : currentValue);
180
+ if (Array.isArray(currentValue)) {
181
+ return resolveArrayLabels(currentValue);
182
+ }
183
+ return resolveLabel(currentValue);
161
184
  };
162
185
  const resolveValue = () => {
186
+ if (field.type === 'file') {
187
+ const fileValue = currentValue;
188
+ return fileValue instanceof File ? fileValue.name : String(fileValue);
189
+ }
163
190
  if (field.type === 'select') {
164
191
  return resolveSelectLabel();
165
192
  }
@@ -178,7 +205,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
178
205
  }
179
206
  }
180
207
  if (Array.isArray(currentValue)) {
181
- return currentValue.map((value) => String(value)).join(', ');
208
+ return resolveArrayLabels(currentValue);
182
209
  }
183
210
  if (typeof currentValue === 'boolean') {
184
211
  return currentValue ? constants_1.BOOLEAN_STRING.TRUE : constants_1.BOOLEAN_STRING.FALSE;
@@ -200,10 +227,24 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
200
227
  }, [flattenedSchema, formValues]);
201
228
  const resolveInitialVisibleKeys = react_1.default.useCallback(() => {
202
229
  const storedKeys = (0, storage_1.readVisibleKeys)(regularFields, storageKey);
203
- if (storedKeys && storedKeys.length > 0) {
204
- return (0, schema_1.ensureSchemaOrder)(regularFields, storedKeys);
205
- }
206
- return (0, schema_1.deriveDefaultVisibleKeys)(regularFields);
230
+ const defaultKeys = (0, schema_1.deriveDefaultVisibleKeys)(regularFields);
231
+ const baseKeys = storedKeys && storedKeys.length > 0
232
+ ? (0, schema_1.ensureSchemaOrder)(regularFields, storedKeys)
233
+ : defaultKeys;
234
+ return regularFields.reduce((acc, field) => {
235
+ const key = String(field.key);
236
+ const explicitVisibility = (0, schema_1.resolveFieldVisibility)(field);
237
+ if (explicitVisibility !== undefined) {
238
+ if (explicitVisibility)
239
+ acc.push(key);
240
+ return acc;
241
+ }
242
+ // No explicit boolean visibility, use stored/default
243
+ if (baseKeys.includes(key)) {
244
+ acc.push(key);
245
+ }
246
+ return acc;
247
+ }, []);
207
248
  }, [regularFields, storageKey]);
208
249
  const [visibleKeys, setVisibleKeys] = react_1.default.useState(resolveInitialVisibleKeys);
209
250
  react_1.default.useEffect(() => {
@@ -428,8 +469,31 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
428
469
  const start = (modalPage - 1) * modalPageSize;
429
470
  return filteredFields.slice(start, start + modalPageSize);
430
471
  }, [filteredFields, modalPage, modalPageSize]);
431
- const visibleFields = react_1.default.useMemo(() => regularFields.filter(field => visibleKeys.includes(String(field.key)) &&
432
- checkIsVisible(field, formValues !== null && formValues !== void 0 ? formValues : {})), [regularFields, visibleKeys, formValues]);
472
+ const visibleFields = react_1.default.useMemo(() => regularFields.filter(field => visibleKeys.includes(String(field.key))), [regularFields, visibleKeys]);
473
+ // Dynamic visibility
474
+ (0, use_dynamic_visibility_1.useDynamicVisibility)({
475
+ regularFields,
476
+ formValues: normalisedValues,
477
+ setVisibleKeys
478
+ });
479
+ // Visibility cleanup
480
+ (0, use_visibility_cleanup_1.useVisibilityCleanup)({
481
+ visibleKeys,
482
+ regularFields,
483
+ onRemove: handleRemoveFilter
484
+ });
485
+ const handleAppliedFilterRemove = react_1.default.useCallback((key) => {
486
+ if (externalAppliedFilters === null || externalAppliedFilters === void 0 ? void 0 : externalAppliedFilters.some(f => f.key === key)) {
487
+ onRemoveExternalFilter === null || onRemoveExternalFilter === void 0 ? void 0 : onRemoveExternalFilter(key);
488
+ }
489
+ else {
490
+ handleRemoveFilter(key);
491
+ }
492
+ }, [externalAppliedFilters, onRemoveExternalFilter, handleRemoveFilter]);
493
+ const handleClearAllApplied = react_1.default.useCallback(() => {
494
+ handleClearAll();
495
+ externalAppliedFilters === null || externalAppliedFilters === void 0 ? void 0 : externalAppliedFilters.forEach(f => onRemoveExternalFilter === null || onRemoveExternalFilter === void 0 ? void 0 : onRemoveExternalFilter(f.key));
496
+ }, [handleClearAll, externalAppliedFilters, onRemoveExternalFilter]);
433
497
  const renderFieldComponent = (field) => {
434
498
  const ariaLabel = (0, schema_1.getFieldAriaLabel)(field);
435
499
  const isDisabled = checkIsDisabled(field, formValues !== null && formValues !== void 0 ? formValues : {});
@@ -439,17 +503,20 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
439
503
  case 'number':
440
504
  return (react_1.default.createElement(ui_input_number_1.InputNumber, { placeholder: field.placeholder, size: "large", className: "akinon-filter__field--number", "aria-label": ariaLabel, disabled: isDisabled }));
441
505
  case 'select':
442
- return (react_1.default.createElement(ui_select_1.Select, { placeholder: field.placeholder, size: "large", options: field.options, showSearch: true, optionFilterProp: "label", "aria-label": ariaLabel, disabled: isDisabled }));
506
+ return (react_1.default.createElement(ui_select_1.Select, { placeholder: field.placeholder, size: "large", options: field.options, showSearch: true, optionFilterProp: "label", "aria-label": ariaLabel, disabled: isDisabled, mode: field.mode }));
443
507
  case 'checkbox':
444
508
  return react_1.default.createElement(ui_checkbox_1.Checkbox, { disabled: isDisabled }, field.label);
445
509
  case 'date':
446
510
  return (react_1.default.createElement(ui_date_picker_1.DatePicker, { placeholder: field.placeholder, showTime: field.showTime, suffixIcon: "calendar", suffixIconSize: "16px", "aria-label": ariaLabel, disabled: isDisabled }));
447
511
  case 'textarea':
448
512
  return (react_1.default.createElement(ui_input_1.InputTextArea, { placeholder: field.placeholder, autoSize: { minRows: 3, maxRows: 6 }, "aria-label": ariaLabel, disabled: isDisabled }));
513
+ case 'file':
514
+ return (react_1.default.createElement(FileFilterInput, { accept: field.fileAccept, "aria-label": ariaLabel, disabled: isDisabled }));
449
515
  case 'custom':
450
516
  if (typeof field.render === 'function') {
451
517
  return field.render({
452
- field,
518
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
519
+ field: field,
453
520
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
454
521
  control: formMethods.control,
455
522
  formValues: formMethods.getValues(),
@@ -471,7 +538,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
471
538
  return (react_1.default.createElement(ui_card_1.Card, { size: "small", className: "akinon-filter shadow", "data-testid": "akifilter-root" },
472
539
  react_1.default.createElement(antd_1.ConfigProvider, { theme: theme_overrides_1.themeOverrides },
473
540
  react_1.default.createElement(filter_toolbar_1.FilterToolbar, { onOpenModal: handleOpenModal, enableImportCsv: enableImportCsv, enableImportXls: enableImportXls, onImportCsv: onImportCsv, onImportXls: onImportXls }),
474
- react_1.default.createElement(applied_filters_1.AppliedFilters, { filters: appliedFilters, onRemove: handleRemoveFilter, onClearAll: handleClearAll }),
541
+ react_1.default.createElement(applied_filters_1.AppliedFilters, { filters: [...appliedFilters, ...(externalAppliedFilters !== null && externalAppliedFilters !== void 0 ? externalAppliedFilters : [])], onRemove: handleAppliedFilterRemove, onClearAll: handleClearAllApplied }),
475
542
  react_1.default.createElement("div", { className: "akinon-filter__body" },
476
543
  react_1.default.createElement(akiform_1.Akiform, { layout: "vertical", className: "akinon-filter__form" },
477
544
  react_1.default.createElement("div", { className: "akinon-filter__form-grid", "data-testid": "akifilter-form-grid" },
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/common/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAqB/C,eAAO,MAAM,eAAe,GAAI,YAAY,SAAS,WAAW,EAC9D,QAAQ,cAAc,CAAC,YAAY,CAAC,EAAE,EACtC,YAAY,MAAM,KACjB,MAKF,CAAC;AAIF,eAAO,MAAM,eAAe,GAAI,YAAY,SAAS,WAAW,EAC9D,QAAQ,cAAc,CAAC,YAAY,CAAC,EAAE,EACtC,YAAY,MAAM,KACjB,MAAM,EAAE,GAAG,IAoBb,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,EAAE,MAAM,MAAM,EAAE,KAAG,IAQrE,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,KAAG,IAQrD,CAAC;AAKF,eAAO,MAAM,gBAAgB,GAAI,YAAY,SAAS,WAAW,EAC/D,QAAQ,cAAc,CAAC,YAAY,CAAC,EAAE,EACtC,YAAY,MAAM,KACjB,OAAO,CAAC,YAAY,CAAC,GAAG,IA+B1B,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,YAAY,SAAS,WAAW,EAChE,YAAY,MAAM,EAClB,QAAQ,OAAO,CAAC,YAAY,CAAC,KAC5B,IAeF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,IAQtD,CAAC"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/common/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AA2B/C,eAAO,MAAM,eAAe,GAAI,YAAY,SAAS,WAAW,EAC9D,QAAQ,cAAc,CAAC,YAAY,CAAC,EAAE,EACtC,YAAY,MAAM,KACjB,MAKF,CAAC;AAIF,eAAO,MAAM,eAAe,GAAI,YAAY,SAAS,WAAW,EAC9D,QAAQ,cAAc,CAAC,YAAY,CAAC,EAAE,EACtC,YAAY,MAAM,KACjB,MAAM,EAAE,GAAG,IAoBb,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,EAAE,MAAM,MAAM,EAAE,KAAG,IAQrE,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,KAAG,IAQrD,CAAC;AAKF,eAAO,MAAM,gBAAgB,GAAI,YAAY,SAAS,WAAW,EAC/D,QAAQ,cAAc,CAAC,YAAY,CAAC,EAAE,EACtC,YAAY,MAAM,KACjB,OAAO,CAAC,YAAY,CAAC,GAAG,IA+B1B,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,YAAY,SAAS,WAAW,EAChE,YAAY,MAAM,EAClB,QAAQ,OAAO,CAAC,YAAY,CAAC,KAC5B,IAeF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,IAQtD,CAAC"}
@@ -14,7 +14,12 @@ const hashString = (value) => {
14
14
  return Math.abs(hash).toString(36);
15
15
  };
16
16
  const buildSchemaSignature = (schema) => {
17
- return schema.map(field => `${String(field.key)}:${field.type}`).join('|');
17
+ return schema
18
+ .map(field => {
19
+ const mode = field.type === 'select' && field.mode ? `:${field.mode}` : '';
20
+ return `${String(field.key)}:${field.type}${mode}`;
21
+ })
22
+ .join('|');
18
23
  };
19
24
  const buildStorageKey = (schema, namespace) => {
20
25
  const signature = buildSchemaSignature(schema);
@@ -1 +1 @@
1
- {"version":3,"file":"applied-filters.d.ts","sourceRoot":"","sources":["../../../src/components/applied-filters.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,mCAI5B,mBAAmB,sBAoDrB,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"applied-filters.d.ts","sourceRoot":"","sources":["../../../src/components/applied-filters.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,mCAI5B,mBAAmB,sBAwDrB,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -13,9 +13,9 @@ const AppliedFilters = ({ filters, onRemove, onClearAll }) => {
13
13
  react_1.default.createElement(ui_space_1.Space, { className: "akinon-filter__applied-summary", size: 8 },
14
14
  react_1.default.createElement(ui_typography_1.Text, { className: "akinon-filter__applied-label" }, i18n_1.i18n.t('applied.label')),
15
15
  hasFilters ? (react_1.default.createElement(ui_space_1.Space, { className: "akinon-filter__applied-items", size: 8, wrap: true }, filters.map(item => (react_1.default.createElement("div", { key: `${item.key}-${item.value}`, className: "akinon-filter__chip" },
16
- react_1.default.createElement("span", { className: "akinon-filter__chip-label" },
16
+ item.label ? (react_1.default.createElement("span", { className: "akinon-filter__chip-label" },
17
17
  item.label,
18
- ":"),
18
+ ":")) : null,
19
19
  react_1.default.createElement("span", { className: "akinon-filter__chip-value" }, item.value),
20
20
  react_1.default.createElement("button", { type: "button", "aria-label": i18n_1.i18n.t('applied.clearSingle', {
21
21
  field: item.label
@@ -3,8 +3,8 @@ type FilterToolbarProps = {
3
3
  onOpenModal: () => void;
4
4
  enableImportCsv?: boolean;
5
5
  enableImportXls?: boolean;
6
- onImportCsv?: () => void;
7
- onImportXls?: () => void;
6
+ onImportCsv?: (file: File) => void;
7
+ onImportXls?: (file: File) => void;
8
8
  };
9
9
  export declare const FilterToolbar: ({ onOpenModal, enableImportCsv, enableImportXls, onImportCsv, onImportXls }: FilterToolbarProps) => React.JSX.Element;
10
10
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"filter-toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/filter-toolbar.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,kBAAkB,GAAG;IACxB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,6EAM3B,kBAAkB,sBAwCpB,CAAC"}
1
+ {"version":3,"file":"filter-toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/filter-toolbar.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,kBAAkB,GAAG;IACxB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACpC,CAAC;AAgDF,eAAO,MAAM,aAAa,GAAI,6EAM3B,kBAAkB,sBAoCpB,CAAC"}
@@ -6,12 +6,28 @@ const ui_space_1 = require("@akinon/ui-space");
6
6
  const ui_typography_1 = require("@akinon/ui-typography");
7
7
  const react_1 = require("react");
8
8
  const i18n_1 = require("../i18n");
9
+ const FileImportButton = ({ accept, label, onImport }) => {
10
+ const inputRef = react_1.default.useRef(null);
11
+ const handleClick = () => { var _a; return (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click(); };
12
+ const handleChange = (e) => {
13
+ var _a;
14
+ const file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
15
+ if (file) {
16
+ onImport(file);
17
+ }
18
+ // Reset so same file can be re-selected
19
+ e.target.value = '';
20
+ };
21
+ return (react_1.default.createElement(react_1.default.Fragment, null,
22
+ react_1.default.createElement("input", { ref: inputRef, type: "file", accept: accept, style: { display: 'none' }, onChange: handleChange }),
23
+ react_1.default.createElement(ui_button_1.Button, { className: "akinon-filter__toolbar-item akinon-filter__toolbar-item--file", icon: "filter", iconSize: 13, onClick: handleClick, type: "primary", title: label, "aria-label": label }, label)));
24
+ };
9
25
  const FilterToolbar = ({ onOpenModal, enableImportCsv, enableImportXls, onImportCsv, onImportXls }) => {
10
26
  return (react_1.default.createElement("div", { className: "akinon-filter__top" },
11
27
  react_1.default.createElement(ui_typography_1.Title, { className: "akinon-filter__title", level: 4 }, i18n_1.i18n.t('header.title')),
12
28
  react_1.default.createElement(ui_space_1.Space, { className: "akinon-filter__toolbar", size: 6 },
13
- enableImportCsv && onImportCsv ? (react_1.default.createElement(ui_button_1.Button, { className: "akinon-filter__toolbar-item", onClick: onImportCsv, type: "primary" }, i18n_1.i18n.t('header.actions.importCsv'))) : null,
14
- enableImportXls && onImportXls ? (react_1.default.createElement(ui_button_1.Button, { className: "akinon-filter__toolbar-item", onClick: onImportXls, type: "primary" }, i18n_1.i18n.t('header.actions.importXls'))) : null,
29
+ enableImportCsv && onImportCsv ? (react_1.default.createElement(FileImportButton, { accept: ".csv", label: i18n_1.i18n.t('header.actions.importCsv'), onImport: onImportCsv })) : null,
30
+ enableImportXls && onImportXls ? (react_1.default.createElement(FileImportButton, { accept: ".xls,.xlsx", label: i18n_1.i18n.t('header.actions.importXls'), onImport: onImportXls })) : null,
15
31
  react_1.default.createElement(ui_button_1.Button, { className: "akinon-filter__toolbar-item", icon: "filter", iconSize: 16, onClick: onOpenModal, type: "primary", title: i18n_1.i18n.t('header.actions.selectFilters'), "aria-label": i18n_1.i18n.t('header.actions.selectFilters') }))));
16
32
  };
17
33
  exports.FilterToolbar = FilterToolbar;
@@ -1,9 +1,9 @@
1
1
  import type { FieldValues } from '@akinon/akiform';
2
2
  import { field } from '@akinon/akiform-builder';
3
- import type { AkifilterField } from './types';
3
+ import type { AkifilterField, AkifilterFieldConfig } from './types';
4
4
  type BaseBuilder<TFieldValues extends FieldValues> = ReturnType<typeof field<TFieldValues>>;
5
- type AkifilterFieldBuilder<TFieldValues extends FieldValues> = BaseBuilder<TFieldValues> & {
6
- visible(isVisible?: boolean): AkifilterFieldBuilder<TFieldValues>;
5
+ type AkifilterFieldBuilder<TFieldValues extends FieldValues> = Omit<BaseBuilder<TFieldValues>, 'build' | 'config'> & {
6
+ config(cfg: AkifilterFieldConfig<TFieldValues>): AkifilterFieldBuilder<TFieldValues>;
7
7
  build(): AkifilterField<TFieldValues>;
8
8
  };
9
9
  export declare const filterField: <TFieldValues extends FieldValues = FieldValues>() => AkifilterFieldBuilder<TFieldValues>;
@@ -1 +1 @@
1
- {"version":3,"file":"filter-builder.d.ts","sourceRoot":"","sources":["../../src/filter-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,KAAK,WAAW,CAAC,YAAY,SAAS,WAAW,IAAI,UAAU,CAC7D,OAAO,KAAK,CAAC,YAAY,CAAC,CAC3B,CAAC;AAEF,KAAK,qBAAqB,CAAC,YAAY,SAAS,WAAW,IACzD,WAAW,CAAC,YAAY,CAAC,GAAG;IAC1B,OAAO,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;IAClE,KAAK,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;CACvC,CAAC;AAEJ,eAAO,MAAM,WAAW,GACtB,YAAY,SAAS,WAAW,GAAG,WAAW,0CA8B/C,CAAC;AAEF,YAAY,EAAE,qBAAqB,EAAE,CAAC"}
1
+ {"version":3,"file":"filter-builder.d.ts","sourceRoot":"","sources":["../../src/filter-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpE,KAAK,WAAW,CAAC,YAAY,SAAS,WAAW,IAAI,UAAU,CAC7D,OAAO,KAAK,CAAC,YAAY,CAAC,CAC3B,CAAC;AAEF,KAAK,qBAAqB,CAAC,YAAY,SAAS,WAAW,IAAI,IAAI,CACjE,WAAW,CAAC,YAAY,CAAC,EACzB,OAAO,GAAG,QAAQ,CACnB,GAAG;IACF,MAAM,CACJ,GAAG,EAAE,oBAAoB,CAAC,YAAY,CAAC,GACtC,qBAAqB,CAAC,YAAY,CAAC,CAAC;IACvC,KAAK,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,YAAY,SAAS,WAAW,GAAG,WAAW,0CA+B/C,CAAC;AAEF,YAAY,EAAE,qBAAqB,EAAE,CAAC"}
@@ -4,21 +4,18 @@ exports.filterField = void 0;
4
4
  const akiform_builder_1 = require("@akinon/akiform-builder");
5
5
  const filterField = () => {
6
6
  const baseBuilder = (0, akiform_builder_1.field)();
7
- let visibility;
7
+ let fieldConfig;
8
8
  const builder = baseBuilder;
9
- builder.visible = (isVisible = true) => {
10
- visibility = isVisible;
9
+ builder.config = cfg => {
10
+ fieldConfig = Object.assign(Object.assign({}, fieldConfig), cfg);
11
11
  return builder;
12
12
  };
13
13
  const originalBuild = baseBuilder.build.bind(baseBuilder);
14
14
  builder.build = () => {
15
15
  const builtField = originalBuild();
16
16
  const filterFieldDefinition = Object.assign({}, builtField);
17
- if (visibility !== undefined) {
18
- filterFieldDefinition.isVisible = visibility;
19
- }
20
- else {
21
- delete filterFieldDefinition.isVisible;
17
+ if (fieldConfig !== undefined) {
18
+ filterFieldDefinition.config = Object.assign(Object.assign({}, filterFieldDefinition.config), fieldConfig);
22
19
  }
23
20
  return filterFieldDefinition;
24
21
  };
@@ -0,0 +1,8 @@
1
+ import type { FieldValues } from '@akinon/akiform';
2
+ import type { AkifilterSchema } from '../types';
3
+ export declare const useDynamicVisibility: <TFieldValues extends FieldValues>({ regularFields, formValues, setVisibleKeys }: {
4
+ regularFields: AkifilterSchema<TFieldValues>;
5
+ formValues: Partial<TFieldValues> | undefined;
6
+ setVisibleKeys: React.Dispatch<React.SetStateAction<string[]>>;
7
+ }) => void;
8
+ //# sourceMappingURL=use-dynamic-visibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-dynamic-visibility.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-dynamic-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AA0ChD,eAAO,MAAM,oBAAoB,GAAI,YAAY,SAAS,WAAW,EAAE,+CAIpE;IACD,aAAa,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC7C,UAAU,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;IAC9C,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CAChE,SAcA,CAAC"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useDynamicVisibility = void 0;
4
+ const react_1 = require("react");
5
+ const schema_1 = require("../utils/schema");
6
+ const computeDynamicKeys = (fields, prev, formValues) => {
7
+ const prevSet = new Set(prev);
8
+ const fieldKeySet = new Set(fields.map(f => String(f.key)));
9
+ const { keys, changed } = fields.reduce((acc, field) => {
10
+ const key = String(field.key);
11
+ const isCurrentlyVisible = prevSet.has(key);
12
+ if (!(0, schema_1.hasDynamicVisibility)(field)) {
13
+ if (isCurrentlyVisible)
14
+ acc.keys.push(key);
15
+ return acc;
16
+ }
17
+ const shouldBeVisible = (0, schema_1.resolveFieldVisibility)(field, formValues, isCurrentlyVisible);
18
+ if (shouldBeVisible)
19
+ acc.keys.push(key);
20
+ if (shouldBeVisible !== isCurrentlyVisible)
21
+ acc.changed = true;
22
+ return acc;
23
+ }, { keys: prev.filter(k => !fieldKeySet.has(k)), changed: false });
24
+ return changed ? (0, schema_1.ensureSchemaOrder)(fields, keys) : null;
25
+ };
26
+ const useDynamicVisibility = ({ regularFields, formValues, setVisibleKeys }) => {
27
+ (0, react_1.useEffect)(() => {
28
+ if (!regularFields.some(schema_1.hasDynamicVisibility))
29
+ return;
30
+ setVisibleKeys(prev => {
31
+ var _a;
32
+ return ((_a = computeDynamicKeys(regularFields, prev, (formValues !== null && formValues !== void 0 ? formValues : {}))) !== null && _a !== void 0 ? _a : prev);
33
+ });
34
+ }, [regularFields, formValues, setVisibleKeys]);
35
+ };
36
+ exports.useDynamicVisibility = useDynamicVisibility;
@@ -0,0 +1,13 @@
1
+ import type { FieldValues } from '@akinon/akiform';
2
+ import type { AkifilterSchema } from '../types';
3
+ /**
4
+ * Cleans up form values when fields become hidden.
5
+ * On first render, clears fields explicitly marked as invisible.
6
+ * On subsequent renders, clears fields that were removed from visibleKeys.
7
+ */
8
+ export declare const useVisibilityCleanup: <TFieldValues extends FieldValues = FieldValues>({ visibleKeys, regularFields, onRemove }: {
9
+ visibleKeys: string[];
10
+ regularFields: AkifilterSchema<TFieldValues>;
11
+ onRemove: (key: string) => void;
12
+ }) => void;
13
+ //# sourceMappingURL=use-visibility-cleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-visibility-cleanup.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-visibility-cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAInD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AA+BhD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,0CAIC;IACD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC7C,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,SAcA,CAAC"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useVisibilityCleanup = void 0;
4
+ const lodash_es_1 = require("lodash-es");
5
+ const react_1 = require("react");
6
+ const schema_1 = require("../utils/schema");
7
+ const getInitialKeysToClean = (fields) => fields
8
+ .filter(field => (0, schema_1.resolveFieldVisibility)(field) === false)
9
+ .map(field => String(field.key));
10
+ const getRemovedKeys = (prev, current) => prev.filter(key => !current.includes(key));
11
+ const cleanupKeys = (keys, onRemove) => {
12
+ keys.forEach(key => onRemove(key));
13
+ };
14
+ const resolveKeysToClean = ({ prev, current, fields }) => {
15
+ if (prev === null)
16
+ return getInitialKeysToClean(fields);
17
+ if ((0, lodash_es_1.isEqual)(prev, current))
18
+ return [];
19
+ return getRemovedKeys(prev, current);
20
+ };
21
+ /**
22
+ * Cleans up form values when fields become hidden.
23
+ * On first render, clears fields explicitly marked as invisible.
24
+ * On subsequent renders, clears fields that were removed from visibleKeys.
25
+ */
26
+ const useVisibilityCleanup = ({ visibleKeys, regularFields, onRemove }) => {
27
+ const previousVisibleKeysRef = (0, react_1.useRef)(null);
28
+ (0, react_1.useEffect)(() => {
29
+ const prev = previousVisibleKeysRef.current;
30
+ previousVisibleKeysRef.current = visibleKeys;
31
+ const keysToClean = resolveKeysToClean({
32
+ prev,
33
+ current: visibleKeys,
34
+ fields: regularFields
35
+ });
36
+ cleanupKeys(keysToClean, onRemove);
37
+ }, [visibleKeys, onRemove, regularFields]);
38
+ };
39
+ exports.useVisibilityCleanup = useVisibilityCleanup;
@@ -3,8 +3,8 @@ declare const translations: {
3
3
  readonly title: "Filters";
4
4
  readonly actions: {
5
5
  readonly selectFilters: "Select filters";
6
- readonly importCsv: "Import CSV";
7
- readonly importXls: "Import XLS/XLSX";
6
+ readonly importCsv: "CSV";
7
+ readonly importXls: "XLS";
8
8
  };
9
9
  };
10
10
  readonly applied: {
@@ -5,8 +5,8 @@ const translations = {
5
5
  title: 'Filters',
6
6
  actions: {
7
7
  selectFilters: 'Select filters',
8
- importCsv: 'Import CSV',
9
- importXls: 'Import XLS/XLSX'
8
+ importCsv: 'CSV',
9
+ importXls: 'XLS'
10
10
  }
11
11
  },
12
12
  applied: {
@@ -3,8 +3,8 @@ declare const translations: {
3
3
  readonly title: "Filtreler";
4
4
  readonly actions: {
5
5
  readonly selectFilters: "Filtreleri seç";
6
- readonly importCsv: "CSV içe aktar";
7
- readonly importXls: "XLS/XLSX içe aktar";
6
+ readonly importCsv: "CSV";
7
+ readonly importXls: "XLS";
8
8
  };
9
9
  };
10
10
  readonly applied: {
@@ -5,8 +5,8 @@ const translations = {
5
5
  title: 'Filtreler',
6
6
  actions: {
7
7
  selectFilters: 'Filtreleri seç',
8
- importCsv: 'CSV içe aktar',
9
- importXls: 'XLS/XLSX içe aktar'
8
+ importCsv: 'CSV',
9
+ importXls: 'XLS'
10
10
  }
11
11
  },
12
12
  applied: {
@@ -1,4 +1,5 @@
1
1
  export * from './akifilter';
2
+ export * from './components/applied-filters';
2
3
  export * from './filter-builder';
3
4
  export * from './i18n';
4
5
  export * from './types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
package/dist/cjs/index.js CHANGED
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./akifilter"), exports);
18
+ __exportStar(require("./components/applied-filters"), exports);
18
19
  __exportStar(require("./filter-builder"), exports);
19
20
  __exportStar(require("./i18n"), exports);
20
21
  __exportStar(require("./types"), exports);