@akinon/akifilter 1.6.1 → 1.7.0-260706-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 (43) hide show
  1. package/dist/cjs/akifilter.d.ts +12 -1
  2. package/dist/cjs/akifilter.d.ts.map +1 -1
  3. package/dist/cjs/akifilter.js +135 -18
  4. package/dist/cjs/common/storage.d.ts +3 -0
  5. package/dist/cjs/common/storage.d.ts.map +1 -1
  6. package/dist/cjs/common/storage.js +50 -1
  7. package/dist/cjs/components/applied-filters.d.ts +6 -1
  8. package/dist/cjs/components/applied-filters.d.ts.map +1 -1
  9. package/dist/cjs/components/applied-filters.js +2 -1
  10. package/dist/cjs/components/filter-buttons.d.ts +14 -0
  11. package/dist/cjs/components/filter-buttons.d.ts.map +1 -0
  12. package/dist/cjs/components/filter-buttons.js +21 -0
  13. package/dist/cjs/i18n/translations/en.d.ts +3 -0
  14. package/dist/cjs/i18n/translations/en.d.ts.map +1 -1
  15. package/dist/cjs/i18n/translations/en.js +4 -1
  16. package/dist/cjs/i18n/translations/tr.d.ts +3 -0
  17. package/dist/cjs/i18n/translations/tr.d.ts.map +1 -1
  18. package/dist/cjs/i18n/translations/tr.js +4 -1
  19. package/dist/cjs/styles.css +36 -6
  20. package/dist/cjs/types.d.ts +45 -0
  21. package/dist/cjs/types.d.ts.map +1 -1
  22. package/dist/esm/akifilter.d.ts +12 -1
  23. package/dist/esm/akifilter.d.ts.map +1 -1
  24. package/dist/esm/akifilter.js +136 -19
  25. package/dist/esm/common/storage.d.ts +3 -0
  26. package/dist/esm/common/storage.d.ts.map +1 -1
  27. package/dist/esm/common/storage.js +46 -0
  28. package/dist/esm/components/applied-filters.d.ts +6 -1
  29. package/dist/esm/components/applied-filters.d.ts.map +1 -1
  30. package/dist/esm/components/applied-filters.js +2 -1
  31. package/dist/esm/components/filter-buttons.d.ts +14 -0
  32. package/dist/esm/components/filter-buttons.d.ts.map +1 -0
  33. package/dist/esm/components/filter-buttons.js +17 -0
  34. package/dist/esm/i18n/translations/en.d.ts +3 -0
  35. package/dist/esm/i18n/translations/en.d.ts.map +1 -1
  36. package/dist/esm/i18n/translations/en.js +4 -1
  37. package/dist/esm/i18n/translations/tr.d.ts +3 -0
  38. package/dist/esm/i18n/translations/tr.d.ts.map +1 -1
  39. package/dist/esm/i18n/translations/tr.js +4 -1
  40. package/dist/esm/styles.css +36 -6
  41. package/dist/esm/types.d.ts +45 -0
  42. package/dist/esm/types.d.ts.map +1 -1
  43. package/package.json +8 -8
@@ -3,7 +3,7 @@ import { FieldValues, Path } from '@akinon/akiform';
3
3
  import { type PanelProps } from '@akinon/ui-collapse';
4
4
  import React from 'react';
5
5
  import { type AppliedFilter } from './components/applied-filters';
6
- import type { AkifilterActionsRef, AkifilterSchema } from './types';
6
+ import type { AkifilterActionsRef, AkifilterButton, AkifilterSchema } from './types';
7
7
  type AkifilterFieldValues = FieldValues;
8
8
  export type AkifilterProps<TFieldValues extends AkifilterFieldValues = AkifilterFieldValues> = {
9
9
  /**
@@ -61,6 +61,17 @@ export type AkifilterProps<TFieldValues extends AkifilterFieldValues = Akifilter
61
61
  * Called when the user removes an externally-provided chip.
62
62
  */
63
63
  onRemoveExternalFilter?: (key: string) => void;
64
+ /**
65
+ * Quick-filter toggle buttons rendered above the filter form. Active button
66
+ * values are merged into the `onValuesChange` payload under each button's
67
+ * `key` (buttons sharing a key produce an array of values), persisted with
68
+ * the rest of the filters and shown as removable chips.
69
+ */
70
+ filterButtons?: AkifilterButton[];
71
+ /**
72
+ * Notified whenever the set of active filter buttons changes.
73
+ */
74
+ onFilterButtonsChange?: (activeButtons: AkifilterButton[]) => void;
64
75
  };
65
76
  export declare const ExpandIcon: ({ isActive }: PanelProps) => {
66
77
  name: "chevron_down";
@@ -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;AAIzB,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAShE,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AActC,OAAO,KAAK,EACV,mBAAmB,EAEnB,eAAe,EAChB,MAAM,SAAS,CAAC;AAcjB,KAAK,oBAAoB,GAAG,WAAW,CAAC;AAoKxC,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;AA4zBF,eAAO,MAAM,UAAU,GAAI,cAAc,UAAU;;;;;;;;CAQjD,CAAC;AA8CH,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;AAIzB,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAShE,OAAO,KAAK,MAAM,OAAO,CAAC;AAgB1B,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AAetC,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EAEf,eAAe,EAChB,MAAM,SAAS,CAAC;AAcjB,KAAK,oBAAoB,GAAG,WAAW,CAAC;AA2KxC,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;IAC/C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;IAClC;;OAEG;IACH,qBAAqB,CAAC,EAAE,CAAC,aAAa,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;CACpE,CAAC;AAq9BF,eAAO,MAAM,UAAU,GAAI,cAAc,UAAU;;;;;;;;CAQjD,CAAC;AA8CH,eAAO,MAAM,SAAS;KACpB,YAAY,SAAS,oBAAoB,uBAElC,cAAc,CAAC,YAAY,CAAC;;CAoBpC,CAAC"}
@@ -31,6 +31,7 @@ const react_error_boundary_1 = require("react-error-boundary");
31
31
  const storage_1 = require("./common/storage");
32
32
  const theme_overrides_1 = require("./common/theme-overrides");
33
33
  const applied_filters_1 = require("./components/applied-filters");
34
+ const filter_buttons_1 = require("./components/filter-buttons");
34
35
  const filter_toolbar_1 = require("./components/filter-toolbar");
35
36
  const visibility_modal_1 = require("./components/visibility-modal");
36
37
  const constants_1 = require("./constants");
@@ -40,6 +41,12 @@ const use_visibility_cleanup_1 = require("./hooks/use-visibility-cleanup");
40
41
  const i18n_1 = require("./i18n");
41
42
  const schema_1 = require("./utils/schema");
42
43
  const values_1 = require("./utils/values");
44
+ /**
45
+ * Prefix for applied-filter chip keys that originate from filter buttons.
46
+ * Keeps button chips from colliding with schema field keys so removals can be
47
+ * routed back to the owning button.
48
+ */
49
+ const BUTTON_CHIP_PREFIX = 'akifilter-button:';
43
50
  const FilterFormItem = (_a) => {
44
51
  var _b, _c;
45
52
  var { children, control, name, valuePropName } = _a, props = __rest(_a, ["children", "control", "name", "valuePropName"]);
@@ -120,7 +127,7 @@ const resolveClearedFieldValue = (field, defaultValue) => {
120
127
  return undefined;
121
128
  }
122
129
  };
123
- const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onValuesChange, onVisibleFieldsChange, onImportCsv, onImportXls, onClearAll, enableImportCsv, enableImportXls, filterActionsRef, externalAppliedFilters, onRemoveExternalFilter }) => {
130
+ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onValuesChange, onVisibleFieldsChange, onImportCsv, onImportXls, onClearAll, enableImportCsv, enableImportXls, filterActionsRef, externalAppliedFilters, onRemoveExternalFilter, filterButtons, onFilterButtonsChange }) => {
124
131
  // Separate regular fields from section fields
125
132
  const { regularFields, sectionFields } = react_1.default.useMemo(() => (0, schema_1.partitionSchema)(filterSchema), [filterSchema]);
126
133
  const excludeSectionKeys = react_1.default.useMemo(() => (0, schema_1.deriveExcludeSectionKeys)(sectionFields), [sectionFields]);
@@ -149,6 +156,34 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
149
156
  const [searchTerm, setSearchTerm] = react_1.default.useState('');
150
157
  const [modalPage, setModalPage] = react_1.default.useState(1);
151
158
  const [modalPageSize, setModalPageSize] = react_1.default.useState(constants_1.DEFAULT_MODAL_PAGE_SIZE);
159
+ // --- Filter buttons (quick-filter toggles) ---------------------------------
160
+ // A button is identified by its `value`, which must be unique across the
161
+ // whole `filterButtons` array.
162
+ const [activeButtonValues, setActiveButtonValues] = react_1.default.useState(() => { var _a; return (_a = (0, storage_1.readStoredButtonValues)(storageKey)) !== null && _a !== void 0 ? _a : []; });
163
+ // Re-read persisted button state when the storage key changes.
164
+ react_1.default.useEffect(() => {
165
+ var _a;
166
+ setActiveButtonValues((_a = (0, storage_1.readStoredButtonValues)(storageKey)) !== null && _a !== void 0 ? _a : []);
167
+ }, [storageKey]);
168
+ // Build the `{ key: value[] }` object contributed by the active buttons.
169
+ // Buttons that share a key are merged into an array (legacy behaviour).
170
+ const computeButtonValues = react_1.default.useCallback((values) => {
171
+ return (filterButtons !== null && filterButtons !== void 0 ? filterButtons : []).reduce((acc, button) => {
172
+ var _a;
173
+ var _b;
174
+ if (!values.includes(button.value)) {
175
+ return acc;
176
+ }
177
+ ((_a = acc[_b = button.key]) !== null && _a !== void 0 ? _a : (acc[_b] = [])).push(button.value);
178
+ return acc;
179
+ }, {});
180
+ }, [filterButtons]);
181
+ // Mirror the current button values in a ref so the value-emission callbacks
182
+ // can merge them without taking button state as a dependency.
183
+ const buttonValuesRef = react_1.default.useRef(computeButtonValues(activeButtonValues));
184
+ react_1.default.useEffect(() => {
185
+ buttonValuesRef.current = computeButtonValues(activeButtonValues);
186
+ }, [computeButtonValues, activeButtonValues]);
152
187
  const appliedFilters = react_1.default.useMemo(() => {
153
188
  if (!formValues) {
154
189
  return [];
@@ -237,6 +272,17 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
237
272
  return acc;
238
273
  }, []);
239
274
  }, [flattenedSchema, formValues, excludeSectionKeys]);
275
+ // Chips for the currently active filter buttons. The chip key is prefixed
276
+ // with the button value so removals can be routed back to the owning button.
277
+ const buttonAppliedFilters = react_1.default.useMemo(() => {
278
+ return (filterButtons !== null && filterButtons !== void 0 ? filterButtons : [])
279
+ .filter(button => activeButtonValues.includes(button.value))
280
+ .map(button => ({
281
+ key: `${BUTTON_CHIP_PREFIX}${button.value}`,
282
+ label: button.appliedPrefix,
283
+ value: button.label
284
+ }));
285
+ }, [filterButtons, activeButtonValues]);
240
286
  const resolveInitialVisibleKeys = react_1.default.useCallback(() => {
241
287
  const storedKeys = (0, storage_1.readVisibleKeys)(regularFields, storageKey);
242
288
  const defaultKeys = (0, schema_1.deriveDefaultVisibleKeys)(regularFields);
@@ -292,6 +338,12 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
292
338
  (0, storage_1.writeStoredValues)(storageKey, values);
293
339
  return nextSerialised;
294
340
  }, [storageKey]);
341
+ // Emit the normalised form values merged with the active filter-button
342
+ // values. Buttons live outside the form state, so every emission point routes
343
+ // through here to keep the two slices combined in the payload.
344
+ const emitValues = react_1.default.useCallback((values) => {
345
+ onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(Object.assign(Object.assign({}, values), buttonValuesRef.current));
346
+ }, [onValuesChange]);
295
347
  // Use a ref to track the current serialised values for staleness checks
296
348
  const currentSerialisedValuesRef = react_1.default.useRef(serialisedValues);
297
349
  react_1.default.useEffect(() => {
@@ -315,15 +367,17 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
315
367
  const isEmpty = Object.keys(parsedValues).length === 0;
316
368
  if (!hasEmittedValuesRef.current &&
317
369
  isEmpty &&
318
- !hasInitialValuesRef.current) {
370
+ !hasInitialValuesRef.current &&
371
+ // Only reached on the first-emit path; short-circuits away on later cycles.
372
+ Object.keys(buttonValuesRef.current).length === 0) {
319
373
  hasEmittedValuesRef.current = true;
320
374
  persistValues(parsedValues, debouncedSerialisedValues);
321
375
  return;
322
376
  }
323
377
  hasEmittedValuesRef.current = true;
324
- onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(parsedValues);
378
+ emitValues(parsedValues);
325
379
  persistValues(parsedValues, debouncedSerialisedValues);
326
- }, [debouncedSerialisedValues, onValuesChange, persistValues]);
380
+ }, [debouncedSerialisedValues, emitValues, persistValues]);
327
381
  react_1.default.useEffect(() => {
328
382
  lastPersistedValuesRef.current = null;
329
383
  }, [storageKey]);
@@ -356,9 +410,9 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
356
410
  currentSerialisedValuesRef.current = nextSerialised;
357
411
  // Update persistedDefaults to prevent stale mergedDefaultValues on re-render
358
412
  setPersistedDefaults(currParsed);
359
- onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(currParsed);
413
+ emitValues(currParsed);
360
414
  }
361
- }, [serialisedValues, onValuesChange, persistValues]);
415
+ }, [serialisedValues, emitValues, persistValues]);
362
416
  const handleClearAll = react_1.default.useCallback(() => {
363
417
  const clearedDefaults = Object.assign({}, schemaDefaults);
364
418
  flattenedSchema.forEach(field => {
@@ -385,13 +439,13 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
385
439
  const nextSerialised = persistValues(nextValues);
386
440
  hasEmittedValuesRef.current = true;
387
441
  lastPersistedValuesRef.current = nextSerialised !== null && nextSerialised !== void 0 ? nextSerialised : null;
388
- onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(nextValues);
442
+ emitValues(nextValues);
389
443
  }, [
390
444
  schemaDefaults,
391
445
  flattenedSchema,
392
446
  formMethods,
393
447
  onClearAll,
394
- onValuesChange,
448
+ emitValues,
395
449
  persistValues
396
450
  ]);
397
451
  const handleOpenModal = react_1.default.useCallback(() => {
@@ -445,14 +499,48 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
445
499
  hasEmittedValuesRef.current = true;
446
500
  hasInitialValuesRef.current = Object.keys(nextValues).length > 0;
447
501
  // Emit the change to parent
448
- onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(nextValues);
502
+ emitValues(nextValues);
503
+ }, [schemaDefaults, flattenedSchema, formMethods, emitValues, persistValues]);
504
+ // Toggle a filter button. Button state lives outside the form, so this syncs
505
+ // the value ref, persists, and emits immediately (bypassing the form debounce).
506
+ const handleButtonToggle = react_1.default.useCallback((button) => {
507
+ const isActive = activeButtonValues.includes(button.value);
508
+ let nextValues;
509
+ if (isActive) {
510
+ nextValues = activeButtonValues.filter(value => value !== button.value);
511
+ }
512
+ else if (button.singleChoice) {
513
+ nextValues = [button.value];
514
+ }
515
+ else {
516
+ nextValues = [...activeButtonValues, button.value];
517
+ }
518
+ // Sync the ref synchronously so emitValues sees the new button values
519
+ // before the state-update effect runs.
520
+ buttonValuesRef.current = computeButtonValues(nextValues);
521
+ setActiveButtonValues(nextValues);
522
+ (0, storage_1.writeStoredButtonValues)(storageKey, nextValues);
523
+ const formValuesNow = (0, values_1.normaliseOutputValues)(flattenedSchema, formMethods.getValues());
524
+ hasEmittedValuesRef.current = true;
525
+ emitValues(formValuesNow);
526
+ onFilterButtonsChange === null || onFilterButtonsChange === void 0 ? void 0 : onFilterButtonsChange((filterButtons !== null && filterButtons !== void 0 ? filterButtons : []).filter(item => nextValues.includes(item.value)));
449
527
  }, [
450
- schemaDefaults,
528
+ activeButtonValues,
529
+ computeButtonValues,
530
+ storageKey,
451
531
  flattenedSchema,
452
532
  formMethods,
453
- onValuesChange,
454
- persistValues
533
+ emitValues,
534
+ onFilterButtonsChange,
535
+ filterButtons
455
536
  ]);
537
+ // Deactivate a button from its applied-filter chip.
538
+ const handleButtonRemove = react_1.default.useCallback((value) => {
539
+ const button = (filterButtons !== null && filterButtons !== void 0 ? filterButtons : []).find(item => String(item.value) === value);
540
+ if (button) {
541
+ handleButtonToggle(button);
542
+ }
543
+ }, [filterButtons, handleButtonToggle]);
456
544
  // Expose imperative methods via ref
457
545
  react_1.default.useImperativeHandle(filterActionsRef, () => ({
458
546
  clearValue: (keys) => {
@@ -490,17 +578,40 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
490
578
  onRemove: handleRemoveFilter
491
579
  });
492
580
  const handleAppliedFilterRemove = react_1.default.useCallback((key) => {
493
- if (externalAppliedFilters === null || externalAppliedFilters === void 0 ? void 0 : externalAppliedFilters.some(f => f.key === key)) {
581
+ if (key.startsWith(BUTTON_CHIP_PREFIX)) {
582
+ handleButtonRemove(key.slice(BUTTON_CHIP_PREFIX.length));
583
+ }
584
+ else if (externalAppliedFilters === null || externalAppliedFilters === void 0 ? void 0 : externalAppliedFilters.some(f => f.key === key)) {
494
585
  onRemoveExternalFilter === null || onRemoveExternalFilter === void 0 ? void 0 : onRemoveExternalFilter(key);
495
586
  }
496
587
  else {
497
588
  handleRemoveFilter(key);
498
589
  }
499
- }, [externalAppliedFilters, onRemoveExternalFilter, handleRemoveFilter]);
590
+ }, [
591
+ externalAppliedFilters,
592
+ onRemoveExternalFilter,
593
+ handleRemoveFilter,
594
+ handleButtonRemove
595
+ ]);
500
596
  const handleClearAllApplied = react_1.default.useCallback(() => {
597
+ // Reset filter buttons before clearing the form so the merged emission in
598
+ // handleClearAll no longer carries button values.
599
+ if (activeButtonValues.length > 0) {
600
+ buttonValuesRef.current = {};
601
+ setActiveButtonValues([]);
602
+ (0, storage_1.clearStoredButtonValues)(storageKey);
603
+ onFilterButtonsChange === null || onFilterButtonsChange === void 0 ? void 0 : onFilterButtonsChange([]);
604
+ }
501
605
  handleClearAll();
502
606
  externalAppliedFilters === null || externalAppliedFilters === void 0 ? void 0 : externalAppliedFilters.forEach(f => onRemoveExternalFilter === null || onRemoveExternalFilter === void 0 ? void 0 : onRemoveExternalFilter(f.key));
503
- }, [handleClearAll, externalAppliedFilters, onRemoveExternalFilter]);
607
+ }, [
608
+ handleClearAll,
609
+ externalAppliedFilters,
610
+ onRemoveExternalFilter,
611
+ activeButtonValues,
612
+ storageKey,
613
+ onFilterButtonsChange
614
+ ]);
504
615
  const renderFieldComponent = (field) => {
505
616
  const ariaLabel = (0, schema_1.getFieldAriaLabel)(field);
506
617
  const isDisabled = checkIsDisabled(field, formValues !== null && formValues !== void 0 ? formValues : {});
@@ -545,12 +656,16 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
545
656
  return (react_1.default.createElement(ui_card_1.Card, { size: "small", className: "akinon-filter shadow", "data-testid": "akifilter-root" },
546
657
  react_1.default.createElement(antd_1.ConfigProvider, { theme: theme_overrides_1.themeOverrides },
547
658
  react_1.default.createElement(filter_toolbar_1.FilterToolbar, { onOpenModal: handleOpenModal, enableImportCsv: enableImportCsv, enableImportXls: enableImportXls, onImportCsv: onImportCsv, onImportXls: onImportXls }),
548
- react_1.default.createElement(applied_filters_1.AppliedFilters, { filters: [...appliedFilters, ...(externalAppliedFilters !== null && externalAppliedFilters !== void 0 ? externalAppliedFilters : [])], onRemove: handleAppliedFilterRemove, onClearAll: handleClearAllApplied }),
659
+ react_1.default.createElement(applied_filters_1.AppliedFilters, { filters: [
660
+ ...appliedFilters,
661
+ ...buttonAppliedFilters,
662
+ ...(externalAppliedFilters !== null && externalAppliedFilters !== void 0 ? externalAppliedFilters : [])
663
+ ], onRemove: handleAppliedFilterRemove, onClearAll: handleClearAllApplied, leading: react_1.default.createElement(filter_buttons_1.FilterButtons, { buttons: filterButtons !== null && filterButtons !== void 0 ? filterButtons : [], activeValues: activeButtonValues, onToggle: handleButtonToggle }) }),
549
664
  react_1.default.createElement("div", { className: "akinon-filter__body" },
550
665
  react_1.default.createElement(akiform_1.Akiform, { layout: "vertical", className: "akinon-filter__form" },
551
666
  react_1.default.createElement("div", { className: "akinon-filter__form-grid", "data-testid": "akifilter-form-grid" },
552
667
  visibleFields.map(renderFormField),
553
- visibleFields.length === 0 ? (react_1.default.createElement("div", { className: "akinon-filter__empty" }, i18n_1.i18n.t('form.noVisibleFields'))) : null),
668
+ visibleFields.length === 0 && regularFields.length > 0 ? (react_1.default.createElement("div", { className: "akinon-filter__empty" }, i18n_1.i18n.t('form.noVisibleFields'))) : null),
554
669
  sectionFields.length > 0 && (react_1.default.createElement("div", { className: "akinon-filter__section-fields" }, sectionFields.map(section => {
555
670
  return (react_1.default.createElement(ui_collapse_1.Collapse, { expandIconPosition: "end", key: section.key, expandIcon: exports.ExpandIcon, defaultActiveKey: section.defaultExpanded === false ? [] : [section.key], ghost: true, items: [
556
671
  {
@@ -598,10 +713,12 @@ const renderErrorFallback = ({ resetErrorBoundary }) => {
598
713
  react_1.default.createElement(ui_button_1.Button, { type: "primary", onClick: resetErrorBoundary, size: "small" }, t('errors.retry'))))));
599
714
  };
600
715
  const Akifilter = (props) => {
716
+ var _a, _b;
601
717
  const { filterSchema } = props, restProps = __rest(props, ["filterSchema"]);
602
718
  const resolvedSchema = (filterSchema !== null && filterSchema !== void 0 ? filterSchema : []);
603
719
  const hasSchema = resolvedSchema.length > 0;
604
- return (react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { fallbackRender: renderErrorFallback }, hasSchema ? (react_1.default.createElement(AkifilterContent, Object.assign({}, restProps, { filterSchema: resolvedSchema }))) : (react_1.default.createElement(AkifilterEmptyState, null))));
720
+ const hasButtons = ((_b = (_a = props.filterButtons) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0;
721
+ return (react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { fallbackRender: renderErrorFallback }, hasSchema || hasButtons ? (react_1.default.createElement(AkifilterContent, Object.assign({}, restProps, { filterSchema: resolvedSchema }))) : (react_1.default.createElement(AkifilterEmptyState, null))));
605
722
  };
606
723
  exports.Akifilter = Akifilter;
607
724
  exports.Akifilter.displayName = 'Akifilter';
@@ -7,4 +7,7 @@ export declare const clearVisibleKeys: (storageKey: string) => void;
7
7
  export declare const readStoredValues: <TFieldValues extends FieldValues>(schema: AkifilterField<TFieldValues>[], storageKey: string) => Partial<TFieldValues> | null;
8
8
  export declare const writeStoredValues: <TFieldValues extends FieldValues>(storageKey: string, values: Partial<TFieldValues>) => void;
9
9
  export declare const clearStoredValues: (storageKey: string) => void;
10
+ export declare const readStoredButtonValues: (storageKey: string) => Array<string | number> | null;
11
+ export declare const writeStoredButtonValues: (storageKey: string, values: Array<string | number>) => void;
12
+ export declare const clearStoredButtonValues: (storageKey: string) => void;
10
13
  //# sourceMappingURL=storage.d.ts.map
@@ -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;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"}
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;AA4B/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;AAKF,eAAO,MAAM,sBAAsB,GACjC,YAAY,MAAM,KACjB,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,IAwB3B,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,YAAY,MAAM,EAClB,QAAQ,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAC7B,IAcF,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,YAAY,MAAM,KAAG,IAQ5D,CAAC"}
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.clearStoredValues = exports.writeStoredValues = exports.readStoredValues = exports.clearVisibleKeys = exports.writeVisibleKeys = exports.readVisibleKeys = exports.buildStorageKey = void 0;
3
+ exports.clearStoredButtonValues = exports.writeStoredButtonValues = exports.readStoredButtonValues = exports.clearStoredValues = exports.writeStoredValues = exports.readStoredValues = exports.clearVisibleKeys = exports.writeVisibleKeys = exports.readVisibleKeys = exports.buildStorageKey = void 0;
4
4
  const i18n_1 = require("../i18n");
5
5
  const STORAGE_PREFIX = 'akifilter:v1';
6
6
  const VALUES_SUFFIX = ':values';
7
+ const BUTTONS_SUFFIX = ':buttons';
7
8
  const hashString = (value) => {
8
9
  let hash = 0;
9
10
  for (let i = 0; i < value.length; i += 1) {
@@ -128,3 +129,51 @@ const clearStoredValues = (storageKey) => {
128
129
  }
129
130
  };
130
131
  exports.clearStoredValues = clearStoredValues;
132
+ const buildButtonsStorageKey = (storageKey) => `${storageKey}${BUTTONS_SUFFIX}`;
133
+ const readStoredButtonValues = (storageKey) => {
134
+ if (!isBrowser)
135
+ return null;
136
+ try {
137
+ const rawValue = window.localStorage.getItem(buildButtonsStorageKey(storageKey));
138
+ if (!rawValue) {
139
+ return null;
140
+ }
141
+ const parsed = JSON.parse(rawValue);
142
+ if (!Array.isArray(parsed)) {
143
+ return null;
144
+ }
145
+ return parsed.filter((value) => typeof value === 'string' || typeof value === 'number');
146
+ }
147
+ catch (error) {
148
+ console.warn(i18n_1.i18n.t('errors.storage.readButtons'), error);
149
+ return null;
150
+ }
151
+ };
152
+ exports.readStoredButtonValues = readStoredButtonValues;
153
+ const writeStoredButtonValues = (storageKey, values) => {
154
+ if (!isBrowser)
155
+ return;
156
+ const buttonsKey = buildButtonsStorageKey(storageKey);
157
+ try {
158
+ if (values.length === 0) {
159
+ window.localStorage.removeItem(buttonsKey);
160
+ return;
161
+ }
162
+ window.localStorage.setItem(buttonsKey, JSON.stringify(values));
163
+ }
164
+ catch (error) {
165
+ console.warn(i18n_1.i18n.t('errors.storage.writeButtons'), error);
166
+ }
167
+ };
168
+ exports.writeStoredButtonValues = writeStoredButtonValues;
169
+ const clearStoredButtonValues = (storageKey) => {
170
+ if (!isBrowser)
171
+ return;
172
+ try {
173
+ window.localStorage.removeItem(buildButtonsStorageKey(storageKey));
174
+ }
175
+ catch (error) {
176
+ console.warn(i18n_1.i18n.t('errors.storage.clearButtons'), error);
177
+ }
178
+ };
179
+ exports.clearStoredButtonValues = clearStoredButtonValues;
@@ -9,7 +9,12 @@ type AppliedFiltersProps = {
9
9
  filters: AppliedFilter[];
10
10
  onRemove: (key: string) => void;
11
11
  onClearAll: () => void;
12
+ /**
13
+ * Content rendered at the start of the bar, before the active-filters
14
+ * summary (e.g. quick-filter toggle buttons).
15
+ */
16
+ leading?: React.ReactNode;
12
17
  };
13
- export declare const AppliedFilters: ({ filters, onRemove, onClearAll }: AppliedFiltersProps) => React.JSX.Element;
18
+ export declare const AppliedFilters: ({ filters, onRemove, onClearAll, leading }: AppliedFiltersProps) => React.JSX.Element;
14
19
  export type { AppliedFilter };
15
20
  //# sourceMappingURL=applied-filters.d.ts.map
@@ -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;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,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,sBA+DrB,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;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,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;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,4CAK5B,mBAAmB,sBAgErB,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -7,9 +7,10 @@ const ui_space_1 = require("@akinon/ui-space");
7
7
  const ui_typography_1 = require("@akinon/ui-typography");
8
8
  const react_1 = require("react");
9
9
  const i18n_1 = require("../i18n");
10
- const AppliedFilters = ({ filters, onRemove, onClearAll }) => {
10
+ const AppliedFilters = ({ filters, onRemove, onClearAll, leading }) => {
11
11
  const hasFilters = filters.length > 0;
12
12
  return (react_1.default.createElement("div", { className: "akinon-filter__applied", "data-testid": "akifilter-applied" },
13
+ leading,
13
14
  react_1.default.createElement(ui_space_1.Space, { className: "akinon-filter__applied-summary", size: 8 },
14
15
  react_1.default.createElement(ui_typography_1.Text, { className: "akinon-filter__applied-label" }, i18n_1.i18n.t('applied.label')),
15
16
  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${item.isExclude ? ' akinon-filter__chip--exclude' : ''}` },
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import type { AkifilterButton } from '../types';
3
+ type FilterButtonsProps = {
4
+ buttons: AkifilterButton[];
5
+ activeValues: Array<string | number>;
6
+ onToggle: (button: AkifilterButton) => void;
7
+ };
8
+ /**
9
+ * Row of quick-filter toggle buttons rendered above the filter form. Active
10
+ * state is owned by the parent; clicking a button delegates to `onToggle`.
11
+ */
12
+ export declare const FilterButtons: ({ buttons, activeValues, onToggle }: FilterButtonsProps) => React.JSX.Element | null;
13
+ export {};
14
+ //# sourceMappingURL=filter-buttons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-buttons.d.ts","sourceRoot":"","sources":["../../../src/components/filter-buttons.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,KAAK,kBAAkB,GAAG;IACxB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,YAAY,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACrC,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;CAC7C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,qCAI3B,kBAAkB,6BA4BpB,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FilterButtons = void 0;
4
+ const ui_button_1 = require("@akinon/ui-button");
5
+ const ui_space_1 = require("@akinon/ui-space");
6
+ const react_1 = require("react");
7
+ /**
8
+ * Row of quick-filter toggle buttons rendered above the filter form. Active
9
+ * state is owned by the parent; clicking a button delegates to `onToggle`.
10
+ */
11
+ const FilterButtons = ({ buttons, activeValues, onToggle }) => {
12
+ if (buttons.length === 0) {
13
+ return null;
14
+ }
15
+ return (react_1.default.createElement("div", { className: "akinon-filter__buttons", "data-testid": "akifilter-buttons" },
16
+ react_1.default.createElement(ui_space_1.Space, { size: 6 }, buttons.map(button => {
17
+ const isActive = activeValues.includes(button.value);
18
+ return (react_1.default.createElement(ui_button_1.Button, { key: button.value, className: `akinon-filter__button${isActive ? ' akinon-filter__button--active' : ''}`, icon: button.icon, iconSize: 20, type: "text", onClick: () => onToggle(button), tooltip: button.label, "aria-label": button.label, "aria-pressed": isActive }));
19
+ }))));
20
+ };
21
+ exports.FilterButtons = FilterButtons;
@@ -36,6 +36,9 @@ declare const translations: {
36
36
  readonly readValues: "Akifilter: unable to read values from storage";
37
37
  readonly writeValues: "Akifilter: unable to persist values";
38
38
  readonly clearValues: "Akifilter: unable to clear stored values";
39
+ readonly readButtons: "Akifilter: unable to read filter buttons from storage";
40
+ readonly writeButtons: "Akifilter: unable to persist filter buttons";
41
+ readonly clearButtons: "Akifilter: unable to clear stored filter buttons";
39
42
  };
40
43
  };
41
44
  };
@@ -1 +1 @@
1
- {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../../src/i18n/translations/en.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCR,CAAC;AAEX,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../../src/i18n/translations/en.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CR,CAAC;AAEX,eAAe,YAAY,CAAC"}
@@ -37,7 +37,10 @@ const translations = {
37
37
  clearVisibility: 'Akifilter: unable to clear visibility state',
38
38
  readValues: 'Akifilter: unable to read values from storage',
39
39
  writeValues: 'Akifilter: unable to persist values',
40
- clearValues: 'Akifilter: unable to clear stored values'
40
+ clearValues: 'Akifilter: unable to clear stored values',
41
+ readButtons: 'Akifilter: unable to read filter buttons from storage',
42
+ writeButtons: 'Akifilter: unable to persist filter buttons',
43
+ clearButtons: 'Akifilter: unable to clear stored filter buttons'
41
44
  }
42
45
  }
43
46
  };
@@ -36,6 +36,9 @@ declare const translations: {
36
36
  readonly readValues: "Akifilter: değerler depodan okunamadı";
37
37
  readonly writeValues: "Akifilter: değerler kalıcı hale getirilemedi";
38
38
  readonly clearValues: "Akifilter: kayıtlı değerler temizlenemedi";
39
+ readonly readButtons: "Akifilter: filtre butonları depodan okunamadı";
40
+ readonly writeButtons: "Akifilter: filtre butonları kalıcı hale getirilemedi";
41
+ readonly clearButtons: "Akifilter: kayıtlı filtre butonları temizlenemedi";
39
42
  };
40
43
  };
41
44
  };
@@ -1 +1 @@
1
- {"version":3,"file":"tr.d.ts","sourceRoot":"","sources":["../../../../src/i18n/translations/tr.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCR,CAAC;AAEX,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"tr.d.ts","sourceRoot":"","sources":["../../../../src/i18n/translations/tr.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CR,CAAC;AAEX,eAAe,YAAY,CAAC"}
@@ -37,7 +37,10 @@ const translations = {
37
37
  clearVisibility: 'Akifilter: görünürlük durumu temizlenemedi',
38
38
  readValues: 'Akifilter: değerler depodan okunamadı',
39
39
  writeValues: 'Akifilter: değerler kalıcı hale getirilemedi',
40
- clearValues: 'Akifilter: kayıtlı değerler temizlenemedi'
40
+ clearValues: 'Akifilter: kayıtlı değerler temizlenemedi',
41
+ readButtons: 'Akifilter: filtre butonları depodan okunamadı',
42
+ writeButtons: 'Akifilter: filtre butonları kalıcı hale getirilemedi',
43
+ clearButtons: 'Akifilter: kayıtlı filtre butonları temizlenemedi'
41
44
  }
42
45
  }
43
46
  };
@@ -1,4 +1,8 @@
1
- .akinon-filter {
1
+ .akinon-filter,
2
+ .akinon-filter *,
3
+ .akinon-filter *::before,
4
+ .akinon-filter *::after {
5
+ box-sizing: border-box;
2
6
  }
3
7
 
4
8
  .akinon-filter__top {
@@ -47,7 +51,7 @@
47
51
  background-color: var(--color-ebonyClay-900);
48
52
  flex: 1;
49
53
  display: flex;
50
- align-items: flex-start;
54
+ align-items: center;
51
55
  border-radius: 5px;
52
56
  padding: 6px 8px;
53
57
  margin-right: 6px;
@@ -58,9 +62,7 @@
58
62
  color: var(--color-white);
59
63
  font-weight: 600;
60
64
  font-size: 13px;
61
- position: relative;
62
65
  white-space: nowrap;
63
- top: 7px;
64
66
  }
65
67
 
66
68
  .akinon-filter__section-header span {
@@ -68,6 +70,36 @@
68
70
  flex: unset !important;
69
71
  }
70
72
 
73
+ .akinon-filter__buttons {
74
+ display: flex;
75
+ align-items: center;
76
+ margin-left: 2px;
77
+ margin-right: 6px;
78
+ }
79
+
80
+ .akinon-filter .akinon-filter__button {
81
+ width: 30px;
82
+ height: 30px;
83
+ padding: 0;
84
+ background-color: var(--color-ebonyClay-960);
85
+ }
86
+
87
+ .akinon-filter .akinon-filter__button--active {
88
+ box-shadow: 0 0 2px 1px var(--color-azure-500);
89
+ }
90
+
91
+ @media (max-width: 640px) {
92
+ .akinon-filter__applied {
93
+ flex-wrap: wrap;
94
+ }
95
+
96
+ .akinon-filter__buttons {
97
+ width: 100%;
98
+ margin-right: 0;
99
+ margin-bottom: 6px;
100
+ }
101
+ }
102
+
71
103
  .akinon-filter__form-grid {
72
104
  display: grid;
73
105
  grid-template-columns: repeat(4, minmax(0, 1fr));
@@ -170,8 +202,6 @@
170
202
  .akinon-filter__applied-empty {
171
203
  color: color(--color-ebonyClay-500);
172
204
  font-size: 12px;
173
- position: relative;
174
- top: 8px;
175
205
  }
176
206
 
177
207
  .akinon-filter__modal-list {