@akinon/akifilter 1.1.1-rc.0 → 1.2.0-next.2
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.
- package/dist/cjs/akifilter.d.ts.map +1 -1
- package/dist/cjs/akifilter.js +48 -18
- package/dist/cjs/types.d.ts +16 -0
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/akifilter.d.ts.map +1 -1
- package/dist/esm/akifilter.js +49 -19
- package/dist/esm/types.d.ts +16 -0
- package/dist/esm/types.d.ts.map +1 -1
- package/package.json +20 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"akifilter.d.ts","sourceRoot":"","sources":["../../src/akifilter.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAGtB,OAAO,EAIL,WAAW,EAEX,IAAI,EAGL,MAAM,iBAAiB,CAAC;AAWzB,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"akifilter.d.ts","sourceRoot":"","sources":["../../src/akifilter.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAGtB,OAAO,EAIL,WAAW,EAEX,IAAI,EAGL,MAAM,iBAAiB,CAAC;AAWzB,OAAO,KAAK,MAAM,OAAO,CAAC;AA0B1B,OAAO,KAAK,EAAkB,eAAe,EAAE,MAAM,SAAS,CAAC;AAY/D,KAAK,oBAAoB,GAAG,WAAW,CAAC;AA2DxC,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;CAC3B,CAAC;AAyrBF,eAAO,MAAM,SAAS;KACpB,YAAY,SAAS,oBAAoB,uBAElC,cAAc,CAAC,YAAY,CAAC;;CAmBpC,CAAC"}
|
package/dist/cjs/akifilter.js
CHANGED
|
@@ -37,6 +37,28 @@ const use_debounced_value_1 = require("./hooks/use-debounced-value");
|
|
|
37
37
|
const i18n_1 = require("./i18n");
|
|
38
38
|
const schema_1 = require("./utils/schema");
|
|
39
39
|
const values_1 = require("./utils/values");
|
|
40
|
+
/**
|
|
41
|
+
* Checks if a field should be disabled based on config.disabled property.
|
|
42
|
+
*/
|
|
43
|
+
const checkIsDisabled = (field, formValues) => {
|
|
44
|
+
var _a;
|
|
45
|
+
const configDisabled = (_a = field.config) === null || _a === void 0 ? void 0 : _a.disabled;
|
|
46
|
+
if (typeof configDisabled === 'function') {
|
|
47
|
+
return configDisabled(formValues);
|
|
48
|
+
}
|
|
49
|
+
return Boolean(configDisabled);
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Checks if a field should be visible based on config.visible property.
|
|
53
|
+
*/
|
|
54
|
+
const checkIsVisible = (field, formValues) => {
|
|
55
|
+
var _a;
|
|
56
|
+
const configVisible = (_a = field.config) === null || _a === void 0 ? void 0 : _a.visible;
|
|
57
|
+
if (typeof configVisible === 'function') {
|
|
58
|
+
return configVisible(formValues);
|
|
59
|
+
}
|
|
60
|
+
return configVisible !== false;
|
|
61
|
+
};
|
|
40
62
|
const resolveClearedFieldValue = (field, defaultValue) => {
|
|
41
63
|
if (defaultValue !== undefined) {
|
|
42
64
|
return defaultValue;
|
|
@@ -109,12 +131,17 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
109
131
|
if (field.type === 'select') {
|
|
110
132
|
return resolveSelectLabel();
|
|
111
133
|
}
|
|
134
|
+
// For custom fields with options (like custom selects), try to find the label
|
|
135
|
+
if (field.type === 'custom' && 'options' in field && field.options) {
|
|
136
|
+
return resolveSelectLabel();
|
|
137
|
+
}
|
|
112
138
|
if (field.type === 'date') {
|
|
113
139
|
const iso = akidate_1.akidate.toIsoDate(currentValue);
|
|
114
140
|
if (iso) {
|
|
115
141
|
// Use localized format with time if showTime is enabled
|
|
116
142
|
const hasShowTime = 'showTime' in field && field.showTime;
|
|
117
|
-
|
|
143
|
+
// L = localized date, LTS = localized time with seconds
|
|
144
|
+
const format = hasShowTime ? 'L LTS' : 'L';
|
|
118
145
|
return akidate_1.akidate.formatIsoDate(iso, format);
|
|
119
146
|
}
|
|
120
147
|
}
|
|
@@ -130,7 +157,8 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
130
157
|
}
|
|
131
158
|
const iso = akidate_1.akidate.toIsoDate(currentValue);
|
|
132
159
|
if (iso) {
|
|
133
|
-
|
|
160
|
+
// Use localized date format for fallback
|
|
161
|
+
return akidate_1.akidate.formatIsoDate(iso, 'L');
|
|
134
162
|
}
|
|
135
163
|
return String(currentValue);
|
|
136
164
|
};
|
|
@@ -218,10 +246,10 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
218
246
|
lastPersistedValuesRef.current = null;
|
|
219
247
|
}, [storageKey]);
|
|
220
248
|
const handleClearAll = react_1.default.useCallback(() => {
|
|
221
|
-
const clearedDefaults = Object.assign({},
|
|
249
|
+
const clearedDefaults = Object.assign({}, schemaDefaults);
|
|
222
250
|
flattenedSchema.forEach(field => {
|
|
223
251
|
const key = String(field.key);
|
|
224
|
-
const defaultValue =
|
|
252
|
+
const defaultValue = schemaDefaults[key];
|
|
225
253
|
const resolved = resolveClearedFieldValue(field, defaultValue);
|
|
226
254
|
if (resolved === undefined) {
|
|
227
255
|
delete clearedDefaults[key];
|
|
@@ -242,7 +270,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
242
270
|
lastPersistedValuesRef.current = nextSerialised !== null && nextSerialised !== void 0 ? nextSerialised : null;
|
|
243
271
|
onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(nextValues);
|
|
244
272
|
}, [
|
|
245
|
-
|
|
273
|
+
schemaDefaults,
|
|
246
274
|
flattenedSchema,
|
|
247
275
|
formMethods,
|
|
248
276
|
onClearAll,
|
|
@@ -274,7 +302,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
274
302
|
if (!schemaField) {
|
|
275
303
|
return;
|
|
276
304
|
}
|
|
277
|
-
const defaultValue =
|
|
305
|
+
const defaultValue = schemaDefaults[String(schemaField.key)];
|
|
278
306
|
const fieldPath = schemaField.key;
|
|
279
307
|
const nextValue = resolveClearedFieldValue(schemaField, defaultValue);
|
|
280
308
|
// Update the form value
|
|
@@ -283,10 +311,9 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
283
311
|
shouldTouch: false,
|
|
284
312
|
shouldValidate: false
|
|
285
313
|
});
|
|
286
|
-
//
|
|
287
|
-
const
|
|
288
|
-
const
|
|
289
|
-
const nextValues = (0, values_1.normaliseOutputValues)(flattenedSchema, updatedFormValues);
|
|
314
|
+
// Get all current form values (includes the updated field)
|
|
315
|
+
const allFormValues = formMethods.getValues();
|
|
316
|
+
const nextValues = (0, values_1.normaliseOutputValues)(flattenedSchema, allFormValues);
|
|
290
317
|
const nextSerialised = JSON.stringify(nextValues);
|
|
291
318
|
// Persist immediately (bypass debounce for remove action)
|
|
292
319
|
persistValues(nextValues);
|
|
@@ -298,7 +325,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
298
325
|
// Emit the change to parent
|
|
299
326
|
onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(nextValues);
|
|
300
327
|
}, [
|
|
301
|
-
|
|
328
|
+
schemaDefaults,
|
|
302
329
|
flattenedSchema,
|
|
303
330
|
formMethods,
|
|
304
331
|
onValuesChange,
|
|
@@ -320,22 +347,25 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
320
347
|
const start = (modalPage - 1) * modalPageSize;
|
|
321
348
|
return filteredFields.slice(start, start + modalPageSize);
|
|
322
349
|
}, [filteredFields, modalPage, modalPageSize]);
|
|
323
|
-
const visibleFields = react_1.default.useMemo(() => regularFields
|
|
350
|
+
const visibleFields = react_1.default.useMemo(() => regularFields
|
|
351
|
+
.filter(field => visibleKeys.includes(String(field.key)))
|
|
352
|
+
.filter(field => checkIsVisible(field, formValues !== null && formValues !== void 0 ? formValues : {})), [regularFields, visibleKeys, formValues]);
|
|
324
353
|
const renderFieldComponent = (field) => {
|
|
325
354
|
const ariaLabel = (0, schema_1.getFieldAriaLabel)(field);
|
|
355
|
+
const isDisabled = checkIsDisabled(field, formValues !== null && formValues !== void 0 ? formValues : {});
|
|
326
356
|
switch (field.type) {
|
|
327
357
|
case 'text':
|
|
328
|
-
return (react_1.default.createElement(ui_input_1.Input, { placeholder: field.placeholder, size: "large", allowClear: true, "aria-label": ariaLabel }));
|
|
358
|
+
return (react_1.default.createElement(ui_input_1.Input, { placeholder: field.placeholder, size: "large", allowClear: true, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
329
359
|
case 'number':
|
|
330
|
-
return (react_1.default.createElement(ui_input_number_1.InputNumber, { placeholder: field.placeholder, size: "large", className: "akinon-filter__field--number", "aria-label": ariaLabel }));
|
|
360
|
+
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 }));
|
|
331
361
|
case 'select':
|
|
332
|
-
return (react_1.default.createElement(ui_select_1.Select, { placeholder: field.placeholder, size: "large", options: field.options, showSearch: true, optionFilterProp: "label", "aria-label": ariaLabel }));
|
|
362
|
+
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 }));
|
|
333
363
|
case 'checkbox':
|
|
334
|
-
return react_1.default.createElement(ui_checkbox_1.Checkbox,
|
|
364
|
+
return react_1.default.createElement(ui_checkbox_1.Checkbox, { disabled: isDisabled }, field.label);
|
|
335
365
|
case 'date':
|
|
336
|
-
return (react_1.default.createElement(ui_date_picker_1.DatePicker, { placeholder: field.placeholder, showTime: field.showTime, suffixIcon: "calendar", suffixIconSize: "16px", "aria-label": ariaLabel }));
|
|
366
|
+
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 }));
|
|
337
367
|
case 'textarea':
|
|
338
|
-
return (react_1.default.createElement(ui_input_1.InputTextArea, { placeholder: field.placeholder, autoSize: { minRows: 3, maxRows: 6 }, "aria-label": ariaLabel }));
|
|
368
|
+
return (react_1.default.createElement(ui_input_1.InputTextArea, { placeholder: field.placeholder, autoSize: { minRows: 3, maxRows: 6 }, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
339
369
|
case 'custom':
|
|
340
370
|
if (typeof field.render === 'function') {
|
|
341
371
|
return field.render({
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
import type { FieldValues, Path } from '@akinon/akiform';
|
|
2
2
|
import type { FormField } from '@akinon/akiform-builder';
|
|
3
|
+
export interface AkifilterFieldConfig<TFieldValues extends FieldValues = FieldValues> {
|
|
4
|
+
/**
|
|
5
|
+
* Controls whether the field is disabled.
|
|
6
|
+
* Can be a boolean or a function that receives form values and returns a boolean.
|
|
7
|
+
*/
|
|
8
|
+
disabled?: boolean | ((formValues: TFieldValues) => boolean);
|
|
9
|
+
/**
|
|
10
|
+
* Controls whether the field is visible.
|
|
11
|
+
* Can be a boolean or a function that receives form values and returns a boolean.
|
|
12
|
+
*/
|
|
13
|
+
visible?: boolean | ((formValues: TFieldValues) => boolean);
|
|
14
|
+
}
|
|
3
15
|
export type AkifilterField<TFieldValues extends FieldValues = FieldValues> = FormField<TFieldValues> & {
|
|
4
16
|
/**
|
|
5
17
|
* Controls whether the field is shown in the main filter form by default.
|
|
6
18
|
*/
|
|
7
19
|
isVisible?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Configuration options for field behavior (disabled, visible).
|
|
22
|
+
*/
|
|
23
|
+
config?: AkifilterFieldConfig<TFieldValues>;
|
|
8
24
|
};
|
|
9
25
|
export type AkifilterFieldKey<TFieldValues extends FieldValues = FieldValues> = Path<TFieldValues>;
|
|
10
26
|
export type AkifilterSchema<TFieldValues extends FieldValues = FieldValues> = AkifilterField<TFieldValues>[];
|
package/dist/cjs/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,MAAM,cAAc,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IACvE,SAAS,CAAC,YAAY,CAAC,GAAG;IACxB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,WAAW,oBAAoB,CACnC,YAAY,SAAS,WAAW,GAAG,WAAW;IAE9C;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,UAAU,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC;IAC7D;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,UAAU,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC;CAC7D;AAED,MAAM,MAAM,cAAc,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IACvE,SAAS,CAAC,YAAY,CAAC,GAAG;IACxB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;CAC7C,CAAC;AAEJ,MAAM,MAAM,iBAAiB,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IAC1E,IAAI,CAAC,YAAY,CAAC,CAAC;AAErB,MAAM,MAAM,eAAe,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IACxE,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"akifilter.d.ts","sourceRoot":"","sources":["../../src/akifilter.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAGtB,OAAO,EAIL,WAAW,EAEX,IAAI,EAGL,MAAM,iBAAiB,CAAC;AAWzB,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"akifilter.d.ts","sourceRoot":"","sources":["../../src/akifilter.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAGtB,OAAO,EAIL,WAAW,EAEX,IAAI,EAGL,MAAM,iBAAiB,CAAC;AAWzB,OAAO,KAAK,MAAM,OAAO,CAAC;AA0B1B,OAAO,KAAK,EAAkB,eAAe,EAAE,MAAM,SAAS,CAAC;AAY/D,KAAK,oBAAoB,GAAG,WAAW,CAAC;AA2DxC,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;CAC3B,CAAC;AAyrBF,eAAO,MAAM,SAAS;KACpB,YAAY,SAAS,oBAAoB,uBAElC,cAAc,CAAC,YAAY,CAAC;;CAmBpC,CAAC"}
|
package/dist/esm/akifilter.js
CHANGED
|
@@ -29,11 +29,33 @@ import { themeOverrides } from './common/theme-overrides';
|
|
|
29
29
|
import { AppliedFilters } from './components/applied-filters';
|
|
30
30
|
import { FilterToolbar } from './components/filter-toolbar';
|
|
31
31
|
import { VisibilityModal } from './components/visibility-modal';
|
|
32
|
-
import { BOOLEAN_STRING,
|
|
32
|
+
import { BOOLEAN_STRING, DEFAULT_MODAL_PAGE_SIZE, FILTER_DEBOUNCE_DELAY } from './constants';
|
|
33
33
|
import { useDebouncedValue } from './hooks/use-debounced-value';
|
|
34
34
|
import { i18n } from './i18n';
|
|
35
35
|
import { deriveDefaultVisibleKeys, ensureSchemaOrder, extractDefaultValues, flattenSchema, getFieldAriaLabel, normaliseValuesBySchema, partitionSchema } from './utils/schema';
|
|
36
36
|
import { normaliseOutputValues } from './utils/values';
|
|
37
|
+
/**
|
|
38
|
+
* Checks if a field should be disabled based on config.disabled property.
|
|
39
|
+
*/
|
|
40
|
+
const checkIsDisabled = (field, formValues) => {
|
|
41
|
+
var _a;
|
|
42
|
+
const configDisabled = (_a = field.config) === null || _a === void 0 ? void 0 : _a.disabled;
|
|
43
|
+
if (typeof configDisabled === 'function') {
|
|
44
|
+
return configDisabled(formValues);
|
|
45
|
+
}
|
|
46
|
+
return Boolean(configDisabled);
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Checks if a field should be visible based on config.visible property.
|
|
50
|
+
*/
|
|
51
|
+
const checkIsVisible = (field, formValues) => {
|
|
52
|
+
var _a;
|
|
53
|
+
const configVisible = (_a = field.config) === null || _a === void 0 ? void 0 : _a.visible;
|
|
54
|
+
if (typeof configVisible === 'function') {
|
|
55
|
+
return configVisible(formValues);
|
|
56
|
+
}
|
|
57
|
+
return configVisible !== false;
|
|
58
|
+
};
|
|
37
59
|
const resolveClearedFieldValue = (field, defaultValue) => {
|
|
38
60
|
if (defaultValue !== undefined) {
|
|
39
61
|
return defaultValue;
|
|
@@ -106,12 +128,17 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
106
128
|
if (field.type === 'select') {
|
|
107
129
|
return resolveSelectLabel();
|
|
108
130
|
}
|
|
131
|
+
// For custom fields with options (like custom selects), try to find the label
|
|
132
|
+
if (field.type === 'custom' && 'options' in field && field.options) {
|
|
133
|
+
return resolveSelectLabel();
|
|
134
|
+
}
|
|
109
135
|
if (field.type === 'date') {
|
|
110
136
|
const iso = akidate.toIsoDate(currentValue);
|
|
111
137
|
if (iso) {
|
|
112
138
|
// Use localized format with time if showTime is enabled
|
|
113
139
|
const hasShowTime = 'showTime' in field && field.showTime;
|
|
114
|
-
|
|
140
|
+
// L = localized date, LTS = localized time with seconds
|
|
141
|
+
const format = hasShowTime ? 'L LTS' : 'L';
|
|
115
142
|
return akidate.formatIsoDate(iso, format);
|
|
116
143
|
}
|
|
117
144
|
}
|
|
@@ -127,7 +154,8 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
127
154
|
}
|
|
128
155
|
const iso = akidate.toIsoDate(currentValue);
|
|
129
156
|
if (iso) {
|
|
130
|
-
|
|
157
|
+
// Use localized date format for fallback
|
|
158
|
+
return akidate.formatIsoDate(iso, 'L');
|
|
131
159
|
}
|
|
132
160
|
return String(currentValue);
|
|
133
161
|
};
|
|
@@ -215,10 +243,10 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
215
243
|
lastPersistedValuesRef.current = null;
|
|
216
244
|
}, [storageKey]);
|
|
217
245
|
const handleClearAll = React.useCallback(() => {
|
|
218
|
-
const clearedDefaults = Object.assign({},
|
|
246
|
+
const clearedDefaults = Object.assign({}, schemaDefaults);
|
|
219
247
|
flattenedSchema.forEach(field => {
|
|
220
248
|
const key = String(field.key);
|
|
221
|
-
const defaultValue =
|
|
249
|
+
const defaultValue = schemaDefaults[key];
|
|
222
250
|
const resolved = resolveClearedFieldValue(field, defaultValue);
|
|
223
251
|
if (resolved === undefined) {
|
|
224
252
|
delete clearedDefaults[key];
|
|
@@ -239,7 +267,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
239
267
|
lastPersistedValuesRef.current = nextSerialised !== null && nextSerialised !== void 0 ? nextSerialised : null;
|
|
240
268
|
onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(nextValues);
|
|
241
269
|
}, [
|
|
242
|
-
|
|
270
|
+
schemaDefaults,
|
|
243
271
|
flattenedSchema,
|
|
244
272
|
formMethods,
|
|
245
273
|
onClearAll,
|
|
@@ -271,7 +299,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
271
299
|
if (!schemaField) {
|
|
272
300
|
return;
|
|
273
301
|
}
|
|
274
|
-
const defaultValue =
|
|
302
|
+
const defaultValue = schemaDefaults[String(schemaField.key)];
|
|
275
303
|
const fieldPath = schemaField.key;
|
|
276
304
|
const nextValue = resolveClearedFieldValue(schemaField, defaultValue);
|
|
277
305
|
// Update the form value
|
|
@@ -280,10 +308,9 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
280
308
|
shouldTouch: false,
|
|
281
309
|
shouldValidate: false
|
|
282
310
|
});
|
|
283
|
-
//
|
|
284
|
-
const
|
|
285
|
-
const
|
|
286
|
-
const nextValues = normaliseOutputValues(flattenedSchema, updatedFormValues);
|
|
311
|
+
// Get all current form values (includes the updated field)
|
|
312
|
+
const allFormValues = formMethods.getValues();
|
|
313
|
+
const nextValues = normaliseOutputValues(flattenedSchema, allFormValues);
|
|
287
314
|
const nextSerialised = JSON.stringify(nextValues);
|
|
288
315
|
// Persist immediately (bypass debounce for remove action)
|
|
289
316
|
persistValues(nextValues);
|
|
@@ -295,7 +322,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
295
322
|
// Emit the change to parent
|
|
296
323
|
onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(nextValues);
|
|
297
324
|
}, [
|
|
298
|
-
|
|
325
|
+
schemaDefaults,
|
|
299
326
|
flattenedSchema,
|
|
300
327
|
formMethods,
|
|
301
328
|
onValuesChange,
|
|
@@ -317,22 +344,25 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
317
344
|
const start = (modalPage - 1) * modalPageSize;
|
|
318
345
|
return filteredFields.slice(start, start + modalPageSize);
|
|
319
346
|
}, [filteredFields, modalPage, modalPageSize]);
|
|
320
|
-
const visibleFields = React.useMemo(() => regularFields
|
|
347
|
+
const visibleFields = React.useMemo(() => regularFields
|
|
348
|
+
.filter(field => visibleKeys.includes(String(field.key)))
|
|
349
|
+
.filter(field => checkIsVisible(field, formValues !== null && formValues !== void 0 ? formValues : {})), [regularFields, visibleKeys, formValues]);
|
|
321
350
|
const renderFieldComponent = (field) => {
|
|
322
351
|
const ariaLabel = getFieldAriaLabel(field);
|
|
352
|
+
const isDisabled = checkIsDisabled(field, formValues !== null && formValues !== void 0 ? formValues : {});
|
|
323
353
|
switch (field.type) {
|
|
324
354
|
case 'text':
|
|
325
|
-
return (React.createElement(Input, { placeholder: field.placeholder, size: "large", allowClear: true, "aria-label": ariaLabel }));
|
|
355
|
+
return (React.createElement(Input, { placeholder: field.placeholder, size: "large", allowClear: true, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
326
356
|
case 'number':
|
|
327
|
-
return (React.createElement(InputNumber, { placeholder: field.placeholder, size: "large", className: "akinon-filter__field--number", "aria-label": ariaLabel }));
|
|
357
|
+
return (React.createElement(InputNumber, { placeholder: field.placeholder, size: "large", className: "akinon-filter__field--number", "aria-label": ariaLabel, disabled: isDisabled }));
|
|
328
358
|
case 'select':
|
|
329
|
-
return (React.createElement(Select, { placeholder: field.placeholder, size: "large", options: field.options, showSearch: true, optionFilterProp: "label", "aria-label": ariaLabel }));
|
|
359
|
+
return (React.createElement(Select, { placeholder: field.placeholder, size: "large", options: field.options, showSearch: true, optionFilterProp: "label", "aria-label": ariaLabel, disabled: isDisabled }));
|
|
330
360
|
case 'checkbox':
|
|
331
|
-
return React.createElement(Checkbox,
|
|
361
|
+
return React.createElement(Checkbox, { disabled: isDisabled }, field.label);
|
|
332
362
|
case 'date':
|
|
333
|
-
return (React.createElement(DatePicker, { placeholder: field.placeholder, showTime: field.showTime, suffixIcon: "calendar", suffixIconSize: "16px", "aria-label": ariaLabel }));
|
|
363
|
+
return (React.createElement(DatePicker, { placeholder: field.placeholder, showTime: field.showTime, suffixIcon: "calendar", suffixIconSize: "16px", "aria-label": ariaLabel, disabled: isDisabled }));
|
|
334
364
|
case 'textarea':
|
|
335
|
-
return (React.createElement(InputTextArea, { placeholder: field.placeholder, autoSize: { minRows: 3, maxRows: 6 }, "aria-label": ariaLabel }));
|
|
365
|
+
return (React.createElement(InputTextArea, { placeholder: field.placeholder, autoSize: { minRows: 3, maxRows: 6 }, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
336
366
|
case 'custom':
|
|
337
367
|
if (typeof field.render === 'function') {
|
|
338
368
|
return field.render({
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
import type { FieldValues, Path } from '@akinon/akiform';
|
|
2
2
|
import type { FormField } from '@akinon/akiform-builder';
|
|
3
|
+
export interface AkifilterFieldConfig<TFieldValues extends FieldValues = FieldValues> {
|
|
4
|
+
/**
|
|
5
|
+
* Controls whether the field is disabled.
|
|
6
|
+
* Can be a boolean or a function that receives form values and returns a boolean.
|
|
7
|
+
*/
|
|
8
|
+
disabled?: boolean | ((formValues: TFieldValues) => boolean);
|
|
9
|
+
/**
|
|
10
|
+
* Controls whether the field is visible.
|
|
11
|
+
* Can be a boolean or a function that receives form values and returns a boolean.
|
|
12
|
+
*/
|
|
13
|
+
visible?: boolean | ((formValues: TFieldValues) => boolean);
|
|
14
|
+
}
|
|
3
15
|
export type AkifilterField<TFieldValues extends FieldValues = FieldValues> = FormField<TFieldValues> & {
|
|
4
16
|
/**
|
|
5
17
|
* Controls whether the field is shown in the main filter form by default.
|
|
6
18
|
*/
|
|
7
19
|
isVisible?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Configuration options for field behavior (disabled, visible).
|
|
22
|
+
*/
|
|
23
|
+
config?: AkifilterFieldConfig<TFieldValues>;
|
|
8
24
|
};
|
|
9
25
|
export type AkifilterFieldKey<TFieldValues extends FieldValues = FieldValues> = Path<TFieldValues>;
|
|
10
26
|
export type AkifilterSchema<TFieldValues extends FieldValues = FieldValues> = AkifilterField<TFieldValues>[];
|
package/dist/esm/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,MAAM,cAAc,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IACvE,SAAS,CAAC,YAAY,CAAC,GAAG;IACxB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,WAAW,oBAAoB,CACnC,YAAY,SAAS,WAAW,GAAG,WAAW;IAE9C;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,UAAU,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC;IAC7D;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,UAAU,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC;CAC7D;AAED,MAAM,MAAM,cAAc,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IACvE,SAAS,CAAC,YAAY,CAAC,GAAG;IACxB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;CAC7C,CAAC;AAEJ,MAAM,MAAM,iBAAiB,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IAC1E,IAAI,CAAC,YAAY,CAAC,CAAC;AAErB,MAAM,MAAM,eAAe,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IACxE,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/akifilter",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-next.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Akifilter is a filtering library for Akinon frontend applications.",
|
|
6
6
|
"type": "module",
|
|
@@ -13,32 +13,32 @@
|
|
|
13
13
|
"antd": "^5.27.0",
|
|
14
14
|
"react-error-boundary": "^6.0.0",
|
|
15
15
|
"@akinon/akiform": "1.1.2",
|
|
16
|
-
"@akinon/akidate": "1.1.
|
|
17
|
-
"@akinon/icons": "1.1.2-rc.0",
|
|
16
|
+
"@akinon/akidate": "1.1.3-next.0",
|
|
18
17
|
"@akinon/akilocale": "1.2.1",
|
|
19
|
-
"@akinon/
|
|
20
|
-
"@akinon/ui-
|
|
21
|
-
"@akinon/ui-checkbox": "1.3.3-
|
|
22
|
-
"@akinon/ui-
|
|
23
|
-
"@akinon/ui-
|
|
24
|
-
"@akinon/ui-
|
|
25
|
-
"@akinon/ui-
|
|
26
|
-
"@akinon/ui-
|
|
27
|
-
"@akinon/ui-
|
|
28
|
-
"@akinon/ui-
|
|
29
|
-
"@akinon/ui-
|
|
30
|
-
"@akinon/ui-
|
|
18
|
+
"@akinon/icons": "1.1.2-next.1",
|
|
19
|
+
"@akinon/ui-button": "1.4.0-next.1",
|
|
20
|
+
"@akinon/ui-checkbox": "1.3.3-next.1",
|
|
21
|
+
"@akinon/ui-card": "1.1.3-next.1",
|
|
22
|
+
"@akinon/ui-date-picker": "1.3.3-next.1",
|
|
23
|
+
"@akinon/ui-collapse": "1.3.2-next.1",
|
|
24
|
+
"@akinon/ui-input-number": "1.3.3-next.1",
|
|
25
|
+
"@akinon/ui-typography": "1.1.2-next.0",
|
|
26
|
+
"@akinon/ui-modal": "1.1.3-next.1",
|
|
27
|
+
"@akinon/ui-input": "1.1.3-next.1",
|
|
28
|
+
"@akinon/ui-select": "1.3.4-next.1",
|
|
29
|
+
"@akinon/ui-pagination": "1.3.4-next.1",
|
|
30
|
+
"@akinon/ui-space": "1.3.3-next.1"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"clean-package": "2.2.0",
|
|
34
34
|
"copyfiles": "^2.4.1",
|
|
35
35
|
"rimraf": "^5.0.5",
|
|
36
36
|
"typescript": "*",
|
|
37
|
-
"@akinon/
|
|
38
|
-
"@akinon/
|
|
39
|
-
"@akinon/ui-theme": "1.1.3-
|
|
40
|
-
"@akinon/
|
|
41
|
-
"@akinon/
|
|
37
|
+
"@akinon/utils": "1.1.4-next.1",
|
|
38
|
+
"@akinon/akiform-builder": "1.3.5-next.1",
|
|
39
|
+
"@akinon/ui-theme": "1.1.3-next.1",
|
|
40
|
+
"@akinon/typescript-config": "1.1.1",
|
|
41
|
+
"@akinon/vitest-config": "1.1.1"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"react": "^18 || ^19",
|